changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / lisp/ffi/rocksdb/merge.lisp

changeset 611: 57813b8ee029
parent: 1a5828267b90
child: c48704d7b06f
author: Richard Westhaver <ellis@rwest.io>
date: Mon, 19 Aug 2024 19:25:55 -0400
permissions: -rw-r--r--
description: more rocksdb work, slice -> slicetransform
1 ;;; rocksdb/merge.lisp --- RocksDB Merge Operators
2 
3 ;; RocksDB Lisp Merge Operator API
4 
5 ;;; Commentary:
6 
7 ;; When to use built-in ROCKSDB-MERGE:
8 
9 ;; - You have data that needs to be incrementally updated.
10 
11 ;; - You would usually need to read the data before knowing what the new value would be.
12 
13 ;; Oterwise as far as the FFI is concerned - which doesn't support
14 ;; AssociateMerge, you should use the Generic Merge API.
15 
16 ;; When to use Associative Merge (unavailable in C/LISP API):
17 
18 ;; - merge operands are formatted the same as Put values AND
19 
20 ;; - it is okay to combine multiple operands into one
21 
22 ;; When to use Generic Merge (this API):
23 
24 ;; - you are unable to use Associate Merge
25 
26 ;; - it is possible to combine multiple operands
27 
28 ;;; Refs:
29 
30 ;; impl: https://github.com/facebook/rocksdb/wiki/Merge-Operator-Implementation
31 
32 ;; wiki: https://github.com/facebook/rocksdb/wiki/merge-operator
33 
34 ;;; Code:
35 (in-package :rocksdb)
36 
37 (defvar *rocksdb-partial-merge-lambda-list*
38  '((key (array unsigned-char))
39  (klen size-t)
40  (ops (array (array unsigned-char)))
41  (ops-length (* size-t))
42  (num-ops size-t)
43  (success (array unsigned-char))
44  (new-vlen (* size-t))))
45 
46 (defvar *rocksdb-full-merge-lambda-list*
47  '((key (array unsigned-char))
48  (klen size-t)
49  (existing-val (array unsigned-char))
50  (existing-vlen size-t)
51  (ops (array (array unsigned-char)))
52  (ops-length (* size-t))
53  (num-ops size-t)
54  (success (array unsigned-char))
55  (new-vlen (* size-t))))
56 
57 #|
58 Gives the client a way to express the read -> modify -> write semantics
59 key: (IN) The key that's associated with this merge operation.
60 existing: (IN) null indicates that the key does not exist before this op
61 operand_list:(IN) the sequence of merge operations to apply, front() first.
62 new_value: (OUT) Client is responsible for filling the merge result here
63 logger: (IN) Client could use this to log errors during merge.
64 
65 Return true on success. Return false failure / error / corruption.
66 |#
67 ;; FullMerge() is used when a Put/Delete is the *existing_value (or null)
68 (define-alien-type rocksdb-full-merge-function
69  (function (* t)
70  (array unsigned-char)
71  size-t
72  (array (array unsigned-char))
73  (array size-t)
74  int
75  (array unsigned-char)
76  (* size-t)))
77 
78 #|
79 This function performs merge(left_op, right_op)
80 when both the operands are themselves merge operation types.
81 Save the result in *new_value and return true. If it is impossible
82 or infeasible to combine the two operations, return false instead.
83 |#
84 ;; PartialMerge() is used to combine two-merge operands (if possible)
85 (define-alien-type rocksdb-partial-merge-function
86  (function (* t)
87  (array unsigned-char)
88  size-t
89  (array (array unsigned-char))
90  (array size-t)
91  int
92  (array unsigned-char)
93  (* size-t)))
94 
95 (define-alien-type rocksdb-delete-value-function
96  (function (* t)
97  (array unsigned-char)
98  size-t))
99 
100 (define-alien-type rocksdb-destructor-function
101  (function void (* t)))
102 
103 #|
104 The name of the MergeOperator. Used to check for MergeOperator
105 mismatches (i.e., a DB created with one MergeOperator is
106 accessed using a different MergeOperator)
107 |#
108 (define-alien-type rocksdb-name-function
109  (function c-string))
110 
111 ;; (sb-alien::define-alien-callable mangle int () 0)
112 
113 (define-alien-routine rocksdb-mergeoperator-create (* rocksdb-mergeoperator)
114  (state (* t))
115  (destructor (* rocksdb-destructor-function))
116  (full-merge (* rocksdb-full-merge-function))
117  (partial-merge (* rocksdb-partial-merge-function))
118  (delete-value (* rocksdb-delete-value-function))
119  (name (* rocksdb-name-function)))
120 
121 #| [[file:~/dev/comp/core/c/rocksdb.h::/* Merge Operator */]] |#
122 
123 (define-alien-routine rocksdb-mergeoperator-destroy void (self (* rocksdb-mergeoperator)))
124 
125 (define-alien-callable rocksdb-destructor void ((self (* t)))
126  (free-alien self)
127  (values))
128 
129 (define-alien-callable rocksdb-name c-string () (make-alien-string (symbol-name (gensym "rocksdb:"))))
130 
131 ;;; Associative Merge
132 
133 ;;; Concat Merge
134 (define-alien-callable rocksdb-concat-merge-name c-string () (make-alien-string "cc:concat"))
135 
136 (define-alien-callable rocksdb-concat-full-merge boolean
137  ((key (array unsigned-char))
138  (klen size-t)
139  (existing-val (array unsigned-char))
140  (existing-vlen size-t)
141  (ops (array (array unsigned-char)))
142  (ops-length (* size-t))
143  (num-ops size-t)
144  (success (array unsigned-char))
145  (new-vlen (* size-t)))
146  (log:debug! (list key klen existing-val existing-vlen ops ops-length num-ops success new-vlen))
147  t)
148 
149 (define-alien-callable rocksdb-concat-partial-merge boolean
150  ((key (array unsigned-char))
151  (klen size-t)
152  (ops (array (array unsigned-char)))
153  (ops-length (* size-t))
154  (num-ops size-t)
155  (success (array unsigned-char))
156  (new-vlen (* size-t)))
157  (log:debug! (list key klen ops ops-length num-ops success new-vlen))
158  nil)
159 
160 (define-alien-callable rocksdb-delete-value void
161  ((state (* t))
162  (value c-string)
163  (value-length size-t))
164  (declare (ignore state))
165  ;; TODO 2024-08-18: test if this is needed
166  (unless (zerop value-length)
167  (log:trace! "deleting value:" value)
168  (setf value nil))
169  (values))