heed/mdb/lmdb_flags.rs
1use bitflags::bitflags;
2use lmdb_master_sys as ffi;
3
4bitflags! {
5 /// LMDB environment flags (see <http://www.lmdb.tech/doc/group__mdb__env.html> for more details).
6 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8 #[repr(transparent)]
9 pub struct EnvFlags: u32 {
10 /// mmap at a fixed address (experimental).
11 const FIXEDMAP = ffi::MDB_FIXEDMAP;
12 /// No environment directory.
13 const NO_SUB_DIR = ffi::MDB_NOSUBDIR;
14 /// Don't fsync after commit.
15 const NO_SYNC = ffi::MDB_NOSYNC;
16 /// Read only.
17 const READ_ONLY = ffi::MDB_RDONLY;
18 /// Don't fsync metapage after commit.
19 const NO_META_SYNC = ffi::MDB_NOMETASYNC;
20 /// Use writable mmap.
21 const WRITE_MAP = ffi::MDB_WRITEMAP;
22 /// Use asynchronous msync when MDB_WRITEMAP is used.
23 const MAP_ASYNC = ffi::MDB_MAPASYNC;
24 /// Tie reader locktable slots to MDB_txn objects instead of to threads.
25 const NO_TLS = ffi::MDB_NOTLS;
26 /// Don't do any locking, caller must manage their own locks.
27 const NO_LOCK = ffi::MDB_NOLOCK;
28 /// Don't do readahead (no effect on Windows).
29 const NO_READ_AHEAD = ffi::MDB_NORDAHEAD;
30 /// Don't initialize malloc'd memory before writing to datafile.
31 const NO_MEM_INIT = ffi::MDB_NOMEMINIT;
32 }
33}
34
35bitflags! {
36 /// LMDB database flags (see <http://www.lmdb.tech/doc/group__mdb__dbi__open.html> for more details).
37 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
38 #[repr(transparent)]
39 pub struct AllDatabaseFlags: u32 {
40 /// Use reverse string keys.
41 const REVERSE_KEY = ffi::MDB_REVERSEKEY;
42 /// Use sorted duplicates.
43 const DUP_SORT = ffi::MDB_DUPSORT;
44 /// Numeric keys in native byte order: either `u32` or `usize`.
45 /// The keys must all be of the same size.
46 const INTEGER_KEY = ffi::MDB_INTEGERKEY;
47 /// With [`DatabaseFlags::DUP_SORT`], sorted dup items have fixed size.
48 const DUP_FIXED = ffi::MDB_DUPFIXED;
49 /// With [`DatabaseKey::DUP_SORT`], dups are [`DatabaseKey::INTEGER_KEY`]-style integers.
50 const INTEGER_DUP = ffi::MDB_INTEGERDUP;
51 /// With [`DatabaseKey::DUP_SORT`], use reverse string dups.
52 const REVERSE_DUP = ffi::MDB_REVERSEDUP;
53 /// Create DB if not already existing.
54 const CREATE = ffi::MDB_CREATE;
55 }
56}
57
58bitflags! {
59 /// LMDB database flags (see <http://www.lmdb.tech/doc/group__mdb__dbi__open.html> for more details).
60 // It is a subset of the whole list of possible flags LMDB exposes but
61 // we only want users to be able to specify these with the DUP flags.
62 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
63 #[repr(transparent)]
64 pub struct DatabaseFlags: u32 {
65 /// Use reverse string keys.
66 ///
67 /// ```
68 /// # use std::fs;
69 /// # use std::path::Path;
70 /// # use heed::{DatabaseFlags, EnvOpenOptions};
71 /// use heed::types::*;
72 /// use heed::byteorder::BigEndian;
73 ///
74 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
75 /// # let dir = tempfile::tempdir()?;
76 /// # let env = unsafe { EnvOpenOptions::new()
77 /// # .map_size(10 * 1024 * 1024) // 10MB
78 /// # .max_dbs(3000)
79 /// # .open(dir.path())?
80 /// # };
81 ///
82 /// let mut wtxn = env.write_txn()?;
83 /// let db = env.database_options()
84 /// .types::<Str, Unit>()
85 /// .flags(DatabaseFlags::REVERSE_KEY)
86 /// .name("reverse-key")
87 /// .create(&mut wtxn)?;
88 ///
89 /// # db.clear(&mut wtxn)?;
90 /// db.put(&mut wtxn, &"bonjour", &())?;
91 /// db.put(&mut wtxn, &"hello", &())?;
92 /// db.put(&mut wtxn, &"holla", &())?;
93 ///
94 /// let mut iter = db.iter(&wtxn)?;
95 /// assert_eq!(iter.next().transpose()?, Some(("holla", ())));
96 /// assert_eq!(iter.next().transpose()?, Some(("hello", ())));
97 /// assert_eq!(iter.next().transpose()?, Some(("bonjour", ())));
98 /// assert_eq!(iter.next().transpose()?, None);
99 /// drop(iter);
100 ///
101 /// let mut iter = db.rev_iter(&wtxn)?;
102 /// assert_eq!(iter.next().transpose()?, Some(("bonjour", ())));
103 /// assert_eq!(iter.next().transpose()?, Some(("hello", ())));
104 /// assert_eq!(iter.next().transpose()?, Some(("holla", ())));
105 /// assert_eq!(iter.next().transpose()?, None);
106 /// drop(iter);
107 ///
108 /// wtxn.commit()?;
109 /// # Ok(()) }
110 /// ```
111 const REVERSE_KEY = ffi::MDB_REVERSEKEY;
112 /// Use sorted duplicates.
113 ///
114 /// ```
115 /// # use std::fs;
116 /// # use std::path::Path;
117 /// # use heed::{DatabaseFlags, EnvOpenOptions};
118 /// use heed::types::*;
119 /// use heed::byteorder::BigEndian;
120 ///
121 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
122 /// # let dir = tempfile::tempdir()?;
123 /// # let env = unsafe { EnvOpenOptions::new()
124 /// # .map_size(10 * 1024 * 1024) // 10MB
125 /// # .max_dbs(3000)
126 /// # .open(dir.path())?
127 /// # };
128 /// type BEI64 = I64<BigEndian>;
129 ///
130 /// let mut wtxn = env.write_txn()?;
131 /// let db = env.database_options()
132 /// .types::<BEI64, BEI64>()
133 /// .flags(DatabaseFlags::DUP_SORT)
134 /// .name("dup-sort")
135 /// .create(&mut wtxn)?;
136 ///
137 /// # db.clear(&mut wtxn)?;
138 /// db.put(&mut wtxn, &68, &120)?;
139 /// db.put(&mut wtxn, &68, &121)?;
140 /// db.put(&mut wtxn, &68, &122)?;
141 /// db.put(&mut wtxn, &68, &123)?;
142 /// db.put(&mut wtxn, &92, &32)?;
143 /// db.put(&mut wtxn, &35, &120)?;
144 /// db.put(&mut wtxn, &0, &120)?;
145 /// db.put(&mut wtxn, &42, &120)?;
146 ///
147 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
148 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
149 /// assert_eq!(iter.next().transpose()?, Some((68, 121)));
150 /// assert_eq!(iter.next().transpose()?, Some((68, 122)));
151 /// assert_eq!(iter.next().transpose()?, Some((68, 123)));
152 /// assert_eq!(iter.next().transpose()?, None);
153 /// drop(iter);
154 ///
155 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
156 /// assert_eq!(iter.last().transpose()?, Some((68, 123)));
157 ///
158 /// assert!(db.delete_one_duplicate(&mut wtxn, &68, &121)?, "The entry must exist");
159 ///
160 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
161 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
162 /// // No more (68, 121) returned here!
163 /// assert_eq!(iter.next().transpose()?, Some((68, 122)));
164 /// assert_eq!(iter.next().transpose()?, Some((68, 123)));
165 /// assert_eq!(iter.next().transpose()?, None);
166 /// drop(iter);
167 ///
168 /// wtxn.commit()?;
169 /// # Ok(()) }
170 /// ```
171 const DUP_SORT = ffi::MDB_DUPSORT;
172 /// Numeric keys in native byte order: either `u32` or `usize`.
173 /// The keys must all be of the same size.
174 ///
175 /// ```
176 /// # use std::fs;
177 /// # use std::path::Path;
178 /// # use heed::{DatabaseFlags, EnvOpenOptions};
179 /// use heed::types::*;
180 /// use heed::byteorder::BigEndian;
181 ///
182 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
183 /// # let dir = tempfile::tempdir()?;
184 /// # let env = unsafe { EnvOpenOptions::new()
185 /// # .map_size(10 * 1024 * 1024) // 10MB
186 /// # .max_dbs(3000)
187 /// # .open(dir.path())?
188 /// # };
189 /// type BEI32 = I32<BigEndian>;
190 ///
191 /// let mut wtxn = env.write_txn()?;
192 /// let db = env.database_options()
193 /// .types::<BEI32, BEI32>()
194 /// .flags(DatabaseFlags::INTEGER_KEY)
195 /// .name("integer-key")
196 /// .create(&mut wtxn)?;
197 ///
198 /// # db.clear(&mut wtxn)?;
199 /// db.put(&mut wtxn, &68, &120)?;
200 /// db.put(&mut wtxn, &92, &32)?;
201 /// db.put(&mut wtxn, &35, &120)?;
202 /// db.put(&mut wtxn, &0, &120)?;
203 /// db.put(&mut wtxn, &42, &120)?;
204 ///
205 /// let mut iter = db.iter(&wtxn)?;
206 /// assert_eq!(iter.next().transpose()?, Some((0, 120)));
207 /// assert_eq!(iter.next().transpose()?, Some((35, 120)));
208 /// assert_eq!(iter.next().transpose()?, Some((42, 120)));
209 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
210 /// assert_eq!(iter.next().transpose()?, Some((92, 32)));
211 /// assert_eq!(iter.next().transpose()?, None);
212 /// drop(iter);
213 ///
214 /// wtxn.commit()?;
215 /// # Ok(()) }
216 /// ```
217 const INTEGER_KEY = ffi::MDB_INTEGERKEY;
218 /// With [`DatabaseFlags::DUP_SORT`], sorted dup items have fixed size.
219 ///
220 /// ```
221 /// # use std::fs;
222 /// # use std::path::Path;
223 /// # use heed::{DatabaseFlags, EnvOpenOptions};
224 /// use heed::types::*;
225 /// use heed::byteorder::BigEndian;
226 ///
227 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
228 /// # let dir = tempfile::tempdir()?;
229 /// # let env = unsafe { EnvOpenOptions::new()
230 /// # .map_size(10 * 1024 * 1024) // 10MB
231 /// # .max_dbs(3000)
232 /// # .open(dir.path())?
233 /// # };
234 /// type BEI64 = I64<BigEndian>;
235 ///
236 /// let mut wtxn = env.write_txn()?;
237 /// let db = env.database_options()
238 /// .types::<BEI64, BEI64>()
239 /// .flags(DatabaseFlags::DUP_SORT | DatabaseFlags::DUP_FIXED)
240 /// .name("dup-sort-fixed")
241 /// .create(&mut wtxn)?;
242 ///
243 /// # db.clear(&mut wtxn)?;
244 /// db.put(&mut wtxn, &68, &120)?;
245 /// db.put(&mut wtxn, &68, &121)?;
246 /// db.put(&mut wtxn, &68, &122)?;
247 /// db.put(&mut wtxn, &68, &123)?;
248 /// db.put(&mut wtxn, &92, &32)?;
249 /// db.put(&mut wtxn, &35, &120)?;
250 /// db.put(&mut wtxn, &0, &120)?;
251 /// db.put(&mut wtxn, &42, &120)?;
252 ///
253 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
254 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
255 /// assert_eq!(iter.next().transpose()?, Some((68, 121)));
256 /// assert_eq!(iter.next().transpose()?, Some((68, 122)));
257 /// assert_eq!(iter.next().transpose()?, Some((68, 123)));
258 /// assert_eq!(iter.next().transpose()?, None);
259 /// drop(iter);
260 ///
261 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
262 /// assert_eq!(iter.last().transpose()?, Some((68, 123)));
263 ///
264 /// assert!(db.delete_one_duplicate(&mut wtxn, &68, &121)?, "The entry must exist");
265 ///
266 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
267 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
268 /// // No more (68, 121) returned here!
269 /// assert_eq!(iter.next().transpose()?, Some((68, 122)));
270 /// assert_eq!(iter.next().transpose()?, Some((68, 123)));
271 /// assert_eq!(iter.next().transpose()?, None);
272 /// drop(iter);
273 ///
274 /// wtxn.commit()?;
275 /// # Ok(()) }
276 /// ```
277 const DUP_FIXED = ffi::MDB_DUPFIXED;
278 /// With [`DatabaseKey::DUP_SORT`], dups are [`DatabaseKey::INTEGER_KEY`]-style integers.
279 ///
280 /// ```
281 /// # use std::fs;
282 /// # use std::path::Path;
283 /// # use heed::{DatabaseFlags, EnvOpenOptions};
284 /// use heed::types::*;
285 /// use heed::byteorder::BigEndian;
286 ///
287 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
288 /// # let dir = tempfile::tempdir()?;
289 /// # let env = unsafe { EnvOpenOptions::new()
290 /// # .map_size(10 * 1024 * 1024) // 10MB
291 /// # .max_dbs(3000)
292 /// # .open(dir.path())?
293 /// # };
294 /// type BEI32 = I32<BigEndian>;
295 ///
296 /// let mut wtxn = env.write_txn()?;
297 /// let db = env.database_options()
298 /// .types::<BEI32, BEI32>()
299 /// .flags(DatabaseFlags::DUP_SORT | DatabaseFlags::INTEGER_DUP)
300 /// .name("dup-sort-integer-dup")
301 /// .create(&mut wtxn)?;
302 ///
303 /// # db.clear(&mut wtxn)?;
304 /// db.put(&mut wtxn, &68, &120)?;
305 /// db.put(&mut wtxn, &68, &121)?;
306 /// db.put(&mut wtxn, &68, &122)?;
307 /// db.put(&mut wtxn, &68, &123)?;
308 /// db.put(&mut wtxn, &92, &32)?;
309 /// db.put(&mut wtxn, &35, &120)?;
310 /// db.put(&mut wtxn, &0, &120)?;
311 /// db.put(&mut wtxn, &42, &120)?;
312 ///
313 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
314 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
315 /// assert_eq!(iter.next().transpose()?, Some((68, 121)));
316 /// assert_eq!(iter.next().transpose()?, Some((68, 122)));
317 /// assert_eq!(iter.next().transpose()?, Some((68, 123)));
318 /// assert_eq!(iter.next().transpose()?, None);
319 /// drop(iter);
320 ///
321 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
322 /// assert_eq!(iter.last().transpose()?, Some((68, 123)));
323 ///
324 /// assert!(db.delete_one_duplicate(&mut wtxn, &68, &121)?, "The entry must exist");
325 ///
326 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
327 /// assert_eq!(iter.next().transpose()?, Some((68, 120)));
328 /// // No more (68, 121) returned here!
329 /// assert_eq!(iter.next().transpose()?, Some((68, 122)));
330 /// assert_eq!(iter.next().transpose()?, Some((68, 123)));
331 /// assert_eq!(iter.next().transpose()?, None);
332 /// drop(iter);
333 ///
334 /// wtxn.commit()?;
335 /// # Ok(()) }
336 /// ```
337 const INTEGER_DUP = ffi::MDB_INTEGERDUP;
338 /// With [`DatabaseKey::DUP_SORT`], use reverse string dups.
339 ///
340 /// ```
341 /// # use std::fs;
342 /// # use std::path::Path;
343 /// # use heed::{DatabaseFlags, EnvOpenOptions};
344 /// use heed::types::*;
345 /// use heed::byteorder::BigEndian;
346 ///
347 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
348 /// # let dir = tempfile::tempdir()?;
349 /// # let env = unsafe { EnvOpenOptions::new()
350 /// # .map_size(10 * 1024 * 1024) // 10MB
351 /// # .max_dbs(3000)
352 /// # .open(dir.path())?
353 /// # };
354 /// type BEI64 = I64<BigEndian>;
355 ///
356 /// let mut wtxn = env.write_txn()?;
357 /// let db = env.database_options()
358 /// .types::<BEI64, Str>()
359 /// .flags(DatabaseFlags::DUP_SORT | DatabaseFlags::REVERSE_DUP)
360 /// .name("dup-sort")
361 /// .create(&mut wtxn)?;
362 ///
363 /// # db.clear(&mut wtxn)?;
364 /// db.put(&mut wtxn, &68, &"bonjour")?;
365 /// db.put(&mut wtxn, &68, &"holla")?;
366 /// db.put(&mut wtxn, &68, &"hello")?;
367 /// db.put(&mut wtxn, &92, &"hallo")?;
368 ///
369 /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists");
370 /// assert_eq!(iter.next().transpose()?, Some((68, "holla")));
371 /// assert_eq!(iter.next().transpose()?, Some((68, "hello")));
372 /// assert_eq!(iter.next().transpose()?, Some((68, "bonjour")));
373 /// assert_eq!(iter.next().transpose()?, None);
374 /// drop(iter);
375 ///
376 /// wtxn.commit()?;
377 /// # Ok(()) }
378 /// ```
379 const REVERSE_DUP = ffi::MDB_REVERSEDUP;
380 }
381}
382
383bitflags! {
384 /// LMDB put flags (see <http://www.lmdb.tech/doc/group__mdb.html#ga4fa8573d9236d54687c61827ebf8cac0>
385 /// or <http://www.lmdb.tech/doc/group__mdb.html#ga1f83ccb40011837ff37cc32be01ad91e> for more details).
386 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
387 #[repr(transparent)]
388 pub struct PutFlags: u32 {
389 /// Enter the new key/data pair only if it does not already appear in the database.
390 ///
391 /// This flag may only be specified if the database was opened with MDB_DUPSORT.
392 /// The function will return MDB_KEYEXIST if the key/data pair already appears in the database.
393 const NO_DUP_DATA = ffi::MDB_NODUPDATA;
394 /// Enter the new key/data pair only if the key does not already appear in the database.
395 ///
396 /// The function will return MDB_KEYEXIST if the key already appears in the database,
397 /// even if the database supports duplicates (MDB_DUPSORT).
398 /// The data parameter will be set to point to the existing item.
399 const NO_OVERWRITE = ffi::MDB_NOOVERWRITE;
400 /// Append the given key/data pair to the end of the database.
401 ///
402 /// This option allows fast bulk loading when keys are already known to be in the correct order.
403 /// Loading unsorted keys with this flag will cause a MDB_KEYEXIST error.
404 const APPEND = ffi::MDB_APPEND;
405 /// Append the given key/data pair to the end of the database but for sorted dup data.
406 ///
407 /// This option allows fast bulk loading when keys and dup data are already known to be in the correct order.
408 /// Loading unsorted key/values with this flag will cause a MDB_KEYEXIST error.
409 const APPEND_DUP = ffi::MDB_APPENDDUP;
410 }
411}