... | ... |
@@ -232,13 +232,43 @@ static inline int cmp(int64_t *a, int64_t *b) { |
232 | 232 |
return ret; |
233 | 233 |
} |
234 | 234 |
|
235 |
+#ifdef CHECK_TREE |
|
236 |
+static int check_tree_rec(struct cache_set *cs, unsigned int *beenthere, struct node *node, struct node *parent) { |
|
237 |
+ unsigned int item = node - cs->data; |
|
238 |
+ if(!node) return 0; |
|
239 |
+ if(beenthere[item]) return 1; |
|
240 |
+ beenthere[item] = 1; |
|
241 |
+ if(node->up != parent) return 1; |
|
242 |
+ return check_tree_rec(cs, beenthere, node->left, node) | check_tree_rec(cs, beenthere, node->right, node); |
|
243 |
+} |
|
244 |
+ |
|
245 |
+static void check_tree(struct cache_set *cs) { |
|
246 |
+ unsigned int i, been_there[1024]; |
|
247 |
+ memset(been_there, 0, sizeof(been_there)); |
|
248 |
+ if(check_tree_rec(cs, been_there, cs->root, NULL)) { |
|
249 |
+ cli_errmsg("tree fukkd up\n"); |
|
250 |
+ abort(); |
|
251 |
+ } |
|
252 |
+ for(i=0; i<cs->used; i++) { |
|
253 |
+ if(!been_there[i]) { |
|
254 |
+ cli_errmsg("tree fukkd up\n"); |
|
255 |
+ abort(); |
|
256 |
+ } |
|
257 |
+ } |
|
258 |
+} |
|
259 |
+#else |
|
260 |
+#define check_tree(a) |
|
261 |
+#endif |
|
262 |
+ |
|
235 | 263 |
static int splay(int64_t *md5, struct cache_set *cs) { |
236 |
- struct node next = {{0, 0}, NULL, NULL, 0}, *right = &next, *left = &next, *temp, *root = cs->root; |
|
264 |
+ struct node next = {{0, 0}, NULL, NULL, NULL, 0}, *right = &next, *left = &next, *temp, *root = cs->root; |
|
237 | 265 |
int ret = 0; |
238 | 266 |
|
239 | 267 |
if(!root) |
240 | 268 |
return 0; |
241 | 269 |
|
270 |
+ check_tree(cs); |
|
271 |
+ |
|
242 | 272 |
while(1) { |
243 | 273 |
int comp = cmp(md5, root->digest); |
244 | 274 |
if(comp < 0) { |
... | ... |
@@ -246,11 +276,14 @@ static int splay(int64_t *md5, struct cache_set *cs) { |
246 | 246 |
if(cmp(md5, root->left->digest) < 0) { |
247 | 247 |
temp = root->left; |
248 | 248 |
root->left = temp->right; |
249 |
+ if(temp->right) temp->right->up = root; |
|
249 | 250 |
temp->right = root; |
251 |
+ root->up = temp; |
|
250 | 252 |
root = temp; |
251 | 253 |
if(!root->left) break; |
252 | 254 |
} |
253 | 255 |
right->left = root; |
256 |
+ root->up = right; |
|
254 | 257 |
right = root; |
255 | 258 |
root = root->left; |
256 | 259 |
} else if(comp > 0) { |
... | ... |
@@ -258,11 +291,14 @@ static int splay(int64_t *md5, struct cache_set *cs) { |
258 | 258 |
if(cmp(md5, root->right->digest) > 0) { |
259 | 259 |
temp = root->right; |
260 | 260 |
root->right = temp->left; |
261 |
+ if(temp->left) temp->left->up = root; |
|
261 | 262 |
temp->left = root; |
263 |
+ root->up = temp; |
|
262 | 264 |
root = temp; |
263 | 265 |
if(!root->right) break; |
264 | 266 |
} |
265 | 267 |
left->right = root; |
268 |
+ root->up = left; |
|
266 | 269 |
left = root; |
267 | 270 |
root = root->right; |
268 | 271 |
} else { |
... | ... |
@@ -272,10 +308,17 @@ static int splay(int64_t *md5, struct cache_set *cs) { |
272 | 272 |
} |
273 | 273 |
|
274 | 274 |
left->right = root->left; |
275 |
+ if(root->left) root->left->up = left; |
|
275 | 276 |
right->left = root->right; |
277 |
+ if(root->right) root->right->up = right; |
|
276 | 278 |
root->left = next.right; |
279 |
+ if(next.right) next.right->up = root; |
|
277 | 280 |
root->right = next.left; |
281 |
+ if(next.left) next.left->up = root; |
|
282 |
+ root->up = NULL; |
|
278 | 283 |
cs->root = root; |
284 |
+ |
|
285 |
+ check_tree(cs); |
|
279 | 286 |
return ret; |
280 | 287 |
} |
281 | 288 |
|
... | ... |
@@ -287,24 +330,6 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size |
287 | 287 |
return splay(hash, cs) * 1337; |
288 | 288 |
} |
289 | 289 |
|
290 |
-static int get_worst(struct node *n, struct node *parent, struct node **worst, struct node **wparent) { |
|
291 |
- unsigned int left, right; |
|
292 |
- struct node *wl = n, *wr = n, *pl = parent, *pr = parent; |
|
293 |
- |
|
294 |
- if(!n) return 0; |
|
295 |
- left = get_worst(n->left, n, &wl, &pl); |
|
296 |
- right = get_worst(n->right, n, &wr, &pr); |
|
297 |
- |
|
298 |
- if(left < right) { |
|
299 |
- *worst = wr; |
|
300 |
- *wparent = pr; |
|
301 |
- return right + 1; |
|
302 |
- } |
|
303 |
- *worst = wl; |
|
304 |
- *wparent = pl; |
|
305 |
- return left +1; |
|
306 |
-} |
|
307 |
- |
|
308 | 290 |
static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size) { |
309 | 291 |
struct node *newnode; |
310 | 292 |
int64_t hash[2]; |
... | ... |
@@ -315,7 +340,20 @@ static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size) |
315 | 315 |
|
316 | 316 |
if(cs->used == cs->total) { |
317 | 317 |
struct node *parent; |
318 |
- get_worst(cs->root, NULL, &newnode, &parent); |
|
318 |
+ int nodeno, bestnode, parents = 0; |
|
319 |
+ for(nodeno = 0; nodeno < cs->total; nodeno++) { |
|
320 |
+ parent = &cs->data[nodeno]; |
|
321 |
+ if(!parent->left && !parent->right) { |
|
322 |
+ int p=0; |
|
323 |
+ do{ p++; } while(parent = parent->up); |
|
324 |
+ if(p>=parents) { |
|
325 |
+ parents = p; |
|
326 |
+ bestnode = nodeno; |
|
327 |
+ } |
|
328 |
+ } |
|
329 |
+ } |
|
330 |
+ newnode=&cs->data[bestnode]; |
|
331 |
+ parent = newnode->up; |
|
319 | 332 |
if(parent->left == newnode) |
320 | 333 |
parent->left = NULL; |
321 | 334 |
else |
... | ... |
@@ -326,17 +364,22 @@ static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size) |
326 | 326 |
if(!cs->root) { |
327 | 327 |
newnode->left = NULL; |
328 | 328 |
newnode->right = NULL; |
329 |
- } else if(cmp(hash, cs->root->digest)) { |
|
330 |
- newnode->left = cs->root->left; |
|
331 |
- newnode->right = cs->root; |
|
332 |
- cs->root->left = NULL; |
|
333 | 329 |
} else { |
334 |
- newnode->right = cs->root->right; |
|
335 |
- newnode->left = cs->root; |
|
336 |
- cs->root->right = NULL; |
|
330 |
+ if(cmp(hash, cs->root->digest)) { |
|
331 |
+ newnode->left = cs->root->left; |
|
332 |
+ newnode->right = cs->root; |
|
333 |
+ cs->root->left = NULL; |
|
334 |
+ } else { |
|
335 |
+ newnode->right = cs->root->right; |
|
336 |
+ newnode->left = cs->root; |
|
337 |
+ cs->root->right = NULL; |
|
338 |
+ } |
|
339 |
+ if(newnode->left) newnode->left->up = newnode; |
|
340 |
+ if(newnode->right) newnode->right->up = newnode; |
|
337 | 341 |
} |
338 | 342 |
newnode->digest[0] = hash[0]; |
339 | 343 |
newnode->digest[1] = hash[1]; |
344 |
+ newnode->up = NULL; |
|
340 | 345 |
cs->root = newnode; |
341 | 346 |
} |
342 | 347 |
#endif /* USE_SPLAY */ |