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}