libsrc/retrie.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: retrie.cxx,v $
00032  * Revision 1.12  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.11  2004/09/04 16:02:18  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.10  2002/07/26 04:32:01  jrush
00040  * Replaced gerror() with assert()
00041  *
00042  * Revision 1.9  2002/05/28 04:22:29  jrush
00043  * Adjusted source files to comply with GPL licensing.
00044  *
00045  * Revision 1.8  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.7  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.6  2002/04/10 18:01:54  jrush
00054  * Renamed class typeisa to IStreamAddr.
00055  *
00056  * Revision 1.5  2002/04/09 21:45:46  jrush
00057  * Renamed class 'tumbler' to 'Tumbler', for consistency with Python sources,
00058  * and changed typeisa from typedef to a subclass, in preparation for cleaning
00059  * up the type/class tree.
00060  *
00061  * Revision 1.4  2002/04/06 19:51:30  jrush
00062  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00063  *
00064  * Revision 1.3  2002/04/06 15:01:17  jrush
00065  * Changed INT to just 'int'.
00066  *
00067  * Revision 1.2  2002/02/14 09:27:43  jrush
00068  * Cleaned up source:
00069  *
00070  * 1. ran thru the indent tool to achieve a standard look,
00071  * 2. added structured comments at top for use with DOxygen reporting
00072  *    as well as CVS keywords,
00073  * 3. fixed compiler warnings re ambiguous assign/compares,
00074  *    needed casts and unused/uninitialized variables,
00075  * 4. fixed funcs that didn't specify a return type,
00076  * 5. centralized prototypes in protos.h, removing incomplete ones,
00077  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00078  * 7. fixed initializer nesting in tumbler constants,
00079  * 8. renamed vars that conflict with C++ keywords (new, this),
00080  * 9. fixed global/extern confusion re some global vars.
00081  *
00082  */
00083 
00084 #include <memory.h>
00085 #include "udanax.h"
00086 
00087 /* all findcbc* routines are recursive with depth of ** recursion == height of enfilade being searched */
00088 
00089 /* Model-T like retrieves */
00097     static CrumContext *
00098 findcbcseqcrum(
00099     typecorecrum *ptr,
00100     typedsp      *offsetptr,
00101     Tumbler      *address)
00102 {
00103     if (!ptr)
00104         assert(0); // findcbcseqcrum called with NULL ptr
00105 
00106     for (; getrightbro(ptr); ptr = ptr->rightbro) {
00107         if (whereoncrum(ptr, offsetptr, address, WIDTH) <= THRUME)
00108             break;
00109 
00110         dspadd(offsetptr, &ptr->cwid, offsetptr, (int) ptr->cenftype);
00111     }
00112 
00113     if (ptr->height != 0) {
00114         ptr = findleftson((typecuc *) ptr);
00115         return findcbcseqcrum(ptr, offsetptr, address);
00116     } else
00117         return createcrumcontext(ptr, offsetptr);
00118 }
00119 
00127     static Context *
00128 findcbcseq(
00129     typecorecrum *ptr,
00130     typedsp      *offsetptr,
00131     Tumbler      *address)
00132 {
00133     for (; getrightbro(ptr); ptr = ptr->rightbro) {
00134         if (whereoncrum(ptr, offsetptr, address, WIDTH) <= THRUME)
00135             break;
00136 
00137         dspadd(offsetptr, &ptr->cwid, offsetptr, (int) ptr->cenftype);
00138     }
00139 
00140     if (ptr->height != 0) {
00141         ptr = findleftson((typecuc *) ptr);
00142         return findcbcseq(ptr, offsetptr, address);
00143     } else
00144         return makecontextfromcbc((typecbc *) ptr, (typewid *) offsetptr);
00145 }
00146 
00154     static Context *
00155 findcbcnd(
00156     typecorecrum *father,
00157     typewid      *offsetptr,
00158     Tumbler      *address,
00159     int           index)
00160 {
00161     typecorecrum *ptr;
00162     typewid       grasp;
00163     Context      *retr = NULL;
00164     int           cmp;
00165 
00166     if ((cmp = whereoncrum(father, offsetptr, address, index)) < ONMYLEFTBORDER || cmp > THRUME)
00167         return NULL;
00168 
00169     if (father->height != 0) {
00170         prologuend(father, offsetptr, &grasp, (typedsp *) NULL);
00171         for (ptr = findleftson((typecuc *) father); ptr; ptr = getrightbro(ptr))
00172             if ((retr = findcbcnd(ptr, &grasp, address, index)) != 0)
00173                 break;
00174 
00175     } else                           /* FOUND IT! */
00176         retr = makecontextfromcbc((typecbc *) father, offsetptr);
00177 
00178     return retr;
00179 }
00180 
00188     static bool                                   /* 6-28-84 old code */
00189 crumqualifies2d(
00190     typecorecrum         *crumptr,
00191     typedsp              *offset,
00192     Tumbler              *span1start,
00193     Tumbler              *span1end,
00194     int                   index1,
00195     Tumbler              *span2start,
00196     Tumbler              *span2end,
00197     int                   index2,
00198     type2dbottomcruminfo *infoptr)
00199 /* NOTE in retrieves this is ---40% -- of cpu */
00200 {
00201     int startcmp, endcmp;
00202 
00203 /* foocrum("entering crumqualifies2d\n",crumptr); */
00204     if ((crumptr->height == 0) && infoptr && !tumblereq(&infoptr->homedoc, &(((type2dcbc *) crumptr)->c2dinfo.homedoc))) {
00205 #ifndef DISTRIBUTION
00206         L("mumble homedoc");
00207 #endif
00208 /* foo("returningfalse case a"); */
00209         return false;
00210     }
00211 
00212     endcmp = iszerotumbler(span1end) ? TOMYRIGHT : whereoncrum(crumptr, offset, span1end, index1);
00213     if (endcmp <= /*=*/ ONMYLEFTBORDER)
00214         return false;
00215 
00216     startcmp = whereoncrum(crumptr, offset, span1start, index1);
00217     if ((startcmp > THRUME /* && endcmp > THRUME */ ))
00218         return false;
00219 
00220     endcmp = iszerotumbler(span2end) ? TOMYRIGHT : whereoncrum(crumptr, offset, span2end, index2);
00221     if (endcmp < ONMYLEFTBORDER) /* <= was < 12/20/84 */
00222         return false;
00223 
00224     startcmp = whereoncrum(crumptr, offset, span2start, index2);
00225     if ((startcmp > THRUME /* && endcmp > THRUME */ ))
00226         return false;
00227 
00228     return true;
00229 }
00230 
00238     static void
00239 findcbcinarea2d(
00240     typecorecrum        *crumptr,
00241     typedsp             *offsetptr,
00242     Tumbler             *span1start,
00243     Tumbler             *span1end,
00244     int                  index1,
00245     Tumbler             *span2start,
00246     Tumbler             *span2end,
00247     int                  index2,
00248     Context            **headptr,
00249     typebottomcruminfo  *infoptr)
00250 {
00251     typedsp localoffset;
00252     Context *context;
00253 
00254 #ifndef DISTRIBUTION
00255 /* foo(" entering findcbcinarea2d\n"); */
00256 /* footumbler("span1start = ",span1start); */
00257 /* footumbler("span1end = ",span1end); */
00258 /* footumbler("span2start = ",span2start); */
00259 /* footumbler("span2end = ",span2end); */
00260 /* foodsp("offset = ",offsetptr,crumptr->cenftype); */
00261     if (infoptr) {
00262         L("not NULL infoptr versions mumble specialcase 11/27/84 shouldent happen till we try something fancier\n");
00263         assert(0); // findcbcinarea2d
00264     }
00265 #else
00266     if (infoptr)
00267         assert(0); // !NULL
00268 #endif
00269 
00270     for (; crumptr; crumptr = getrightbro(crumptr)) {
00271         if (!crumqualifies2d(crumptr, offsetptr, span1start, span1end, index1, span2start, span2end, index2, (type2dbottomcruminfo *) infoptr))
00272             continue;
00273 
00274 /* foocrum("crumqualifies in findcbcinarea2d\n",crumptr); */
00275         if (crumptr->height != 0) {
00276             dspadd(offsetptr, &crumptr->cdsp, &localoffset, (int) crumptr->cenftype);
00277             findcbcinarea2d(findleftson((typecuc *) crumptr), &localoffset, span1start, span1end, index1, span2start, span2end, index2, headptr, infoptr);
00278         } else {
00279 /* foo("make context in findcbcinarea2d\n"); */
00280             context = makecontextfromcbc((typecbc *) crumptr, (typewid *) offsetptr);
00281             incontextlistnd(headptr, context, index1);
00282         }
00283     }
00284 
00285 /* contextfree(context); */
00286 /* foo("leaving findcbcinarea2d\n"); */
00287 }
00288 
00296     CrumContext *
00297 retrievecrums(
00298     typecuc *fullcrumptr,
00299     Tumbler *address,
00300     int      index)
00301 {
00302     typedsp offset;
00303     clear(&offset, sizeof(typedsp));
00304 
00305     if (fullcrumptr->cenftype == GRAN)
00306         return findcbcseqcrum((typecorecrum *) fullcrumptr, &offset, address);
00307     else {
00308         assert(0); // retrivecrum - bad enftype
00309         return NULL;                 /* for lint */
00310     }
00311 }
00312 
00320     Context *
00321 retrieve(
00322     typecuc *fullcrumptr,
00323     Tumbler *address,
00324     int      index)
00325     /* index:: used when enftype == SPAN or POOM */
00326 {
00327     typedsp offset;
00328 
00329     clear(&offset, sizeof(typedsp));
00330     switch (fullcrumptr->cenftype) {
00331     case GRAN:
00332         return findcbcseq((typecorecrum *) fullcrumptr, &offset, address);
00333     case SPAN:
00334     case POOM:
00335         return findcbcnd((typecorecrum *) fullcrumptr, &offset, address, index);
00336     default:
00337         assert(0); // retrieve - bad enftype
00338         return NULL;
00339     }
00340 }
00341 
00349     static Context *
00350 retrieveinarea(
00351     typecuc            *fullcrumptr,
00352     Tumbler            *span1start,
00353     Tumbler            *span1end,
00354     int                 index1,
00355     Tumbler            *span2start,
00356     Tumbler            *span2end,
00357     int                 index2,
00358     typebottomcruminfo *infoptr)
00359 {
00360 /* foo("entering retrieveinarea\n"); */
00361     typedsp offset;
00362     clear(&offset, sizeof(offset));
00363 
00364     Context *context = NULL;
00365 
00366     switch (fullcrumptr->cenftype) {
00367     case SPAN:
00368     case POOM:
00369         findcbcinarea2d((typecorecrum *) fullcrumptr, &offset, span1start, span1end, index1, span2start, span2end,
00370                         index2, &context, infoptr);
00371         break;
00372     default:
00373 /* L("%s\n", enftypestring (fullcrumptr->cenftype)); */
00374         assert(0); // retrieveinarea - wrong enftype
00375     }
00376 /* foo("leaving retrieveinarea\n"); */
00377 
00378     return context;
00379 }
00380 
00388     Context *
00389 retrieverestricted(
00390     typecuc     *fullcrumptr,
00391     typespan    *span1ptr,
00392     int          index1,
00393     typespan    *span2ptr,
00394     int          index2,
00395     IStreamAddr *docisaptr)
00396 {
00397     Tumbler span1start, span1end, span2start, span2end;
00398     type2dbottomcruminfo info, *infoptr;
00399 
00400     if (span1ptr) {
00401         movetumbler(&span1ptr->stream, &span1start);
00402         tumbleradd(&span1start, &span1ptr->width, &span1end);
00403     } else {
00404         tumblerclear(&span1start);
00405         tumblerclear(&span1end);
00406     }
00407 
00408     if (span2ptr) {
00409         movetumbler(&span2ptr->stream, &span2start);
00410         tumbleradd(&span2start, &span2ptr->width, &span2end);
00411     } else {
00412         tumblerclear(&span2start);
00413         tumblerclear(&span2end);
00414     }
00415 
00416     if (docisaptr) {
00417         movetumbler(docisaptr, &info.homedoc /* shouldberestrictiondoc */ );
00418         infoptr = &info;
00419     } else {
00420         infoptr = NULL;
00421     }
00422 
00423     return retrieveinarea(fullcrumptr, &span1start, &span1end, index1, &span2start, &span2end, index2,
00424                           (typebottomcruminfo *) infoptr);
00425 }
00426 
00434     static Context *
00435 findlastcbcseq(
00436     typecorecrum *fullcrumptr)
00437 {
00438     Tumbler offset;
00439     tumblerclear(&offset);
00440 
00441     typecorecrum *ptr;
00442     for (ptr = fullcrumptr; ptr; ptr = findleftson((typecuc *) ptr)) {
00443         for (; getrightbro(ptr); ptr = ptr->rightbro)
00444             tumbleradd(&offset, &ptr->cwid.dsas[WIDTH], &offset);
00445 
00446         if (ptr->height == 0)
00447             return makecontextfromcbc((typecbc *) ptr, (typewid *) &offset);
00448     }
00449 
00450     assert(0); // in findlastcbcseq couldn't find anything
00451     return NULL;                     /* for lint */
00452 }
00453 
00461     static bool
00462 crumintersectsspanseq(
00463     typecorecrum *crumptr,
00464     Tumbler      *offsetptr,
00465     Tumbler      *spanstart,
00466     Tumbler      *spanend)
00467 {
00468     if (iszerotumbler(&crumptr->cwid.dsas[WIDTH]))
00469         return false;
00470 
00471     return (whereoncrum(crumptr, (typewid *) offsetptr, spanstart, WIDTH) < ONMYRIGHTBORDER)
00472             && (whereoncrum(crumptr, (typewid *) offsetptr, spanend, WIDTH) >
00473                 /*=*/ ONMYLEFTBORDER);
00474 }
00475 
00483     static void
00484 findcbcinspanseq(
00485     typecorecrum *crumptr,
00486     typewid      *offsetptr,
00487     Tumbler      *spanstart,
00488     Tumbler      *spanend,
00489     Context     **headptr)
00490 {
00491     typewid localoffset;
00492     Context *context;
00493 
00494     movewisp(offsetptr, &localoffset);
00495     for (; crumptr; crumptr = getrightbro(crumptr)) {
00496         if (!crumintersectsspanseq(crumptr, (Tumbler *) & localoffset, spanstart, spanend)) {
00497             dspadd(&localoffset, &crumptr->cwid, &localoffset, (int) crumptr->cenftype);
00498             continue;
00499         }
00500 
00501         if (crumptr->height == 0) {
00502             context = makecontextfromcbc((typecbc *) crumptr, offsetptr);
00503             oncontextlistseq(headptr, context);
00504         } else {
00505             findcbcinspanseq(findleftson((typecuc *) crumptr), &localoffset, spanstart, spanend, headptr);
00506         }
00507 
00508         dspadd(&localoffset, &crumptr->cwid, &localoffset, (int) crumptr->cenftype);
00509     }
00510 }
00511 
00519     Context *
00520 retrieveinspan(
00521     typecuc *fullcrumptr,
00522     Tumbler *spanstart,
00523     Tumbler *spanend,
00524     int      index)
00525 {
00526     typedsp offset;
00527     clear(&offset, sizeof(offset));
00528 
00529     Context *context = NULL;
00530 
00531     switch (fullcrumptr->cenftype) {
00532     case GRAN:
00533         findcbcinspanseq((typecorecrum *) fullcrumptr, &offset, spanstart, spanend, &context);
00534         if (tumblercmp(spanend, &fullcrumptr->cwid.dsas[WIDTH]) == GREATER) {
00535             Context *c = findlastcbcseq((typecorecrum *) fullcrumptr);
00536             oncontextlistseq(&context, c);
00537         }
00538         return context;
00539     default:
00540         assert(0); // retrieveinspan - wrong enftype
00541         return NULL;
00542     }
00543 }
00544 
00552 /* sets grasp & reach from ptr & offset */
00553 /* reach may be NULL so that we won't set it */
00554     void
00555 prologuend(
00556     typecorecrum *ptr,
00557     typedsp      *offset,
00558     typedsp      *grasp,
00559     typedsp      *reach)
00560 {
00561     dspadd(offset, &ptr->cdsp, grasp, (int) ptr->cenftype);
00562     if (reach)
00563         dspadd(grasp, &ptr->cwid, reach, (int) ptr->cenftype);
00564 }
00565 
00566 #define intervalcmppart1(left,address) cmp = tumblercmp ((address), (left)); if (cmp == LESS) return (TOMYLEFT); else if (cmp == EQUAL) return (ONMYLEFTBORDER);
00567 
00568 #define intervalcmppart2(right,address) cmp = tumblercmp ((address), (right)); if (cmp == LESS) return (THRUME); else if (cmp == EQUAL) return (ONMYRIGHTBORDER); else return (TOMYRIGHT);
00569 
00577     int
00578 whereoncrum(
00579     typecorecrum *ptr,
00580     typewid      *offset,
00581     Tumbler      *address,
00582     int           index)
00583 /* speed up by subsuming intervalcmp */
00584     /* index:: used when enftype == SPAN or POOM */
00585 {
00586     Tumbler left, right;
00587     int cmp;
00588 
00589     switch (ptr->cenftype) {
00590     case GRAN:
00591         tumbleradd(&offset->dsas[WIDTH], &ptr->cwid.dsas[WIDTH], &right);
00592         return intervalcmp(&offset->dsas[WIDTH], &right, address);
00593 
00594     case SPAN:
00595     case POOM:
00596         tumbleradd(&offset->dsas[index], &ptr->cdsp.dsas[index], &left);
00597         cmp = tumblercmp(address, &left);
00598         if (cmp == LESS) {
00599             return TOMYLEFT;
00600         } else if (cmp == EQUAL) {
00601             return ONMYLEFTBORDER;
00602         }
00603 
00604 /* intervalcmppart1(&left,address); */
00605         tumbleradd(&left, &ptr->cwid.dsas[index], &right);
00606         cmp = tumblercmp(address, &right);
00607         if (cmp == LESS) {
00608             return THRUME;
00609         } else if (cmp == EQUAL) {
00610             return ONMYRIGHTBORDER;
00611         } else {
00612             return TOMYRIGHT;
00613         }
00614 
00615 /* intervalcmppart2(&right,address); */
00616 /* #ifndef DISTRIBUTION assert(0); "whereoncrum:can't get here" #else assert(0); #endif */
00617 /* 
00618  * tumbleradd(&offset->dsas[index],&ptr->cdsp.dsas[index], &left); tumbleradd 
00619  * (&left, &ptr->cwid.dsas[index], &right); return (intervalcmp (&left,
00620  * &right, address)); */
00621     default:
00622         assert(0); // whereoncrum: bad enftype
00623     }
00624 
00625     assert(0); // whereoncrum: can't get here either
00626     return 0;                        /* for lint */
00627 }

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