[elephant-devel] Lisp-only data store (prototype)

Elliott Slaughter elliottslaughter at gmail.com
Fri Feb 6 08:24:35 UTC 2009


Hi,

I've been working on debugging the red-black tree in cl-containers, and am
becoming increasingly convinced that the red-black tree isn't buggy.

The failures caused by using the red-black tree seem to spout from, among
other places, get-instances-by-class, which erroneously returns a subset of
the actual instances of a class. And get-instances-by-class calls map-index,
which iterates over nodes in the class index btree to find the all instances
of that class. After a bit of digging around, I found that proxy-find-node,
and thus get-start-node, didn't return the first element whose car is the
schema-id. Which shouldn't be surprising we are using proxy-equal and
proxy-compare< in a tree with duplicate keys. So first node with the key was
returned, instead of the one with the smallest value. The reason the
binary-search trees didn't have this problem is because they never
restructured the tree and thus left the first node near the top of the tree.

So I tried changing clp-btree-index's constructor to

(defmethod initialize-instance :after ((obj clp-btree-index) &rest initargs)
  (declare (ignore initargs))
  (setf (tree obj) (make-btree-proxy :duplicate-keys t)))

which fixes about 9 testcases (all the ones involving get-instances-by-...
and associations), but breaks about 4 more (errors listed below). Which
makes me wonder if that is really the correct solution or not.

Any advice for what to do about this would be appreciated.

Thanks.

 GET-FROM-INDEX3 []:
      Unexpected Error: #<SIMPLE-TYPE-ERROR {A836661}>
Argument N is not a NUMBER: NIL..
 --------------------------------
 --------------------------------
 INDEXED-GET-FROM-SLOT2 []:
      Unexpected Error: #<SIMPLE-ERROR {B9E51A1}>
There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION SLOT2 (15)>
when called with arguments
  (NIL)...
 --------------------------------
 --------------------------------
 INDEXED-GET-FROM-SLOT1 []:
      Unexpected Error: #<SIMPLE-ERROR {B958E09}>
There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION SLOT1 (15)>
when called with arguments
  (NIL)...
 --------------------------------
 --------------------------------
 SIMPLE-SLOT-GET []:
      Unexpected Error: #<SIMPLE-ERROR {B8E0249}>
There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION SLOT1 (15)>
when called with arguments
  (NIL)...

On Tue, Feb 3, 2009 at 6:05 AM, Ian Eslick <eslick at media.mit.edu> wrote:

> Thanks Elliott,
>
> The performance should get much better if we implement some of the
> performance improvements.  Would you like to try working on one of these
> three problems?
>
> 1. Fix the CLP store re-open problem
> 2. Debug the red-black tree implementation in cl-containers
> 3. Consolidate transactions
>
> To work on 2, just change the containers:binary-search-tree to
> containers:red-black-tree in the two classes in db-clp/primitives.lisp and
> work through any bugs that in the tests that fail now that didn't then.
>
> To work on #3, look at the clp-controller and identify the list of tx-***
> functions used to support operations like (setf get-value) and such.  Then
> in the elephant execute-transaction function bind a special variable that
> changes the behavior of internal-transaction so that we record the sequence
> of 'tx- function calls and argument that are referenced by primitive
> operations.  Go ahead and call them directly, but at the end of the
> transaction, call some new function 'tx-record-transaction-set using the
> cl-prevalence:execute function to create a log entry that consolidates all
> those operations.
>
> I fixed a few more small bugs last night, by the way.
>
> Cheers,
> Ian
>
>
> On Feb 3, 2009, at 3:11 AM, Elliott Slaughter wrote:
>
>  Ok, I checked out the new code and got it running with your patches. I ran
>> the test suite under Windows/SBCL and have attached the results for you to
>> look at. (Although I am not sure what it means exactly to run
>> multi-threading tests when SBCL on Windows doesn't support threads....)
>>
>> I also tried my application on the new backend, and it actually ran.
>> Running the stress test for my application resulted in performance roughly
>> that of BDB.
>>
>> Anyways, let me know what else I can do to help.
>>
>> On Mon, Feb 2, 2009 at 3:39 PM, Ian Eslick <eslick at media.mit.edu> wrote:
>> Hi Elliott,
>>
>> Sounds great.  Just getting it to run the test suite would be a good
>> start.  Speed will take some work and it's not quite functional enough to
>> make any conclusions yet.
>>
>> In particular, we really need the red-black tree or splay tree working to
>> get acceptable performance.  There are still some bugs in tree updating and
>> the rb-tree was never properly debugged, I'm told, in cl-containers.  The
>> test suite bogs down in some of the tests with large numbers of objects due
>> to the linear time cost of standard binary-trees on sequential insertion.
>>
>> I won't be able to put much development time in for awhile, but I can
>> certainly advise, check out patches, do a little debugging, etc.
>>
>> Attached are the two patches I made against cl-prevalence and
>> cl-containers.  I'll try to get them both integrated soon, but we can use
>> these to get going.
>>
>> Cheers,
>> Ian
>>
>>
>>
>>
>> On Feb 2, 2009, at 3:58 PM, Elliott Slaughter wrote:
>>
>> Hi,
>>
>> Thanks for working on this. I am particularly interested in the potential
>> of this backend because I need (a) speed and (b) the ability to build a
>> binary which will run on end-user machines without requiring them to install
>> a separate library.
>>
>> If you send me the necessary patches (or get them integrated into their
>> respective libraries), I would be happy to help you test this code on my
>> application.
>>
>> I look forward to hearing from you.
>>
>> On Mon, Feb 2, 2009 at 12:29 PM, Ian Eslick <eslick at media.mit.edu> wrote:
>> Hi All,
>>
>> I was inspired the other day to come up with a minimal, quick-and-
>> dirty, all-lisp data store for Elephant based on cl-prevalence.  The
>> problem with cl-prevalence is that every access to a persistent slot
>> has to be explicitly transactionally protected so it can be
>> recovered.  This is onerous and violates the abstractions provided by
>> the rest of the elephant data stores.
>>
>> The general idea is to hide the cl-prevalence transaction model inside
>> the existing meta-object protocol.  Instead of the usual hash table,
>> we use trees from cl-collections as our replacement for btrees and
>> indexes - this gives us reasonably efficient successor/predecessor ops
>> and makes it easier to implement the mapping and cursor APIs.
>>
>> It's not going to be nearly as fast as a full prevalence solution, but
>> it will be faster than BDB and should be much easier to install and
>> work with on a single-image basis.  The new db-clp store requires a
>> patches to cl-prevalence and cl-containers.  I'll see about getting
>> those put into the mainstream, but can send them to anyone interesting
>> in hacking on this in the meantime.
>>
>> I checked a prototype of this into elephant-1.0 today; it does not
>> interfere with existing functionality at all and I'm not sure yet
>> whether it will be part of 1.0.  You can open a new store, subject to
>> the following caveats, by:
>>
>> In elephant root: ln -s src/contrib/eslick/db-clp/ele-clp.asd ele-
>> clp.asd
>>
>> (open-store '(:CLP "/home/me/db/"))
>>
>> where /home/me/db/ is a fresh directory.
>>
>> 85%+ of the tests pass and a ton of stuff does work: persistent
>> classes, btrees, dup-btrees, indexed-btrees, mapping (mostly), and
>> class indexing (mostly).
>>
>>
>> However, there are still some very serious holes.
>> The ones I'm aware of are:
>>
>> - You can only create, but not re-open a store
>>  (this is due to a bootstrapping problem in recreating persistent
>> instances
>>  when loading a snapshot)
>>
>> - No cursors are supported (all those tests fail), but should be easy
>> as there is a good match between the RB tree and the btree
>> abstractions but you will need to add a couple of functions to cl-
>> containers.
>>
>> - On-line recovery has not been tested.
>>
>> - I'm unsure of how cl-prevalence guarantees global transaction
>> serializability - I don't see locks anywhere in the code.
>>
>> - I faked out a bunch of serializer tests by including the default
>> serializer,
>>  because they depend on buffer streams which the xml serializer
>> doesn't support;
>>  the tests should be fixed to be more general and not rely on buffer
>> streams.
>>
>> - Some issues in schema evolution tests
>>
>> Performance issues:
>>
>> - Reads need to be serialized so are currently considered transactions
>> for simplicity, but they write a transaction log - they should be
>> rewritten to only use the serialization mechanism but not write a log
>> and the grabbing of a lock during serialization should be done once
>> per with-transaction call.
>>
>> - with-transaction is a no-op, a significant performance enhancement
>> would be to bundle a set of primitive operations such as tx-write-
>> slot, tx-remove-kv and write a single prevalence log entry for them.
>> This would avoid a disk write per primop.
>>
>> - I started using splay trees, retreated to RB trees due to bugs and
>> finally retreated to binary-search-trees due to more bugs.  Moving to
>> a more efficient, balanced tree data structure will improve the
>> performance of all operations.  However, several tests use linear
>> insertion, reducing the asymptotic behavior of the tree to that of a
>> list - it really grinds the tests to a halt.
>>
>> Obvious next steps, in order of increasing difficulty:
>> - Implement cursor API
>> - Fix red-black or splay tree implementation in cl-containers
>> - Figure out how to load from a snapshot
>> - Use with-transaction to improve performance
>> - Read transaction optimizations
>>
>> Regards,
>> Ian
>>
>>
>>
>> _______________________________________________
>> elephant-devel site list
>> elephant-devel at common-lisp.net
>> http://common-lisp.net/mailman/listinfo/elephant-devel
>>
>>
>>
>> --
>> Elliott Slaughter
>>
>> "Any road followed precisely to its end leads precisely nowhere." - Frank
>> Herbert
>> _______________________________________________
>> elephant-devel site list
>> elephant-devel at common-lisp.net
>> http://common-lisp.net/mailman/listinfo/elephant-devel
>>
>>
>>
>>
>>
>> --
>> Elliott Slaughter
>>
>> "Any road followed precisely to its end leads precisely nowhere." - Frank
>> Herbert
>> <clp-test-run.txt>
>>
>
>


-- 
Elliott Slaughter

"Any road followed precisely to its end leads precisely nowhere." - Frank
Herbert
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/elephant-devel/attachments/20090206/187493fc/attachment.html>


More information about the elephant-devel mailing list