libsrc/wisp.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: wisp.cxx,v $
00032  * Revision 1.10  2004/09/04 16:02:18  jrush
00033  * Added Doxygen headers before each and every function definition.
00034  *
00035  * Revision 1.9  2002/07/26 04:33:47  jrush
00036  * Replaced gerror() with assert()
00037  *
00038  * Revision 1.8  2002/05/28 04:22:29  jrush
00039  * Adjusted source files to comply with GPL licensing.
00040  *
00041  * Revision 1.7  2002/05/28 02:52:23  jrush
00042  * Made static any functions and global variables private to this source file
00043  * and commented out any unused functions.
00044  *
00045  * Revision 1.6  2002/04/12 11:56:43  jrush
00046  * Reorganized include file layout, renamed xanadu.h to udanax.h and
00047  * typecontext/typecrumcontext to C++ class Context/CrumContext.
00048  *
00049  * Revision 1.5  2002/04/09 21:45:46  jrush
00050  * Renamed class 'tumbler' to 'Tumbler', for consistency with Python sources,
00051  * and changed typeisa from typedef to a subclass, in preparation for cleaning
00052  * up the type/class tree.
00053  *
00054  * Revision 1.4  2002/04/06 19:51:30  jrush
00055  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00056  *
00057  * Revision 1.3  2002/04/06 15:01:17  jrush
00058  * Changed INT to just 'int'.
00059  *
00060  * Revision 1.2  2002/02/14 09:27:43  jrush
00061  * Cleaned up source:
00062  *
00063  * 1. ran thru the indent tool to achieve a standard look,
00064  * 2. added structured comments at top for use with DOxygen reporting
00065  *    as well as CVS keywords,
00066  * 3. fixed compiler warnings re ambiguous assign/compares,
00067  *    needed casts and unused/uninitialized variables,
00068  * 4. fixed funcs that didn't specify a return type,
00069  * 5. centralized prototypes in protos.h, removing incomplete ones,
00070  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00071  * 7. fixed initializer nesting in tumbler constants,
00072  * 8. renamed vars that conflict with C++ keywords (new, this),
00073  * 9. fixed global/extern confusion re some global vars.
00074  *
00075  */
00076 
00077 #include <memory.h>
00078 #include "udanax.h"
00079 
00087 /* GRAN dsps across, POOM and SPAN dsp down */
00088     void
00089 dspadd(
00090     typedsp  *a,
00091     typewisp *b,
00092     typedsp  *c,
00093     int      enftype)
00094     /* adds a dsp */
00095     /* to either a wid or a dsp */
00096     /* to get another dsp */
00097 {
00098     lockadd(a->dsas, b->dsas, c->dsas, (unsigned)dspsize(enftype));
00099 }
00100 
00108     void
00109 dspsub(
00110     typedsp  *a,
00111     typewisp *b,
00112     typedsp  *c,
00113     int      enftype)
00114 {
00115     locksubtract(a->dsas, b->dsas, c->dsas, (unsigned)dspsize(enftype));
00116 }
00117 
00118 // widequal(a,b) char//typewisp// *a,*b; { int i; for( i=0 ;i<widsize(enftype);i++){ if(*a++ != *b++) return(false); }
00119 // return(true); } */
00120 
00121 // These two routines are presently macros int dspsize (enftype) short enftype; { switch (enftype) { case GRAN: return
00122 // (DSPSIZEGR); case POOM: return (DSPSIZEPM); case SPAN: return (DSPSIZESP); default: #ifndef DISTRIBUTION assert(0);
00123 // /* dspsize: bad enftype */); #else assert(0); #endif } return (-1); } int widsize (enftype) short enftype; { switch
00124 // (enftype) { case GRAN: return (WIDSIZEGR); case POOM: return (WIDSIZEPM); case SPAN: return (WIDSIZESP); default:
00125 // #ifndef DISTRIBUTION assert(0); /* widsize: bad enftype */); #else assert(0); #endif } return (-1); } */
00126 
00134 // Should be called whenever the wisp of a crum may need to be recalculated by looking at its son.
00135     bool
00136 setwispupwards(
00137     typecuc *ptr,
00138     int      testflag)
00139 {
00140     typecuc *father;
00141 
00142     int ntimeschanged = 0;
00143 /* checkwholesubtree(ptr); */
00144 /* asserttreeisok(ptr); */
00145     if (!ptr)
00146         return 0;
00147 
00148     typecuc *oldptr = ptr;
00149 
00150     bool changed;
00151     for (changed = true; changed && ptr; ptr = father) {
00152         father  = findfather((typecorecrum *) ptr);
00153         changed = setwisp((typecorecrum *) ptr);
00154         if (changed)
00155             ntimeschanged += 1;
00156     }
00157 
00158     if (ntimeschanged)
00159         ivemodified((typecorecrum *) oldptr);
00160 
00161 #ifndef DISTRIBUTION
00162     if (testflag)
00163         asserttreeisok((typecorecrum *) oldptr);
00164 #endif
00165 
00166     return 0 != ntimeschanged;
00167 }
00168 
00169 //UNUSED void
00170 //UNUSED setwispsofsons(typecuc *ptr)
00171 //UNUSED {
00172 //UNUSED     for (ptr = (typecuc *) findleftmostbro((typecorecrum *) ptr); ptr;
00173 //UNUSED          ptr = (typecuc *) getrightbro((typecorecrum *) ptr)) {
00174 //UNUSED         setwisp((typecorecrum *) ptr);
00175 //UNUSED     }
00176 //UNUSED }
00177 
00178 /* the local widditive operation in sequential enfilades */
00179 /* widopseq (aptr, bptr, cptr) typewid *aptr,*bptr,*cptr; { lockadd (aptr->dsas, bptr->dsas, cptr->dsas,
00180  * widsize(GRAN)); } */
00181 #define widopseq(a,b,c) lockadd((a)->dsas,(b)->dsas,(c)->dsas,widsize(GRAN))
00182 
00190 /* the widditive operation in sequential enfilades */
00191     static bool
00192 setwidseq(
00193     typecuc *father)
00194 {
00195     typecorecrum *ptr;
00196 
00197     if (father->height == 0)
00198         return false;
00199 
00200     typewid sum;
00201     clear(&sum, sizeof(sum));
00202 
00203     for (ptr = findleftson(father); ptr; ptr = getrightbro(ptr))
00204         widopseq(&sum, &ptr->cwid, &sum);
00205 
00206     if (lockeq(sum.dsas, father->cwid.dsas, (unsigned) widsize(father->cenftype)))
00207         return false;
00208 
00209     movewisp(&sum, &father->cwid);
00210     ivemodified((typecorecrum *) father);       /* zzzz */
00211 
00212     return true;
00213 }
00214 
00222     static void
00223 lockmin(
00224     Tumbler  *lock1,
00225     Tumbler  *lock2,
00226     Tumbler  *lock3,
00227     unsigned  loxize)
00228 {
00229     while (loxize--) {
00230         macrotumblermin(lock1, lock2, lock3);
00231         lock1++;
00232         lock2++;
00233         lock3++;
00234     }
00235 }
00236 
00244     static void
00245 lockmax(
00246     Tumbler  *lock1,
00247     Tumbler  *lock2,
00248     Tumbler  *lock3,
00249     unsigned  loxize)
00250 {
00251     while (loxize--) {
00252         macrotumblermax(lock1, lock2, lock3);
00253         lock1++;
00254         lock2++;
00255         lock3++;
00256     }
00257 }
00258 
00266     static void
00267 didntchangewisps()
00268 {
00269 }
00270 
00278 /* the widditive operation for nd */
00279     static bool
00280 setwispnd(
00281     typecuc *father)
00282 {
00283     typecorecrum *ptr;
00284     typedsp newdsp, mindsp;
00285     typewid newwid, tempwid;
00286     bool lockiszerop;
00287     bool somethingchangedp = false;     /* mindsp != 0 or some tempwid !=0 */
00288 
00289     if (father->height == 0)
00290         return false;
00291 
00292 /* remember original so can tell if changed */
00293     if ((ptr = findleftson(father)) == NULL) {
00294 #ifndef DISTRIBUTION
00295         assert(0); // in setwispnd null findleftson
00296         clear(&father->cdsp, sizeof(father->cdsp));
00297         clear(&father->cwid, sizeof(father->cwid));
00298         ivemodified((typecorecrum *) father);
00299         return true;
00300 #else
00301         assert(0);
00302 #endif
00303     }
00304 
00305 /* find new upper-left corner */
00306     movewisp(&ptr->cdsp, &mindsp);
00307     for (ptr = getrightbro(ptr); ptr; ptr = getrightbro(ptr))
00308         lockmin((Tumbler *) & mindsp, (Tumbler *) & ptr->cdsp, (Tumbler *) & mindsp, (unsigned)dspsize(ptr->cenftype));
00309 
00310     lockiszerop = iszerolock((Tumbler *) & mindsp, (unsigned)dspsize(father->cenftype));
00311     if (!lockiszerop) {
00312         somethingchangedp = true;
00313         dspadd(&father->cdsp, &mindsp, &newdsp, (int) father->cenftype);
00314     } else
00315         movewisp(&father->cdsp, &newdsp);
00316 
00317 /* find new lower-right corner at the same time that */
00318 /* we are readjusting the son's dsps to compensate */
00319 /* for change in the father */
00320     clear(&newwid, sizeof(newwid));
00321     for (ptr = findleftson(father); ptr; ptr = getrightbro(ptr)) {
00322         if (!lockiszerop) {
00323             ptr->modified = true;      /* father gets ivemodified soon */
00324             dspsub(&ptr->cdsp, &mindsp, &ptr->cdsp, (int) ptr->cenftype);
00325         }
00326 
00327         lockadd((Tumbler *) & ptr->cdsp, (Tumbler *) & ptr->cwid, (Tumbler *) & tempwid,
00328                 (unsigned)widsize(ptr->cenftype));
00329         lockmax((Tumbler *) & newwid, (Tumbler *) & tempwid, (Tumbler *) & newwid, (unsigned) widsize(ptr->cenftype));
00330     }
00331 
00332     if (!somethingchangedp && !lockeq((Tumbler *) & newwid, (Tumbler *) & father->cwid, (unsigned) widsize(father->cenftype)))
00333         somethingchangedp = true;
00334 
00335 /* report whether anything changed */
00336     if (!somethingchangedp) {
00337         didntchangewisps();
00338         return false;
00339     }
00340 
00341     movewisp(&newdsp, &father->cdsp);
00342     movewisp(&newwid, &father->cwid);
00343     ivemodified((typecorecrum *) father);
00344 
00345     return true;
00346 }
00347 
00355 /* the widditive operation in general */
00356     bool                                   /* return whether wisp of ptr has changed */
00357 setwisp(
00358     typecorecrum *ptr)
00359 {
00360     if (ptr->height == 0)
00361         return false;
00362 
00363     switch (ptr->cenftype) {
00364     case GRAN:
00365         return setwidseq((typecuc *) ptr);
00366     case SPAN:
00367     case POOM:
00368         return setwispnd((typecuc *) ptr);
00369     default:
00370         assert(0); // setwisp: bad enftype
00371     }
00372 
00373     return -1;                       /* Oh, the things one has to do to make computers happy */
00374 }
00375 
00383 /* reset father's wid but leave dsp alone */
00384     void
00385 setwidnd(
00386     typecuc *father)
00387 {
00388     typecorecrum *ptr;
00389     typewid newwid;
00390 
00391     for (ptr = findleftson(father); ptr; ptr = getrightbro(ptr)) {
00392         clear(&newwid, sizeof(newwid));
00393         lockmax((Tumbler *) &newwid, (Tumbler *) &ptr->cwid, (Tumbler *) &newwid, (unsigned) widsize(ptr->cenftype));
00394     }
00395 
00396     if (!lockeq((Tumbler *) &father->cwid, (Tumbler *) &newwid, (unsigned) widsize(father->cenftype))) {
00397         movewisp(&newwid, &father->cwid);
00398         ivemodified((typecorecrum *) father);   /* zzz */
00399     }
00400 }
00401 
00409 /* --------- lock routines deal with full lock ------------- */
00410 /* a lock is an array of loxize tumblers */
00411 
00412     bool
00413 iszerolock(
00414     Tumbler  *lock,
00415     unsigned  loxize)
00416 {
00417     while (loxize--)
00418         if (!iszerotumbler(lock++))
00419             return false;
00420 
00421     return true;
00422 }
00423 
00431     bool
00432 lockeq(
00433     Tumbler  *lock1,
00434     Tumbler  *lock2,
00435     unsigned  loxize)
00436 {
00437     while (loxize--)
00438         if (!tumblereq(lock1++, lock2++))
00439             return false;
00440 
00441     return true;
00442 }
00443 
00451     void
00452 lockadd(
00453     Tumbler  *lock1,
00454     Tumbler  *lock2,
00455     Tumbler  *lock3,
00456     unsigned  loxize)
00457 /* arrays of tumblers */
00458 {
00459     while (loxize--)
00460         tumbleradd(lock1++, lock2++, lock3++);
00461 }
00462 
00470     void
00471 locksubtract(
00472     Tumbler  *lock1,
00473     Tumbler  *lock2,
00474     Tumbler  *lock3,
00475     unsigned  loxize)
00476 {
00477     while (loxize--)
00478         tumblersub(lock1++, lock2++, lock3++);
00479 }
00480 
00488 /* Returns whether ALL the lock is 1 story */
00489     bool
00490 lockis1story(
00491     Tumbler  *lock,
00492     unsigned  loxize)
00493 {
00494     while (loxize--)
00495         if (!is1story(lock++))
00496             return false;
00497 
00498     return true;
00499 }

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