[bknr-cvs] hans changed branches/anon-transaction-fixes-2/bknr/datastore/src/data/object
BKNR Commits
bknr at bknr.net
Mon Sep 22 18:33:13 UTC 2008
Revision: 3940
Author: hans
URL: http://bknr.net/trac/changeset/3940
Store next object id to use in snapshot file. This removes the
previous buggy behaviour that the store would re-use an object IDs
of objects deleted right before the snapshot has been written.
U branches/anon-transaction-fixes-2/bknr/datastore/src/data/object-tests.lisp
U branches/anon-transaction-fixes-2/bknr/datastore/src/data/object.lisp
Modified: branches/anon-transaction-fixes-2/bknr/datastore/src/data/object-tests.lisp
===================================================================
--- branches/anon-transaction-fixes-2/bknr/datastore/src/data/object-tests.lisp 2008-09-22 18:31:17 UTC (rev 3939)
+++ branches/anon-transaction-fixes-2/bknr/datastore/src/data/object-tests.lisp 2008-09-22 18:33:13 UTC (rev 3940)
@@ -54,15 +54,19 @@
(defvar *tests* (make-hash-table))
(defun do-run-test (thunk)
- (let ((bknr.datastore::*store-verbose* nil)
- initial-objects)
+ "Run the test in THUNK, then verify that the store contains the
+`same' objects after a restore and after snapshot and a restore."
+ (let ((bknr.datastore::*store-verbose* nil) initial-objects)
(funcall thunk)
- (setf initial-objects (object-classes-and-ids))
- (restore)
- (test-equal initial-objects (object-classes-and-ids))
- (snapshot)
- (restore)
- (test-equal initial-objects (object-classes-and-ids))))
+ (let ((next-object-id (bknr.datastore::next-object-id (bknr.datastore::store-object-subsystem))))
+ (setf initial-objects (object-classes-and-ids))
+ (restore)
+ (test-equal initial-objects (object-classes-and-ids))
+ (test-equal next-object-id (bknr.datastore::next-object-id (bknr.datastore::store-object-subsystem)))
+ (snapshot)
+ (restore)
+ (test-equal initial-objects (object-classes-and-ids))
+ (test-equal next-object-id (bknr.datastore::next-object-id (bknr.datastore::store-object-subsystem))))))
(defmacro defdstest (name args &body body)
(when args
@@ -150,6 +154,13 @@
(time (map-store-objects #'delete-object))
(test-equal (all-store-objects) nil)))
+(defdstest holes-test ()
+ (dotimes (i +stress-size+)
+ (let ((delete (zerop (random 2))))
+ (with-transaction (:foo)
+ (funcall (if delete #'delete-object #'identity)
+ (make-instance 'store-object))))))
+
(defdstest make-instance-in-anon-txn ()
(with-transaction ()
(make-instance 'store-object))
@@ -228,14 +239,7 @@
(restore)
(test-assert (< object-id (store-object-id (make-instance 'store-object))))))
-#+(or)
(defdstest delete-object-and-check-object-id-of-next-3 ()
-;; This test currently fails: The store has no explicit knowledge of
-;; the object ID that it created. Instead, the next free object ID is
-;; determined during restore by looking at the IDs of the objects
-;; being restored. If the last object that has been created is
-;; deleted right before the snapshot is written, the next object after
-;; a restore will receive the same ID.
(let (object-id)
(with-transaction (:make)
(let ((object (make-instance 'store-object)))
Modified: branches/anon-transaction-fixes-2/bknr/datastore/src/data/object.lisp
===================================================================
--- branches/anon-transaction-fixes-2/bknr/datastore/src/data/object.lisp 2008-09-22 18:31:17 UTC (rev 3939)
+++ branches/anon-transaction-fixes-2/bknr/datastore/src/data/object.lisp 2008-09-22 18:33:13 UTC (rev 3940)
@@ -498,7 +498,8 @@
(when class
(let ((object (allocate-instance class)))
(setf (slot-value object 'id) object-id
- (next-object-id (store-object-subsystem)) (1+ object-id))
+ (next-object-id (store-object-subsystem)) (max (1+ object-id)
+ (next-object-id (store-object-subsystem))))
(dolist (index (class-slot-indices class 'id))
(index-add index object)))))))
@@ -590,6 +591,10 @@
id slot-name (type-of container)
(if container (store-object-id container) "unknown object"))))))
+(defun encode-current-object-id (stream)
+ (%write-tag #\I stream)
+ (%encode-integer (next-object-id (store-object-subsystem)) stream))
+
(defmethod snapshot-subsystem ((store store) (subsystem store-object-subsystem))
(let ((snapshot (store-subsystem-snapshot-pathname store subsystem)))
(with-open-file (s snapshot
@@ -600,6 +605,7 @@
(let ((class-layouts (make-hash-table)))
(with-transaction (:prepare-for-snapshot)
(map-store-objects #'prepare-for-snapshot))
+ (encode-current-object-id s)
(map-store-objects (lambda (object) (when (subtypep (type-of object) 'store-object)
(encode-create-object class-layouts object s))))
(map-store-objects (lambda (object) (when (subtypep (type-of object) 'store-object)
@@ -644,10 +650,11 @@
(report-progress "~A of ~A objects initialized.~%" read-slots created-objects)
(force-output))
(let ((char (%read-tag s nil nil)))
- (unless (member char '(#\O #\L #\S nil))
+ (unless (member char '(#\I #\L #\O #\S nil))
(error "unknown char ~A at offset ~A~%" char (file-position s)))
(ecase char
((nil) (return))
+ (#\I (setf (next-object-id (store-object-subsystem)) (%decode-integer s)))
(#\L (snapshot-read-layout s class-layouts))
(#\O (snapshot-read-object s class-layouts) (incf created-objects))
(#\S (snapshot-read-slots s class-layouts) (incf read-slots))))))
More information about the Bknr-cvs
mailing list