Revision: 14368
Author: adrian.chadd
Date: Fri Nov 13 00:29:21 2009
Log: Add the client db entries into a linked list and walk -that- when  
removing radix entries

The radix tree implementation may remove and shuffle around nodes during a
radix_remove() call. This means that keeping pointers to radix_node_t's  
around
after a call to radix_remove() is not allowed.

Instead, use a dlink_list as well and walk that when determining which  
nodes need
to be removed.

This adds a radix lookup for each node being removed. Not a big deal.


http://code.google.com/p/lusca-cache/source/detail?r=14368

Modified:
  /branches/LUSCA_HEAD/src/client_db.c

=======================================
--- /branches/LUSCA_HEAD/src/client_db.c        Wed Nov  4 15:05:00 2009
+++ /branches/LUSCA_HEAD/src/client_db.c        Fri Nov 13 00:29:21 2009
@@ -37,10 +37,12 @@

  #include "../libcore/radix.h"

-#define        CLIENT_DB_SCHEDULE_TIME 30
+#define        CLIENT_DB_SCHEDULE_BACKGROUND_TIME      5
+#define        CLIENT_DB_SCHEDULE_IMMEDIATE_TIME       5

  struct _ClientInfo {
      struct in_addr addr;
+    dlink_node node;
      struct {
          int result_hist[LOG_TYPE_MAX];
          int n_requests;
@@ -60,6 +62,7 @@
  typedef struct _ClientInfo ClientInfo;

  static radix_tree_t *client_tree = NULL;
+dlink_list client_list;

  static ClientInfo *clientdbAdd(struct in_addr addr);
  static void clientdbStartGC(void);
@@ -84,10 +87,11 @@
      c->addr = addr;
      rn = radix_lookup(client_tree, &p);
      rn->data = c;
+    dlinkAddTail(c, &c->node, &client_list);
      statCounter.client_http.clients++;
      if ((statCounter.client_http.clients > max_clients)  
&& !cleanup_running && !cleanup_scheduled) {
        cleanup_scheduled = 1;
-       eventAdd("client_db garbage collector", clientdbScheduledGC, NULL, 90, 
0);
+       eventAdd("client_db garbage collector", clientdbScheduledGC, NULL,  
CLIENT_DB_SCHEDULE_IMMEDIATE_TIME, 0);
      }
      return c;
  }
@@ -96,7 +100,7 @@
  clientdbInitMem(void)
  {
      pool_client_info = memPoolCreate("ClientInfo", sizeof(ClientInfo));
-    eventAdd("client_db garbage collector", clientdbScheduledGC, NULL,  
CLIENT_DB_SCHEDULE_TIME, 0);
+    eventAdd("client_db garbage collector", clientdbScheduledGC, NULL,  
CLIENT_DB_SCHEDULE_BACKGROUND_TIME, 0);
  }

  void
@@ -291,6 +295,7 @@
  static void
  clientdbFreeItem(ClientInfo *c)
  {
+    dlinkDelete(&c->node, &client_list);
      memPoolFree(pool_client_info, c);
  }

@@ -321,48 +326,40 @@
  clientdbGC(void *unused)
  {
      radix_node_t *rn;
-    Stack items;
-
-    stackInit(&items);
-
-    RADIX_WALK(client_tree->head, rn) {
-      ClientInfo *c = rn->data;
+    dlink_node *n = client_list.head;
+    prefix_t p;
+
+    while (n != NULL) {
+      ClientInfo *c = n->data;
+      n = n->next;
        int age = squid_curtime - c->last_seen;
        if (c->n_established)
-          goto next;
+          continue;
        if (age < 24 * 3600 && c->Http.n_requests > 100)
-          goto next;
+          continue;
        if (age < 4 * 3600 && (c->Http.n_requests > 10 || c->Icp.n_requests  
> 10))
-          goto next;
+          continue;
        if (age < 5 * 60 && (c->Http.n_requests > 1 || c->Icp.n_requests >  
1))
-          goto next;
+          continue;
        if (age < 60)
-          goto next;
-
-      /* remove the item from the tree */
-      /* XXX it may not be possible to delete an item from the tree whilst  
walking it! */
-      stackPush(&items, rn);
+          continue;
+
+      Init_Prefix(&p, AF_INET, &c->addr, 32);
+      rn = radix_search_exact(client_tree, &p);
+      rn->data = NULL;
+      radix_remove(client_tree, rn);
+      clientdbFreeItem(c);
+
        cleanup_removed++;
-next:
-      (void) 0;
-
-    } RADIX_WALK_END;
+      statCounter.client_http.clients--;
+    }

      if (!cleanup_scheduled) {
          cleanup_scheduled = 1;
-        eventAdd("client_db garbage collector", clientdbScheduledGC, NULL,  
CLIENT_DB_SCHEDULE_TIME, 0);
+        eventAdd("client_db garbage collector", clientdbScheduledGC, NULL,  
CLIENT_DB_SCHEDULE_IMMEDIATE_TIME, 0);
      }

-    while ( (rn = stackPop(&items)) != NULL) {
-      ClientInfo *c = rn->data;
-      rn->data = NULL;
-      radix_remove(client_tree, rn);
-      clientdbFreeItem(c);
-      statCounter.client_http.clients--;
-      cleanup_removed++;
-    }
      debug(49, 2) ("clientdbGC: Removed %d entries\n", cleanup_removed);
-    stackClean(&items);
  }

  static void

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"lusca-commit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/lusca-commit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to