changelog shortlog graph tags branches changeset files revisions annotate raw help

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

changeset 678: 2b7d5a8d63ac
parent: 97dd03beda03
child: 12287fab15d0
author: Richard Westhaver <ellis@rwest.io>
date: Wed, 25 Sep 2024 21:39:39 -0400
permissions: -rw-r--r--
description: alien octets fix, workin with org-graph-db
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 (defun %set-rocksdb-option (opt key val)
12  (funcall (rdb-opt-setter key) opt val))
13 
14 (defun %get-rocksdb-option (opt key)
15  (if-let ((g (rdb-opt-getter key)))
16  (funcall g opt)
17  (warn 'opt-handler-missing :message key)))
18 
19 (defun opt-no-setter-p (k)
20  (let ((k (typecase k
21  (string (string-downcase k))
22  (symbol (string-downcase (symbol-name k)))
23  (t (string-downcase (format nil "~s" k))))))
24  (member t
25  (mapcar (lambda (x) (equal k x)) (list "parallelism" "enable-statistics")))))
26 
27 (defclass rdb-opts ()
28  ((table :initarg :table :type hash-table :accessor rdb-opts-table)
29  (sap :initarg :sap :type (or null alien) :accessor rdb-opts-sap)))
30 
31 (defmethod initialize-instance ((self rdb-opts) &rest initargs &key &allow-other-keys)
32  (with-slots (sap table) self
33  ;; initialize slots - remember, initargs doesn't refer to slot
34  ;; names, they're opt names.
35  (unless (getf initargs :table) (setf table (make-hash-table :test #'equal)))
36  (unless (getf initargs :sap) (setf sap (rocksdb-options-create)))
37  (loop for (k v) on initargs by #'cddr while v
38  do (let ((k (typecase k
39  (string (string-downcase k))
40  (symbol (string-downcase (symbol-name k)))
41  (t (string-downcase (format nil "~s" k))))))
42  (set-opt self k v)))
43  self))
44 
45 (defun make-rdb-opts (&rest values)
46  (let ((opts (apply #'make-instance 'rdb-opts values)))
47  (push-sap* opts)
48  opts))
49 
50 (defmethod get-opt ((self rdb-opts) key)
51  "Return the current value of KEY in SELF if found, else return nil."
52  (gethash key (rdb-opts-table self)))
53 
54 (defmethod set-opt ((self rdb-opts) key val &key push)
55  "Set the VAL of KEY in SELF with '(setf (gethash SELF KEY) VAL)'."
56  (prog1
57  (setf (gethash key (rdb-opts-table self)) val)
58  (when push (push-sap self key))))
59 
60 (defmethod push-sap ((self rdb-opts) key)
61  "Push KEY from slot :TABLE to the instance :SAP."
62  (%set-rocksdb-option (rdb-opts-sap self) key (get-opt self key)))
63 
64 (defmethod push-sap* ((self rdb-opts))
65  "Initialized the SAP slot with values from TABLE."
66  (with-slots (table) self
67  (loop for k in (hash-table-keys table)
68  ;; note how we don't handle any special cases here - we can
69  ;; always set an opt but sometimes we can't get it.
70  do (push-sap self k))))
71 
72 (defmethod pull-sap ((self rdb-opts) key)
73  (setf (gethash key (rdb-opts-table self)) (%get-rocksdb-option (rdb-opts-sap self) key)))
74 
75 (defmethod pull-sap* ((self rdb-opts))
76  (with-slots (table) self
77  (loop for k in (hash-table-keys table)
78  unless (opt-no-setter-p k)
79  do (pull-sap self k))
80  table))
81 
82 (defmethod backfill-opts ((self rdb-opts) &key full)
83  "Backfill the TABLE slot with values from SAP.
84 
85 When FULL is non-nil, retrieve the full set of options available, not
86 just the keys currently present in TABLE."
87  (if full
88  (loop for k across *rocksdb-options*
89  unless (opt-no-setter-p k)
90  do (pull-sap self k))
91  (pull-sap* self))
92  (rdb-opts-table self))
93 
94 (defun default-rdb-opts ()
95  (make-rdb-opts :create-if-missing t :create-missing-column-families t
96  :parallelism (num-cpus)))
97 
98 (defclass rdb-kv ()
99  ((key :initarg :key :type octet-vector :accessor rdb-key)
100  (val :initarg :val :type octet-vector :accessor rdb-val)))
101 
102 (defmethod make-kv (key val)
103  (make-instance 'rdb-kv
104  :key (make-key key)
105  :val (make-val val)))
106 
107 (defvar *default-rdb-kv* (make-kv #() #()))
108 
109 ;;; iterator
110 (defclass rdb-iter (sequence)
111  ((sap :initform nil :initarg :sap :type (or null alien) :accessor rdb-iter-sap)))
112 
113 (defmethod iter-valid-p ((self rdb-iter))
114  (rocksdb-iter-valid (rdb-iter-sap self)))
115 
116 (defmethod iter-seek-to-first ((self rdb-iter))
117  (rocksdb-iter-seek-to-first (rdb-iter-sap self)))
118 
119 (defmethod iter-seek-to-last ((self rdb-iter))
120  (rocksdb-iter-seek-to-last (rdb-iter-sap self)))
121 
122 (defmethod iter-seek-for-prev ((self rdb-iter) (key vector) &key)
123  (rocksdb-iter-seek-for-prev (rdb-iter-sap self) key (length key)))
124 
125 (defmethod iter-seek ((self rdb-iter) (key simple-vector) &key)
126  (rocksdb-iter-seek (rdb-iter-sap self) key (length key)))
127 
128 (defmethod iter-next ((self rdb-iter))
129  (rocksdb-iter-next (rdb-iter-sap self)))
130 
131 (defmethod iter-prev ((self rdb-iter))
132  (rocksdb-iter-prev (rdb-iter-sap self)))
133 
134 (defmethod iter-key ((self rdb-iter))
135  (with-alien ((klen size-t))
136  (let ((key (rocksdb-iter-key (rdb-iter-sap self) (addr klen))))
137  (let ((k (make-array klen :element-type 'octet)))
138  (clone-octets-from-alien key k klen)
139  (values
140  k
141  klen)))))
142 
143 (defmethod iter-val ((self rdb-iter))
144  (with-alien ((vlen size-t))
145  (let ((val (rocksdb-iter-value (rdb-iter-sap self) (addr vlen))))
146  (let ((v (make-array vlen :element-type 'octet)))
147  (clone-octets-from-alien val v vlen)
148  (values
149  v
150  vlen)))))
151 
152 (defmethod iter-kv ((self rdb-iter))
153  (make-kv (iter-key self) (iter-val self)))
154 
155 (defmethod iter-timestamp ((self rdb-iter))
156  (with-alien ((tslen size-t))
157  (values
158  (rocksdb-iter-timestamp (rdb-iter-sap self) (addr tslen))
159  tslen)))
160 
161 ;;; column family
162 (defstruct (rdb-cf (:constructor make-rdb-cf (name &key key-type val-type sap)))
163  "RDB Column Family structure. Contains a name, key-type, val-type,
164 and a system-area-pointer to the underlying rocksdb_cf_t handle.
165 
166 A NIL key-type or val-type indicates an unitialized value which defaults to
167 'octet-vector. This is needed to distinguish the value 'octet-vector being
168 supplied by the user from the default value."
169  (name "" :type string)
170  (key-type nil :type (or list symbol))
171  (val-type nil :type (or list symbol))
172  (sap nil :type (or null alien)))
173 
174 (defmethod close-cf ((self rdb-cf) &optional error)
175  (if-let ((sap (rdb-cf-sap self)))
176  (setf (rdb-cf-sap self) (rocksdb:rocksdb-column-family-handle-destroy sap))
177  (when error (rdb-error "column family is already closed."))))
178 
179 ;;; rdb-stats
180 (defstruct (rdb-stats (:constructor make-rdb-stats (&optional sap)))
181  (sap nil :type (or null alien)))
182 
183 ;;; metadata
184 (defstruct rdb-cf-metadata
185  (name "default" :type string)
186  (size 0 :type fixnum)
187  (level-count 7 :type fixnum)
188  (file-count 0 :type fixnum)
189  (sap nil :type (or null alien)))
190 
191 (defmethod get-metadata ((self rdb-cf-metadata) &optional (level 0))
192  (with-slots (sap) self
193  (if (null sap)
194  (warn 'metadata-missing :message "ignoring attempt to pull fields from null sap.")
195  (make-rdb-level-metadata :sap (rocksdb-column-family-metadata-get-level-metadata sap level)))))
196 
197 (defmethod print-object ((self rdb-cf-metadata) stream)
198  (print-unreadable-object (self stream :type t)
199  (with-slots (name size level-count file-count) self
200  (format stream "~A :size ~A :levels ~A :files ~A" name size level-count file-count))))
201 
202 (defmethod pull-sap* ((self rdb-cf-metadata))
203  (with-slots (name size level-count file-count sap) self
204  (if (null sap)
205  (warn 'metadata-missing :message "ignoring attempt to pull fields from null sap.")
206  (setf name (rocksdb-column-family-metadata-get-name sap)
207  size (rocksdb-column-family-metadata-get-size sap)
208  level-count (rocksdb-column-family-metadata-get-level-count sap)
209  file-count (rocksdb-column-family-metadata-get-file-count sap)))
210  self))
211 
212 (defstruct rdb-level-metadata
213  (level 0 :type fixnum)
214  (size 0 :type fixnum)
215  (file-count 0 :type fixnum)
216  (sap nil :type (or null alien)))
217 
218 (defmethod get-metadata ((self rdb-level-metadata) &optional (file 0))
219  (with-slots (sap) self
220  (if (null sap)
221  (warn 'metadata-missing :message "ignoring attempt to pull fields from null sap.")
222  (make-rdb-sst-file-metadata :sap (rocksdb-level-metadata-get-sst-file-metadata sap file)))))
223 
224 (defmethod print-object ((self rdb-level-metadata) stream)
225  (print-unreadable-object (self stream :type t)
226  (with-slots (level size file-count) self
227  (format stream "~A :size ~A :files ~A" level size file-count))))
228 
229 (defmethod pull-sap* ((self rdb-level-metadata))
230  (with-slots (level size file-count sap) self
231  (if (null sap)
232  (warn 'metadata-missing :message "ignoring attempt to pull fields from null sap.")
233  (setf level (rocksdb-level-metadata-get-level sap)
234  size (rocksdb-level-metadata-get-size sap)
235  file-count (rocksdb-level-metadata-get-file-count sap)))
236  self))
237 
238 ;; NOTE: we only store the sizes of largest and smallest key, not the
239 ;; keys themselves. This may change in the future.
240 (defstruct rdb-sst-file-metadata
241  (relative-filename "" :type string)
242  (directory "" :type string)
243  (size 0 :type fixnum)
244  (smallestkey 0 :type fixnum)
245  (largestkey 0 :type fixnum)
246  (sap nil :type (or null alien)))
247 
248 (defmethod print-object ((self rdb-sst-file-metadata) stream)
249  (print-unreadable-object (self stream :type t)
250  (with-slots (relative-filename directory size smallestkey largestkey) self
251  (format stream "~A :dir ~A :size ~A :smallest ~A :largest ~A"
252  relative-filename directory size smallestkey largestkey))))
253 
254 (defmethod pull-sap* ((self rdb-sst-file-metadata))
255  (with-slots (relative-filename directory size smallestkey largestkey sap) self
256  (if (null sap)
257  (warn 'metadata-missing :message "ignoring attempt to pull fields from null sap.")
258  (with-alien ((ssize size-t 0)
259  (lsize size-t 0))
260  (rocksdb-sst-file-metadata-get-largestkey sap (addr lsize))
261  (rocksdb-sst-file-metadata-get-smallestkey sap (addr ssize))
262  (setf relative-filename (rocksdb-sst-file-metadata-get-relative-filename sap)
263  directory (rocksdb-sst-file-metadata-get-directory sap)
264  size (rocksdb-sst-file-metadata-get-size sap)
265  largestkey lsize
266  smallestkey ssize)))
267  self))
268 
269 ;;; rdb
270 (defstruct (rdb (:constructor make-rdb (name opts &optional cfs db)))
271  (name "" :type string)
272  (opts (default-rdb-opts) :type rdb-opts)
273  (cfs (make-array 0 :element-type 'rdb-cf :adjustable t :fill-pointer 0) :type (vector rdb-cf))
274  (db nil :type (or null alien))
275  (backup nil :type (or null alien))
276  (snapshots #() :type (array alien)))
277 
278 (defvar *default-rdb-opts* (default-rdb-opts))
279 
280 (defmethod print-object ((self rdb) stream)
281  (print-unreadable-object (self stream :type t :identity t)
282  (format stream ":cfs ~A :open ~A" (length (rdb-cfs self)) (db-open-p self))))
283 
284 (defmethod db ((self rdb))
285  (rdb-db self))
286 
287 (defmethod db-open-p ((self rdb))
288  (when (db self) t))
289 
290 (defmethod db-closed-p ((self rdb))
291  (unless (db self) t))
292 
293 (defun translate-cf-to-field (cf)
294  (let ((vt (or (rdb-cf-val-type cf) 'octet-vector))
295  (kt (unless (rdb-cf-val-type cf) (or (rdb-cf-key-type cf) 'octet-vector))))
296  (make-field :name (rdb-cf-name cf)
297  :type (if kt
298  (cons kt vt)
299  vt))))
300 
301 (defmethod load-field ((self rdb-cf) (field field))
302  (let ((type (field-type field)))
303  (typecase type
304  ;; note that this means you can't use LOAD-SCHEMA to reset an
305  ;; rdb schema as you may expect.
306  (null nil)
307  (atom (setf (rdb-cf-val-type self) type))
308  (list (setf (rdb-cf-key-type self) (car type)
309  (rdb-cf-val-type self)
310  (if (and (listp (cdr type))
311  (= 1 (length (cdr type))))
312  (cadr type)
313  (cdr type)))))
314  self))
315 
316 (defmethod load-schema ((self rdb) (schema schema))
317  "Load SCHEMA into rdb database object SELF. This will add any missing rdb-cfs
318 and update existing key/value types for cfs with the same name. Existing cfs
319 only get their their type slots updated on non-nil values."
320  (loop for field across (fields schema)
321  do (if-let ((cf (find-cf (field-name field) self)))
322  (load-field cf field)
323  (push-cf
324  (load-field (make-rdb-cf (field-name field)) field)
325  self)))
326  self)
327 
328 (defmethod derive-schema ((self rdb))
329  (apply 'make-schema
330  (loop for cf across (rdb-cfs self)
331  collect (translate-cf-to-field cf))))
332 
333 (defun create-db (name &key opts cfs schema open)
334  "Construct a new RDB instance from NAME.
335 
336 OPTS = rdb-opts
337 CFS = (sequence rdb-cf)
338 SCHEMA = rdb-schema
339 OPEN = boolean
340 
341 CFS are always added before the SCHEMA which is loaded with LOAD-SCHEMA.
342 
343 When OPEN is non-nil, the database and all column families are opened and
344 internal sap slots are initialized."
345  ;; (when (probe-file name) (log:trace! "db exists: " name))
346  (let* ((opts (or opts (default-rdb-opts)))
347  (obj
348  (make-rdb
349  (string-right-trim '(#\/)
350  (typecase name
351  (pathname (namestring name))
352  (string name)
353  (t (error "invalid NAME: ~S" name))))
354  opts
355  (or (when cfs
356  (typecase cfs
357  (list (coerce cfs 'vector))
358  ((array rdb-cf) cfs)
359  (rdb-cf (vector cfs))
360  (t (log:warn! "invalid CF passed to create-db"))))
361  (make-array 0 :element-type 'rdb-cf :fill-pointer 0)))))
362  (when schema
363  (load-schema obj schema))
364  (when open
365  (open-db obj))
366  obj))
367 
368 (defmethod backfill-opts ((self rdb) &key full)
369  (with-slots (opts) self
370  (if full
371  (loop for k across *rocksdb-options*
372  unless (opt-no-setter-p k)
373  do (pull-sap opts k))
374  (pull-sap* opts))
375  (rdb-opts-table opts)))
376 
377 (defmethod push-cf ((cf rdb-cf) (db rdb))
378  (vector-push-extend cf (rdb-cfs db)))
379 
380 (defmethod create-cf ((db rdb) (cf rdb-cf))
381  (create-cf-raw (rdb-db db) (rdb-cf-name cf) (rdb-opts-sap (rdb-opts db))))
382 
383 (defmethod open-cf ((db rdb) (cf rdb-cf) &optional error)
384  (unless (null (rdb-cf-sap cf))
385  (if error
386  (rdb-error "column family is already open - close before re-opening.")
387  cf)
388  (setf (rdb-cf-sap cf) (open-cf-raw (rdb-db db) (default-rocksdb-options) (rdb-cf-name cf)))))
389 
390 (defmethod open-cf ((db rdb) (cf string) &optional (error t))
391  (if-let ((cf (find-cf cf db)))
392  (or (rdb-cf-sap cf)
393  (setf (rdb-cf-sap cf) (create-cf db cf)))
394  (when error (rdb-error "unable to find column-family"))))
395 
396 (defmethod open-cfs ((self rdb))
397  (loop for cf across (rdb-cfs self)
398  do (setf (rdb-cf-sap cf)
399  (create-cf self cf))))
400 
401 (defmethod close-cfs ((self rdb))
402  (loop for cf across (rdb-cfs self)
403  do (close-cf cf)))
404 
405 (defmacro unless-null-db (slots self &body body)
406  `(with-slots (db ,@slots) ,self
407  (unless (null db)
408  ,@body)))
409 
410 (defmethod destroy-cf ((cf rdb-cf))
411  (with-slots (sap) cf
412  (unless (null sap)
413  (setf sap (destroy-cf-raw sap)))))
414 
415 (defmethod set-opt ((self rdb) key val &key push)
416  (with-slots (opts) self
417  (set-opt opts key val :push push)))
418 
419 (defmethod get-opt ((self rdb) key)
420  (with-slots (opts) self
421  (get-opt opts key)))
422 
423 (defmethod push-opts ((self rdb))
424  (with-slots (opts) self
425  (push-sap* opts)))
426 
427 (defmethod open-db ((self rdb))
428  (with-slots (name db opts) self
429  (if db
430  (rdb-error "DB already opened - close before re-opening")
431  (setf db (open-db-raw name (rdb-opts-sap opts))))))
432 
433 (defmethod get-prop ((self rdb) (propname string))
434  (unless-null-db () self
435  (get-property-raw db propname)))
436 
437 (defmethod repair-db ((self rdb) &key)
438  (repair-db-raw (rdb-name self)))
439 
440 (defmethod open-backup-db ((self rdb) &key path)
441  (with-slots (opts) self
442  (setf (rdb-backup self) (open-backup-engine-raw path (rdb-opts-sap opts)))))
443 
444 (defmethod close-backup-db ((self rdb))
445  (with-slots (backup) self
446  (unless (null backup)
447  (setf backup (close-backup-engine-raw backup)))))
448 
449 (defmethod backup-db ((self rdb) &key path)
450  (unless-null-db (opts backup) self
451  (when (null backup)
452  (if (null path)
453  (error 'open-backup-engine-error :db db)
454  (open-backup-db self :path path)))
455  (create-new-backup-raw backup db)))
456 
457 (defmethod restore-db ((self rdb) (from string) &key id opts)
458  (unless-null-db (name backup) self
459  (when (null backup)
460  (open-backup-db self :path from))
461  (restore-from-backup-raw backup name from id opts)))
462 
463 (defmethod snapshot-db ((self rdb))
464  (unless-null-db (snapshots) self
465  (vector-push-extend (create-snapshot-raw db) snapshots)))
466 
467 (defmethod get-metadata ((self rdb) &optional cf)
468  (make-rdb-cf-metadata :sap (get-metadata-raw (rdb-db self) cf)))
469 
470 (defmethod get-stats ((self rdb) &optional (htype (rocksdb-statistics-level "all")))
471  (make-rdb-stats (get-stats-raw (rdb-opts-sap (rdb-opts self)) htype)))
472 
473 (defmethod create-iter ((self rdb) &optional cf (opts (rocksdb-readoptions-create)))
474  (when cf
475  (setf cf (etypecase cf
476  (rdb-cf (rdb-cf-sap cf))
477  (string (rdb-cf-sap (find-cf cf self)))
478  (alien cf))))
479  (unless-null-db () self
480  (make-instance 'rdb-iter :sap (if cf
481  (create-cf-iter-raw db cf opts)
482  (create-iter-raw db opts)))))
483 
484 (defmethod print-stats ((self rdb) &optional stream)
485  (print (rocksdb-options-statistics-get-string (rdb-opts-sap (rdb-opts self))) stream))
486 
487 (defmethod flush-db ((self rdb) &key) ;; todo flushopts
488  (flush-db-raw (rdb-db self)))
489 
490 (defmethod sync-db ((self rdb) (other null) &key)
491  (flush-db self))
492 
493 (defmethod shutdown-db ((self rdb) &key wait)
494  (log:trace! "shutting down database" (rdb-name self))
495  (when-let ((db (rdb-db self)))
496  (rocksdb-cancel-all-background-work db wait)
497  (close-db self)))
498 
499 (defmethod create-cfs ((self rdb) &key &allow-other-keys)
500  (if (null (rdb-db self))
501  (warn 'db-missing :message "ignoring attempt to create column-families before opening")
502  (loop for cf across (rdb-cfs self)
503  do (create-cf self cf))))
504 
505 (defmethod find-cf ((cf string) (self rdb) &key)
506  "Find a CF by name."
507  (find cf (rdb-cfs self) :key 'rdb-cf-name :test 'equal))
508 
509 (defmethod ingest-db ((self rdb) (files list) &key cf (opts (rocksdb-ingestexternalfileoptions-create)))
510  (if cf
511  (ingest-db-cf-raw (rdb-db self) (find-cf cf self) files opts)
512  (ingest-db-raw (rdb-db self) files opts)))
513 
514 (defmethod destroy-cfs ((self rdb) &key &allow-other-keys)
515  (with-slots (cfs) self
516  (declare (type (array rdb-cf) cfs))
517  (loop for cf across cfs
518  do (setf cf (destroy-cf cf)))))
519 
520 (defmethod close-db ((self rdb) &key &allow-other-keys)
521  (with-slots (db cfs backup snapshots) self
522  (close-backup-db self)
523  (unless (zerop (length snapshots))
524  (loop for s across snapshots do (release-snapshot-raw db s)))
525  (destroy-cfs self)
526  (unless (null db)
527  (setf db (close-db-raw db)))))
528 
529 (defmethod destroy-db ((self rdb))
530  ;; close all handles before destruction ensues
531  (close-db self)
532  (destroy-db-raw (rdb-name self)))
533 
534 (defmethod put-key ((self rdb) (key t) (val t))
535  (put-kv-raw
536  (rdb-db self)
537  key
538  val))
539 
540 (defmethod put-key ((self rdb) (key string) (val string))
541  (put-kv-raw
542  (rdb-db self)
543  (sb-ext:string-to-octets key)
544  (sb-ext:string-to-octets val)))
545 
546 (defmethod put-kv ((self rdb) (kv rdb-kv))
547  (put-kv-raw
548  (rdb-db self)
549  (rdb-key kv)
550  (rdb-val kv)))
551 
552 (defmethod insert-key ((self rdb) key val &key cf)
553  (if-let ((cf (and cf (find-cf cf self))))
554  (if-let ((sap (rdb-cf-sap cf)))
555  (put-cf-raw
556  (rdb-db self)
557  sap
558  key
559  val
560  (rocksdb-writeoptions-create))
561  (rdb-error "column-family is not open"))
562  (put-key self key val)))
563 
564 (defmethod insert-key ((self rdb) (key string) (val string) &key cf)
565  (insert-key self (string-to-octets key) (string-to-octets val) :cf cf))
566 
567 (defmethod insert-key ((self rdb) (key string) val &key cf)
568  (insert-key self (string-to-octets key) val :cf cf))
569 
570 (defmethod insert-key ((self rdb) key (val string) &key cf)
571  (insert-key self key (string-to-octets val) :cf cf))
572 
573 (defmethod insert-kv ((self rdb) (kv rdb-kv) &key cf (opts (rocksdb-writeoptions-create)))
574  (if cf
575  (let ((cf (etypecase cf
576  (rdb-cf cf)
577  (t (find cf (rdb-cfs self)
578  :key #'rdb-cf-name
579  :test #'equal)))))
580  (put-cf-raw (rdb-db self)
581  (rdb-cf-sap cf)
582  (rdb-key kv)
583  (rdb-val kv)
584  opts))
585  (put-kv self kv)))
586 
587 (defmethod get-key ((self rdb) (key string) &key (opts (rocksdb-readoptions-create)) cf)
588  (with-slots (db) self
589  (if cf
590  (get-cf-str-raw db (rdb-cf-sap (find-cf cf self)) key opts)
591  (get-kv-str-raw db key opts))))
592 
593 (defmethod get-key ((self rdb) key &key (opts (rocksdb-readoptions-create)) cf)
594  (with-slots (db) self
595  (if cf
596  (get-cf-raw db (rdb-cf-sap (find-cf cf self)) key opts)
597  (get-kv-raw db key opts))))