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

1.1     ! root        1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; db.l ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             2: ; Functions for building and releasing a forest of data bases.
        !             3: ;    See the file "template" plus the discussion in the "lowlevel.l" file for
        !             4: ;        a picture and an idea of how data bases are arranged internally.
        !             5: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             6: ; Copyright (c) 1983 ,  The Regents of the University of California.
        !             7: ; All rights reserved.  
        !             8: ; Authors: Joseph Faletti and Michael Deering.
        !             9: 
        !            10: ; Clear out the *db* conscells in the two parts of the data base,
        !            11: ;    thus releasing the old buckets for GC, IF they aren't pointed
        !            12: ;    to from elsewhere.
        !            13: (de cleardb (&optional (db *db*))
        !            14:   (let ((parent (getdbparent db))
        !            15:        (db1 (getdb1 db))
        !            16:        (db2 (getdb2 db)))
        !            17:        (cond (parent (connectdb db parent))
        !            18:             (  t  (for slotnum 0 (1- *db1size*)
        !            19:                        (rplacd (cxr slotnum db1) nil))
        !            20:                   (for slotnum 0 (1- *db2size*)
        !            21:                        (rplacd (cxr slotnum db2) nil))))
        !            22:        t))
        !            23:  
        !            24: ; Used by builddb to connect the sibling's buckets with its parent's.
        !            25: ; Also used by cleardb on a sibling.
        !            26: (de connectdb (newdb olddb)
        !            27:   (let ((newdb1 (getdb1 newdb))
        !            28:        (newdb2 (getdb2 newdb))
        !            29:        (olddb1 (getdb1 olddb))
        !            30:        (olddb2 (getdb2 olddb)))
        !            31:        (for slotnum 0 (1- *db1size*)
        !            32:            (rplacd (cxr slotnum newdb1) (cxr slotnum olddb1)))
        !            33:        (for slotnum 0 (1- *db2size*)
        !            34:            (rplacd (cxr slotnum newdb2) (cxr slotnum olddb2)))
        !            35:        t))
        !            36:  
        !            37: ; Set the size for data bases to 2 to the "poweroftwo" -- actually
        !            38: ;    the next smaller prime number.
        !            39: ;    *Availablesizes* is in inits.l and is designed to
        !            40: ;        make the data bases a factor of 4 apart
        !            41: ;        EXCEPT in Franz, where the largest are equal-sized.
        !            42: (de setdbsize (poweroftwo)
        !            43:   (let (pair rebuilddb)
        !            44:        (and *activedbnames*
        !            45:            (progn (and *warn*
        !            46:                        (msg t "SETDBSIZE: Warning: Size change "
        !            47:                             "is causing the release of all databases."
        !            48:                             t "     You must rebuild all "
        !            49:                             "but the default yourself." t))
        !            50:                   (mapcar (funl (dbname) (releasedb (eval dbname)))
        !            51:                           (copy *activedbnames*))
        !            52:                   (setq rebuilddb t)
        !            53:                   ))
        !            54:        (and (or (<& poweroftwo 2.)
        !            55:                (>& poweroftwo 13.))
        !            56:            (progn (msg t "SETDBSIZE: Database size is a power to raise 2 to"
        !            57:                        t "    and must be greater than 1 and less than 14."
        !            58:                        t "    It cannot be " poweroftwo "." t)
        !            59:                   (pearlbreak)))
        !            60:        (or (setq pair (assq poweroftwo *availablesizes*))
        !            61:           (progn (msg t "SETDBSIZE: "
        !            62:                       "Database sizes are integer powers to raise 2 to." t)
        !            63:                  (pearlbreak)))
        !            64:        (setq *db2size* (cdr pair))
        !            65:        ; The sizes of the two parts of the data base are 
        !            66:        ;   in a 1 to 4 ratio.
        !            67:        (setq pair (assq (- poweroftwo 2.) *availablesizes*))
        !            68:        (setq *db1size* (cdr pair))
        !            69:        (and rebuilddb
        !            70:            (setq *db* (builddb *maindb*)))
        !            71:        t))
        !            72:  
        !            73: ; (BUILDDB NEWDB OLDDB)  Build an extension to OLDDB called NEWDB.  If OLDDB
        !            74: ;     is NIL then build at the bottom level, else add as a leaf of the tree.
        !            75: ; The new data base is stored under the atom which is its name,
        !            76: ;     unlike the rest of PEARL objects (i.e., no special-prefix atom).
        !            77: ; Each new leaf has each of its hash buckets tied into the buckets of the
        !            78: ;     parent so that nextitem need not know how many data bases it is
        !            79: ;     dealing with.
        !            80: (df builddb (l)
        !            81:   (let ((newdbname (car l))
        !            82:        (olddbname (cadr l)))
        !            83:        (and (memq newdbname *activedbnames*)
        !            84:            (progn (msg t "BUILDDB: " newdbname
        !            85:                        " is already an active database name." t)
        !            86:                   (pearlbreak)))
        !            87:        (and olddbname
        !            88:            ; Two db's given but old one bad.
        !            89:            (not (memq olddbname *activedbnames*))
        !            90:            (progn (msg t "BUILDDB: " olddbname
        !            91:                        " is not an active database name." t)
        !            92:                   (pearlbreak)))
        !            93:        (let ((newdb (makhunk 7))
        !            94:             (olddb (and olddbname
        !            95:                         (eval olddbname)))
        !            96:             (db1 (makhunk *db1size*))
        !            97:             (db2 (makhunk *db2size*)))
        !            98:            (push newdbname *activedbnames*)
        !            99:            (putdbname newdbname newdb)
        !           100:            (set newdbname newdb)
        !           101:            (puttypetag '*pearldb* newdb)
        !           102:            (putdbchildren nil newdb)
        !           103:            (setdbactive newdb)
        !           104:            (putdbparent olddb newdb)
        !           105:            (putdb1 db1 newdb)
        !           106:            (putdb2 db2 newdb)
        !           107:            ; add the *db* conscells.
        !           108:            (for slotnum 0 (1- *db1size*)
        !           109:                 (rplacx slotnum db1 (cons '*db* nil)))
        !           110:            (for slotnum 0 (1- *db2size*)
        !           111:                 (rplacx slotnum db2 (cons '*db* nil)))
        !           112:            (and olddb ; Two db's.
        !           113:                 ; add to parent's children.
        !           114:                 (putdbchildren (cons newdb (getdbchildren olddb))
        !           115:                                olddb)
        !           116:                 ; Connectdb does the extra work for adding to the tree.
        !           117:                 (connectdb newdb olddb))
        !           118:            newdb)))
        !           119:  
        !           120: ; Release a data base.   If its children are also released, then
        !           121: ;    it can be garbage collected.  If not, do not mark it inactive
        !           122: ;    until they are.
        !           123: (de releasedb (db)
        !           124:   (and (not (databasep db))
        !           125:        (progn (msg t "RELEASEDB: Argument is not a database." t)
        !           126:              (pearlbreak)))
        !           127:   (let ((dbname (getdbname db))
        !           128:        (parent (getdbparent db)))
        !           129:        (and (not (memq dbname *activedbnames*))
        !           130:            (progn (msg t "RELEASEDB: Trying to release an inactive database: "
        !           131:                        db t)
        !           132:                   (pearlbreak)))
        !           133:        (cond ((null (getdbchildren db))    ; No children.
        !           134:              (setq *activedbnames* (delq (getdbname db) *activedbnames*))
        !           135:              (and (equal *activedbnames* '(nil))
        !           136:                   (setq *activedbnames* nil))
        !           137:              (set dbname (unbound))
        !           138:              (putdbname nil db)
        !           139:              (and parent
        !           140:                   (putdbchildren (delq db (getdbchildren parent)) parent))
        !           141:              (cleardbactive db)
        !           142:              (putdbparent nil db)
        !           143:              (while (and parent                        ; There's a parent --
        !           144:                          (null (getdbchildren parent)) ; with 0 children --
        !           145:                          (not (getdbactive parent)))   ; that's inactive.
        !           146:                     (cleardb parent)
        !           147:                     (putdb1 nil parent)
        !           148:                     (putdb2 nil parent)
        !           149:                     ; Save next parent with prog1 and then remove self from
        !           150:                     ; parent's child list and clear out own parent pointer
        !           151:                     (setq parent
        !           152:                           (prog1
        !           153:                            (getdbparent parent)  ; To be the new parent
        !           154:                            (and (getdbparent parent)
        !           155:                                 (putdbchildren
        !           156:                                  (delq parent
        !           157:                                        (getdbchildren (getdbparent parent)))
        !           158:                                  (getdbparent parent))
        !           159:                                 )
        !           160:                            (putdbparent nil parent))))
        !           161:              (cleardb db)
        !           162:              (puttypetag '*pearlinactivedb* db)
        !           163:              (putdb1 nil db)
        !           164:              (putdb2 nil db))
        !           165:             ( t (setq *activedbnames* (delq dbname *activedbnames*))
        !           166:                 (and (equal *activedbnames* '(nil))
        !           167:                      (setq *activedbnames* nil))
        !           168:                 (set dbname (unbound))
        !           169:                 (putdbname nil db)
        !           170:                 (cleardbactive db)
        !           171:                 (puttypetag '*pearlinactivedb* db)
        !           172:                 (putdb1 nil db)
        !           173:                 (putdb2 nil db)))
        !           174:        t))
        !           175:  
        !           176: 
        !           177: ; 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.