allow ARL to cleanup periodically
Costa Tsaousis (ktsaou) committed
Jan 20, 2017 at 10:23 UTC
c41fea03077803977dec24d94a26c5425da07806
2 files changed
+45
-7
src/adaptive_resortable_list.c
+30
-7
@@ -51,14 +51,17 @@ void arl_begin(ARL_BASE *base) {
51
ARL_ENTRY *e;
52
53
/*
54
- info("iteration %zu, expected %zu, wanted %zu, allocated %zu, relinkings %zu, found %zu, added %zu"
54
+ info("iteration %zu, expected %zu, wanted %zu, allocated %zu, fred %zu, relinkings %zu, found %zu, added %zu, fast %zu, slow %zu"
55
, base->iteration
56
, base->expected
57
, base->wanted
58
, base->allocated
59
+ , base->fred
60
, base->relinkings
61
, base->found
62
, base->added
63
+ , base->fast
64
+ , base->slow
65
);
66
for(e = base->head; e ; e = e->next) fprintf(stderr, "%s ", e->name);
67
fprintf(stderr, "\n");
@@ -67,9 +70,29 @@ void arl_begin(ARL_BASE *base) {
70
if(unlikely(base->added || base->iteration % base->rechecks) == 1) {
71
base->added = 0;
72
base->wanted = 0;
70
- for(e = base->head; e ; e = e->next)
71
- if(e->flags & ARL_ENTRY_FLAG_FOUND && e->flags & ARL_ENTRY_FLAG_EXPECTED)
72
- base->wanted++;
73
+ for(e = base->head; e ; e = e->next) {
74
+ if(e->flags & ARL_ENTRY_FLAG_FOUND) {
75
+
76
+ // remove the found flag
77
+ e->flags &= ~ARL_ENTRY_FLAG_FOUND;
78
+
79
+ // count it in wanted
80
+ if(e->flags & ARL_ENTRY_FLAG_EXPECTED)
81
+ base->wanted++;
82
+ }
83
+ else if(e->flags & ARL_ENTRY_FLAG_DYNAMIC) {
84
+ // we can remove this entry
85
+ // it is not found, and it was created because
86
+ // it was found in the source file
87
+ if(e->next) e->next->prev = e->prev;
88
+ if(e->prev) e->prev->next = e->next;
89
+ if(base->head == e) base->head = e->next;
90
+ freez(e->name);
91
+ freez(e);
92
+
93
+ base->fred++;
94
+ }
95
+ }
96
}
97
98
base->iteration++;
@@ -152,15 +175,15 @@ int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, uint32_t hash,
175
e->prev = base->next_keyword->prev;
176
base->next_keyword->prev = e;
177
178
+ if(e->prev)
179
+ e->prev->next = e;
180
+
181
if(base->head == base->next_keyword)
182
base->head = e;
183
}
184
else
185
e->prev = NULL;
186
161
- if(e->prev)
162
- e->prev->next = e;
163
-
187
base->next_keyword = e->next;
188
if(unlikely(!base->next_keyword))
189
base->next_keyword = base->head;
src/adaptive_resortable_list.h
+15
@@ -63,7 +63,9 @@ typedef struct arl_base {
63
// i.e. the number of keywords found and expected
64
65
size_t relinkings; // the number of relinkings we have made so far
66
+
67
size_t allocated; // the number of keywords allocated
68
+ size_t fred; // the number of keywords cleaned up
69
70
size_t rechecks; // the number of iterations between re-checks of the
71
// wanted number of keywords
@@ -74,6 +76,11 @@ typedef struct arl_base {
76
// this is only needed to detect new lines have
77
// been added to the file, over time.
78
79
+#ifdef NETDATA_INTERNAL_CHECKS
80
+ size_t fast; // the number of times we have taken the fast path
81
+ size_t slow; // the number of times we have taken the slow path
82
+#endif
83
+
84
// the processor to do the job
85
void (*processor)(const char *name, uint32_t hash, const char *value, void *dst);
86
@@ -114,6 +121,10 @@ static inline int arl_check(ARL_BASE *base, const char *keyword, const char *val
121
if(likely(hash == e->hash && !strcmp(keyword, e->name))) {
122
// it is
123
124
+#ifdef NETDATA_INTERNAL_CHECKS
125
+ base->fast++;
126
+#endif
127
+
128
e->flags |= ARL_ENTRY_FLAG_FOUND;
129
130
// execute the processor
@@ -134,6 +145,10 @@ static inline int arl_check(ARL_BASE *base, const char *keyword, const char *val
145
return 0;
146
}
147
148
+#ifdef NETDATA_INTERNAL_CHECKS
149
+ base->slow++;
150
+#endif
151
+
152
// we read from source, a not-expected keyword
153
return arl_find_or_create_and_relink(base, keyword, hash, value);
154
}