libsrc/genf.cxx

Go to the documentation of this file.
00001 /**********************************************************************
00002  * Copyright 2002 Jeff Rush <jrush@taupro.com>
00003  * Original Copyright 1979-2002 Udanax.com
00004  *
00005  * This file is part of the Udanax xanalogical storage system.
00006  *
00007  * Udanax is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Udanax is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with Udanax; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  **********************************************************************/
00021 
00030 /* Modification History:
00031  * $Log: genf.cxx,v $
00032  * Revision 1.10  2004/09/11 13:59:21  jrush
00033  * Changed all fprintf's to stderr to use the Nana library L() macro.  Also
00034  * removed a 2-3 minor compiler warnings.
00035  *
00036  * Revision 1.9  2004/09/04 16:02:17  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.8  2002/07/14 08:32:51  jrush
00040  * Replace gerror() with assert(), comment out unused qerror() definition
00041  *
00042  * Revision 1.7  2002/05/28 04:22:29  jrush
00043  * Adjusted source files to comply with GPL licensing.
00044  *
00045  * Revision 1.6  2002/05/28 02:51:11  jrush
00046  * Made static any functions and global variables private to this source file
00047  * and commented out any unused functions.
00048  *
00049  * Revision 1.5  2002/04/12 11:56:43  jrush
00050  * Reorganized include file layout, renamed xanadu.h to udanax.h and
00051  * typecontext/typecrumcontext to C++ class Context/CrumContext.
00052  *
00053  * Revision 1.4  2002/04/06 19:51:30  jrush
00054  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00055  *
00056  * Revision 1.3  2002/04/06 15:01:17  jrush
00057  * Changed INT to just 'int'.
00058  *
00059  * Revision 1.2  2002/02/14 09:27:43  jrush
00060  * Cleaned up source:
00061  *
00062  * 1. ran thru the indent tool to achieve a standard look,
00063  * 2. added structured comments at top for use with DOxygen reporting
00064  *    as well as CVS keywords,
00065  * 3. fixed compiler warnings re ambiguous assign/compares,
00066  *    needed casts and unused/uninitialized variables,
00067  * 4. fixed funcs that didn't specify a return type,
00068  * 5. centralized prototypes in protos.h, removing incomplete ones,
00069  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00070  * 7. fixed initializer nesting in tumbler constants,
00071  * 8. renamed vars that conflict with C++ keywords (new, this),
00072  * 9. fixed global/extern confusion re some global vars.
00073  *
00074  */
00075 
00076 #include <stdlib.h>
00077 #include "udanax.h"
00078 
00079 #ifndef RESERVED
00080 #define RESERVED -1                    /* in this file, this is used to flag calls from coredisk */
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); // isempytenfilade - bad enftype
00257     }
00258     return false; // Just to keep compiler from complaining
00259 }
00260 
00268 /* Just does pointer following */
00269     typecuc * // UNUSED
00270 functionweakfindfather(
00271     typecorecrum *ptr)
00272 {
00273     if (!ptr)
00274         assert(0); // weakfindfater called with NULL
00275 
00276     if (isfullcrum(ptr))               /* what about spanf */
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 /* checkenftypes( */ 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 /* checkenftypes( */ 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 * // UNUSED
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 * // UNUSED
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 /* checkenftypes( */ 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); // trying to read 0 block
00445         }
00446         inloaf(ptr);
00447 /* THIS IS A REAL REJUVINATE FOR A RESERVE */
00448         if (oldage != RESERVED)        /* zzz experimental zz */
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) /* brings in leftson if not here */
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) /* brings in leftson if not here */
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)             /* bottom crums */
00533         return;
00534 
00535     if (from->cenftype == SPAN || from->cenftype == POOM) {
00536         /* the sucker dosen't know what it is yet anywow */
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 /* to->sonorigin = from->sonorigin; from->sonorigin = DISKPTRNULL; */
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 /* checkwholesubtree(fullcrumptr); */
00566 #endif
00567 
00568     if (!isfullcrum((typecorecrum *) fullcrumptr))
00569         assert(0); // Levelpush not called with fullcrum
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);     /* adopt new under fullcurm */
00579 
00580     newcuc->sonorigin = temploafptr;
00581     setwispupwards(newcuc, 1);
00582     ivemodified((typecorecrum *) newcuc);
00583     ivemodified((typecorecrum *) fullcrumptr);  /* is this redundant */
00584 
00585 #ifndef DISTRIBUTION
00586     L("leaving levelpush");
00587 #endif
00588 }
00589 
00597     void
00598 levelpull(
00599     typecuc *fullcrumptr)
00600 {
00601 /* typecuc *ptr; */
00602     return;
00603 /* 
00604  * if (!isfullcrum (fullcrumptr)) #ifndef DISTRIBUTION assert(0); "Levelpull not called with fullcrum"); #else assert(0); #endif if
00605  * (fullcrumptr->numberofsons > 1) return; if (fullcrumptr->height <= 1)
00606  * return; ptr = (typecuc *) findleftson (fullcrumptr); dspadd
00607  * (&fullcrumptr->cdsp, &ptr->cdsp, &fullcrumptr->cdsp,
00608  * fullcrumptr->cenftype);
00609  * 
00610  * disown (ptr); fullcrumptr->height--; transferloaf (ptr, fullcrumptr);
00611  * setwispupwards (fullcrumptr,1); freecrum (ptr); */
00612 }
00613 
00614 /* 
00615  * ** Remove crum from its father and siblings. ** It keeps any kids it has */
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); // can't disownnomodify fullcrum
00634 #else
00635         assert(0);
00636 #endif
00637     }
00638 
00639     if (!(father = weakfindfather(crumptr))) {
00640 #ifndef DISTRIBUTION
00641         dump(crumptr);
00642         assert(0); // disownnomodify called without a father
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); // can't disownnomodify fullcrum
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); // disownnomodify called without a father
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 {                           /* has left brother */
00694         left = findleftbro(crumptr);
00695         left->rightbro = right;
00696         if (right) {
00697             right->leftbroorfather = left;
00698         }
00699     }
00700     crumptr->leftbroorfather = crumptr->rightbro = NULL;
00701 /* ivemodified(father) ; *//*for now till we remove this */
00702 }
00703 
00711 /* 
00712  * ** Adopt "new" crum (and his kids) into a family of which "old" ** is a
00713  * member. */
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);  // ERROR: adopt with NULL
00724     assert(newcc != old);  // ERROR: adopt with both crums same
00725 
00726     // assert(!isfullcrum(newcc); // adopt called with fullcrum
00727 
00728     newcc->cenftype = old->cenftype; // make crum know what kind it is
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); // ERROR: adopt 1
00746         left   = old;
00747         father = findfather(left);
00748         right  = findrightbro(left);
00749         break;
00750 
00751     case LEFTBRO:
00752         assert(newcc->height == old->height); // ERROR: adopt 2
00753         right  = old;
00754         father = findfather(right);
00755         left   = findleftbro(right);
00756         break;
00757 
00758     default:
00759         assert(false); // ERROR: bad relative
00760     }
00761 
00762     assert(father);                              // ERROR: adopt without a father!
00763     assert(father->height == newcc->height + 1); // ERROR: height mismatch in adopt
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;                 /* not really, but the incoming ptr wants to get modified */
00803     while (ptr) {
00804 /* if (ptr->height == 0) *//* 10-2-84 what was this for bug */
00805 
00806         rejuvinateifnotRESERVED(ptr);
00807         if (fatherflag) {
00808 /* if (ptr->modified) return; *//* this optimization commented out because createcrum sets flag true to fix this makesure that all created crums get ivemodified then change createcrum then fix here */
00809             ptr->modified = true;
00810         }
00811         fatherflag = ptr->isleftmost;
00812         ptr = ptr->leftbroorfather;
00813     }
00814 }

Generated on Sun Aug 21 04:18:14 2005 for Udanax-Green by doxygen1.3.4