libsrc/split.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: split.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:18  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.8  2002/07/26 04:33:47  jrush
00040  * Replaced gerror() with assert()
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: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.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 <memory.h>
00077 #include "udanax.h"
00078 
00086 /* Should be called whenever a crum may have too many sons ** if it does, it is split, and its father is checked,
00087  * etc... */
00088     bool
00089 splitcrumupwards(
00090     typecuc *father)
00091 {
00092     bool splitsomething = false;
00093 
00094     if (father->height <= 0)
00095         assert(0); // splitcrumupwards on bottom crum
00096 
00097     for (; toomanysons(father); father = (typecuc *) findfather((typecorecrum *) father)) {
00098         if (isfullcrum((typecorecrum *) father)) {
00099             levelpush(father);
00100             splitcrum((typecuc *) findleftson(father));
00101 
00102 #ifndef DISTRIBUTION
00103             L("splitcrumupwards split something\n");
00104             asserttreeisok((typecorecrum *) father);
00105 #endif
00106             return true;
00107         }
00108         splitcrum(father);
00109         splitsomething = true;
00110     }
00111 
00112 #ifndef DISTRIBUTION
00113     asserttreeisok((typecorecrum *) father);
00114 #endif
00115 
00116     return splitsomething;
00117 }
00118 
00126 /* splits a crum for sequential enfilades */
00127     static void
00128 splitcrumseq(
00129     typecuc *father)
00130 {
00131     typecorecrum *newcc, *ptr, *next;
00132     int i, halfsons;
00133 
00134     ivemodified((typecorecrum *) father);
00135     newcc = createcrum((int) father->height, (int) father->cenftype);
00136     reserve(newcc);
00137     adopt(newcc, RIGHTBRO, (typecorecrum *) father);
00138     rejuvinate(newcc);
00139     ivemodified(newcc);
00140     halfsons = father->numberofsons / 2;
00141     for (i = 0, ptr = findrightmostson(father); i < halfsons && ptr; ++i, ptr = next) {
00142         next = findleftbro(ptr);
00143         disown(ptr);
00144         adopt(ptr, LEFTMOSTSON, newcc);
00145         rejuvinate(ptr);
00146         ivemodified(ptr);              /* zzz */
00147     }
00148 
00149     setwispupwards(father, 0);
00150     setwispupwards((typecuc *) newcc, 0);
00151 }
00152 
00160     static void
00161 splitcrumsp(
00162     typecuc *father)
00163 {
00164     typecorecrum *ptr, *correctone;
00165 
00166     for (correctone = ptr = findleftson(father); ptr; ptr = findrightbro(ptr)) {
00167 /* if (tumblercmp(&ptr->cdsp.dsas[SPANRANGE], &correctone->cdsp.dsas[SPANRANGE]) == GREATER) */
00168         if (comparecrumsdiagonally(ptr, correctone) == GREATER)
00169             correctone = ptr;
00170     }
00171     peelcrumoffnd(correctone);
00172 }
00173 
00181     static void
00182 splitcrumpm(
00183     typecuc *father)
00184 {
00185     typecorecrum *ptr, *correctone;
00186 
00187     for (correctone = ptr = findleftson(father); ptr; ptr = findrightbro(ptr)) {
00188         if (tumblercmp(&ptr->cdsp.dsas[SPANRANGE], &correctone->cdsp.dsas[SPANRANGE]) == GREATER)
00189 /* if (comparecrumsdiagonally(ptr, correctone) == LESS) */
00190             correctone = ptr;
00191     }
00192     peelcrumoffnd(correctone);
00193 }
00194 
00202 /* splits an individual crum */
00203     void
00204 splitcrum(
00205     typecuc *father)
00206 {
00207     switch (father->cenftype) {
00208     case GRAN:  splitcrumseq(father);  break;
00209     case POOM:  splitcrumpm(father);   break;
00210     case SPAN:  splitcrumsp(father);   break;
00211     default:
00212         assert(0); // splitcrum: bad enftype
00213     }
00214     setwispupwards(father, 0);
00215 }
00216 
00224     void
00225 peelcrumoffnd(
00226     typecorecrum *ptr)
00227 {
00228     if (isfullcrum(ptr))
00229         assert(0); // peeloffcurmnd called with fullcrum
00230 
00231     typecuc *father     = findfather(ptr);
00232     int      ofatherage = father->age;
00233     int      optrage    = ptr->age;
00234 
00235     father->age = NEW;
00236     ptr->age    = NEW;
00237 
00238     reserve((typecorecrum *) father);
00239     father->modified = true;           /* an uncle will get ivemodified shortly in 10 lines */
00240     reserve(ptr);
00241     disown(ptr);
00242 
00243     typecorecrum *newcc = createcrum((int) father->height, (int) father->cenftype);
00244     adopt(newcc, RIGHTBRO, (typecorecrum *) father);
00245     movewisp(&father->cdsp, &newcc->cdsp);
00246     adopt(ptr, LEFTMOSTSON, newcc);
00247     rejuvinate(newcc);
00248     rejuvinate(ptr);
00249     rejuvinate((typecorecrum *) father);
00250 
00251     if (ofatherage == RESERVED)
00252         father->age = RESERVED;
00253 
00254     if (optrage == RESERVED)
00255         ptr->age = RESERVED;
00256 
00257     ivemodified(ptr);
00258     setwispupwards(father, 0);
00259     setwispupwards((typecuc *) newcc, 0);
00260     setwispupwards((typecuc *) ptr, 1);
00261 }

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