| 1 |
(in-package :bknr.indices) |
|---|
| 2 |
|
|---|
| 3 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|---|
| 4 |
;;; CLOS Protocol for index objects |
|---|
| 5 |
|
|---|
| 6 |
;;; A CLOS cursor is a CLOS class that complies to the following |
|---|
| 7 |
;;; protocol (note that a cursor doesn't have to support both |
|---|
| 8 |
;;; CURSOR-NEXT and CURSOR-PREVIOUS): |
|---|
| 9 |
|
|---|
| 10 |
(defgeneric cursor-next (cursor &optional eoc) |
|---|
| 11 |
(:documentation "Return the current value and advance the |
|---|
| 12 |
cursor. Returns EOC if the cursor is at its end.")) |
|---|
| 13 |
|
|---|
| 14 |
(defgeneric cursor-previous (cursor &optional eoc) |
|---|
| 15 |
(:documentation "Return the current value and advance the |
|---|
| 16 |
cursor. Returns EOC if the cursor is at its end.")) |
|---|
| 17 |
|
|---|
| 18 |
;;; A CLOS index is a CLOS class that complies to the following |
|---|
| 19 |
;;; protocol (note that an index doesn't have to support all the |
|---|
| 20 |
;;; protocol methods): |
|---|
| 21 |
|
|---|
| 22 |
(defgeneric index-add (index object) |
|---|
| 23 |
(:documentation "Add OBJECT to the INDEX. Throws an ERROR if a |
|---|
| 24 |
problem happened while inserting OBJECT.")) |
|---|
| 25 |
|
|---|
| 26 |
(defgeneric index-get (index key) |
|---|
| 27 |
(:documentation "Get the object (or the objects) stored under the index-key KEY.")) |
|---|
| 28 |
|
|---|
| 29 |
(defgeneric index-remove (index object) |
|---|
| 30 |
(:documentation "Remove OBJECT from the INDEX.")) |
|---|
| 31 |
|
|---|
| 32 |
(defgeneric index-keys (index) |
|---|
| 33 |
(:documentation "Returns all the KEYs of the INDEX.")) |
|---|
| 34 |
|
|---|
| 35 |
(defgeneric index-values (index) |
|---|
| 36 |
(:documentation "Returns all the objects (or object lists) stored in |
|---|
| 37 |
INDEX.")) |
|---|
| 38 |
|
|---|
| 39 |
(defgeneric index-values-cursor (index) |
|---|
| 40 |
(:documentation "Returns a cursor that walks all the objects stored in INDEX.")) |
|---|
| 41 |
|
|---|
| 42 |
(defgeneric index-keys-cursor (index) |
|---|
| 43 |
(:documentation "Returns a cursor that walks all the keys stored in INDEX.")) |
|---|
| 44 |
|
|---|
| 45 |
(defgeneric index-mapvalues (index fun) |
|---|
| 46 |
(:documentation "Apply FUN to every object in the INDEX.")) |
|---|
| 47 |
|
|---|
| 48 |
(defgeneric index-reinitialize (new-index old-index) |
|---|
| 49 |
(:documentation "Called when the definition of an index is changed.")) |
|---|
| 50 |
|
|---|
| 51 |
(defgeneric index-clear (index) |
|---|
| 52 |
(:documentation "Remove all indexed objects from the index.")) |
|---|
| 53 |
|
|---|
| 54 |
(defun index-create (class-name &rest initargs) |
|---|
| 55 |
"Instantiate the index object with class CLASS-NAME with INITARGS." |
|---|
| 56 |
(apply #'make-instance class-name initargs)) |
|---|
| 57 |
|
|---|
| 58 |
;;; Adding to an index can throw the following errors: |
|---|
| 59 |
|
|---|
| 60 |
(define-condition index-existing-error (error) |
|---|
| 61 |
((index :initarg :index :reader condition-index) |
|---|
| 62 |
(key :initarg :key :reader condition-key) |
|---|
| 63 |
(value :initarg :value :reader condition-value))) |
|---|
| 64 |
|
|---|
| 65 |
(defmethod print-object ((obj index-existing-error) stream) |
|---|
| 66 |
(print-unreadable-object (obj stream :type t) |
|---|
| 67 |
(format stream "INDEX: ~A KEY: ~S VALUE: ~S" |
|---|
| 68 |
(condition-index obj) (condition-key obj) (condition-value obj)))) |
|---|
| 69 |
|
|---|