Update of /project/elephant/cvsroot/elephant/src In directory common-lisp.net:/tmp/cvs-serv25325/src
Modified Files: controller.lisp Log Message: doc-strings table-layout for btrees better with-open-store macro
Date: Thu Sep 16 06:15:32 2004 Author: blee
Index: elephant/src/controller.lisp diff -u elephant/src/controller.lisp:1.9 elephant/src/controller.lisp:1.10 --- elephant/src/controller.lisp:1.9 Sat Sep 4 10:28:44 2004 +++ elephant/src/controller.lisp Thu Sep 16 06:15:31 2004 @@ -49,12 +49,16 @@ (environment :type (or null pointer-void) :accessor controller-environment) (db :type (or null pointer-void) :accessor controller-db) + (btrees :type (or null pointer-void) :accessor controller-btrees) + (indices :type (or null pointer-void) :accessor controller-indices) + (indices-assoc :type (or null pointer-void) + :accessor controller-indices-assoc) (root :reader controller-root) (instance-cache :accessor instance-cache :initform (make-cache-table :test 'eql))) - (:documentation "Class of objects responsible for handling -the book-keeping of holding DB handles, the cache, table -creation, counters, locks, the root and garbage collection, + (:documentation "Class of objects responsible for the +book-keeping of holding DB handles, the cache, table +creation, counters, locks, the root (for garbage collection,) et cetera."))
(defgeneric cache-instance (sc obj)) @@ -65,26 +69,24 @@
(defun add-to-root (key value &key (store-controller *store-controller*)) "Add an arbitrary persistent thing to the root, so you can -retrieve it in a later session. Keys may be arbitrary -persistables as well (though note collection key semantics!) -N.B. this means it (and everything it points to) won't get -gc'd." +retrieve it in a later session. N.B. this means it (and +everything it points to) won't get gc'd." (setf (get-value key (controller-root store-controller)) value))
-(defmethod get-from-root (key &key (store-controller *store-controller*)) - "Get a persistent thing from the root." +(defun get-from-root (key &key (store-controller *store-controller*)) + "Get a something from the root." (get-value key (controller-root store-controller)))
-(defmethod remove-from-root (key &key (store-controller *store-controller*)) - "Get a persistent thing from the root." +(defun remove-from-root (key &key (store-controller *store-controller*)) + "Remove something from the root." (remove-kv key (controller-root store-controller)))
(defmethod cache-instance ((sc store-controller) obj) - "Register an instance of a user persistent-class with the -controller." + "Cache a persistent object with the controller." (setf (get-cache (oid obj) (instance-cache sc)) obj))
(defmethod get-cached-instance ((sc store-controller) oid class-name) + "Get a cached instance, or instantiate!" (let ((obj (get-cache oid (instance-cache sc)))) (if obj obj ;; Should get cached since make-instance calls cache-instance @@ -111,6 +113,7 @@ (defvar %oid-lock-length 16)
(defmethod next-oid ((sc store-controller)) + "Get the next OID." (sleepycat::next-counter (controller-environment sc) (controller-db sc) *current-transaction* @@ -128,19 +131,46 @@ (db-env-open env (controller-path sc) :create t :init-txn t :init-lock t :init-mpool t :init-log t :thread thread :recover recover :recover-fatal recover-fatal) - (let ((db (db-create env))) + (let ((db (db-create env)) + (btrees (db-create env)) + (indices (db-create env)) + (indices-assoc (db-create env))) (setf (controller-db sc) db) (db-open db :file "%ELEPHANT" :database "%ELEPHANTDB" :auto-commit t :type DB-BTREE :create t :thread thread) + + (setf (controller-btrees sc) btrees) + (sleepycat::db-set-lisp-compare btrees) + (db-open btrees :file "%ELEPHANT" :database "%ELEPHANTBTREES" + :auto-commit t :type DB-BTREE :create t :thread thread) + + (setf (controller-indices sc) indices) + (sleepycat::db-set-lisp-compare indices) + (sleepycat::db-set-lisp-dup-compare indices) + (db-set-flags indices :dup-sort t) + (db-open indices :file "%ELEPHANT" :database "%ELEPHANTINDICES" + :auto-commit t :type DB-BTREE :create t :thread thread) + + (setf (controller-indices-assoc sc) indices-assoc) + (sleepycat::db-set-lisp-compare indices-assoc) + (sleepycat::db-set-lisp-dup-compare indices-assoc) + (db-set-flags indices-assoc :dup-sort t) + (db-open indices-assoc :file "%ELEPHANT" :database "%ELEPHANTINDICES" + :auto-commit t :type DB-UNKNOWN :thread thread :rdonly t) + (sleepycat::db-fake-associate btrees indices-assoc :auto-commit t) + (let ((root (make-instance 'btree :from-oid -1))) (setf (slot-value sc 'root) root) - (let ((*auto-commit* t)) - (unless (db-get-key-buffered db %oid-entry %oid-entry-length) - (buffer-write-int 0 *out-buf*) - (db-put-buffered db %oid-entry %oid-entry-length - (buffer-stream-buffer *out-buf*) 4 - :auto-commit t) - (finish-buffer *out-buf*))) + (with-transaction () + (with-buffer-streams (key-buf value-buf) + (let ((key-b (buffer-stream-buffer key-buf))) + (setf (buffer-stream-buffer key-buf) %oid-entry) + (setf (sleepycat::buffer-stream-size key-buf) %oid-entry-length) + (unless (db-get-key-buffered db key-buf value-buf) + (reset-buffer-stream value-buf) + (buffer-write-int 0 value-buf) + (db-put-buffered db key-buf value-buf)) + (setf (buffer-stream-buffer key-buf) key-b)))) sc))))
(defmethod close-controller ((sc store-controller)) @@ -151,7 +181,13 @@ (setf (slot-value sc 'root) nil) ;; clean instance cache (setf (instance-cache sc) (make-cache-table :test 'eql)) - ;; close environment + ;; close handles / environment + (db-close (controller-indices-assoc sc)) + (setf (controller-indices-assoc sc) nil) + (db-close (controller-indices sc)) + (setf (controller-indices sc) nil) + (db-close (controller-btrees sc)) + (setf (controller-btrees sc) nil) (db-close (controller-db sc)) (setf (controller-db sc) nil) (db-env-close (controller-environment sc)) @@ -160,6 +196,8 @@
(defmacro with-open-controller ((&optional (sc '*store-controller*)) &body body) + "Executes body with the specified controller open, closing +the controller unconditionally on exit." `(unwind-protect (progn (let (*store-controller* (open-controller ,sc)) @@ -167,21 +205,24 @@ ,@body)) (close-controller ,sc)))
-(defun open-store (path) +(defun open-store (path &key (recover nil) + (recover-fatal nil) (thread t)) + "Conveniently open a store controller." (setq *store-controller* (make-instance 'store-controller :path path)) - (open-controller *store-controller*)) + (open-controller *store-controller* :recover recover + :recover-fatal recover-fatal :thread thread))
(defun close-store () + "Conveniently close the store controller." (close-controller *store-controller*))
(defmacro with-open-store ((path) &body body) - (let ((sc (gensym))) - `(let ((,sc (make-instance 'store-controller :path ,path))) - (unwind-protect - (progn - (let ((*store-controller* ,sc)) - (declare (special *store-controller*)) - (open-controller *store-controller*) - ,@body)) - (close-controller ,sc))))) + "Executes the body with an open controller, +unconditionally closing the controller on exit." + `(let ((*store-controller* (make-instance 'store-controller :path ,path))) + (declare (special *store-controller*)) + (open-controller *store-controller*) + (unwind-protect + (progn ,@body) + (close-controller *store-controller*))))