00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #include <memory.h>
00082 #include "udanax.h"
00083
00084
00085 long noishouldbother = 0;
00086 long notakenephewnd = 0;
00087 long noeatbrosnd = 0;
00088
00089
00090
00098 static void
00099 takeovernephewsseq(
00100 typecorecrum *me)
00101 {
00102 typecuc *ptr;
00103 typecorecrum *next;
00104
00105 for (ptr = (typecuc *) getleftson((typecuc *) routinegetrightbro(me)); ptr && roomformoresons((typecuc *) me); ptr = (typecuc *) next) {
00106 next = (typecorecrum *) routinegetrightbro((typecorecrum *) ptr);
00107 if (ptr->age == RESERVED)
00108 continue;
00109 disown((typecorecrum *) ptr);
00110 adopt((typecorecrum *) ptr, RIGHTMOSTSON, me);
00111 ivemodified((typecorecrum *) ptr);
00112 }
00113 setwispupwards((typecuc *) getrightbro(me), 0);
00114 setwispupwards((typecuc *) me, 1);
00115 }
00116
00124 static void
00125 eatbrossubtreeseq(
00126 typecuc *me)
00127 {
00128 typecuc *bro;
00129
00130 bro = (typecuc *) getrightbro((typecorecrum *) me);
00131 getleftson(bro)->leftbroorfather = getrightmostbro(getleftson(me));
00132 getrightmostbro(getleftson(me))->rightbro = bro->leftson;
00133 bro->leftson->isleftmost = false;
00134
00135 me->numberofsons += bro->numberofsons;
00136 disown((typecorecrum *) bro);
00137 freecrum((typecorecrum *) bro);
00138 setwispupwards(me, 1);
00139 }
00140
00148 static void
00149 fixdspsofbroschildren(
00150 typecuc *me,
00151 typecuc *bro)
00152 {
00153 typecorecrum *nephew;
00154
00155 for (nephew = getleftson(bro); nephew; nephew = (typecorecrum *) getrightbro(nephew)) {
00156 dspadd(&bro->cdsp, &nephew->cdsp, &nephew->cdsp, me->cenftype);
00157 dspsub(&nephew->cdsp, &me->cdsp, &nephew->cdsp, me->cenftype);
00158 ivemodified(nephew);
00159 }
00160 }
00161
00169 static void
00170 eatbrossubtreend(
00171 typecuc *me,
00172 typecuc *bro)
00173 {
00174 typedsp offset, grasp;
00175 typecuc *oldfather;
00176 typecorecrum *son;
00177
00178 ++noeatbrosnd;
00179 reserve((typecorecrum *) bro);
00180 clear(&offset, sizeof(offset));
00181
00182 makeroomonleftnd(me, &offset, &bro->cdsp, &grasp);
00183 fixdspsofbroschildren(me, bro);
00184 getleftson(bro)->leftbroorfather = getrightmostbro(getleftson(me));
00185 getrightmostbro(getleftson(me))->rightbro = getleftson(bro);
00186 bro->leftson->isleftmost = false;
00187
00188 me->numberofsons += bro->numberofsons;
00189 for (son = findleftson(me); son; son = findrightbro(son))
00190 setwisp(son);
00191
00192 oldfather = (typecuc *) findfather((typecorecrum *) bro);
00193 rejuvinate((typecorecrum *) bro);
00194 disown((typecorecrum *) bro);
00195 freecrum((typecorecrum *) bro);
00196 setwispupwards(me, 0);
00197 setwispupwards(oldfather, 1);
00198 ivemodified((typecorecrum *) me);
00199
00200 }
00201
00209 static void
00210 takenephewnd(
00211 typecuc *me,
00212 typecuc *nephew)
00213 {
00214 typedsp nephewsgrasp, grasp, offset;
00215
00216 ++notakenephewnd;
00217
00218 typecuc *bro = (typecuc *) getfather((typecorecrum *) nephew);
00219 disown((typecorecrum *) nephew);
00220 dspadd(&bro->cdsp, &nephew->cdsp, &nephew->cdsp, bro->cenftype);
00221 adopt((typecorecrum *) nephew, RIGHTMOSTSON, (typecorecrum *) me);
00222 prologuend((typecorecrum *) nephew, &bro->cdsp, &nephewsgrasp, (typedsp *) NULL);
00223
00224 makeroomonleftnd(me, &offset, &nephew->cdsp, &grasp);
00225 dspsub(&nephew->cdsp, &me->cdsp, &nephew->cdsp, me->cenftype);
00226
00227 if (!bro->numberofsons) {
00228 disown((typecorecrum *) bro);
00229 freecrum((typecorecrum *) bro);
00230 } else {
00231 setwispupwards(bro, 0);
00232 }
00233
00234 ivemodified((typecorecrum *) nephew);
00235 setwispupwards(me, 1);
00236 }
00237
00245 static void
00246 shellsort(
00247 typecorecrum *v[],
00248 int n)
00249 {
00250 typecorecrum *temp;
00251 int gap, i, j;
00252
00253 Tumbler tarray[100], *tarrayp[100], *temptp;
00254
00255 if (n > 100)
00256 assert(0);
00257
00258 for (i = 0; i < n; i++) {
00259
00260 tumbleradd(&v[i]->cdsp.dsas[0], &v[i]->cdsp.dsas[1], &tarray[i]);
00261 tarrayp[i] = &tarray[i];
00262 }
00263 for (gap = n / 2; gap > 0; gap /= 2)
00264 for (i = gap; i < n; i++)
00265 for (j = i - gap; j >= 0 && tumblercmp(tarrayp[j], tarrayp[j + gap]) == GREATER; j -= gap) {
00266 temp = v[j];
00267 temptp = tarrayp[j];
00268 v[j] = v[j + gap];
00269 tarrayp[j] = tarrayp[j + gap];
00270 v[j + gap] = temp;
00271 tarrayp[j + gap] = temptp;
00272 }
00273 }
00274
00282 static void
00283 getorderedsons(
00284 typecuc *father,
00285 typecorecrum *sons[])
00286 {
00287 typecorecrum *ptr;
00288 int i;
00289
00290 sons[0] = NULL;
00291 for (ptr = getleftson(father), i = 0; ptr; ptr = (typecorecrum *) getrightbro(ptr))
00292 sons[i++] = ptr;
00293 sons[i] = NULL;
00294 shellsort(sons, i);
00295 }
00296
00304 static bool
00305 takeovernephewsnd(
00306 typecuc **meptr,
00307 typecuc **broptr)
00308 {
00309 typecorecrum *sons[MAXUCINLOAF], *ptr;
00310 int i, n;
00311
00312 typecuc *me = *meptr;
00313 typecuc *bro = *broptr;
00314
00315 if (!me->leftson || !bro->leftson)
00316 return false;
00317
00318 bool ret = false;
00319 if (me->numberofsons + bro->numberofsons <= MAXUCINLOAF) {
00320 eatbrossubtreend(me, bro);
00321 *broptr = NULL;
00322 return true;
00323
00324 } else {
00325 getorderedsons(bro, sons);
00326 findleftson(bro);
00327 n = bro->numberofsons;
00328 for (i = 0; i < n && roomformoresons(me); i++) {
00329 ptr = sons[i];
00330 takenephewnd(me, (typecuc *) ptr);
00331
00332 ret = true;
00333 }
00334 }
00335
00336 if (bro->numberofsons)
00337 setwispupwards(bro, 0);
00338 else {
00339 disown((typecorecrum *) bro);
00340 freecrum((typecorecrum *) bro);
00341 *broptr = NULL;
00342 }
00343
00344 setwispupwards(me, 1);
00345 return ret;
00346 }
00347
00355 static void
00356 recombineseq(
00357 typecuc *father)
00358 {
00360 typecuc *ptr;
00361
00362 if (father->height < 3 || !father->modified)
00363 return;
00364
00365 if (!roomformoresons(father))
00366 return;
00367
00368 for (ptr = (typecuc *) getleftson(father); ptr; ptr = (typecuc *) macrogetrightbro((typecorecrum *) ptr))
00369 recombineseq(ptr);
00370
00371 for (ptr = (typecuc *) getleftson(father); ptr && ptr->rightbro; ptr = (typecuc *) macrogetrightbro((typecorecrum *) ptr)) {
00372 if (ptr->age == RESERVED)
00373 continue;
00374
00375 if (ptr->leftson && roomformoresons(ptr)) {
00376
00377 if (((typecuc *) ptr->rightbro)->leftson) {
00378 if (ptr->numberofsons + ((typecuc *) ptr->rightbro)->numberofsons <= MAXUCINLOAF) {
00379 eatbrossubtreeseq(ptr);
00380 break;
00381 } else {
00382 takeovernephewsseq((typecorecrum *) ptr);
00383 break;
00384 }
00385 }
00386 }
00387 }
00388 if (father->isapex)
00389 levelpull(father);
00390 }
00391
00392
00393
00401 static void
00402 recombinend(
00403 typecuc *father)
00404 {
00405
00406 typecorecrum *ptr;
00407 typecorecrum *sons[MAXUCINLOAF];
00408 int i, j, n;
00409
00410 if (father->height < 2 || !father->modified)
00411 return;
00412
00413 for (ptr = getleftson(father); ptr; ptr = (typecorecrum *) getrightbro(ptr))
00414 recombinend((typecuc *) ptr);
00415
00416 getorderedsons(father, sons);
00417 n = father->numberofsons;
00418 for (i = 0; i < n - 1; i++) {
00419 for (j = i + 1; sons[i] && j < n; j++) {
00420 if (i != j && sons[j] && ishouldbother((typecuc *) sons[i], (typecuc *) sons[j])) {
00421 takeovernephewsnd((typecuc **) &sons[i], (typecuc **) &sons[j]);
00422
00423
00424 }
00425 }
00426 }
00427 if (father->isapex)
00428 levelpull(father);
00429 }
00430
00438 void
00439 recombine(
00440 typecuc *father)
00441 {
00442 switch (father->cenftype) {
00443 case GRAN: recombineseq(father); break;
00444 case SPAN: recombinend(father); break;
00445 case POOM: recombinend(father); break;
00446 }
00447 }
00448
00456 static bool
00457 randomness(
00458 float probability)
00459 {
00460
00461
00462 return true;
00463
00464
00465
00466 }
00467
00475 bool
00476 ishouldbother(
00477 typecuc *dest,
00478 typecuc *src)
00479 {
00480 ++noishouldbother;
00481
00482 if (src->numberofsons == 0) {
00483 if (src->sonorigin.diskblocknumber == DISKPTRNULL)
00484 check(src);
00485 else
00486 return false;
00487 }
00488
00489 if (dest->age == RESERVED || src->age == RESERVED)
00490 return false;
00491
00492 return dest->numberofsons + src->numberofsons <= (dest->height > 1 ? MAXUCINLOAF : MAX2DBCINLOAF) && randomness(.3);
00493 }
00494
00502 int
00503 comparecrumsdiagonally(
00504 typecorecrum *a,
00505 typecorecrum *b)
00506 {
00507 Tumbler amagnitude, bmagnitude;
00508
00509 tumbleradd(&a->cdsp.dsas[0], &a->cdsp.dsas[1], &amagnitude);
00510 tumbleradd(&b->cdsp.dsas[0], &b->cdsp.dsas[1], &bmagnitude);
00511 return (tumblercmp(&amagnitude, &bmagnitude));
00512 }
00513
00521 void
00522 fixincoresubtreewids(
00523 typecuc *ptr)
00524 {
00525 typecorecrum *son;
00526
00527 if (ptr->height == 0)
00528 return;
00529
00530 for (son = (typecorecrum *) getleftson(ptr); son; son = (typecorecrum *) getrightbro(son))
00531 fixincoresubtreewids((typecuc *) son);
00532
00533 if (setwisp((typecorecrum *) ptr)) {
00534 #ifndef DISTRIBUTION
00535 L("fixing %x \n", (int) ptr);
00536 #endif
00537 }
00538 }