Browse code

track parents

aCaB authored on 2010/01/12 02:37:54
Showing 1 changed files
... ...
@@ -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 */