Annotation of 42BSD/ucb/lisp/pearl/hash.l, revision 1.1

1.1     ! root        1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; hash.l ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             2: ; Functions for hashing, inserting, and fetching items into the
        !             3: ;    data bases, plus operating on streams.
        !             4: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             5: ; Copyright (c) 1983 ,  The Regents of the University of California.
        !             6: ; All rights reserved.  
        !             7: ; Authors: Joseph Faletti and Michael Deering.
        !             8: 
        !             9: ; Find the next item on the CDDR list of the stream that matches the CADR of
        !            10: ; the stream and return it, also updating the stream.
        !            11: (de nextitem (stream)
        !            12:   (or (streamp stream)
        !            13:       (progn (msg t "NEXTITEM: Not a stream: " stream t)
        !            14:             (pearlbreak)))
        !            15:   (setq stream (cdr stream))             ; Throw away the *STREAM*.
        !            16:   (cond ((eq t (car stream))             ; This means function structure.
        !            17:         (prog1 (evalfcn (cdr stream))
        !            18:                (rplacd (rplaca stream nil) nil)))
        !            19:        ((null (cadr stream)) nil)        ; Test for empty stream
        !            20:        ; Stream built by standardfetch.
        !            21:        ; To debug or modify this, you must draw a picture of what
        !            22:        ;   standardfetch built because of the way it is written.
        !            23:        ((not (dtpr (cadr stream)))
        !            24:         (prog (item result)
        !            25:               (setq item (car stream))
        !            26:               (setq *currentpearlstructure* item)
        !            27:               (checkrunhandlebasehooks1 '<nextitem *runnextitemhooks*)
        !            28:               (while (and (cdr stream)
        !            29:                           (or (eq (cadr stream) '*db*)
        !            30:                               (not (match item (cadr stream)))))
        !            31:                      (rplacd stream (cddr stream)))
        !            32:               (setq item (cadr stream))
        !            33:               (rplacd stream (cddr stream))
        !            34:               (checkrunhandlebasehooks1 '>nextitem *runnextitemhooks*)
        !            35:               (return item)))
        !            36:        ; Stream built by expandedfetch (or fetcheverywhere).
        !            37:        ; To debug or modify this, you must draw a picture of what
        !            38:        ;   expandedfetch built because of the way it is written.
        !            39:        ((not (dtpr (caadr stream)))
        !            40:         (prog (item result)
        !            41:               (setq item (car stream))
        !            42:               (setq *currentpearlstructure* item)
        !            43:               (checkrunhandlebasehooks1 '<nextitem *runnextitemhooks*)
        !            44:               (while (and (cdr stream)
        !            45:                           (or (eq (caadr stream) '*db*)
        !            46:                               (not (expandedmatch item (caadr stream)))))
        !            47:                      (or (car (rplaca (cdr stream) (cdadr stream)))
        !            48:                          (rplacd stream (cddr stream))))
        !            49:               (setq item (caadr stream))
        !            50:               (or (not (cdr stream))
        !            51:                   (car (rplaca (cdr stream) (cdadr stream)))
        !            52:                   (rplacd stream (cddr stream)))
        !            53:               (checkrunhandlebasehooks1 '>nextitem *runnextitemhooks*)
        !            54:               (return item)))))
        !            55:  
        !            56: (defmacro hashinfo (slotnum)
        !            57:   `(cxr ,slotnum *hashingmarks*))
        !            58: 
        !            59: (defmacro sethashinfo (slotnum value)
        !            60:   `(rplacx ,slotnum *hashingmarks* ,value))
        !            61: 
        !            62: (defmacro slotval (slotnum)
        !            63:   `(cxr ,slotnum *slotvalues*))
        !            64: 
        !            65: (defmacro storeslot (slotnum value)
        !            66:   `(rplacx ,slotnum *slotvalues* ,value))
        !            67: 
        !            68: ; If there is anything to hash this slot on, say so and put it in HASHV.
        !            69: (defmacro hashablevalue (slotnum item defblock hashinfo)
        !            70:   `(not (memq (setq hashv (gethashvalue ,slotnum ,item ,defblock ,hashinfo))
        !            71:              *unhashablevalues*)))
        !            72:  
        !            73: ; If this slot is to take part in a hashing combination, (and it is the
        !            74: ;    second one in :: or ** hashing), then add it to the right hash bucket.
        !            75: (dm hashslot (none)
        !            76:   '(cond ((\=& 0 hashinfo) nil) ; No hashing to be done
        !            77:         ((hashablevalue slotnum item defblock hashinfo) ; Sets HASHV
        !            78:          (and (gethash*  hashinfo)
        !            79:               (puthash2  unique hashv db2 item))
        !            80: ;        (and (gethash:  hashinfo)
        !            81: ;             (puthash1  hashv db1 item))
        !            82:          (and (gethash** hashinfo)
        !            83:               (cond ((null mark**)
        !            84:                      ; First one found.
        !            85:                      (setq mark** hashv))
        !            86:                     ; Second one found
        !            87:                     ((neq t mark**)
        !            88:                      (puthash3 unique mark** hashv db2 item)
        !            89:                      (setq mark** t))
        !            90:                     ; Third or greater found.
        !            91:                     (  t  (msg t "HASH: More than two **'s in: "
        !            92:                                (getpname defblock) t))))
        !            93: ;        (and (gethash:: hashinfo)
        !            94: ;             (cond ((null mark::)
        !            95: ;                    ; First one found.
        !            96: ;                    (setq mark:: hashv))
        !            97: ;                   ; Second one found
        !            98: ;                   ((neq t mark::)
        !            99: ;                    (puthash2 mark:: hashv db2 item)
        !           100: ;                    (setq mark:: t))
        !           101: ;                   ; Third or greater found.
        !           102: ;                   (  t  (msg t "HASH: More than two ::'s in: "
        !           103: ;                              (getpname defblock) t))))
        !           104:          (and (gethash*** hashinfo)
        !           105:               (cond ((null mark***)
        !           106:                      ; First one found.
        !           107:                      (setq mark*** (ncons hashv)))
        !           108:                     ; Later ones found.
        !           109:                     (  t  (tconc mark*** hashv))))
        !           110: )))
        !           111:  
        !           112: ; For each of the four ways of hashing, or else just based on the type,
        !           113: ;    check to see if the pattern can be hashed that way and if so,
        !           114: ;    RETURN the right hashbucket.  If the previous one can't be done,
        !           115: ;    try the next one but stop with the first that can be done.
        !           116: ;    The order is ***, **, ::, &&, *, and :.
        !           117: (dm insidestandardfetch (none)
        !           118:   '(cond ((prog2
        !           119:           (for slotnum 1 length
        !           120:                (and (gethash*** (hashinfo slotnum))
        !           121:                     (cond ((eq (punbound)
        !           122:                                (setq hashv (slotval slotnum)))
        !           123:                            (setq mark nil)
        !           124:                            (return nil))
        !           125:                           ((null mark)
        !           126:                            (setq mark (ncons nil))
        !           127:                            (tconc mark hashv)
        !           128:                            nil)
        !           129:                           ( t  (tconc mark hashv)))))
        !           130:           mark)
        !           131:          (gethashmulti unique (car mark) db2))
        !           132:         ((for slotnum 1 length
        !           133:               (and (gethash** (hashinfo slotnum))
        !           134:                    (cond ((eq (punbound)
        !           135:                               (setq hashv (slotval slotnum)))
        !           136:                           (return nil))
        !           137:                          ((null mark) (setq mark hashv) nil)
        !           138:                          ( t (return (gethash3 unique mark hashv db2)))))))
        !           139: ;       ((for slotnum 1 length
        !           140: ;             (and (gethash:: (hashinfo slotnum))
        !           141: ;                  (cond ((eq (punbound)
        !           142: ;                             (setq hashv (slotval slotnum)))
        !           143: ;                         (return nil))
        !           144: ;                        ((null mark) (setq mark hashv) nil)
        !           145: ;                        ( t (return (gethash2 mark hashv db2)))))))
        !           146:         ((and (not (\=& 0 focus))
        !           147:               (pboundp (setq hashv (slotval focus))))
        !           148:          (recursetoinsidestandardfetch (getslotvalue focus item) db1 db2))
        !           149:         ((for slotnum 1 length
        !           150:               (and (gethash* (hashinfo slotnum))
        !           151:                    (and (pboundp (setq hashv
        !           152:                                        (slotval slotnum)))
        !           153:                         (return (gethash2 unique hashv db2))))))
        !           154: ;       ((for slotnum 1 length
        !           155: ;             (and (gethash: (hashinfo slotnum))
        !           156: ;                  (and (pboundp (setq hashv
        !           157: ;                                      (slotval slotnum)))
        !           158: ;                       (return (gethash1 hashv db1))))))
        !           159:         ( t (gethash1 unique db1))))
        !           160:  
        !           161: (de recursetoinsidestandardfetch (item db1 db2)
        !           162:   (let* ((defblock (getdefinition item))
        !           163:         (length (getstructlength defblock))
        !           164:         (*slotvalues* (makhunk (1+ length)))
        !           165:         (*hashingmarks* (makhunk (1+ length)))
        !           166:         (unique (getuniquenum defblock))
        !           167:         mark hashv focus hashinfo)
        !           168:        (setq focus (gethashfocus defblock))
        !           169:        (for slotnum 1 length
        !           170:             (setq hashinfo (gethashinfo slotnum defblock))
        !           171:             (sethashinfo slotnum hashinfo)
        !           172:             (or (and (\=& 0 hashinfo)
        !           173:                      (not (\=& focus slotnum)))
        !           174:                 (storeslot slotnum
        !           175:                            (gethashvalue slotnum item defblock hashinfo))))
        !           176:        (insidestandardfetch)))
        !           177: 
        !           178: ; Return a pair consisting of the ITEM and a hash-bucket-list that should
        !           179: ; have what we are looking for in it.
        !           180: (de standardfetch (item &optional (db *db*))
        !           181:   (cond ((get (pname item) 'functionstruct)
        !           182:         (cons '*stream* (cons t item)))
        !           183:        ( t (prog (mark defblock bucket db1 db2 hashv result focus
        !           184:                        length hashinfo unique)
        !           185:                  (setq defblock (getdefinition item))
        !           186:                  (setq *currentpearlstructure* item)
        !           187:                  (checkrunhandlebasehooks1 '<fetch *runfetchhooks*)
        !           188:                  (setq db1 (getdb1 db))
        !           189:                  (setq db2 (getdb2 db))
        !           190:                  (setq length (getstructlength defblock))
        !           191:                  (setq focus (gethashfocus defblock))
        !           192:                  (for slotnum 1 length
        !           193:                       (setq hashinfo (gethashinfo slotnum defblock))
        !           194:                       (sethashinfo slotnum hashinfo)
        !           195:                       (or (and (\=& 0 hashinfo)
        !           196:                                (not (\=& focus slotnum)))
        !           197:                           (storeslot slotnum
        !           198:                                      (gethashvalue slotnum item
        !           199:                                                    defblock hashinfo))))
        !           200:                  (setq unique (getuniquenum defblock))
        !           201:                  (setq bucket (insidestandardfetch))
        !           202:                  (checkrunhandlebasehooks1 '>fetch *runfetchhooks*)
        !           203:                  (return (cons '*stream* (cons item bucket)))))))
        !           204:  
        !           205: (aliasdef 'fetch 'standardfetch)
        !           206: 
        !           207: (de expandedfetch (item &optional (db *db*))
        !           208:   (cond ((get (pname item) 'functionstruct)
        !           209:         (cons '*stream* (cons t item)))
        !           210:        ( t (prog (mark defblock defblocklist buckets db1 db2 hashv result
        !           211:                        focus length hashinfo)
        !           212:                  (setq defblock (getdefinition item))
        !           213:                  (setq *currentpearlstructure* item)
        !           214:                  (checkrunhandlebasehooks1 '<fetch *runfetchhooks*)
        !           215:                  (setq db1 (getdb1 db))
        !           216:                  (setq db2 (getdb2 db))
        !           217:                  (setq length (getstructlength defblock))
        !           218:                  (setq focus (gethashfocus defblock))
        !           219:                  (for slotnum 1 length
        !           220:                       (setq hashinfo (gethashinfo slotnum defblock))
        !           221:                       (sethashinfo slotnum hashinfo)
        !           222:                       (or (and (\=& 0 hashinfo)
        !           223:                                (not (\=& focus slotnum)))
        !           224:                           (storeslot slotnum
        !           225:                                      (gethashvalue slotnum item
        !           226:                                                    defblock hashinfo))))
        !           227:                  (setq defblocklist (cons defblock
        !           228:                                           (getexpansionlist defblock)))
        !           229:                  ; Note that instead of being one list, buckets is a
        !           230:                  ;    list of lists.
        !           231:                  (setq buckets
        !           232:                        (mapcar
        !           233:                         (funl (expandeddefblock)
        !           234:                               (let ((unique (getuniquenum expandeddefblock)))
        !           235:                                    (insidestandardfetch)))
        !           236:                         defblocklist))
        !           237:                  (dremove nil buckets)
        !           238:                  (checkrunhandlebasehooks1 '>fetch *runfetchhooks*)
        !           239:                  (return (cons '*stream* (cons item buckets)))))))
        !           240:  
        !           241: ; Find the object EVERYWHERE it might be: ; (Well, only 1 for each hash method).
        !           242: ; For each of the four ways of hashing, plus just based on the type,
        !           243: ;    check to see if the pattern can be hashed that way and if so,
        !           244: ;    return the right hash bucket. A list of these lists is made.
        !           245: ;    NIL's are removed in the main function.
        !           246: ;    The order is ***, **, ::, &&, *, and :.
        !           247: (dm insidefetcheverywhere (none)
        !           248:   '(let ((bucketlist (ncons nil)))
        !           249:        (for slotnum 1 length
        !           250:             (and (gethash*** (hashinfo slotnum))
        !           251:                  (cond ((eq (punbound)
        !           252:                             (setq hashv (slotval slotnum)))
        !           253:                         (setq mark nil)
        !           254:                         (return nil))
        !           255:                        ((null mark) (setq mark (ncons hashv)) nil)
        !           256:                        ( t  (tconc mark hashv)))))
        !           257:        (and mark
        !           258:             (tconc bucketlist
        !           259:                    (gethashmulti unique (car mark) db2))
        !           260:             (setq mark nil))
        !           261:        (for slotnum 1 length
        !           262:             (and (gethash** (hashinfo slotnum))
        !           263:                  (cond ((eq (punbound)
        !           264:                             (setq hashv (slotval slotnum)))
        !           265:                         (return nil))
        !           266:                        ((null mark) (setq mark hashv) nil)
        !           267:                        ( t (tconc bucketlist
        !           268:                                   (gethash3 unique mark hashv db2))
        !           269:                            (setq mark nil)
        !           270:                            (return nil)))))
        !           271:        (and (not (\=& 0 focus))
        !           272:             (pboundp (setq hashv (slotval focus)))
        !           273:             (tconc bucketlist
        !           274:                    (recursetoinsidestandardfetch (getslotvalue focus item)
        !           275:                                                  db1 db2)))
        !           276:        (for slotnum 1 length
        !           277:             (and (gethash* (hashinfo slotnum))
        !           278:                  (and (pboundp (setq hashv
        !           279:                                      (slotval slotnum)))
        !           280:                       (tconc bucketlist
        !           281:                              (gethash2 unique hashv db2)))))
        !           282:        (tconc bucketlist
        !           283:               (gethash1 unique db1))
        !           284:        (car bucketlist)))
        !           285: 
        !           286: ; Return a list consisting of the ITEM and a list of hash-bucket-list
        !           287: ;   that must have what we are looking for in it if it's there.
        !           288: (de fetcheverywhere (item &optional (db *db*))
        !           289:   (cond ((get (pname item) 'functionstruct)
        !           290:         (cons '*stream* (cons t item)))
        !           291:        ( t (prog (mark defblock buckets db1 db2 hashv result focus
        !           292:                        length hashinfo unique)
        !           293:                  (setq defblock (getdefinition item))
        !           294:                  (setq length (getstructlength defblock))
        !           295:                  (setq focus (gethashfocus defblock))
        !           296:                  (for slotnum 1 length
        !           297:                       (setq hashinfo (gethashinfo slotnum defblock))
        !           298:                       (sethashinfo slotnum hashinfo)
        !           299:                       (or (and (\=& 0 hashinfo)
        !           300:                                (not (\=& focus slotnum)))
        !           301:                           (storeslot slotnum
        !           302:                                      (gethashvalue slotnum item
        !           303:                                                    defblock hashinfo))))
        !           304:                  (setq *currentpearlstructure* item)
        !           305:                  (checkrunhandlebasehooks1 '<fetch *runfetchhooks*)
        !           306:                  (setq db1 (getdb1 db))
        !           307:                  (setq db2 (getdb2 db))
        !           308:                  (setq unique (getuniquenum defblock))
        !           309:                  (setq buckets (insidefetcheverywhere))
        !           310:                  (dremove nil buckets)
        !           311:                  (checkrunhandlebasehooks1 '>fetch *runfetchhooks*)
        !           312:                  (return (cons '*stream* (cons item buckets)))))))
        !           313:  
        !           314: ; Discover if a hash alias is to be used.
        !           315: (dm noalias (none)
        !           316:   '(cond ((>& alias 0)
        !           317:          (cond ((gethash< hashinfo)
        !           318:                 (cond ((gethash> hashinfo) nil) ; < > cancels
        !           319:                       ( t t)))
        !           320:                ( t nil)))
        !           321:         ( t (cond ((gethash< hashinfo) t)
        !           322:                   ( t (cond ((gethash> hashinfo) nil) ; < > cancels
        !           323:                             ( t t)))))))
        !           324:  
        !           325: ; Get the value that should be hashed for the given slot of ITEM
        !           326: ;     else return unbound.
        !           327: (de gethashvalue (slotnum item defblock hashinfo)
        !           328:   (let
        !           329:    ((potential (getvalue slotnum item))
        !           330:     alias)
        !           331:    (cond ((null potential) nil)
        !           332:         ((pboundp potential)
        !           333:          (let ((potdef (getdefinition potential)))
        !           334:               (selectq (getslottype slotnum defblock)
        !           335:                        (0 (setq alias (gethashalias potdef))
        !           336:                           (cond ((or (noalias)
        !           337:                                      (\=& 0 alias))
        !           338:                                  (getuniquenum potdef))
        !           339:                                 ( t
        !           340:                                  (setq alias (abs alias))
        !           341:                                  (gethashvalue alias potential potdef
        !           342:                                                (gethashinfo alias potdef)))))
        !           343:                        (1  (getuniquenum potential)) ; Symbol.
        !           344:                        (2  potential)                ; Integer.
        !           345:                        (3  (punbound))               ; Lisp not hashed.
        !           346:                        (otherwise nil))))            ; SetOf not hashed (YET).
        !           347:         ( t (punbound)))))
        !           348: 
        !           349: ; Fetch the first item matching the pattern.
        !           350: (defmacro firstfetch (pattern)
        !           351:   `(nextitem (fetch ,pattern)))
        !           352:  
        !           353: (defmacro fetchcreate (&rest rest)
        !           354:   `(fetch (create .,rest)))
        !           355:  
        !           356: (defmacro inlinefetchcreate (&rest rest)
        !           357:   `(fetch (quote ,(create rest))))
        !           358:  
        !           359: (defmacro inlinecreate (&rest rest)       
        !           360:   `(quote ,(create rest)))
        !           361:  
        !           362: ; Build a value to pass to the function for the parameter for this slot.
        !           363: (dm fcnslot (none)
        !           364:   '(let ((slotv (getvalue slotnum item))
        !           365:         (type (getslottype slotnum defblock)))
        !           366:        (cond ((eq slotv (punbound))       (punbound))
        !           367:              ((and (<& type 4)
        !           368:                    (or (not (\=& 0 type))
        !           369:                        (not (get (getpname (getdefinition slotv))
        !           370:                                  'functionstruct))))        slotv)
        !           371:              ((\=& 0 type)
        !           372:               (evalfcn slotv))
        !           373:              ((\=& 0 (boole 1 3 type))
        !           374:               (mapcar (function evalfcn) slotv))
        !           375:              ( t slotv))))
        !           376:  
        !           377: ; Evaluate a function structure.
        !           378: (de evalfcn (item)
        !           379:   (cond ((dtpr item) (mapcar (function evalfcn) item))
        !           380:        ((not (get (getpname (getdefinition item)) 'functionstruct)) item)
        !           381:        ( t (let* ((defblock (getdefinition item))
        !           382:                   (length (getstructlength defblock))
        !           383:                   (fcncall (ncons nil))
        !           384:                   slotv)
        !           385:                  (tconc fcncall (getpname defblock))
        !           386:                  (for slotnum 1 length
        !           387:                       (tconc fcncall (fcnslot)))
        !           388:                  (apply* (caar fcncall) (cdar fcncall))))))
        !           389:  
        !           390: ; A kludge to be removed (with disguisedas) when we implement VIEWS.
        !           391: (defmacro getstructorsymnum (strsym) 
        !           392:   `(cond ((psymbolp ,strsym) (getuniquenum ,strsym))
        !           393:         (  t  (getuniquenum (getdefinition ,strsym)))))
        !           394:  
        !           395: ; (DISGUISEDAS Filler Struct DB) means "Is filler a struct?
        !           396: ; if there is an item in the data base DB of the form
        !           397: ;         (STRUCT (<first slot> FILLER) ... )
        !           398: ; then return it.   If not, return NIL.
        !           399: (de disguisedas (filler struct &optional (db *db*))
        !           400:   (prog (fillernum bucket db2 item value)
        !           401:        (setq db2 (getdb2 db))
        !           402:        (setq fillernum (getstructorsymnum filler))
        !           403:        (setq bucket (remq '*db*
        !           404:                           (gethash2 (getuniquenum struct) fillernum db2)))
        !           405:        loop
        !           406:        (cond ((null bucket) (return nil))
        !           407:              ((and (eq struct (getdefinition (setq item (pop bucket))))
        !           408:                    (neq (punbound) (setq value (getvalue 1 item)))
        !           409:                    (eq (getstructorsymnum value) fillernum))
        !           410:               (return item))
        !           411:              ( t (go loop)))))
        !           412: 
        !           413: (de insertbyfocus (focus item db1 db2)
        !           414:   (prog (unique mark** mark:: mark*** defblock
        !           415:                value hashinfo hashv focusslotnum)
        !           416:        (setq defblock (getdefinition focus))
        !           417:        (setq unique (getuniquenum defblock))
        !           418:        (puthash1 unique db1 item)
        !           419:        (and (not (\=& 0 (setq focusslotnum (gethashfocus defblock))))
        !           420:             (pboundp (setq value (getvalue focusslotnum focus)))
        !           421:             (insertbyfocus value item db1 db2))
        !           422:        (for slotnum 1 (getstructlength defblock)
        !           423:             (setq hashinfo (gethashinfo slotnum defblock))
        !           424:             (cond ((\=& 0 hashinfo) nil)
        !           425:                   ((hashablevalue slotnum focus defblock hashinfo) ; Sets HASHV
        !           426:                    (and (gethash*  hashinfo)
        !           427:                         (puthash2  unique hashv db2 item))
        !           428: ;                  (and (gethash:  hashinfo)
        !           429: ;                       (puthash1  hashv db1 item))
        !           430:                    (and (gethash** hashinfo)
        !           431:                         (cond ((null mark**)
        !           432:                                ; First one found.
        !           433:                                (setq mark** hashv))
        !           434:                               ; Second one found
        !           435:                               ((neq t mark**)
        !           436:                                (puthash3 unique mark** hashv db2 item)
        !           437:                                (setq mark** t))
        !           438:                               ; Third or greater found.
        !           439:                               (  t  (msg t "HASH: More than two **'s in: "
        !           440:                                          (getpname defblock) t))))
        !           441: ;                  (and (gethash:: hashinfo)
        !           442: ;                       (cond ((null mark::)
        !           443: ;                              ; First one found.
        !           444: ;                              (setq mark:: hashv))
        !           445: ;                             ; Second one found
        !           446: ;                             ((neq t mark::)
        !           447: ;                              (puthash2 mark:: hashv db2 item)
        !           448: ;                              (setq mark:: t))
        !           449: ;                             ; Third or greater found.
        !           450: ;                             (  t  (msg t "HASH: More than two ::'s in: "
        !           451: ;                                        (getpname defblock) t))))
        !           452:                    (and (gethash*** hashinfo)
        !           453:                         (cond ((null mark***)
        !           454:                                ; First one found.
        !           455:                                (setq mark*** (ncons hashv)))
        !           456:                               ; Later ones found.
        !           457:                               (  t  (tconc mark*** hashv))))
        !           458:                    )))
        !           459:        (and mark***
        !           460:             (puthashmulti unique (car mark***) db2 item))))
        !           461: 
        !           462: ; We must put this struct into the data base somewhere,
        !           463: ; perhaps in several places.
        !           464: (de insertdb (item &optional (db *db*))
        !           465:   (or item
        !           466:       (progn (msg t "Trying to INSERTDB a nil item: " item t)
        !           467:             (pearlbreak)))
        !           468:   (and (dtpr item)
        !           469:        (progn (msg t "Trying to INSERTDB a cons-cell: " item t)
        !           470:              (pearlbreak)))
        !           471:   (cond ((get (getpname (getdefinition item)) 'functionstruct)
        !           472:         (evalfcn item))
        !           473:        (  t
        !           474:         (prog (unique mark** mark:: mark*** defblock db1 db2
        !           475:                       value hashinfo hashv result focus)
        !           476:               (setq defblock (getdefinition item))
        !           477:               (setq *currentpearlstructure* item)
        !           478:               (checkrunhandlebasehooks1 '<insertdb *runinsertdbhooks*)
        !           479:               (setq unique (getuniquenum defblock))
        !           480:               (setq db1 (getdb1 db))
        !           481:               (setq db2 (getdb2 db))
        !           482:               (puthash1 unique db1 item)
        !           483:               (and (not (\=& 0 (setq focus (gethashfocus defblock))))
        !           484:                    (pboundp (setq value (getvalue focus item)))
        !           485:                    (insertbyfocus value item db1 db2))
        !           486:               
        !           487:               (for slotnum 1 (getstructlength defblock)
        !           488:                    (setq hashinfo (gethashinfo slotnum defblock))
        !           489:                    (hashslot))
        !           490:               (and mark***
        !           491:                    (puthashmulti unique (car mark***) db2 item))
        !           492:               (checkrunhandlebasehooks1 '>insertdb *runinsertdbhooks*)
        !           493:               (return item)))))
        !           494:  
        !           495: ; For each way that this slot can be hashed, destructively remove the
        !           496: ;     item from the correct bucket.  Expects SLOTNUM, DEFBLOCK, ITEM,
        !           497: ;     MARK**, MARK::, MARK***, HASHV, UNIQUE, DB1, DB2.
        !           498: (dm removeslot (none)
        !           499:   '(cond ((\=& 0 hashinfo) nil) ; No hashing to be done
        !           500:         ((hashablevalue slotnum item defblock hashinfo) ; Sets HASHV
        !           501:          (and (gethash*  hashinfo)
        !           502:               (delq item (gethash2 unique hashv db2)))
        !           503: ;        (and (gethash:  hashinfo)
        !           504: ;             (delq item (gethash1 hashv db1)))
        !           505:          (and (gethash** hashinfo)
        !           506:               (cond ((null mark**)
        !           507:                      (setq mark** hashv))
        !           508:                     ((neq t mark**)
        !           509:                      (delq item (gethash3 unique mark** hashv db2))
        !           510:                      (setq mark** t))
        !           511:                     (  t  (msg t "More than two **'s in: "
        !           512:                                (getpname defblock) t))))
        !           513: ;        (and (gethash:: hashinfo)
        !           514: ;             (cond ((null mark::)
        !           515: ;                    (setq mark:: hashv))
        !           516: ;                   ((neq t mark::)
        !           517: ;                    (delq item (gethash2 mark:: hashv db2))
        !           518: ;                    (setq mark:: t))
        !           519: ;                   (  t  (msg t "More than two ::'s in: "
        !           520: ;                              (getpname defblock) t))))
        !           521:           (and (gethash*** hashinfo)
        !           522:               (cond ((null mark***)
        !           523:                      ; First one found.
        !           524:                      (setq mark*** (ncons hashv)))
        !           525:                     ; Later ones found.
        !           526:                     (  t  (tconc mark*** hashv))))
        !           527: )))
        !           528:  
        !           529: (de removebyfocus (focus item db1 db2)
        !           530:   (prog (unique mark** mark:: mark*** defblock hashinfo hashv focusslotnum)
        !           531:        (setq defblock (getdefinition focus))
        !           532:        (setq unique (getuniquenum defblock))
        !           533:        (dremove item (gethash1 unique db1))
        !           534:        (and (not (\=& 0 (setq focusslotnum (gethashfocus defblock))))
        !           535:             (removebyfocus (getvalue focusslotnum focus) item db1 db2))
        !           536:        (for slotnum 1 (getstructlength defblock)
        !           537:             (setq hashinfo (gethashinfo slotnum defblock))
        !           538:             (cond ((\=& 0 hashinfo) nil)
        !           539:                   ((hashablevalue slotnum focus defblock hashinfo) ; Sets HASHV
        !           540:                    (and (gethash*  hashinfo)
        !           541:                         (delq item (gethash2 unique hashv db2)))
        !           542: ;                  (and (gethash:  hashinfo)
        !           543: ;                       (delq item (gethash1 hashv db1)))
        !           544:                    (and (gethash** hashinfo)
        !           545:                         (cond ((null mark**)
        !           546:                                (setq mark** hashv))
        !           547:                               ((neq t mark**)
        !           548:                                (delq item (gethash3 unique mark** hashv db2))
        !           549:                                (setq mark** t))
        !           550:                               (  t  (msg t "More than two **'s in: "
        !           551:                                          (getpname defblock) t))))
        !           552: ;                  (and (gethash:: hashinfo)
        !           553: ;                       (cond ((null mark::)
        !           554: ;                              (setq mark:: hashv))
        !           555: ;                             ((neq t mark::)
        !           556: ;                              (delq item (gethash2 mark:: hashv db2))
        !           557: ;                              (setq mark:: t))
        !           558: ;                             (  t  (msg t "More than two ::'s in: "
        !           559: ;                                      (getpname defblock) t))))
        !           560:                    (and (gethash*** hashinfo)
        !           561:                         (cond ((null mark***)
        !           562:                                ; First one found.
        !           563:                                (setq mark*** (ncons hashv)))
        !           564:                               ; Later ones found.
        !           565:                               (  t  (tconc mark*** hashv))))
        !           566:                    )))
        !           567:        (and mark***
        !           568:             (delq item (gethashmulti unique mark*** db2)))
        !           569:        ))
        !           570: 
        !           571: ; We may have to remove this struct from several places so look
        !           572: ;   every place it might have been hashed.
        !           573: (de removedb (item &optional (db *db*))
        !           574:   (or item
        !           575:       (progn (msg t "Trying to REMOVEDB a nil item: " item t)
        !           576:             (pearlbreak)))
        !           577:   (and (dtpr item)
        !           578:        (progn (msg t "Trying to REMOVEDB a cons-cell: " item t)
        !           579:              (pearlbreak)))
        !           580:   (or (structurep item)
        !           581:       (progn (msg t "Trying to REMOVEDB a non-structure: " item t)
        !           582:             (pearlbreak)))
        !           583:   (cond ((get (getpname (getdefinition item)) 'functionstruct) nil)
        !           584:        (  t
        !           585:         (prog (unique mark** mark:: mark*** defblock db1 db2
        !           586:                       hashinfo hashv result focus)
        !           587:               (setq defblock (getdefinition item))
        !           588:               (setq *currentpearlstructure* item)
        !           589:               (checkrunhandlebasehooks1 '<removedb *runremovedbhooks*)
        !           590:               (setq unique (getuniquenum defblock))
        !           591:               (or db
        !           592:                   (setq db *db*))
        !           593:               (setq db1 (getdb1 db))
        !           594:               (setq db2 (getdb2 db))
        !           595:               (delq item (gethash1 unique db1))
        !           596:               (and (not (\=& 0 (setq focus (gethashfocus defblock))))
        !           597:                    (removebyfocus (getvalue focus item) item db1 db2))
        !           598:               (for slotnum 1 (getstructlength defblock)
        !           599:                    (setq hashinfo (gethashinfo slotnum defblock))
        !           600:                    (removeslot))
        !           601:               (and mark***
        !           602:                    (delq item (gethashmulti unique mark*** db2)))
        !           603:               (checkrunhandlebasehooks1 '>removedb *runremovedbhooks*)
        !           604:               (return item)))))
        !           605:  
        !           606: ; Find the next item on the CDDR list of the stream that is STREQUAL to
        !           607: ; the CADR of the stream and return it, also updating the stream.
        !           608: (de nextequal (stream)
        !           609:   (or (streamp stream)
        !           610:       (progn (msg t "NEXTEQUAL:  not a stream: " stream t)
        !           611:             (pearlbreak)))
        !           612:   (setq stream (cdr stream))    ; Throw away the *STREAM*.
        !           613:   (cond ((eq t (car stream))    ; This means function structure.
        !           614:         (prog1 (evalfcn (cdr stream))
        !           615:                (rplacd (rplaca stream nil) nil)))
        !           616:        ((null (cadr stream)) nil)   ; Test for empty stream
        !           617:        ; Stream built by standardfetch.
        !           618:        ; To debug or modify this, you must draw a picture of what
        !           619:        ;   standardfetch built because of the way it is written.
        !           620:        ((not (dtpr (cadr stream)))
        !           621:         (prog (item result)
        !           622:               (setq item (car stream))
        !           623:               (setq *currentpearlstructure* item)
        !           624:               (checkrunhandlebasehooks1 '<nextequal *runnextequalhooks*)
        !           625:               (while (and (cdr stream)
        !           626:                           (or (eq (cadr stream) '*db*)
        !           627:                               (not (strequal item (cadr stream)))))
        !           628:                      (rplacd stream (cddr stream)))
        !           629:               (cond ((cadr stream)
        !           630:                      (setq item (cadr stream)))
        !           631:                     ( t (setq item nil)))
        !           632:               (rplacd stream (cddr stream))
        !           633:               (checkrunhandlebasehooks1 '>nextequal *runnextequalhooks*)
        !           634:               (return item)))
        !           635:        ; Stream built by expandedfetch (or fetcheverywhere).
        !           636:        ; To debug or modify this, you must draw a picture of what
        !           637:        ;   expandedfetch built because of the way it is written.
        !           638:        ((not (dtpr (caadr stream)))
        !           639:         (prog (item result)
        !           640:               (setq item (car stream))
        !           641:               (setq *currentpearlstructure* item)
        !           642:               (checkrunhandlebasehooks1 '<nextequal *runnextequalhooks*)
        !           643:               (while (and (cdr stream)
        !           644:                           (or (eq (caadr stream) '*db*)
        !           645:                               (not (strequal item (caadr stream)))))
        !           646:                      (or (car (rplaca (cdr stream) (cdadr stream)))
        !           647:                          (rplacd stream (cddr stream))))
        !           648:               (cond ((cadr stream)
        !           649:                      (setq item (caadr stream)))
        !           650:                     ( t (setq item nil)))
        !           651:               (or (not (cdr stream))
        !           652:                   (car (rplaca (cdr stream) (cdadr stream)))
        !           653:                   (rplacd stream (cddr stream)))
        !           654:               (checkrunhandlebasehooks1 '>nextequal *runnextequalhooks*)
        !           655:               (return item)))))
        !           656:  
        !           657: ; Find out if an EQUAL ITEM is in the DB by using FETCH and then
        !           658: ;  applying NEXTEQUAL.
        !           659: (de indb (item &optional (db *db*))
        !           660:   (prog (result newitem answer)
        !           661:        (setq *currentpearlstructure* item)
        !           662:        (checkrunhandlebasehooks1 '<indb *runindbhooks*)
        !           663:        (setq newitem nil)
        !           664:        (and (setq answer (nextequal (fetch item db)))
        !           665:             (setq newitem (setq item answer)))
        !           666:        (checkrunhandlebasehooks1 '>indb *runindbhooks*)
        !           667:        (and newitem
        !           668:             (neq item newitem)
        !           669:             (setq answer item))
        !           670:        (return answer)))
        !           671: 
        !           672: ; (FOREACH STREAM FCN) applies FCN to each element returned by
        !           673: ;    NEXTITEM from STREAM.
        !           674: (df foreach (l)
        !           675:   (let ((stream (eval (car l)))
        !           676:        (fcn (cadr l))
        !           677:        item)
        !           678:        (while (setq item (nextitem stream))
        !           679:              (apply* fcn (ncons item)))))
        !           680:  
        !           681: ; Convert a stream to a list of actual matchers.
        !           682: (de streamtolist (stream)
        !           683:   (let ((result (ncons nil))
        !           684:        item)
        !           685:        (while (setq item (nextitem stream))
        !           686:              (tconc result item))
        !           687:        (car result)))
        !           688:  
        !           689: 
        !           690: ; vi: set lisp:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.