[elephant-cvs] CVS elephant/doc

ieslick ieslick at common-lisp.net
Wed Apr 26 17:53:43 UTC 2006


Update of /project/elephant/cvsroot/elephant/doc
In directory clnet:/tmp/cvs-serv12311/doc

Modified Files:
	installation.texinfo intro.texinfo reference.texinfo 
	tutorial.texinfo 
Log Message:

Significant additions to the 0.6.0 release on the trunk.  Updates to 
documentation, 0.5.0 compliance, final on 0.6.0 features.  There are
one or two BDB interactions on migration to work out but this should
be a nearly code complete 0.6.0 release.  Please start testing and
evaluating this - especially the ability to open and tag 0.5.0 databases.

Features:
- Database version tagging
- Support for 0.5.0 namespaces & databases
- New migration system
- class indexing without slot indexing
- various bug fixes
- reverted fast allegro/sbcl string support to
  allow 0.5.0 databases to work correctly.  I 
  couldn't find a good way to work around this
  without creating infinite headaches
- validated that running db_deadlock will stop all
  lisp freezes that I've encountered.  This has to
  be run each time a DB environment is opened/created
  so eventually should be made part of the open-controller
  functionality for the BDB backend



--- /project/elephant/cvsroot/elephant/doc/installation.texinfo	2006/01/24 20:37:43	1.1
+++ /project/elephant/cvsroot/elephant/doc/installation.texinfo	2006/04/26 17:53:43	1.2
@@ -12,7 +12,6 @@
 * Extention Status:: The current status of the SQL back-end extention.
 * Multi-repository Operation:: Specifying repositories
 * Setting up PostGres:: An example
-* Repository Migration:: How to move objects from one repository to another
 @end menu
 
 @node Installation Basics 
@@ -28,11 +27,11 @@
 (asdf:operate 'asdf:load-op :elephant)
 @end lisp
 
-
-
 However, Elephant cannot function without a back-end repository.
 Elephant presents exactly the same API no matter what you choose
-as a repository.  However, you have to use asdf to load the 
+as a repository.  In most cases Elephant will automatically load
+the backend you refer to with your controller spec when you call
+open store.  However, you may have to use asdf to load the 
 code that interfaces to particular repository system.
 
 The basic choices are to use the BerkeleyDB system or 
@@ -53,7 +52,6 @@
 (asdf:oos 'asdf:load-op :clsql-postgresql-socket)
 @end lisp
 
-
 You will have to have the CL-SQL package installed.  Following the 
 documentation for CL-SQL under the section ``How CLSQL finds and loads foreign
 libraries'' you may need to do something like:
@@ -81,10 +79,10 @@
 same time.  More particularly, you can seamlessly migrate your
 data from one repository to a different one at a later date.
 In a long duration project, this might occur because of a licensing
-or performance issue with a particular respository.
-
-
-
+or performance issue with a particular respository.  Migrating to
+a new repository of the same type is a cheap form of GC although
+migration is limited to the total size of main memory to store
+a hash table that tracks all copied object ID's.
 
 @node Test-Suites
 @comment node-name, next, previous, up
@@ -200,14 +198,14 @@
 As of Elephant 0.3, Elephant has been tested to work with both Postgres, and 
 SQLite 3, thanks do Dan Knapp.
 
- at node Extention Status
+ at node Extension Status
 @comment node-name, next, previous, up
- at section Extention Status
+ at section Extension Status
 
 As far as is known at this writing, all functionality except nested transaction
-support and cursor-put's that is supported by the BerkeleyDB backend is supported by the CL-SQL
-based back-end.  Concurrency and transaction atomicity has not been tested well
-for the CL-SQL based system.
+support and cursor-puts supported by the BerkeleyDB backend is supported by the 
+CL-SQL back-end.  Concurrency and transaction atomicity have not been stress tested 
+well for the CL-SQL based system.
 
 Additionally, it is NOT the case that the Elephant system currently provides
 transaction support across multiple repositories; it provides the transaction
@@ -223,11 +221,7 @@
 
 The SQL back-end is as easy to use as the BerkeleyDB back-end.  However,
 the multi-repository version somewhat complicates the underlying 
-persistent object management.  At the time of this writing, the 
-community has not decided if this extention will be a part of 
-Elephant proper or a separate branch; if it is not made a part of 
-Elephant proper, a user might prefer the simpler (and better maintained?)
-system if they only want to use the BerkeleyDB back-end.
+persistent object management. 
 
 @node Multi-repository Operation
 @comment node-name, next, previous, up
@@ -247,7 +241,6 @@
 ELE-TESTS> 
 @end lisp
 
-
 The tests now have a function @code{do-all-tests-spec} that take a spec and 
 based on its type attempt to open the correct kind of store controller and 
 perform the tests.
@@ -366,42 +359,7 @@
 support but have not yet been tested.  The basic pattern of 
 the ``path'' specifiers is (cons clsqal-database-type-symbol (normal-clsql-connection-specifier)).
 
- at node Repository Migration
- at comment node-name, next, previous, up
- at section Repository Migration
-
-
-This version of Elephant supports migration betwen store controllers,
-whether of the same implementation strategy or not.
-
-The tests @code{migrate1} - @code{migrate5} are demonstrations of this techinque.
-
-The functions for performing these migrations are:
-
- at code{migraten-pobj}
-
-The name of this function is meant to imply that it is 
-destructive of the object in question, mutating it to 
-point at the new repository.
-
-Which requies that you provide a copy-function to copy whatever 
-slots you want from the persistent object as deeply or as shallowly 
-as you desire.
-
-Data collections (btree's) can be move with the function:
-
- at code{migrate}
-
-A simple object that does not inherit from ``persistent'' but is 
-attached to a key (on the root) can be copied with the routine
 
- at code{copy-from-key}
 
-It is hoped that these routines would allow, with some labor,
-a user to use one repository, and later decide to start using 
-a different implementation strategy, and easily migrate the 
-objects to the the new repository.  The old repository could
-then be abandoned, or multiple repositories could be used
-at the same time.
 
  
--- /project/elephant/cvsroot/elephant/doc/intro.texinfo	2006/03/02 14:44:49	1.3
+++ /project/elephant/cvsroot/elephant/doc/intro.texinfo	2006/04/26 17:53:43	1.4
@@ -5,52 +5,66 @@
 @chapter Introduction
 @cindex Introduction
 
-Elephant is an object database for Common Lisp. It supports
-storing CLOS objects and most lisp primitives, and access to
-BTrees. It can use the Sleepycat / Berkeley DB, a
-widely-distributed embedded database; many unix systems have
-it installed by default.  Sleepycat is server-less, ACID
-compliant, transactional, process and thread safe, and fast
-relative to relational databases; hopefully Elephant
-inherits these properties.
-
-It also provieds support for relational backends.  
-It has been tested with Postgres and SQLite 3.
-It supports simultaneous multi-repository
-operation and convenient migration of data between repositories.
-This hopefully allows decisions about the prefered back-end
-storage mechanism to be delayed and changed, even after 
-an application that uses Elephant is mature.
+Elephant is a persistent object database for Common Lisp that 
+supports storing CLOS objects and most lisp primitives.
+It supports persistent collections via a BTree interface.
+
+Elephant was originally developed as an interface layer on top 
+of the Sleepycat / Berkeley DB library, a widely-distributed 
+embedded database.  Many unix systems have it installed by default.  
+Berkeley DB is ACID compliant, transactional, process and 
+thread safe, and fast relative to relational databases.  Recently,
+Elephant was extended to provide support for relational database backends.
+It has been tested with Postgres and SQLite 3.  It supports, with some
+care, simultaneous multi-repository operation and enables convenient 
+migration of data between repositories.
+
+The support for relational backends and migration to the LLGPL was to 
+allow for broader use of Elephant in both not-for-profit and commercial
+settings. 
 
-Goals:
+Elephant goals:
 
 @itemize
 @item Transparency: most Lisp values are easy to persist without
-much effort or special syntax. Talk to the DB with Lisp code, not SQL
-or another domain-specific language. No additional server to run.
-
- at item Safety: ACID, transactions. Concurrent with good
-multi-user and -thread semantics / isolation, locking and deadlock
-detection.
-
- at item Simplicity: be a small library with few surprises for the
-programmer. Lisp and Berkeley DB together are an excellent substrate,
-try to use their features as much as possible.
+signifcant effort or special syntax.  Talk to the DB entirely from Lisp;
+not requirement for domain-specific languages (such as SQL) to access persistent
+resources.  Enable interactive control of the database with no external 
+server dependencies.
+
+ at item Safety: ACID, transactions. Concurrent with good multi-user and 
+multi-threaded semantics, isolation, locking and deadlock detection.
+(Deadlock detection does require an external process to be launched)
+
+ at item Simplicity: a small library with few surprises for the
+programmer. Lisp and Berkeley DB together are an excellent substrate;
+Elephant tries to leverage their features as much as possible.  
+Support for multiple backends should be load-time options and mostly
+transparent to the user.
 
 @item Performance: leverage Sleepycat performance and
 reliability.  In addition to fast concurrent / transactional modes,
-elephant will (eventually) offer an accellerated single-user mode.
+elephant will (eventually) offer an accellerated single-user as
+well as in-memory modes that should be comparable to prevalence 
+style solutions, but leverage a common interface.  
+
+ at item Historical continuity: Elephant does not try to innovate
+significantly over prior Lisp persistent object stores such as
+AllegroStore (also based on Berkeley DB), the new AllegroCache,
+the Symbolics system Statice and PLOB.  Anyone familiar with
+those systems will recognize the Elephant interface.
 
 @item License Flexibility: Elephant is released under the LLGPL.
 Because it supports multiple implementation of the backend, one
-can choose a backend with licensing and other features appropriate to your needs.
- at end itemize
-
+can choose a backend with licensing and other features appropriate 
+to your needs.
 
+ at end itemize
 
 Join the Elephant mailing lists to ask your questions and
-receive updates.  They're on the Elephant website at
+receive updates.  Pointers can be found on the Elephant website at
 
 @uref{http://www.common-lisp.net/project/elephant}.
 
 Installation documents can be found in the file @file{INSTALL}.
+Opportunities to contribute can be found in the file @file{TODO}.
--- /project/elephant/cvsroot/elephant/doc/reference.texinfo	2005/11/23 17:51:34	1.2
+++ /project/elephant/cvsroot/elephant/doc/reference.texinfo	2006/04/26 17:53:43	1.3
@@ -56,6 +56,23 @@
 @include includes/class-elephant-persistent.texinfo
 @include includes/class-elephant-persistent-object.texinfo
 
+ at node Persistent Slot Indexing
+ at comment node-name, next, previous, up
+ at section Persistent Slot Indexing
+ at cindex Persistent Slot Indexing
+
+ at include includes/get-instances-by-class
+ at include includes/get-instance-by-value
+ at include includes/get-instances-by-value
+ at include includes/get-instances-by-range
+
+ at include includes/fun-elephant-enable-class-indexing
+ at include includes/fun-elephant-disable-class-indexing
+ at include includes/fun-add-class-slot-index
+ at include includes/fun-remove-class-slot-index
+ at include includes/fun-add-class-derived-index
+ at include includes/fun-remove-class-derived-index
+
 @node Collections
 @comment node-name, next, previous, up
 @section Collections
--- /project/elephant/cvsroot/elephant/doc/tutorial.texinfo	2006/03/02 14:44:49	1.5
+++ /project/elephant/cvsroot/elephant/doc/tutorial.texinfo	2006/04/26 17:53:43	1.6
@@ -16,9 +16,10 @@
 * Using Transactions:: Using ACID.
 * Using BTrees:: Storing lots of things.
 * Using Cursors:: Tranversing BTrees.
+* Secondary Indices:: By any other name...
 * Class Indices:: Speed and Convenience.
-* Secondary Indices:: by any other name...
-* The Store Controller:: behind the curtain.
+* The Store Controller:: Behind the curtain.
+* Repository Migration:: How to move objects from one repository to another
 * Threading:: Playing nice with others.
 * Performance Tips:: Bogoflops for your buck.
 @end menu
@@ -27,43 +28,33 @@
 @comment node-name, next, previous, up
 @section Preliminaries
 
-Elephant isa Common Lisp OODB.  It solves the problem of 
-making Lisp data persistent.  It does this through two mechanisms:
-a very simple API, and the ability to declare a CLOS class to be 
-persistent.  It offers simple and powerful functional indexes
-as well as convenient slot-based indexes.  It represents 
-
-Elephant is an Common Lisp OODB, as opposed to a language-neutral
-(e.g. language-unspecific) RDBMS.  This means it can store and efficient index
-most Lisp values without programmer intervention, special syntax or laborious
-conversion.  In that way it is similar to prevalence, but it is
-actually a database: it is not in-memory (though it can be.)
-
-When someone says "database," most people think of SQL RDBMSs (oracle,
-postgresql, mysql).  Elephant uses RDBMSs or Berekely DB (Sleepycat) as 
-a data repository, but simply uses LISP as its data manipulation system.
-Unlike systems such as Hibernate for Java, the user does not need to 
-construct or worry about a mapping from the object space into 
-the database.  Elephant is a very convenient system for the 
-programmer.
-
-Elephant can employ several different data repositories as a ``back-ends''.
-It also supports easy migration of data between these repositories,
-which allows the user to flexibly choose, or to late-bind, which
-repository will use at a particular point in time.
-
-
-Berkeley DB/Sleepycat is a very fast database that is well-matched
-to Elephant.
-Berkeley DB is a C library, not a server.  On
-the other hand it is quite robust, and has many features, like
-transactions and replication.  While you don't need to understand
-a specific backend to use Elephant, reading the docs will certainly help you.
-For the Sleepycat backend, they can be found at @uref{http://www.sleepycat.com}.
-
-Elephant can also employ relational databases, based on the excellent CL-SQL
-package.  It has been tested with Postgres and SQLite3, and can probably easily
-work with others.
+Elephant is a Common Lisp OODB.  It provides a partial solution to the 
+problem of making Lisp data persistent.  It does this through two mechanisms:
+a simple API for storing and retrieving lisp values from a persistent store, 
+and the ability to make CLOS class slot values be persistent.
+
+When someone says "database," most people think of SQL Relation Data Base 
+Management Systems (e.g. Oracle, Postgresql, MySql).  Elephant can use either 
+RDBMSs or Berkeley DB (Sleepycat) as a backend repository, but relies on 
+LISP as its data manipulation system.  Unlike systems such as Hibernate 
+for Java, the user does not need to construct or worry about a mapping 
+from the object space into the database.  Elephant is designed to be a 
+simple and convenient tool for the programmer.
+
+Elephant supports easy migration of data between different repositories and
+different backends, allowing the user to choose which repository backend they 
+will use at a particular point in time.
+
+Berkeley DB/Sleepycat is a database library that was the initial inspiration for Elephant's
+design and is well-matched to Elephant's data model.  BDB is implemented as a C library, 
+not a client/server model, so access can be very fast.  Berkeley DB is also quite mature, 
+robust and has many features, such as transactions and replication.  While we hope 
+that you won't need to understand a specific backend to use Elephant, reading the 
+docs will certainly help you when things go wrong.  For the Sleepycat backend, 
+they can be found at @uref{http://www.sleepycat.com}.
+
+Elephant can also use RDBMS backends via the excellent CL-SQL package.  
+It has been tested with Postgres and SQLite3, and can probably easily work with others.
 
 @node Running the Tests
 @comment node-name, next, previous, up
@@ -107,11 +98,7 @@
 @section Getting Started 
 
 In order to use Elephant, you have to have an open store controller.
-To obtain an open store controller, you have to decide which back-end
-you will use and properly install that back-end system.  The actual
-use of Elephant once you have an open store controller is almost 
-completely independent of what the actual back-end choice is; Elephant
-attempts to abstract away all such details.
+To obtain an open store controller you call @code{open-store}
 
 The chapter ``SQL back-end'' has information about setting up a 
 SQL based backend; this tutorial will assume that you are using 
@@ -159,9 +146,12 @@
 @section The Root
 
 Liveness in a store is determined by reachability from the root
-object.  (When garbage collection is implemented, dead objects will be
-collected on gc's.)  The root object is a BTree which is like a
-hash-table with sorted keys. @xref{Using BTrees}.
+object.  Technically, liveness also applies to indexed
+classes, as described in @xref{Class Indices}, which live in a 
+separate class-root namespace.  When garbage collection is 
+implemented, dead objects will be collected on gc's.)  The root and
+class-root objects are BTrees, effectively a table with sorted keys
+and log(N) access time. @xref{Using BTrees}.
 
 You can put something into the root object by
 
@@ -220,7 +210,7 @@
 => NIL
 @end lisp
 
- at item Changing substructures is not automatically saved:
+ at item Mutated substructure does not persist
 
 @lisp
 * (setf (car foo) T)
@@ -230,7 +220,9 @@
 @end lisp
 
 This will affect all aggregate types: objects, conses, hash-tables, et
-cetera.  (You can of course manually re-store the cons.)
+cetera.  (You can of course manually re-store the cons.)  In this sense
+elephant does not automatically provide persistent collections.  If you 
+want to persist a collection on every access see @xref{Using BTrees}.
 
 @item Serialization and deserialization are pretty fast, but it is still
 expensive to store large aggregate objects wholesale.  Also, since
@@ -244,7 +236,7 @@
 on this later.
 @end enumerate
 
-But don't despair, we'll solve these problems in the next section.....
+But don't despair, we'll solve most of these problems in the next section.....
 
 @node Persistent Classes
 @comment node-name, next, previous, up
@@ -328,14 +320,14 @@
 instrumented, so override these with care.  Because @code{slot-value,
 slot-unboundp, slot-makunbound} are not generic functions, they are
 not guaranteed to work properly with persistent slots.  Use the
- at code{*-using-class} versions.
+ at code{*-using-class} versions or the @code{closer-to-mop} MOP compliance
+layer by Pascal Costanza (we may integrate this in later versions).
 
 Persistent classes may inherit from other classes.  Slots inherited
 from persistent classes remain persistent.  Transient slots and slots
 inherited from ordinary classes remain transient.  Ordinary classes
 cannot inherit from persistent classes -- persistent slots need to get
-stored!  Likewise, once a slot is declared persistent, it cannot later
-be changed to a transient slot.
+stored!  
 
 Note that the database is read every time you access a slot.  This is
 a feature, not a bug, especially in concurrent situations: you want
@@ -351,14 +343,14 @@
 which already exists in the database, @code{initargs} take precedence
 over values in the database, which take precedences over
 @code{initforms}.  Also currently there is a bug where
- at code{initforms} are always evaluated, so beware.  (This will be fixed
-soon.)
+ at code{initforms} are always evaluated, so beware.  
+(What is the current model here?)
 
 @node Using Transactions
 @comment node-name, next, previous, up
 @section Using Transactions
 
-Elephant by default uses the Berkeley DB Transactional Data Store.
+Elephant uses the Berkeley DB Transactional Data Store.
 This means most destructive operations need to be protected by
 transactions.  By default Elephant does this:
 
@@ -367,7 +359,12 @@
 => T
 @end lisp
 
-Most real applications will want to control their own transactions.
+Most real applications will want to control their own transactions because
+you will want one or more read-modify-update operations to happen as an
+atomic unit.  This is guaranteed by the use of a transaction, but auto
+commits will only protect each individual update irrespective of whether
+the read value has changed.
+
 If, for some reason, you want to turn off an implicit transaction when
 no explicit transactions are in effect, you can do
 
@@ -427,19 +424,18 @@
 
 @lisp
 * (setq *current-transaction* 
-        (db-transaction-begin (controller-environment
-                               *store-controller*)))
+        (controller-transaction-begin store-controller ))
 @end lisp
 
 To commit:
 
 @lisp
-* (db-transaction-commit *current-transaction*)
+* (controller-transaction-commit store-controller *current-transaction*)
 NIL
 @end lisp
 
 If for some reason (like db error) you decide to abort, you can do so
-via @code{(db-transaction-abort *current-transaction*)}.
+via @code{(controller-transaction-abort store-controller *current-transaction*)}.
 
 @node Using BTrees
 @comment node-name, next, previous, up
@@ -557,89 +553,6 @@
 @code{map-btree} function, which functions analogously to the
 @code{maphash} CL function.
 
-
- at node Class Indices
- at comment node-name, next, previous, up
- at section Class Indices
-
-Class indices are a very convenient way of gaining the efficiency
-that indexes provide.  If a given object is most often sought by 
-the value of one of its slots, which is of course quite common,
-it is convenient to define a class index on that slot, although
-the same functionality can be gained in a more complicated way through
-the use fo secondary indices.
-
-The file @file{tests/testindexing.lisp} provides many useful examples
-of both declaring class indexes and using the API to seek objects using them.
-
-The following code from that file in the test ``indexing-range'' demonstrates
-the convenience of a class indexes and the function ``get-instances-by-range''.
-Note in the definiton of the ``slot1'' the keyword ``:index'' is used to 
-specify that this slot should be indexed.
-
- at lisp
-	(defclass idx-four ()
-	((slot1 :initarg :slot1 :initform 1 :accessor slot1 :index t))
-	(:metaclass persistent-metaclass))
-      
-
-      (defun make-idx-four (val)
-	(make-instance 'idx-four :slot1 val))
-      
-      (with-transaction ()
-	(mapc #'make-idx-four '(1 1 1 2 2 4 5 5 5 6 10)))
-
-      (let ((x1 (get-instances-by-range 'idx-four 'slot1 2 6))
-	    (x2 (get-instances-by-range 'idx-four 'slot1 0 2))
-	    (x3 (get-instances-by-range 'idx-four 'slot1 6 15))
-	    )
-	(format t " x1 = ~A~%" (mapcar #'slot1 x1))
-      	(format t " x2 = ~A~%" (mapcar #'slot1 x2))
-	(format t " x3 = ~A~%" (mapcar #'slot1 x3))
- at end lisp
-
-Additionally, the test 
- at lisp 
-(do-test 'INDEXING-TIMING) 
- at end lisp
-Can be used to judge the performance of indexing a large dataset.
-
-The file @file{src/elephant/classindex.lisp} provides the source code and
-some crisp documentation of the class indexing system.
-
-Note that for retrieving items, the API is provided by three functions:
-
- at lisp 
-(defgeneric get-instances-by-class (persistent-metaclass))
-(defgeneric get-instances-by-value (persistent-metaclass slot-name value))
-(defgeneric get-instances-by-range (persistent-metaclass slot-name start end))
- at end lisp
-
-By using these functions, any class that is a subclass of persistent-metaclass
-can also be thought of a as a container of all of its instances, which are 
-persistent in the database between lisp invocations.  Morover an individual 
-object can be looked up on O(log n) time via a value which is indexed.
-
-At the top of this same file, you will find the a description of the API
-which can be used to dynamically add and remove indexes.  (Adding and 
-removing indexes can also be performed by a re-execution of the ``defclass''
-macro with different values.)
-
-Thus, the question of if and how a given class should be indexed is 
-very flexible and dynamic, and does not need to be determined at the 
-beginning of your development.  This represents the ability to ``late bind''
-the and change the decision of what to index for efficiencty.
-
-In general, there is always a tradeoff: an index makes reads in a 
-particular way fast, but makes writes slower.  The Elephant system
-makes it simple to choose where and when one wants to utilize this tradeoff.
-
-Finally, that file @file{src/elephant/classindex-utils.lisp} documents 
-tools for handling class redefinitions and the policy that should be 
-used for synchronizing the classes with the database.
-
-Thanks to Ian Eslick for this functionality.
-
 @node Secondary Indices
 @comment node-name, next, previous, up
 @section Secondary Indices
@@ -756,6 +669,119 @@
 There are also @code{cursor-p*} functions like @code{pcurrent, pnext},
 et cetera which also return the primary key.  @xref{Cursors}.
 
+
+
+ at node Class Indices
+ at comment node-name, next, previous, up
+ at section Class Indices
+
+Class indices are a very convenient way of gaining the efficiency
+that BTree indices provide.  If a given object is most often sought by 
+the value of one of its slots, which is of course quite common,
+it is convenient to define a class index on that slot, although
+the same functionality can be gained in a more complicated way through
+the use of secondary indices.
+
+The file @file{tests/testindexing.lisp} provides many useful examples
+of both declaring class indexes and using the API to seek objects using them.
+
+The following code from that file in the test ``indexing-range'' demonstrates
+the convenience of a class indexes and the function ``get-instances-by-range''.
+Note in the definition of the ``slot1'' the keyword ``:index'' is used to 
+specify that this slot should be indexed.
+
+ at lisp
+      (defclass idx-four ()
+	((slot1 :initarg :slot1 :initform 1 :accessor slot1 :index t))
+	(:metaclass persistent-metaclass))
+      
+
+      (defun make-idx-four (val)
+	(make-instance 'idx-four :slot1 val))
+      
+      (with-transaction ()
+	(mapc #'make-idx-four '(1 1 1 2 2 4 5 5 5 6 10)))
+
+      (let ((x1 (get-instances-by-range 'idx-four 'slot1 2 6))
+	    (x2 (get-instances-by-range 'idx-four 'slot1 0 2))
+	    (x3 (get-instances-by-range 'idx-four 'slot1 6 15))
+	    )
+	(format t " x1 = ~A~%" (mapcar #'slot1 x1))
+      	(format t " x2 = ~A~%" (mapcar #'slot1 x2))
+	(format t " x3 = ~A~%" (mapcar #'slot1 x3))
+ at end lisp
+
+Additionally, the test 
+ at lisp 
+(do-test 'INDEXING-TIMING) 
+ at end lisp
+Can be used to judge the performance of indexing a medium sized dataset.
+
+The file @file{src/elephant/classindex.lisp} provides the source code and
+some crisp documentation of the class indexing system.
+
+Note that for retrieving items, the API is provided by three functions:
+
+ at lisp 
+(defgeneric get-instances-by-class (persistent-metaclass))
+(defgeneric get-instances-by-value (persistent-metaclass slot-name value))
+(defgeneric get-instances-by-range (persistent-metaclass slot-name start end))
+ at end lisp
+
+By using these functions, any class that is a subclass of persistent-metaclass
+can also be thought of as a container of all of its instances, which are 
+persistent in the database between lisp invocations.  Moreover an individual 
+object can be looked up on O(log n) time via a value on which it is indexed.
+
+At the top of this same file, you will find the a description of the API
+which can be used to dynamically add and remove indexes.  (Adding and 
+removing indexes can also be performed by a re-execution of the ``defclass''
+macro with different values.)
+
+You can enable/disable class indexing for an entire class.  When you disable
+indexing all references to instances of that class are lost.  If you re-enable
+class indexing only newly created classes will be stored in the class index.
+You can manually restore them by using @code{find-class-index} to get the 
+clas index BTree if you have an alternate in-memory index.
+
+You can add/remove a secondary index for a slot.  So long as the class index
+remains, this can be done multiple times without losing any data.
+
+There is also a facility for defining 'derived slots'.  These can be non-slot
+parameters which are a function of the class's persistent slot values.  For
+example you can use an index to keep an alternate representation available
+for fast indexing.  If an object has an x,y coordinate, you could define a
+derived index for r,theta which stored references in polar coordinates.
+These would be ordered so you could iterate over a class-index to get objects
+in order of increasing radius from the origin or over a range of theta.
+
+Beware, however, that derived indices have to compute their result every
+time you update any persistent instance's slot.  This is because there is 
+no way to know which persistent slots the derived index value(s) depends

[142 lines skipped]




More information about the Elephant-cvs mailing list