|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.