00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "setup.h"
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028
00029 #include "splay.h"
00030
00031 #define compare(i,j) ((i)-(j))
00032
00033
00034 #define KEY_NOTUSED -1
00035
00036
00037
00038
00039
00040 struct Curl_tree *Curl_splay(int i, struct Curl_tree *t)
00041 {
00042 struct Curl_tree N, *l, *r, *y;
00043 int comp;
00044
00045 if (t == NULL)
00046 return t;
00047 N.smaller = N.larger = NULL;
00048 l = r = &N;
00049
00050 for (;;) {
00051 comp = compare(i, t->key);
00052 if (comp < 0) {
00053 if (t->smaller == NULL)
00054 break;
00055 if (compare(i, t->smaller->key) < 0) {
00056 y = t->smaller;
00057 t->smaller = y->larger;
00058 y->larger = t;
00059 t = y;
00060 if (t->smaller == NULL)
00061 break;
00062 }
00063 r->smaller = t;
00064 r = t;
00065 t = t->smaller;
00066 }
00067 else if (comp > 0) {
00068 if (t->larger == NULL)
00069 break;
00070 if (compare(i, t->larger->key) > 0) {
00071 y = t->larger;
00072 t->larger = y->smaller;
00073 y->smaller = t;
00074 t = y;
00075 if (t->larger == NULL)
00076 break;
00077 }
00078 l->larger = t;
00079 l = t;
00080 t = t->larger;
00081 }
00082 else
00083 break;
00084 }
00085
00086 l->larger = t->smaller;
00087 r->smaller = t->larger;
00088 t->smaller = N.larger;
00089 t->larger = N.smaller;
00090
00091 return t;
00092 }
00093
00094
00095
00096 struct Curl_tree *Curl_splayinsert(int i,
00097 struct Curl_tree *t,
00098 struct Curl_tree *node)
00099 {
00100 if (node == NULL)
00101 return t;
00102
00103 if (t != NULL) {
00104 t = Curl_splay(i,t);
00105 if (compare(i, t->key)==0) {
00106
00107
00108
00109
00110 node->same = t;
00111 node->key = i;
00112 node->smaller = t->smaller;
00113 node->larger = t->larger;
00114
00115 t->smaller = node;
00116
00117
00118
00119 t->key = KEY_NOTUSED;
00120
00121
00122 return node;
00123 }
00124 }
00125
00126 if (t == NULL) {
00127 node->smaller = node->larger = NULL;
00128 }
00129 else if (compare(i, t->key) < 0) {
00130 node->smaller = t->smaller;
00131 node->larger = t;
00132 t->smaller = NULL;
00133
00134 }
00135 else {
00136 node->larger = t->larger;
00137 node->smaller = t;
00138 t->larger = NULL;
00139 }
00140 node->key = i;
00141
00142 node->same = NULL;
00143 return node;
00144 }
00145
00146 #if 0
00147
00148
00149
00150
00151
00152 struct Curl_tree *Curl_splayremove(int i, struct Curl_tree *t,
00153 struct Curl_tree **removed)
00154 {
00155 struct Curl_tree *x;
00156
00157 *removed = NULL;
00158
00159 if (t==NULL)
00160 return NULL;
00161
00162 t = Curl_splay(i,t);
00163 if (compare(i, t->key) == 0) {
00164
00165
00166 if((x = t->same)) {
00167
00168
00169
00170
00171 x->key = t->key;
00172 x->larger = t->larger;
00173 x->smaller = t->smaller;
00174
00175 *removed = t;
00176 return x;
00177 }
00178
00179 if (t->smaller == NULL) {
00180 x = t->larger;
00181 }
00182 else {
00183 x = Curl_splay(i, t->smaller);
00184 x->larger = t->larger;
00185 }
00186 *removed = t;
00187
00188 return x;
00189 }
00190 else
00191 return t;
00192 }
00193 #endif
00194
00195
00196
00197 struct Curl_tree *Curl_splaygetbest(int i, struct Curl_tree *t,
00198 struct Curl_tree **removed)
00199 {
00200 struct Curl_tree *x;
00201
00202 if (!t) {
00203 *removed = NULL;
00204 return NULL;
00205 }
00206
00207 t = Curl_splay(i,t);
00208 if(compare(i, t->key) < 0) {
00209
00210 if(t->smaller)
00211 t=Curl_splay(t->smaller->key, t);
00212 else {
00213
00214 *removed = NULL;
00215 return t;
00216 }
00217 }
00218
00219 if (compare(i, t->key) >= 0) {
00220
00221 x = t->same;
00222 if(x) {
00223
00224
00225
00226
00227 x->key = t->key;
00228 x->larger = t->larger;
00229 x->smaller = t->smaller;
00230
00231 *removed = t;
00232 return x;
00233 }
00234
00235 if (t->smaller == NULL) {
00236 x = t->larger;
00237 }
00238 else {
00239 x = Curl_splay(i, t->smaller);
00240 x->larger = t->larger;
00241 }
00242 *removed = t;
00243
00244 return x;
00245 }
00246 else {
00247 *removed = NULL;
00248 return t;
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 int Curl_splayremovebyaddr(struct Curl_tree *t,
00263 struct Curl_tree *remove,
00264 struct Curl_tree **newroot)
00265 {
00266 struct Curl_tree *x;
00267
00268 if (!t || !remove)
00269 return 1;
00270
00271 if(KEY_NOTUSED == remove->key) {
00272
00273
00274
00275 if (remove->smaller == NULL)
00276 return 3;
00277
00278 remove->smaller->same = remove->same;
00279 if(remove->same)
00280 remove->same->smaller = remove->smaller;
00281
00282
00283 remove->smaller = NULL;
00284
00285
00286 *newroot = t;
00287 return 0;
00288 }
00289
00290 t = Curl_splay(remove->key, t);
00291
00292
00293
00294
00295
00296
00297
00298
00299 if(t != remove)
00300 return 2;
00301
00302
00303
00304 x = t->same;
00305 if(x) {
00306
00307
00308
00309 x->key = t->key;
00310 x->larger = t->larger;
00311 x->smaller = t->smaller;
00312 }
00313 else {
00314
00315 if (t->smaller == NULL)
00316 x = t->larger;
00317 else {
00318 x = Curl_splay(remove->key, t->smaller);
00319 x->larger = t->larger;
00320 }
00321 }
00322
00323 *newroot = x;
00324
00325 return 0;
00326 }
00327
00328 #ifdef CURLDEBUG
00329
00330 void Curl_splayprint(struct Curl_tree * t, int d, char output)
00331 {
00332 struct Curl_tree *node;
00333 int i;
00334 int count;
00335 if (t == NULL)
00336 return;
00337
00338 Curl_splayprint(t->larger, d+1, output);
00339 for (i=0; i<d; i++)
00340 if(output)
00341 printf(" ");
00342
00343 if(output) {
00344 printf("%d[%d]", t->key, i);
00345 }
00346
00347 for(count=0, node = t->same; node; node = node->same, count++)
00348 ;
00349
00350 if(output) {
00351 if(count)
00352 printf(" [%d more]\n", count);
00353 else
00354 printf("\n");
00355 }
00356
00357 Curl_splayprint(t->smaller, d+1, output);
00358 }
00359 #endif
00360
00361 #ifdef TEST_SPLAY
00362
00363
00364 #define MAX 50
00365 #define TEST2
00366
00367
00368
00369 int main(int argc, argv_item_t argv[])
00370 {
00371 struct Curl_tree *root, *t;
00372 void *ptrs[MAX];
00373 int adds=0;
00374 int rc;
00375
00376 long sizes[]={
00377 50, 60, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120, 200, 300,
00378 220, 80, 90, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120, 200,
00379 300, 220, 80, 90, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120,
00380 200, 300, 220, 80, 90};
00381 int i;
00382 root = NULL;
00383
00384 for (i = 0; i < MAX; i++) {
00385 int key;
00386 ptrs[i] = t = (struct Curl_tree *)malloc(sizeof(struct Curl_tree));
00387
00388 #ifdef TEST2
00389 key = sizes[i];
00390 #elif defined(TEST1)
00391 key = (541*i)%1023;
00392 #elif defined(TEST3)
00393 key = 100;
00394 #endif
00395
00396 t->payload = (void *)key;
00397 if(!t) {
00398 puts("out of memory!");
00399 return 0;
00400 }
00401 root = Curl_splayinsert(key, root, t);
00402 }
00403
00404 #if 0
00405 puts("Result:");
00406 Curl_splayprint(root, 0, 1);
00407 #endif
00408
00409 #if 1
00410 for (i = 0; i < MAX; i++) {
00411 int rem = (i+7)%MAX;
00412 struct Curl_tree *r;
00413 printf("Tree look:\n");
00414 Curl_splayprint(root, 0, 1);
00415 printf("remove pointer %d, payload %d\n", rem,
00416 (int)((struct Curl_tree *)ptrs[rem])->payload);
00417 rc = Curl_splayremovebyaddr(root, (struct Curl_tree *)ptrs[rem], &root);
00418 if(rc)
00419
00420 printf("remove %d failed!\n", rem);
00421 }
00422 #endif
00423
00424 return 0;
00425 }
00426
00427 #endif