libsrc/recombine.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: recombine.cxx,v $
00032  * Revision 1.11  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.10  2004/09/04 16:02:18  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.9  2002/07/26 04:32:01  jrush
00040  * Replaced gerror() with assert()
00041  *
00042  * Revision 1.8  2002/05/28 04:22:29  jrush
00043  * Adjusted source files to comply with GPL licensing.
00044  *
00045  * Revision 1.7  2002/05/28 02:52:23  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.6  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.5  2002/04/09 21:45:46  jrush
00054  * Renamed class 'tumbler' to 'Tumbler', for consistency with Python sources,
00055  * and changed typeisa from typedef to a subclass, in preparation for cleaning
00056  * up the type/class tree.
00057  *
00058  * Revision 1.4  2002/04/06 19:51:30  jrush
00059  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00060  *
00061  * Revision 1.3  2002/04/06 15:01:17  jrush
00062  * Changed INT to just 'int'.
00063  *
00064  * Revision 1.2  2002/02/14 09:27:43  jrush
00065  * Cleaned up source:
00066  *
00067  * 1. ran thru the indent tool to achieve a standard look,
00068  * 2. added structured comments at top for use with DOxygen reporting
00069  *    as well as CVS keywords,
00070  * 3. fixed compiler warnings re ambiguous assign/compares,
00071  *    needed casts and unused/uninitialized variables,
00072  * 4. fixed funcs that didn't specify a return type,
00073  * 5. centralized prototypes in protos.h, removing incomplete ones,
00074  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00075  * 7. fixed initializer nesting in tumbler constants,
00076  * 8. renamed vars that conflict with C++ keywords (new, this),
00077  * 9. fixed global/extern confusion re some global vars.
00078  *
00079  */
00080 
00081 #include <memory.h>
00082 #include "udanax.h"
00083 
00084 // Globals used by corediskout.cxx only
00085 long noishouldbother = 0;
00086 long notakenephewnd  = 0;
00087 long noeatbrosnd     = 0;
00088 
00089 /* GRANfilade recombine */
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 /* L("in eatbrossubtreend calling makeroom onleftnd \n"); */
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 /* fixincoresubtreewids(me); */
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 /* L("in takenephewnd calling makeroomnd \n"); */
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); // fatal error in shellsort in be under recombine - n > 100
00257 
00258     for (i = 0; i < n; i++) {          /* build up a list of sumps of disp[0] and dsp[1] */
00259 /* for compare crums diagonally hack */
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);              /* to make sure its in core zzzz */
00327         n = bro->numberofsons;
00328         for (i = 0; i < n && roomformoresons(me); i++) {
00329             ptr = sons[i];
00330             takenephewnd(me, (typecuc *) ptr);
00331 /* fixincoresubtreewids(me); */
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 /* if (ptr->leftson && toofewsons (ptr)) {* */
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 /* 2d recombine */
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 /* break; */
00423 /* break;//zzz6/16/84 reg// */
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     //UNUSED static float i = 0;
00461 
00462     return true;
00463 /* 
00464  * i += probability; if(i>=1.){ while (i>1){ i -= 1.; } return(true); }else{
00465  * return false; } */
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 }

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