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 #include <stdlib.h>
00077 #include "udanax.h"
00078
00079 #ifndef RESERVED
00080 #define RESERVED -1
00081 #endif
00082
00090 bool
00091 is2dcrum(
00092 typecorecrum *ptr)
00093 {
00094 return ptr->cenftype != GRAN;
00095 }
00096
00104 typecorecrum *
00105 getleftson(
00106 typecuc *ptr)
00107 {
00108 rejuvinateifnotRESERVED((typecorecrum *) ptr);
00109
00110 ptr = (typecuc *) ptr->leftson;
00111 if (ptr)
00112 rejuvinateifnotRESERVED((typecorecrum *) ptr);
00113
00114 return (typecorecrum *) ptr;
00115 }
00116
00124 typecorecrum *
00125 routinegetrightbro(
00126 typecorecrum *ptr)
00127 {
00128 rejuvinateifnotRESERVED((typecorecrum *) ptr);
00129
00130 ptr = ptr->rightbro;
00131 if (ptr)
00132 rejuvinateifnotRESERVED((typecorecrum *) ptr);
00133
00134 return ptr;
00135 }
00136
00144 typecorecrum *
00145 getrightmostbro(
00146 typecorecrum *ptr)
00147 {
00148 typecorecrum *p;
00149
00150 while ((p = getrightbro(ptr)) != 0)
00151 ptr = p;
00152
00153 return ptr;
00154 }
00155
00163 static typecorecrum *
00164 getleftbro(
00165 typecorecrum *ptr)
00166 {
00167 rejuvinateifnotRESERVED(ptr);
00168
00169 if (ptr->isleftmost)
00170 return NULL;
00171
00172 ptr = ptr->leftbroorfather;
00173 if (ptr)
00174 rejuvinateifnotRESERVED((typecorecrum *) ptr);
00175
00176 return ptr;
00177 }
00178
00186 static typecorecrum *
00187 getleftmostbro(
00188 typecorecrum *ptr)
00189 {
00190 typecorecrum *p;
00191
00192 while ((p = getleftbro(ptr)) != 0)
00193 ptr = p;
00194
00195 return ptr;
00196 }
00197
00205 typecuc *
00206 getfather(
00207 typecorecrum *ptr)
00208 {
00209 ptr = getleftmostbro(ptr)->leftbroorfather;
00210 if (ptr)
00211 rejuvinateifnotRESERVED(ptr);
00212
00213 return (typecuc *) ptr;
00214 }
00215
00223 typecuc *
00224 findfullcrum(
00225 typecorecrum *descendant)
00226 {
00227 typecuc *ptr;
00228
00229 for (ptr = (typecuc *) descendant; !isfullcrum((typecorecrum *) ptr); ptr = findfather((typecorecrum *) ptr))
00230 ;
00231
00232 return ptr;
00233 }
00234
00242 bool
00243 isemptyenfilade(
00244 typecuc *ptr)
00245 {
00246 if (!isfullcrum((typecorecrum *) ptr))
00247 return false;
00248
00249 switch (ptr->cenftype) {
00250 case GRAN:
00251 return iszerolock(ptr->cwid.dsas, (unsigned)widsize(ptr->cenftype));
00252 case SPAN:
00253 case POOM:
00254 return iszerolock(ptr->cwid.dsas, (unsigned) widsize(ptr->cenftype)) && iszerolock(ptr->cdsp.dsas, (unsigned) dspsize(ptr->cenftype));
00255 default:
00256 assert(0);
00257 }
00258 return false;
00259 }
00260
00268
00269 typecuc *
00270 functionweakfindfather(
00271 typecorecrum *ptr)
00272 {
00273 if (!ptr)
00274 assert(0);
00275
00276 if (isfullcrum(ptr))
00277 return NULL;
00278
00279 for (; ptr && !ptr->isleftmost; ptr = ptr->leftbroorfather)
00280 ;
00281
00282 if (ptr)
00283 return (typecuc *) ptr->leftbroorfather;
00284 else
00285 return NULL;
00286 }
00287
00295 typecuc *
00296 findfather(
00297 typecorecrum *son)
00298 {
00299 typecuc *ptr;
00300
00301 if ((ptr = weakfindfather(son)) != 0)
00302 rejuvinateifnotRESERVED((typecorecrum *) ptr);
00303
00304 return ptr;
00305 }
00306
00314 typecorecrum *
00315 findleftbro(
00316 typecorecrum *ptr)
00317 {
00318 if (ptr->isleftmost) {
00319 rejuvinateifnotRESERVED(ptr);
00320 return NULL;
00321 }
00322
00323 ptr = ptr->leftbroorfather;
00324 rejuvinateifnotRESERVED(ptr);
00325 return ptr ;
00326 }
00327
00335 typecorecrum *
00336 findleftmostbro(
00337 typecorecrum *ptr)
00338 {
00339 while (!ptr->isleftmost) {
00340 ptr = ptr->leftbroorfather;
00341 rejuvinateifnotRESERVED(ptr);
00342 }
00343 return ptr ;
00344 }
00345
00353 typecorecrum *
00354 weakfindleftmostbro(
00355 typecorecrum *ptr)
00356 {
00357 while (!ptr->isleftmost)
00358 ptr = ptr->leftbroorfather;
00359
00360 return ptr;
00361 }
00362
00370 typecorecrum *
00371 funcfindrightbro(
00372 typecorecrum *ptr)
00373 {
00374 if (!ptr->rightbro) {
00375 rejuvinateifnotRESERVED(ptr);
00376 return NULL;
00377 }
00378
00379 ptr = ptr->rightbro;
00380 rejuvinateifnotRESERVED(ptr);
00381 return ptr;
00382 }
00383
00391 typecorecrum *
00392 weakfindrightbro(
00393 typecorecrum *ptr)
00394 {
00395 if (!ptr->rightbro)
00396 return NULL;
00397
00398 ptr = ptr->rightbro;
00399 return ptr;
00400 }
00401
00409 typecorecrum *
00410 findrightmostbro(
00411 typecorecrum *leftbro)
00412 {
00413 typecorecrum *temp;
00414
00415 for (; leftbro && (temp = findrightbro(leftbro)); leftbro = temp)
00416 ;
00417
00418 rejuvinateifnotRESERVED(leftbro);
00419 return leftbro ;
00420 }
00421
00429 typecorecrum *
00430 findleftson(
00431 typecuc *ptr)
00432 {
00433 if (ptr == NULL)
00434 return NULL;
00435
00436 int oldage = ptr->age;
00437 if (ptr->leftson == NULL) {
00438 if (ptr->sonorigin.diskblocknumber == DISKPTRNULL)
00439 return NULL;
00440
00441 reserve((typecorecrum *) ptr);
00442 if (ptr->sonorigin.diskblocknumber == 0) {
00443 dump((typecorecrum *) ptr);
00444 assert(0);
00445 }
00446 inloaf(ptr);
00447
00448 if (oldage != RESERVED)
00449 rejuvinate((typecorecrum *) ptr);
00450 }
00451 rejuvinateifnotRESERVED(ptr->leftson);
00452 return ptr->leftson;
00453 }
00454
00462 typecorecrum *
00463 findrightmostson(
00464 typecuc *ptr)
00465 {
00466 return findrightmostbro(findleftson(ptr));
00467 }
00468
00476 bool
00477 toomanysons(
00478 typecuc * ptr)
00479 {
00480 if (ptr->height)
00481 findleftson(ptr);
00482
00483 return ptr->numberofsons > (ptr->height > 1 ? MAXUCINLOAF : (is2dcrum((typecorecrum *) ptr) ? MAX2DBCINLOAF : MAXBCINLOAF));
00484 }
00485
00493 bool
00494 toofewsons(
00495 typecuc *ptr)
00496 {
00497 if (ptr->height && !ptr->leftson)
00498 findleftson(ptr);
00499
00500 return ptr->numberofsons < (ptr->height > 1 ? MAXUCINLOAF - 1 : (is2dcrum((typecorecrum *) ptr) ? MAX2DBCINLOAF : MAXBCINLOAF));
00501 }
00502
00510 bool
00511 roomformoresons(
00512 typecuc *ptr)
00513 {
00514 if (ptr->height && !ptr->leftson)
00515 findleftson(ptr);
00516
00517 return ptr->numberofsons < (ptr->height > 1 ? MAXUCINLOAF : (is2dcrum((typecorecrum *) ptr) ? MAX2DBCINLOAF : MAXBCINLOAF));
00518 }
00519
00527 static void
00528 transferloaf(
00529 typecuc *from,
00530 typecuc *to)
00531 {
00532 if (from->height == 0)
00533 return;
00534
00535 if (from->cenftype == SPAN || from->cenftype == POOM) {
00536
00537 }
00538
00539 typecuc *ptr = (typecuc *) findleftson(from);
00540 int nsons = from->numberofsons;
00541 from->numberofsons = 0;
00542 to->numberofsons = nsons;
00543 ptr->leftbroorfather = (typecorecrum *) to;
00544 to->leftson = (typecorecrum *) ptr;
00545 from->leftson = NULL;
00546
00547 }
00548
00556 void
00557 levelpush(
00558 typecuc *fullcrumptr)
00559 {
00560 typecuc *newcuc;
00561 typediskloafptr temploafptr;
00562
00563 #ifndef DISTRIBUTION
00564 L("in levelpush");
00565
00566 #endif
00567
00568 if (!isfullcrum((typecorecrum *) fullcrumptr))
00569 assert(0);
00570
00571 newcuc = (typecuc *) createcrum((int) fullcrumptr->height, (int) fullcrumptr->cenftype);
00572 newcuc->isleftmost = true;
00573
00574 transferloaf(fullcrumptr, newcuc);
00575 temploafptr = fullcrumptr->sonorigin;
00576 fullcrumptr->sonorigin.diskblocknumber = DISKPTRNULL;
00577 fullcrumptr->height++;
00578 adopt((typecorecrum *) newcuc, SON, (typecorecrum *) fullcrumptr);
00579
00580 newcuc->sonorigin = temploafptr;
00581 setwispupwards(newcuc, 1);
00582 ivemodified((typecorecrum *) newcuc);
00583 ivemodified((typecorecrum *) fullcrumptr);
00584
00585 #ifndef DISTRIBUTION
00586 L("leaving levelpush");
00587 #endif
00588 }
00589
00597 void
00598 levelpull(
00599 typecuc *fullcrumptr)
00600 {
00601
00602 return;
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 }
00613
00614
00615
00616
00624 void
00625 disown(
00626 typecorecrum *crumptr)
00627 {
00628 typecuc *father;
00629
00630 if (isfullcrum(crumptr)) {
00631 #ifndef DISTRIBUTION
00632 dump(crumptr);
00633 assert(0);
00634 #else
00635 assert(0);
00636 #endif
00637 }
00638
00639 if (!(father = weakfindfather(crumptr))) {
00640 #ifndef DISTRIBUTION
00641 dump(crumptr);
00642 assert(0);
00643 #else
00644 assert(0);
00645 #endif
00646 }
00647
00648 disownnomodify(crumptr);
00649 ivemodified((typecorecrum *) father);
00650 }
00651
00659 void
00660 disownnomodify(
00661 typecorecrum *crumptr)
00662 {
00663 typecuc *father;
00664 typecorecrum *left, *right;
00665
00666 if (isfullcrum(crumptr)) {
00667 #ifndef DISTRIBUTION
00668 dump(crumptr);
00669 assert(0);
00670 #else
00671 assert(0);
00672 #endif
00673 }
00674
00675 if (!(father = weakfindfather((typecorecrum *) crumptr))) {
00676 #ifndef DISTRIBUTION
00677 dump((typecorecrum *) crumptr);
00678 assert(0);
00679 #else
00680 assert(0);
00681 #endif
00682 }
00683
00684 right = findrightbro(crumptr);
00685 father->numberofsons -= 1;
00686
00687 if (crumptr->isleftmost) {
00688 father->leftson = right;
00689 if (right) {
00690 right->leftbroorfather = (typecorecrum *) father;
00691 right->isleftmost = true;
00692 }
00693 } else {
00694 left = findleftbro(crumptr);
00695 left->rightbro = right;
00696 if (right) {
00697 right->leftbroorfather = left;
00698 }
00699 }
00700 crumptr->leftbroorfather = crumptr->rightbro = NULL;
00701
00702 }
00703
00711
00712
00713
00714 void
00715 adopt(
00716 typecorecrum *newcc,
00717 int relative,
00718 typecorecrum *old)
00719 {
00720 typecuc *father = NULL;
00721 typecorecrum *left = NULL, *right = NULL;
00722
00723 assert(newcc && old);
00724 assert(newcc != old);
00725
00726
00727
00728 newcc->cenftype = old->cenftype;
00729
00730 switch (relative) {
00731 case LEFTMOSTSON:
00732 father = (typecuc *) old;
00733 left = NULL;
00734 right = findleftson(father);
00735 break;
00736
00737 case RIGHTMOSTSON:
00738 father = (typecuc *) old;
00739 if (father->leftson) left = findrightmostson(father);
00740 else left = NULL;
00741 right = NULL;
00742 break;
00743
00744 case RIGHTBRO:
00745 assert(newcc->height == old->height);
00746 left = old;
00747 father = findfather(left);
00748 right = findrightbro(left);
00749 break;
00750
00751 case LEFTBRO:
00752 assert(newcc->height == old->height);
00753 right = old;
00754 father = findfather(right);
00755 left = findleftbro(right);
00756 break;
00757
00758 default:
00759 assert(false);
00760 }
00761
00762 assert(father);
00763 assert(father->height == newcc->height + 1);
00764
00765 if (left) {
00766 left->rightbro = newcc;
00767 newcc->leftbroorfather = left;
00768 newcc->isleftmost = false;
00769 } else {
00770 father->leftson = newcc;
00771 newcc->leftbroorfather = (typecorecrum *) father;
00772 newcc->isleftmost = true;
00773 }
00774
00775 newcc->rightbro = right;
00776 if (right) {
00777 right->leftbroorfather = newcc;
00778 right->isleftmost = false;
00779 }
00780
00781 ++father->numberofsons;
00782 }
00783
00791 void
00792 ivemodified(
00793 typecorecrum *ptr)
00794 {
00795 bool fatherflag;
00796
00797 if (!ptr)
00798 return;
00799
00800 rejuvinateifnotRESERVED(ptr);
00801
00802 fatherflag = true;
00803 while (ptr) {
00804
00805
00806 rejuvinateifnotRESERVED(ptr);
00807 if (fatherflag) {
00808
00809 ptr->modified = true;
00810 }
00811 fatherflag = ptr->isleftmost;
00812 ptr = ptr->leftbroorfather;
00813 }
00814 }