]> arthur.barton.de Git - netdata.git/commitdiff
allow ARL to cleanup periodically
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Fri, 20 Jan 2017 08:23:33 +0000 (10:23 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Fri, 20 Jan 2017 08:23:33 +0000 (10:23 +0200)
src/adaptive_resortable_list.c
src/adaptive_resortable_list.h

index 2010650cae29dac849bb5a4ca9abeb95268b77cb..3f7f7c193dcde83084c3691a36f1873d36bd5b1c 100644 (file)
@@ -51,14 +51,17 @@ void arl_begin(ARL_BASE *base) {
     ARL_ENTRY *e;
 
     /*
-    info("iteration %zu, expected %zu, wanted %zu, allocated %zu, relinkings %zu, found %zu, added %zu"
+    info("iteration %zu, expected %zu, wanted %zu, allocated %zu, fred %zu, relinkings %zu, found %zu, added %zu, fast %zu, slow %zu"
          , base->iteration
          , base->expected
          , base->wanted
          , base->allocated
+         , base->fred
          , base->relinkings
          , base->found
          , base->added
+         , base->fast
+         , base->slow
     );
     for(e = base->head; e ; e = e->next) fprintf(stderr, "%s ", e->name);
     fprintf(stderr, "\n");
@@ -67,9 +70,29 @@ void arl_begin(ARL_BASE *base) {
     if(unlikely(base->added || base->iteration % base->rechecks) == 1) {
         base->added = 0;
         base->wanted = 0;
-        for(e = base->head; e ; e = e->next)
-            if(e->flags & ARL_ENTRY_FLAG_FOUND && e->flags & ARL_ENTRY_FLAG_EXPECTED)
-                base->wanted++;
+        for(e = base->head; e ; e = e->next) {
+            if(e->flags & ARL_ENTRY_FLAG_FOUND) {
+
+                // remove the found flag
+                e->flags &= ~ARL_ENTRY_FLAG_FOUND;
+
+                // count it in wanted
+                if(e->flags & ARL_ENTRY_FLAG_EXPECTED)
+                    base->wanted++;
+            }
+            else if(e->flags & ARL_ENTRY_FLAG_DYNAMIC) {
+                // we can remove this entry
+                // it is not found, and it was created because
+                // it was found in the source file
+                if(e->next) e->next->prev = e->prev;
+                if(e->prev) e->prev->next = e->next;
+                if(base->head == e) base->head = e->next;
+                freez(e->name);
+                freez(e);
+
+                base->fred++;
+            }
+        }
     }
 
     base->iteration++;
@@ -152,15 +175,15 @@ int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, uint32_t hash,
         e->prev = base->next_keyword->prev;
         base->next_keyword->prev = e;
 
+        if(e->prev)
+            e->prev->next = e;
+
         if(base->head == base->next_keyword)
             base->head = e;
     }
     else
         e->prev = NULL;
 
-    if(e->prev)
-        e->prev->next = e;
-
     base->next_keyword = e->next;
     if(unlikely(!base->next_keyword))
         base->next_keyword = base->head;
index ccd92b9b2791cb34753575a27dca8f2b9ef342ef..157e1f5e72f73719b346afda7cc0859cfc1c4320 100644 (file)
@@ -63,7 +63,9 @@ typedef struct arl_base {
                         // i.e. the number of keywords found and expected
 
     size_t relinkings;  // the number of relinkings we have made so far
+
     size_t allocated;   // the number of keywords allocated
+    size_t fred;        // the number of keywords cleaned up
 
     size_t rechecks;    // the number of iterations between re-checks of the
                         // wanted number of keywords
@@ -74,6 +76,11 @@ typedef struct arl_base {
                         // this is only needed to detect new lines have
                         // been added to the file, over time.
 
+#ifdef NETDATA_INTERNAL_CHECKS
+    size_t fast;        // the number of times we have taken the fast path
+    size_t slow;        // the number of times we have taken the slow path
+#endif
+
     // the processor to do the job
     void (*processor)(const char *name, uint32_t hash, const char *value, void *dst);
 
@@ -114,6 +121,10 @@ static inline int arl_check(ARL_BASE *base, const char *keyword, const char *val
     if(likely(hash == e->hash && !strcmp(keyword, e->name))) {
         // it is
 
+#ifdef NETDATA_INTERNAL_CHECKS
+        base->fast++;
+#endif
+
         e->flags |= ARL_ENTRY_FLAG_FOUND;
 
         // execute the processor
@@ -134,6 +145,10 @@ static inline int arl_check(ARL_BASE *base, const char *keyword, const char *val
         return 0;
     }
 
+#ifdef NETDATA_INTERNAL_CHECKS
+    base->slow++;
+#endif
+
     // we read from source, a not-expected keyword
     return arl_find_or_create_and_relink(base, keyword, hash, value);
 }