forked from domsj/orocksdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rocks_common.ml
159 lines (128 loc) · 3.18 KB
/
rocks_common.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
open Ctypes
open Foreign
(* Trick taken from Janestreet's core_kernel library.
* This function guarantees `o` will not be garbage collected.
* It is safer than using `ignore` to provide this guarantee, as
* the compiler won't optimize int_of_string away and will not perform
* constant folding on invocations of `keep_alive` *)
let rec keep_alive o = if Sys.opaque_identity (int_of_string "0") <> 0 then keep_alive (Sys.opaque_identity o)
module Views = struct
open Unsigned
let bool_to_int =
view
~read:(fun i -> i <> 0)
~write:(function true -> 1 | false -> 0)
int
let bool_to_uchar =
view
~read:(fun u -> u <> UChar.zero)
~write:(function true -> UChar.one | false -> UChar.zero)
uchar
let int_to_size_t =
view
~read:Size_t.to_int
~write:Size_t.of_int
size_t
let int_to_uint_t =
view
~read:UInt.to_int
~write:UInt.of_int
uint
let int_to_uint32_t =
view
~read:UInt32.to_int
~write:UInt32.of_int
uint32_t
let int_to_uint64_t =
view
~read:UInt64.to_int
~write:UInt64.of_int
uint64_t
end
let free =
foreign
"free"
(ptr void @-> returning void)
module type RocksType =
sig
val name : string
val constructor : string
val destructor : string
val setter_prefix : string
end
module type RocksType' =
sig
val name : string
end
type t = {
ptr : unit ptr;
mutable valid : bool;
}
let get_pointer t = t.ptr
exception OperationOnInvalidObject
let t : t typ =
view
~read:(fun ptr -> { ptr; valid = true; })
~write:(
fun { ptr; valid; } ->
if valid
then ptr
else raise OperationOnInvalidObject)
(ptr void)
let make_destroy t destructor =
let inner =
foreign
destructor
(t @-> returning void) in
fun t ->
inner t;
t.valid <- false
let finalize f finalizer =
match f () with
| a -> finalizer ();
a
| exception exn -> finalizer ();
raise exn
module type S = sig
type t
val t : t Ctypes.typ
val get_pointer : t -> unit Ctypes.ptr
val type_name : string
val create : unit -> t
val create_no_gc : unit -> t
val destroy : t -> unit
val with_t : (t -> 'a) -> 'a
val create_setter : string -> 'a Ctypes.typ -> t -> 'a -> unit
end
module CreateConstructors(T : RocksType) = struct
type nonrec t = t
let t = t
let get_pointer = get_pointer
let type_name = T.name
let create_no_gc =
foreign
T.constructor
(void @-> returning t)
let destroy = make_destroy t T.destructor
let create () =
let t = create_no_gc () in
Gc.finalise destroy t;
t
let with_t f =
let t = create_no_gc () in
finalize
(fun () -> f t)
(fun () -> destroy t)
let create_setter property_name property_typ =
foreign
(T.setter_prefix ^ property_name)
(t @-> property_typ @-> returning void)
end
module CreateConstructors_(T : RocksType') = struct
include CreateConstructors(struct
let name = T.name
let constructor = "rocksdb_" ^ T.name ^ "_create"
let destructor = "rocksdb_" ^ T.name ^ "_destroy"
let setter_prefix = "rocksdb_" ^ T.name ^ "_"
end)
end