Ok, this is an architectural issue that wasn't completely thought out. Currently class indexing effectively limits instances of a class to a specific store. The first time an instance is saved, the current *store-controller* is used to create the class index tying the class to that store.

I have a local patch which changes this behavior to create a class index for each store's objects. For example, in your test code, if you call get-instances-by-class in the context of *sc1*, you'll get nothing, in the context of *sc2* you'll get the instance you created in *sc2*. Each store has it's own local set of class indices.

The problem here is that there are quite a few assumptions baked into class indexing that ties a given class to a given store: - The class object has an index cache which can only point to one store at a time. - The list of indexed slots in-memory can be synchronized to a store's version when the class is first used (to avoid losing track of existing indices of objects); two stores with two different versions of indexed slots would create very complex behavior - What if one store is created with one definition of a class, but another store is created with different defintion? If the classes are both indexed and have the same class name, one store's data may be overwritten by the definition created for another.

The solution is probably to ensure that the class behaves differently in the context of a given store, but then I imagine we'd have to keep a per-store list of indexed slots and dispatch writes based on those differences.

I'm concerned there are other areas where the policy choice becomes difficult. My inclination is to assert that if you want to index persistent objects in multiple stores, you should plan for that explicitly and not use the class indexing mechanism.

I'm willing to be argued in the other direction, but I'm not terribly motivated to chase down all the possible corner cases at this point.

Ian


On Feb 20, 2008, at 10:49 AM, Leslie P. Polzer wrote:


This concerns indexed classes.

Observe:


(asdf:oos 'asdf:load-op 'elephant)

(defpackage #:ele-test (:use :cl :elephant))

(in-package :ele-test)

(defvar *sc2* nil)
(defvar item nil)

(defpclass myclass ()
 ((testslot :accessor testslot :initarg testslot :index t)))

(open-store '(:BDB "/tmp/db1") :recover t)
(setf *sc2* (open-store '(:BDB "/tmp/db2") :recover t))

(let ((*store-controller* *sc2*))
 (setf item (make-instance 'myclass)))

(setf (testslot item) 5)
; ==> Attempted to write object #<MYCLASS oid:100> with home store
; #<BDB-STORE-CONTROLLER /tmp/db2> into store #<BDB-STORE- CONTROLLER /tmp/db1>


(close-store)
(close-store *sc2*)


Intuitively, the SLOT-VALUE writer should have figured out the
correct store controller on its own, by simply looking up ITEM's
home controller. Instead, one has to specify it explicitly:

(let ((*store-controller* *sc2*))
 (setf (testslot item) 5)) ; works

Is there any sensible reason for this behaviour?
Is my suspicion correct that multi-store operation is a point that isn't
covered well by the unit tests and experience?

 Leslie

_______________________________________________
elephant-devel site list
elephant-devel@common-lisp.net
http://common-lisp.net/mailman/listinfo/elephant-devel

_______________________________________________
elephant-devel site list
elephant-devel@common-lisp.net
http://common-lisp.net/mailman/listinfo/elephant-devel

Reply via email to