package lmdb

  1. Overview
  2. Docs

Source file lmdb_bindings.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
exception Exists
exception Map_full
exception Error of int

(* return codes *)
external strerror : int -> string = "mdbs_strerror"

(* Initialise constants and exceptions *)
external init : unit -> ((string * int * int * int) * int array)
  = "mdbs_init"
[@@@ocaml.warning "-8"]
let
  ( version
  , [| append
     ; appenddup
     ; cp_compact
     ; create
     ; current
     ; dupfixed
     ; dupsort
     ; first
     ; first_dup
     ; fixedmap
     ; get_both
     ; get_both_range
     ; get_current
     ; get_multiple
     ; integerdup
     ; integerkey
     ; last
     ; last_dup
     ; mapasync
     ; multiple
     ; next
     ; next_dup
     ; next_multiple
     ; next_nodup
     ; nodupdata
     ; nolock
     ; nomeminit
     ; nometasync
     ; nooverwrite
     ; nordahead
     ; nosubdir
     ; nosync
     ; notls
     ; prev
     ; prev_dup
  (* ; prev_multiple - only since lmdb 0.9.19 *)
     ; prev_nodup
     ; rdonly
     ; reserve
     ; reversedup
     ; reversekey
     ; set
     ; set_key
     ; set_range
     ; writemap
     ; sizeof_int
     ; sizeof_size_t
    |] )
  =
  Callback.register_exception "LmdbExists" Exists;
  Callback.register_exception "LmdbError" (Error 0);
  Callback.register_exception "LmdbMapFull" (Map_full);
  Printexc.register_printer @@ begin function
    | Error i -> Some ("Lmdb.Error(" ^ strerror i ^ ")")
    | Exists -> Some "Lmdb.Exists"
    | _ -> None
  end;
  init ()
[@@@ocaml.warning "+8"]

module type Flags = sig
  type t
  external ( + ) : t -> t -> t = "%orint"
  external ( * ) : t -> t -> t = "%andint"
  val test : t -> t -> bool
  val unset : t -> t -> t
  external eq : t -> t -> bool = "%equal"
  external of_int : int -> t   = "%identity"
  external to_int : t -> int   = "%identity"
  val none : t
end
module Flags :Flags with type t = int = struct
  type t = int
  external ( + ) : t -> t -> t = "%orint"
  external ( * ) : t -> t -> t = "%andint"
  let test f m = f * m = f
  let unset kill flags = flags * lnot kill
  external eq : t -> t -> bool = "%equal"
  external of_int : int -> t   = "%identity"
  external to_int : t -> int   = "%identity"
  let none :t = 0
end

(* returned by env_stat and dbi_stat *)
type stat =
  { psize : int
  ; depth : int
  ; branch_pages : int
  ; leaf_pages : int
  ; overflow_pages : int
  ; entries : int
  }

(* returned by env_info *)
type envinfo =
  { map_addr : int
  ; map_size : int
  ; last_pgno : int
  ; last_txnid : int
  ; max_readers : int
  ; num_readers : int
  }

type bigstring = Bigstringaf.t

(* env *)
type env
module EnvFlags = struct
  include Flags
  let fixed_map       = fixedmap
  let no_subdir       = nosubdir
  let no_sync         = nosync
  let read_only       = rdonly
  let no_meta_sync    = nometasync
  let write_map       = writemap
  let map_async       = mapasync
  let no_tls          = notls
  let no_lock         = nolock
  let no_read_ahead   = nordahead
  let no_mem_init     = nomeminit
end
module CopyFlags = struct
  include Flags
  let compact         = cp_compact
end
external env_create : unit -> env
  = "mdbs_env_create"
external env_open : env -> string -> EnvFlags.t -> int -> unit
  = "mdbs_env_open"
external env_close : env -> unit
  = "mdbs_env_close"
external env_set_mapsize : env -> int -> unit
  = "mdbs_env_set_mapsize"
external env_set_maxdbs : env -> int -> unit
  = "mdbs_env_set_maxdbs"
external env_set_maxreaders : env -> int -> unit
  = "mdbs_env_set_maxreaders"
external env_copy : env -> string -> CopyFlags.t -> unit
  = "mdbs_env_copy2"
external env_copyfd : env -> Unix.file_descr -> CopyFlags.t -> unit
  = "mdbs_env_copyfd2"
external env_set_flags : env -> EnvFlags.t -> bool -> unit
  = "mdbs_env_set_flags"
external env_get_flags : env -> int
  = "mdbs_env_get_flags"
external env_get_path : env -> string
  = "mdbs_env_get_path"
external env_get_fd : env -> Unix.file_descr
  = "mdbs_env_get_fd"
external env_sync : env -> bool -> unit
  = "mdbs_env_sync"
external env_get_maxreaders : env -> int
  = "mdbs_env_get_maxreaders"
external env_get_maxkeysize : env -> int
  = "mdbs_env_get_maxkeysize"
external reader_list : env -> (string -> int) -> int
  = "mdbs_reader_list"
external reader_check : env -> int
  = "mdbs_reader_check"
external env_stat : env -> stat
  = "mdbs_env_stat"
external env_info : env -> envinfo
  = "mdbs_env_info"

(* txn *)
type txn
external txn_env : txn -> env
  = "mdbs_txn_env"
external txn_begin : env -> txn option -> EnvFlags.t -> txn
  = "mdbs_txn_begin"
external txn_commit : txn -> unit
  = "mdbs_txn_commit"
external txn_abort : txn -> unit
  = "mdbs_txn_abort"

(* dbi *)
type dbi
let invalid_dbi :dbi = Obj.magic ~-1
module DbiFlags = struct
  include Flags
  let reverse_key	= reversekey
  let dup_sort   	= dupsort
  let integer_key	= integerkey
  let dup_fixed  	= dupfixed
  let integer_dup	= integerdup
  let reverse_dup     = reversedup
  let create          = create
end
module PutFlags = struct
  include Flags
  let no_overwrite    = nooverwrite
  let no_dup_data     = nodupdata
  let current         = current
  let reserve        = reserve
  let append          = append
  let append_dup      = appenddup
  let multiple       = multiple
end
module Block_option = struct
  type +'a t
  let none :_ t = Obj.magic None
  external some_unsafe : 'a -> 'a t = "%identity"
  external get_unsafe  : 'a t -> 'a = "%identity"
  let is_some o = Obj.(is_block (repr o))
  let is_none o = not (is_some o)
  let some x = assert (is_some x); some_unsafe x
  let get_exn o =
    if is_some o
    then get_unsafe o
    else raise Not_found
end
external dbi_open
  : txn -> string option -> Flags.t -> dbi
  = "mdbs_dbi_open"
external dbi_close : env -> dbi -> unit
  = "mdbs_dbi_close"
external dbi_flags : txn -> dbi -> Flags.t
  = "mdbs_dbi_flags"
external dbi_stat : txn -> dbi -> stat
  = "mdbs_stat"
external drop : txn -> dbi -> bool -> unit
  = "mdbs_drop"
external get
  : txn -> dbi -> bigstring -> bigstring
  = "mdbs_get"
external put
  : txn -> dbi -> bigstring -> bigstring ->
    PutFlags.t -> unit
  = "mdbs_put"
external put_reserve
  : txn -> dbi -> bigstring -> int ->
    PutFlags.t -> bigstring
  = "mdbs_put"
external del
  : txn -> dbi ->
    bigstring -> bigstring Block_option.t -> unit
  = "mdbs_del"
external cmp
  : txn -> dbi -> bigstring -> bigstring -> int
  = "mdbs_cmp"
external dcmp
  : txn -> dbi -> bigstring -> bigstring -> int
  = "mdbs_dcmp"

(* cursor *)
type cursor
module Ops = struct
  type t = int
  let first           = first
  let first_dup       = first_dup
  let get_both        = get_both
  let get_both_range  = get_both_range
  let get_current     = get_current
  let get_multiple    = get_multiple
  let last            = last
  let last_dup        = last_dup
  let next            = next
  let next_dup        = next_dup
  let next_multiple   = next_multiple
  let next_nodup      = next_nodup
  let prev            = prev
  let prev_dup        = prev_dup
  let prev_nodup      = prev_nodup
  let set             = set
  let set_key         = set_key
  let set_range       = set_range
  (* let prev_multiple  = prev_multiple - only since lmdb 0.9.19 *)
end
external cursor_open : txn -> dbi -> cursor
  = "mdbs_cursor_open"
external cursor_close : cursor -> unit
  = "mdbs_cursor_close"
external cursor_put
  : cursor -> bigstring -> bigstring ->
    PutFlags.t -> unit
  = "mdbs_cursor_put"
external cursor_put_reserve
  : cursor -> bigstring -> int ->
    PutFlags.t -> bigstring
  = "mdbs_cursor_put"
external cursor_del
  : cursor -> PutFlags.t -> unit
  = "mdbs_cursor_del"
external cursor_get
  : cursor ->
    bigstring Block_option.t -> bigstring Block_option.t -> Ops.t ->
    bigstring * bigstring
  = "mdbs_cursor_get"
external cursor_count : cursor -> int
  = "mdbs_cursor_count"