[elephant-cvs] CVS elephant/src
ieslick
ieslick at common-lisp.net
Thu Feb 2 21:48:39 UTC 2006
Update of /project/elephant/cvsroot/elephant/src
In directory common-lisp:/tmp/cvs-serv6576/src
Modified Files:
Tag: ELEPHANT-0-4-1-rc1-IAN
IAN-TODO classes.lisp controller.lisp index-utils.lisp
indexing.lisp
Log Message:
There may be a bug or two left, but the major locking problems have been
resolved. Interactions due to reconnecting to databases can be problematic
(i.e. indexing a new object when a cursor is walking the indices for that
object leads to deadlock in the bdb code where the cursor has a read lock
on an index that the persistent indexing wanted to write)
More tests needed, but the system appears largely stable now.
--- /project/elephant/cvsroot/elephant/src/classes.lisp 2006/01/30 04:55:00 1.16.2.5
+++ /project/elephant/cvsroot/elephant/src/classes.lisp 2006/02/02 21:48:38 1.16.2.6
@@ -79,20 +79,30 @@
metaclass.")
(:metaclass persistent-metaclass))
-(defmethod initialize-instance ((instance persistent-object) &rest initargs)
+;;(defmethod print-object ((obj persistent) stream)
+
+(defmethod initialize-instance ((instance persistent-object) &rest initargs &key from-oid &allow-other-keys)
(declare (ignore initargs))
(if (indexed (class-of instance))
- (progn
- (inhibit-indexing (oid instance))
- (unwind-protect
- (progn
- (call-next-method)
- (uninhibit-indexing (oid instance))
- (let ((class-index (find-class-index (class-of instance))))
- (with-transaction ()
- (setf (get-value (oid instance) class-index) instance))))
- (uninhibit-indexing (oid instance))))
- (call-next-method)))
+ (progn
+ (let ((oid (oid instance)))
+ (declare (type fixnum oid))
+ (inhibit-indexing oid)
+ (unwind-protect
+ (call-next-method)
+ (uninhibit-indexing oid))
+ ;; Inhibit indexing if the object already was defined (ie being created from an oid)
+ ;; as it should be indexed already. This hack avoids a deadlock situation where we
+ ;; write the class or index page that we are currently reading via a cursor without
+ ;; going through the cursor abstraction. There has to be a better way to do this.
+ (when (not from-oid)
+ (let ((class-index (find-class-index (class-of instance))))
+ (when class-index
+;; (format t "Indexing initial instance: ~A :: ~A~%" oid instance)
+ (with-transaction ()
+ (setf (get-value oid class-index) instance)))))))
+ ;; else
+ (call-next-method)))
(defmethod shared-initialize :around ((class persistent-metaclass) slot-names &rest args &key direct-superclasses)
"Ensures we inherit from persistent-object."
--- /project/elephant/cvsroot/elephant/src/controller.lisp 2006/01/29 04:57:20 1.14.2.2
+++ /project/elephant/cvsroot/elephant/src/controller.lisp 2006/02/02 21:48:38 1.14.2.3
@@ -56,15 +56,17 @@
)
(defun get-controller (spec)
- (let ((store-controllers nil))
- (dolist (s *strategies*)
- (let ((sc (funcall s spec)))
- (if sc
- (push sc store-controllers))))
- (if (not (= (length store-controllers) 1))
- (error "Strategy resolution for this spec completely failed!")
- (car store-controllers))
- ))
+ (let ((cached-sc (gethash spec *dbconnection-spec*)))
+ (if cached-sc cached-sc
+ (let ((store-controllers nil))
+ (dolist (s *strategies*)
+ (let ((sc (funcall s spec)))
+ (if sc
+ (push sc store-controllers))))
+ (if (not (= (length store-controllers) 1))
+ (error "Strategy resolution for this spec completely failed!")
+ (car store-controllers))
+ ))))
(defclass store-controller ()
@@ -359,7 +361,7 @@
(setf (slot-value sc 'class-root) nil)
(setf (slot-value sc 'root) nil)
;; clean instance cache
- (setf (instance-cache sc) (make-cache-table :test 'eql))
+ (reset-instance-cache sc)
;; close handles / environment
(db-sequence-close (controller-oid-seq sc))
(setf (controller-oid-seq sc) nil)
@@ -375,7 +377,10 @@
(setf (controller-db sc) nil)
(db-env-close (controller-environment sc))
(setf (controller-environment sc) nil)
- nil))
+ nil)
+ ;; Delete connection spec so object ops on cached db info fail
+ (remhash (controller-path *store-controller*) *dbconnection-spec*))
+
;; Do these things need to take &rest arguments?
(defmethod build-btree ((sc bdb-store-controller))
@@ -426,23 +431,25 @@
the controller unconditionally on exit."
`(unwind-protect
(progn
- (let (*store-controller* (open-controller ,sc))
+ (let ((*store-controller* (open-controller ,sc)))
(declare (special *store-controller*))
, at body))
(close-controller ,sc)))
(defun close-store ()
"Conveniently close the store controller."
+ (declare (special *store-controller*))
(if *store-controller*
- (close-controller *store-controller*)))
+ (progn
+ (close-controller *store-controller*)
+ (setf *store-controller* nil))))
(defmacro with-open-store ((spec) &body body)
"Executes the body with an open controller,
unconditionally closing the controller on exit."
- `(let ((*store-controller*
- (get-controller ,spec)))
+ `(let ((*store-controller* (get-controller ,spec)))
(declare (special *store-controller*))
-;; (open-controller *store-controller*)
+ (open-controller *store-controller*)
(unwind-protect
(progn , at body)
(close-controller *store-controller*))))
More information about the Elephant-cvs
mailing list