Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyc

# Logs and databases #
######################
*.log

# OS generated files #
######################
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db
16 changes: 8 additions & 8 deletions planks.org
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
planks: persistent lisp, mumble mumble mumble mumble

* Features
* Features
- 100% portable common lisp
uses bordeaux threads!
- functional, append-only index
- persistent CLOS objects
- thread safe
- multi-value concurrency control
- multi-value concurrency control
- easy to install and to use

* Download and Install

** Release tarballs

http://common-lisp.net/project/planks/planks-release.tar.gz

** Version Control

planks is available via git
planks is available via git











* Examples

** Basic key/value store
8 changes: 4 additions & 4 deletions src/btree-class.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@
(defmethod btree-pathname (object)
(btree-class-pathname (class-of object)))

(defmethod shared-initialize :around
((object btree-object) slots &rest initargs
(defmethod shared-initialize :around
((object btree-object) slots &rest initargs
&key (btree (btree-pathname object)))
(declare (ignore slots initargs))
(let* ((parent (find-btree btree))
(lock (btree-lock parent)))
(bt:with-recursive-lock-held (lock)
(let ((id (btree-footer-next-id (btree-file-footer parent))))
(setf (btree-object-id object)
(setf (btree-object-id object)
id)
(update-btree parent :key id :value (call-next-method) :action :make-instance)))))

(defmethod initialize-instance :around
((class btree-class) &rest initargs
&key direct-superclasses)
Expand Down
2 changes: 1 addition & 1 deletion src/btree-protocol.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ ORDER is either :ASCENDING (default) or :DESCENDING."))


(defgeneric update-btree (btree &key key value &allow-other-keys)
(:documentation
(:documentation
"This is the function that implements the functional b+tree. It is not meant to be called by users, but is specialized when extending"))

(define-condition btree-error (error)
Expand Down
2 changes: 1 addition & 1 deletion src/btree-search.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
(:method (btree (node null) function
min max include-min include-max
order)
nil)
nil)
(:method (btree node function
min max include-min include-max
order)
Expand Down
44 changes: 22 additions & 22 deletions src/btree-test.lisp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(in-package :cl)

(defpackage :planks.btree-test
(defpackage :planks.btree-test
(:use :cl :planks.btree))

(in-package :planks.btree-test)
Expand All @@ -26,7 +26,7 @@
(defun test-btree-balance (&key (path *path*))
(let ((bt (make-btree path :if-exists :supersede :max-node-size 5)))
(assert (null (btree-search bt 1 :errorp nil)))
(loop for i upto 1234 for b = (btree-insert bt i i) then (btree-insert b i i)
(loop for i upto 1234 for b = (btree-insert bt i i) then (btree-insert b i i)
:finally (assert (planks.btree::btree-balanced-p b)))))

(defun reverse-map (k v)
Expand All @@ -41,18 +41,18 @@
(list (cons v (length v))))

(defun test-multi-btree-existing-data-insert (&key (path *path*))
(let ((bt (make-btree path
(let ((bt (make-btree path
:if-exists :supersede
:class 'multi-btree))
(data (remove-duplicates
(loop
for i upto 1234
(data (remove-duplicates
(loop
for i upto 1234
for r = (format nil "~R" i)
:collect (cons i r))
:key #'car)))
(loop
for (i . r) in data
for b = (btree-insert bt i r)
(loop
for (i . r) in data
for b = (btree-insert bt i r)
then (btree-insert b i r))

(add-function-btree (find-btree path) 'reverse-map :key= 'equal :key< 'string<)
Expand All @@ -62,16 +62,16 @@
(find-btree path)))

(defun test-multi-btree-existing-data (&optional (bt (test-multi-btree-existing-data-insert)))
(map-btree (find-function-btree bt 'reverse-map)

(map-btree (find-function-btree bt 'reverse-map)
(lambda (k v)
(assert (equal k (btree-search bt v)))))

(map-btree (find-function-btree bt 'add-one-to-key)
(map-btree (find-function-btree bt 'add-one-to-key)
(lambda (k v)
(assert (equal (1+ k) v))))

(map-btree (find-function-btree bt 'length-of-value)
(map-btree (find-function-btree bt 'length-of-value)
(lambda (k v)
(assert (equal (length k) v)))))

Expand All @@ -93,23 +93,23 @@
:key< 'string<
:key= 'equalp)
(symbol-macrolet ((bt (find-btree *path*)))
(loop for n to 115000 do
(loop for n to 115000 do
(btree-insert bt (uuid:print-bytes nil (uuid:make-v1-uuid)) n)
(close-btree bt))

(format t "File Size : ~A" (float (/ (btree-file-size bt) (* 1024 1024))))
bt))
(progn



(progn
(test-file-btree-insert)
(test-btree-balance)
(test-multi-btree-existing-data))










6 changes: 3 additions & 3 deletions src/btree-utils.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
(let ((key< (slot-value btree 'key<))
(key-key (btree-key-key btree)))
(lambda (key1 key2)
(and
(and
(funcall key<
(funcall key-key key1)
(funcall key-key key2))))))
Expand Down Expand Up @@ -63,15 +63,15 @@
0
(loop for i below (btree-node-binding-count node)
for binding = (btree-node-binding node i)
maximize (1+ (btree-node-max-depth (btree-node-binding-value
maximize (1+ (btree-node-max-depth (btree-node-binding-value
node binding))))))

(defmethod btree-node-min-depth ((node btree-node))
(if (btree-node-leaf-p node)
0
(loop for i below (btree-node-binding-count node)
for binding = (btree-node-binding node i)
minimize (1+ (btree-node-min-depth (btree-node-binding-value
minimize (1+ (btree-node-min-depth (btree-node-binding-value
node binding))))))

(defmethod btree-depths ((btree btree))
Expand Down
62 changes: 31 additions & 31 deletions src/btree.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ of keys per btree node.")
(SETF (SLOT-VALUE NEW 'KEY<) (SLOT-VALUE btree 'KEY<)
(SLOT-VALUE NEW 'KEY=) (SLOT-VALUE btree 'KEY=)
(SLOT-VALUE NEW 'KEY-KEY) (SLOT-VALUE btree 'KEY-KEY)
(SLOT-VALUE NEW 'VALUE-KEY) (SLOT-VALUE btree 'VALUE-KEY)
(SLOT-VALUE NEW 'VALUE-KEY) (SLOT-VALUE btree 'VALUE-KEY)
(SLOT-VALUE NEW 'VALUE=) (SLOT-VALUE btree 'VALUE=)
(SLOT-VALUE NEW 'NODE-CLASS) (SLOT-VALUE btree 'NODE-CLASS)
(SLOT-VALUE NEW 'MAX-NODE-SIZE) (SLOT-VALUE btree 'MAX-NODE-SIZE)
Expand All @@ -53,19 +53,19 @@ of keys per btree node.")
(if (and (null key) (null value))
(%update-btree btree)
(let ((root (btree-root btree)))
(%update-btree
btree
:root (cond
((not root)
(%update-btree
btree
:root (cond
((not root)
(make-root-node btree key value))
((node-almost-full-p btree root)
(update-node
root :index (split-binding-node
(update-node
root :index (split-binding-node
btree root key value nil)))
(t
(update-node
root :index (update-index-for-insert
btree (btree-node-index root)
(t
(update-node
root :index (update-index-for-insert
btree (btree-node-index root)
key value (btree-node-leaf-p root)))))))))

(defclass btree-node ()
Expand All @@ -84,18 +84,18 @@ of keys per btree node.")
(format stream "~A" (btree-node-index object))))

(defmethod update-node (node &key (index (btree-node-index node))
(leaf-p (btree-node-leaf-p node)))
(leaf-p (btree-node-leaf-p node)))
(make-instance (class-of node) :index index :leaf-p leaf-p))

(defmethod make-root-node (btree key val)
(let* ((left (update-node (make-instance (btree-node-class btree)
:leaf-p t
:index (vector (funcall
(let* ((left (update-node (make-instance (btree-node-class btree)
:leaf-p t
:index (vector (funcall
(if (btree-unique-keys-p btree)
'cons
'list)
key val))))))
(update-node (make-instance (btree-node-class btree)
(update-node (make-instance (btree-node-class btree)
:index (vector (cons key left))
:leaf-p nil))))

Expand All @@ -107,7 +107,7 @@ of keys per btree node.")
;; Find the first binding with a key >= the given key and return
;; the corresponding subnode.
;; DO: We should probably use binary search for this.
(loop
(loop
:for (bkey . value) :across index
:for i from 0
:when (or (= (1+ i) (length index))
Expand All @@ -126,7 +126,7 @@ of keys per btree node.")
(defmethod btree-node-binding-value (node binding)
(cdr binding))


(defmethod largest-key-in-node (node)
(let ((index (btree-node-index node))
(leaf-p (btree-node-leaf-p node)))
Expand All @@ -137,32 +137,32 @@ of keys per btree node.")


(defun update-bnode (btree node key value)
(update-node
node :index (update-index-for-insert
btree (btree-node-index node)
(update-node
node :index (update-index-for-insert
btree (btree-node-index node)
key value (btree-node-leaf-p node))))

(defun update-index-for-insert (btree index key value leaf-p)
(cond ((eql 0 (length index))
(vector (cons key value)))
(t
(t
(let* ((pos (find-key-position-in-index btree index key))
(binding (aref index pos))
(left-index (unless (eql 0 pos)
(left-index (unless (eql 0 pos)
(make-array pos :displaced-to index)))
(right-index (unless (<= (length index) (1+ pos))
(right-index (unless (<= (length index) (1+ pos))
(make-array (1- (- (length index) pos))
:displaced-to index
:displaced-index-offset (1+ pos)))))
(concatenate 'vector
left-index
(concatenate 'vector
left-index
(update-binding-for-insert btree binding key value leaf-p)
right-index)))))

(defmethod update-node-for-insert (btree node binding-key key value leaf-p)
(if (and (not leaf-p) (node-almost-full-p btree node))
(split-binding-node btree node key value (btree-node-leaf-p node))
(if leaf-p
(if leaf-p
(if (funcall (btree-key= btree) binding-key key)
;; replacing existing binding
(vector (cons key (if (btree-unique-keys-p btree)
Expand All @@ -172,9 +172,9 @@ of keys per btree node.")
)))
;;new key
(sort (vector (funcall (if (btree-unique-keys-p btree)
'cons
'cons
'list)
key value)
key value)
(cons binding-key node))
(btree-key< btree) :key #'car))
(vector (cons binding-key (update-bnode btree node key value))))))
Expand All @@ -192,11 +192,11 @@ of keys per btree node.")
(sub-index (if (<= (1+ node-pos) (length split-left-index))
split-left-index
split-right-index))
(left-node (update-node
(left-node (update-node
node :index (if (eql split-left-index sub-index)
(update-index-for-insert btree split-left-index key value leaf-p)
split-left-index)))
(right-node (update-node
(right-node (update-node
node :index (if (eql split-right-index sub-index)
(update-index-for-insert btree split-right-index key value leaf-p)
split-right-index))))
Expand Down
Loading