changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / lisp/lib/rdb/obj.lisp

changeset 269: 87f503c7a365
parent: f3d814fb136a
child: 0a5e37693fdf
author: Richard Westhaver <ellis@rwest.io>
date: Sun, 07 Apr 2024 21:17:30 -0400
permissions: -rw-r--r--
description: more rocksdb
1 (in-package :rdb)
2 
3 ;;; rdb-opts
4 (defvar *rdb-opts-lookup-table*
5  (let ((table (make-hash-table :test #'equal)))
6  (mapc (lambda (x) (setf (gethash (car x) table) (cdr x)))
7  (loop for y across *rocksdb-options*
8  collect (cons y (format nil "~:@(rocksdb-options-set-~x~)" y))))
9  table))
10 
11 (defmacro rdb-opt-setter (key)
12  `(find-symbol (format nil "~:@(rocksdb-options-set-~x~)" ,key) :rocksdb))
13 
14 (defmacro rdb-opt-getter (key)
15  `(find-symbol (format nil "~:@(rocksdb-options-get-~x~)" ,key) :rocksdb))
16 
17 (defun %set-rocksdb-option (opt key val)
18  (funcall (rdb-opt-setter key) opt val))
19 
20 #| special cases
21 WARNING: #<OPT-HANDLER-MISSING compression-options {101A423693}>
22 WARNING: #<OPT-HANDLER-MISSING allow-mmap-write {101A5F0C93}>
23 WARNING: #<OPT-HANDLER-MISSING use-direct-io-for-flush-compaction {101A5F1913}>
24 WARNING: #<OPT-HANDLER-MISSING stas-persist-period-sec {101A5F32C3}>
25 WARNING: #<OPT-HANDLER-MISSING writable-file-max-buffer-size {101A5F4523}>
26 WARNING: #<OPT-HANDLER-MISSING disable-auto-compactions {101A5F54E3}>
27 WARNING: #<OPT-HANDLER-MISSING prepare-for-bulk-load {101A5F62E3}>
28 WARNING: #<OPT-HANDLER-MISSING memtable-vector-rep {101A5F6DB3}>
29 WARNING: #<OPT-HANDLER-MISSING memtable-prefix-bloom-size-ratio {101A5F78B3}>
30 WARNING: #<OPT-HANDLER-MISSING hash-skip-list-rep {101A620573}>
31 WARNING: #<OPT-HANDLER-MISSING plain-table-factory {101A621083}>
32 WARNING: #<OPT-HANDLER-MISSING min-level-to-compress {101A621B53}>
33 WARNING: #<OPT-HANDLER-MISSING inplace-update-num-locks {101A6230F3}>
34 WARNING: #<OPT-HANDLER-MISSING universal-compaction-options {101A624CD3}>
35 WARNING: #<OPT-HANDLER-MISSING ratelimiter {101A625723}>
36 WARNING: #<OPT-HANDLER-MISSING row-cache {101A6262E3}>
37 |#
38 
39 (defun %get-rocksdb-option (opt key)
40  (if-let ((g (rdb-opt-getter key)))
41  (funcall g opt)
42  (warn 'opt-handler-missing :message key)))
43 
44 (defclass rdb-opts ()
45  ((table :initarg :table :type hash-table :accessor rdb-opts-table)
46  (sap :initarg :sap :type (or null alien) :accessor rdb-opts-sap)))
47 
48 (defmethod initialize-instance ((self rdb-opts) &rest initargs &key &allow-other-keys)
49  (with-slots (sap table) self
50  (unless (getf initargs :table) (setf table (make-hash-table :test #'equal)))
51  (unless (getf initargs :sap) (setf sap (rocksdb-options-create)))
52  (loop for (k v) on initargs by #'cddr while v
53  do (let ((k (typecase k
54  (string (string-downcase k))
55  (symbol (string-downcase (symbol-name k)))
56  (t (string-downcase (format nil "~s" k))))))
57  (set-opt self k v)))
58  self))
59 
60 (defun make-rdb-opts (&rest values)
61  (let ((opts (apply #'make-instance 'rdb-opts values)))
62  (push-sap* opts)
63  opts))
64 
65 (defmethod get-opt ((self rdb-opts) key)
66  "Return the current value of KEY in SELF if found, else return nil."
67  (gethash key (rdb-opts-table self)))
68 
69 (defmethod set-opt ((self rdb-opts) key val &key push)
70  "Set the VAL of KEY in SELF with '(setf (gethash SELF KEY) VAL)'."
71  (prog1
72  (setf (gethash key (rdb-opts-table self)) val)
73  (when push (push-sap self key))))
74 
75 (defmethod push-sap ((self rdb-opts) key)
76  "Push KEY from slot :TABLE to the instance :SAP."
77  (%set-rocksdb-option (rdb-opts-sap self) key (get-opt self key)))
78 
79 (defmethod push-sap* ((self rdb-opts))
80  "Initialized the SAP slot with values from TABLE."
81  (with-slots (table) self
82  (loop for k in (hash-table-keys table)
83  do (push-sap self k))))
84 
85 (defmethod pull-sap ((self rdb-opts) key)
86  (setf (gethash key (rdb-opts-table self)) (%get-rocksdb-option (rdb-opts-sap self) key)))
87 
88 (defmethod pull-sap* ((self rdb-opts))
89  (with-slots (table) self
90  (loop for k in (hash-table-keys table)
91  do (pull-sap self k))
92  table))
93 
94 (defmethod backfill-opts ((self rdb-opts) &key full)
95  "Backfill the TABLE slot with values from SAP.
96 
97 When FULL is non-nil, retrieve the full set of options available, not
98 just the keys currently present in TABLE."
99  (if full
100  (loop for k across *rocksdb-options*
101  do (pull-sap self k))
102  (pull-sap* self))
103  (rdb-opts-table self))
104 
105 (defun default-rdb-opts ()
106  ;; TODO 2024-03-10: handle lisp->C types
107  (make-rdb-opts :create-if-missing 1))
108 
109 (defclass rdb-kv ()
110  ((key :initarg :key :type octet-vector :accessor rdb-key)
111  (val :initarg :val :type octet-vector :accessor rdb-val)))
112 
113 (defmethod make-kv (key val)
114  (make-instance 'rdb-kv
115  :key (make-key key)
116  :val (make-val val)))
117 
118 (defvar *default-rdb-kv* (make-kv #() #()))
119 
120 ;;; column family
121 (defstruct (rdb-cf (:constructor make-rdb-cf (name &key kv sap)))
122  "RDB Column Family structure. Contains a name, a cons of (rdb-key-type
123 . rdb-val-type), and a system-area-pointer to the underlying
124 rocksdb_cf_t handle."
125  (name "" :type string)
126  (kv *default-rdb-kv* :type rdb-kv)
127  (sap nil :type (or null alien)))
128 
129 ;;; rdb
130 (defstruct (rdb (:constructor make-rdb (name opts &optional cfs db)))
131  (name "" :type string)
132  (opts (default-rdb-opts) :type rdb-opts)
133  (cfs (make-array 0 :element-type 'rdb-cf :adjustable t :fill-pointer 0) :type (array rdb-cf))
134  (db nil :type (or null alien)))
135 
136 ;; (defvar *default-rdb-opts* (default-rdb-opts))
137 
138 (defmethod print-object ((self rdb) stream)
139  (print-unreadable-object (self stream :type t :identity t)
140  (format stream ":cfs ~A" (length (rdb-cfs self)))))
141 
142 (defun create-db (name &key opts cfs open)
143  "Construct a new RDB instance from NAME.
144 
145 OPTS = rdb-opts
146 CFS = (sequence rdb-cf)
147 OPEN = boolean
148 
149 When OPEN is non-nil, the database and all column families are opened
150 and internal sap slots are initialized."
151  (when (probe-file name) (log:warn! "directory already exists: " name))
152  (let* ((opts (or opts (default-rdb-opts)))
153  (obj
154  (make-rdb (string-right-trim '(#\/)
155  (typecase name
156  (pathname (namestring name))
157  (string name)
158  (t (error "invalid NAME: ~S" name))))
159  opts
160  (or (when cfs
161  (typecase cfs
162  (list (coerce cfs 'vector))
163  (vector cfs)
164  (rdb-cf (vector cfs))
165  (t (log:warn! "invalid CF passed to create-db"))))
166  (make-array 0 :element-type 'rdb-cf :fill-pointer 0)))))
167  (when open
168  (open-db obj)
169  (create-cfs obj))
170  obj))
171 
172 (defmethod push-cf ((cf rdb-cf) (db rdb))
173  (vector-push cf (rdb-cfs db)))
174 
175 ;; TODO: fix
176 (defmethod create-cf ((db rdb) (cf rdb-cf))
177  (setf (rdb-cf-sap cf)
178  (create-cf-raw (rdb-db db) (rdb-cf-name cf))))
179 
180 (defmethod close-cf ((cf rdb-cf))
181  (with-slots (sap) cf
182  (unless (null sap)
183  (free-alien sap))))
184 
185 (defmethod open-db ((self rdb))
186  (with-slots (name db opts) self
187  (setq db (open-db-raw name (rdb-opts-sap opts)))))
188 
189 (defmethod create-cfs ((self rdb) &key &allow-other-keys)
190  (loop for cf across (rdb-cfs self)
191  do (create-cf self cf)))
192 
193 (defmethod close-cfs ((self rdb) &key &allow-other-keys)
194  (with-slots (cfs) self
195  (declare (type (array rdb-cf) cfs))
196  (loop for cf across cfs
197  do (setf cf (close-cf cf)))))
198 
199 (defmethod close-db ((self rdb) &key &allow-other-keys)
200  (with-slots (db cfs) self
201  (unless (null db)
202  (close-cfs self)
203  (setf db (close-db-raw db)))))
204 
205 (defmethod destroy-db ((self rdb))
206  (destroy-db-raw (rdb-name self)))
207 
208 (defmethod put-key ((self rdb) key val)
209  (put-kv-raw
210  (rdb-db self)
211  key
212  val))
213 
214 (defmethod put-kv ((self rdb) (kv rdb-kv))
215  (put-kv-raw
216  (rdb-db self)
217  (rdb-key kv)
218  (rdb-val kv)))
219 
220 (defmethod insert-key ((self rdb) key val &key cf)
221  (if cf
222  (put-cf-raw
223  (rdb-db self)
224  (rdb-cf-sap (find cf (rdb-cfs self) :key #'rdb-cf-name :test #'equal))
225  key
226  val)
227  (put-key self key val)))
228 
229 (defmethod insert-key ((self rdb) (key string) (val string) &key cf)
230  (insert-key self (string-to-octets key) (string-to-octets val) :cf cf))
231 
232 (defmethod insert-key ((self rdb) (key string) val &key cf)
233  (insert-key self (string-to-octets key) val :cf cf))
234 
235 (defmethod insert-key ((self rdb) key (val string) &key cf)
236  (insert-key self key (string-to-octets val) :cf cf))
237 
238 (defmethod insert-kv ((self rdb) (kv rdb-kv) &key cf)
239  (if cf
240  (put-cf-raw (rdb-db self)
241  (rdb-cf-sap
242  (find cf (rdb-cfs self)
243  :key #'rdb-cf-name
244  :test #'string=))
245  (rdb-key kv)
246  (rdb-val kv))
247  (put-kv self kv)))
248 
249 (defmethod get-key ((self rdb) (key string) &key (opts (rocksdb-readoptions-create)) cf)
250  (with-slots (db) self
251  (when cf
252  (get-cf-str-raw db cf key opts)
253  (get-kv-str-raw db key opts))))