heed/iterator/
mod.rs

1mod iter;
2mod prefix;
3mod range;
4
5pub use self::iter::{RoIter, RoRevIter, RwIter, RwRevIter};
6pub use self::prefix::{RoPrefix, RoRevPrefix, RwPrefix, RwRevPrefix};
7pub use self::range::{RoRange, RoRevRange, RwRange, RwRevRange};
8
9#[cfg(test)]
10mod tests {
11    use std::ops;
12
13    #[test]
14    fn prefix_iter_last_with_byte_255() {
15        use crate::types::*;
16        use crate::EnvOpenOptions;
17
18        let dir = tempfile::tempdir().unwrap();
19        let env = unsafe {
20            EnvOpenOptions::new()
21                .map_size(10 * 1024 * 1024) // 10MB
22                .max_dbs(3000)
23                .open(dir.path())
24                .unwrap()
25        };
26
27        let mut wtxn = env.write_txn().unwrap();
28        let db = env.create_database::<Bytes, Str>(&mut wtxn, None).unwrap();
29        wtxn.commit().unwrap();
30
31        // Create an ordered list of keys...
32        let mut wtxn = env.write_txn().unwrap();
33        db.put(&mut wtxn, &[0, 0, 0, 254, 119, 111, 114, 108, 100], "world").unwrap();
34        db.put(&mut wtxn, &[0, 0, 0, 255, 104, 101, 108, 108, 111], "hello").unwrap();
35        db.put(&mut wtxn, &[0, 0, 0, 255, 119, 111, 114, 108, 100], "world").unwrap();
36        db.put(&mut wtxn, &[0, 0, 1, 0, 119, 111, 114, 108, 100], "world").unwrap();
37
38        db.put(&mut wtxn, &[255, 255, 0, 254, 119, 111, 114, 108, 100], "world").unwrap();
39        db.put(&mut wtxn, &[255, 255, 0, 255, 104, 101, 108, 108, 111], "hello").unwrap();
40        db.put(&mut wtxn, &[255, 255, 0, 255, 119, 111, 114, 108, 100], "world").unwrap();
41        db.put(&mut wtxn, &[255, 255, 1, 0, 119, 111, 114, 108, 100], "world").unwrap();
42
43        // Lets check that we properly get the last entry.
44        let iter = db.prefix_iter(&wtxn, &[0, 0, 0, 255]).unwrap();
45        assert_eq!(
46            iter.last().transpose().unwrap(),
47            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], "world"))
48        );
49
50        // Lets check that we can prefix_iter on that sequence with the key "255".
51        let mut iter = db.prefix_iter(&wtxn, &[0, 0, 0, 255]).unwrap();
52        assert_eq!(
53            iter.next().transpose().unwrap(),
54            Some((&[0u8, 0, 0, 255, 104, 101, 108, 108, 111][..], "hello"))
55        );
56        assert_eq!(
57            iter.next().transpose().unwrap(),
58            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], "world"))
59        );
60        assert_eq!(iter.next().transpose().unwrap(), None);
61        drop(iter);
62
63        // Lets check that we properly get the last entry.
64        let iter = db.prefix_iter(&wtxn, &[255]).unwrap();
65        assert_eq!(
66            iter.last().transpose().unwrap(),
67            Some((&[255, 255, 1, 0, 119, 111, 114, 108, 100][..], "world"))
68        );
69
70        // Lets check that we can prefix_iter on that sequence with the key "255".
71        let mut iter = db.prefix_iter(&wtxn, &[255]).unwrap();
72        assert_eq!(
73            iter.next().transpose().unwrap(),
74            Some((&[255, 255, 0, 254, 119, 111, 114, 108, 100][..], "world"))
75        );
76        assert_eq!(
77            iter.next().transpose().unwrap(),
78            Some((&[255, 255, 0, 255, 104, 101, 108, 108, 111][..], "hello"))
79        );
80        assert_eq!(
81            iter.next().transpose().unwrap(),
82            Some((&[255, 255, 0, 255, 119, 111, 114, 108, 100][..], "world"))
83        );
84        assert_eq!(
85            iter.next().transpose().unwrap(),
86            Some((&[255, 255, 1, 0, 119, 111, 114, 108, 100][..], "world"))
87        );
88        assert_eq!(iter.next().transpose().unwrap(), None);
89        drop(iter);
90
91        wtxn.abort();
92    }
93
94    #[test]
95    fn iter_last() {
96        use crate::byteorder::BigEndian;
97        use crate::types::*;
98        use crate::EnvOpenOptions;
99
100        let dir = tempfile::tempdir().unwrap();
101        let env = unsafe {
102            EnvOpenOptions::new()
103                .map_size(10 * 1024 * 1024) // 10MB
104                .max_dbs(3000)
105                .open(dir.path())
106                .unwrap()
107        };
108
109        let mut wtxn = env.write_txn().unwrap();
110        let db = env.create_database::<BEI32, Unit>(&mut wtxn, None).unwrap();
111        wtxn.commit().unwrap();
112
113        type BEI32 = I32<BigEndian>;
114
115        // Create an ordered list of keys...
116        let mut wtxn = env.write_txn().unwrap();
117        db.put(&mut wtxn, &1, &()).unwrap();
118        db.put(&mut wtxn, &2, &()).unwrap();
119        db.put(&mut wtxn, &3, &()).unwrap();
120        db.put(&mut wtxn, &4, &()).unwrap();
121
122        // Lets check that we properly get the last entry.
123        let iter = db.iter(&wtxn).unwrap();
124        assert_eq!(iter.last().transpose().unwrap(), Some((4, ())));
125
126        let mut iter = db.iter(&wtxn).unwrap();
127        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
128        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
129        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
130        assert_eq!(iter.last().transpose().unwrap(), Some((4, ())));
131
132        let mut iter = db.iter(&wtxn).unwrap();
133        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
134        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
135        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
136        assert_eq!(iter.next().transpose().unwrap(), Some((4, ())));
137        assert_eq!(iter.last().transpose().unwrap(), None);
138
139        let mut iter = db.iter(&wtxn).unwrap();
140        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
141        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
142        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
143        assert_eq!(iter.next().transpose().unwrap(), Some((4, ())));
144        assert_eq!(iter.next().transpose().unwrap(), None);
145        assert_eq!(iter.last().transpose().unwrap(), None);
146
147        wtxn.abort();
148
149        // Create an ordered list of keys...
150        let mut wtxn = env.write_txn().unwrap();
151        db.put(&mut wtxn, &1, &()).unwrap();
152
153        // Lets check that we properly get the last entry.
154        let iter = db.iter(&wtxn).unwrap();
155        assert_eq!(iter.last().transpose().unwrap(), Some((1, ())));
156
157        let mut iter = db.iter(&wtxn).unwrap();
158        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
159        assert_eq!(iter.last().transpose().unwrap(), None);
160
161        wtxn.abort();
162    }
163
164    #[test]
165    fn range_iter_last() {
166        use crate::byteorder::BigEndian;
167        use crate::types::*;
168        use crate::EnvOpenOptions;
169
170        let dir = tempfile::tempdir().unwrap();
171        let env = unsafe {
172            EnvOpenOptions::new()
173                .map_size(10 * 1024 * 1024) // 10MB
174                .max_dbs(3000)
175                .open(dir.path())
176                .unwrap()
177        };
178
179        let mut wtxn = env.write_txn().unwrap();
180        let db = env.create_database::<BEI32, Unit>(&mut wtxn, None).unwrap();
181        wtxn.commit().unwrap();
182
183        type BEI32 = I32<BigEndian>;
184
185        // Create an ordered list of keys...
186        let mut wtxn = env.write_txn().unwrap();
187        db.put(&mut wtxn, &1, &()).unwrap();
188        db.put(&mut wtxn, &2, &()).unwrap();
189        db.put(&mut wtxn, &3, &()).unwrap();
190        db.put(&mut wtxn, &4, &()).unwrap();
191
192        // Lets check that we properly get the last entry.
193        let iter = db.range(&wtxn, &(..)).unwrap();
194        assert_eq!(iter.last().transpose().unwrap(), Some((4, ())));
195
196        let mut iter = db.range(&wtxn, &(..)).unwrap();
197        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
198        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
199        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
200        assert_eq!(iter.last().transpose().unwrap(), Some((4, ())));
201
202        let mut iter = db.range(&wtxn, &(..)).unwrap();
203        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
204        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
205        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
206        assert_eq!(iter.next().transpose().unwrap(), Some((4, ())));
207        assert_eq!(iter.last().transpose().unwrap(), None);
208
209        let mut iter = db.range(&wtxn, &(..)).unwrap();
210        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
211        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
212        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
213        assert_eq!(iter.next().transpose().unwrap(), Some((4, ())));
214        assert_eq!(iter.next().transpose().unwrap(), None);
215        assert_eq!(iter.last().transpose().unwrap(), None);
216
217        let range = 2..=4;
218        let mut iter = db.range(&wtxn, &range).unwrap();
219        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
220        assert_eq!(iter.last().transpose().unwrap(), Some((4, ())));
221
222        let range = 2..4;
223        let mut iter = db.range(&wtxn, &range).unwrap();
224        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
225        assert_eq!(iter.last().transpose().unwrap(), Some((3, ())));
226
227        let range = 2..4;
228        let mut iter = db.range(&wtxn, &range).unwrap();
229        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
230        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
231        assert_eq!(iter.last().transpose().unwrap(), None);
232
233        let range = 2..2;
234        let iter = db.range(&wtxn, &range).unwrap();
235        assert_eq!(iter.last().transpose().unwrap(), None);
236
237        #[allow(clippy::reversed_empty_ranges)]
238        let range = 2..=1;
239        let iter = db.range(&wtxn, &range).unwrap();
240        assert_eq!(iter.last().transpose().unwrap(), None);
241
242        wtxn.abort();
243
244        // Create an ordered list of keys...
245        let mut wtxn = env.write_txn().unwrap();
246        db.put(&mut wtxn, &1, &()).unwrap();
247
248        // Lets check that we properly get the last entry.
249        let iter = db.range(&wtxn, &(..)).unwrap();
250        assert_eq!(iter.last().transpose().unwrap(), Some((1, ())));
251
252        let mut iter = db.range(&wtxn, &(..)).unwrap();
253        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
254        assert_eq!(iter.last().transpose().unwrap(), None);
255
256        wtxn.abort();
257    }
258
259    #[test]
260    fn range_iter_last_with_byte_255() {
261        use crate::types::*;
262        use crate::EnvOpenOptions;
263
264        let dir = tempfile::tempdir().unwrap();
265        let env = unsafe {
266            EnvOpenOptions::new()
267                .map_size(10 * 1024 * 1024) // 10MB
268                .max_dbs(3000)
269                .open(dir.path())
270                .unwrap()
271        };
272
273        let mut wtxn = env.write_txn().unwrap();
274        let db = env.create_database::<Bytes, Unit>(&mut wtxn, None).unwrap();
275        wtxn.commit().unwrap();
276
277        // Create an ordered list of keys...
278        let mut wtxn = env.write_txn().unwrap();
279        db.put(&mut wtxn, &[0, 0, 0], &()).unwrap();
280        db.put(&mut wtxn, &[0, 0, 0, 1], &()).unwrap();
281        db.put(&mut wtxn, &[0, 0, 0, 2], &()).unwrap();
282        db.put(&mut wtxn, &[0, 0, 1, 0], &()).unwrap();
283
284        // Lets check that we properly get the last entry.
285        let iter = db
286            .range(
287                &wtxn,
288                &(ops::Bound::Excluded(&[0, 0, 0][..]), ops::Bound::Included(&[0, 0, 1, 0][..])),
289            )
290            .unwrap();
291        assert_eq!(iter.last().transpose().unwrap(), Some((&[0, 0, 1, 0][..], ())));
292
293        // Lets check that we can range_iter on that sequence with the key "255".
294        let mut iter = db
295            .range(
296                &wtxn,
297                &(ops::Bound::Excluded(&[0, 0, 0][..]), ops::Bound::Included(&[0, 0, 1, 0][..])),
298            )
299            .unwrap();
300        assert_eq!(iter.next().transpose().unwrap(), Some((&[0, 0, 0, 1][..], ())));
301        assert_eq!(iter.next().transpose().unwrap(), Some((&[0, 0, 0, 2][..], ())));
302        assert_eq!(iter.next().transpose().unwrap(), Some((&[0, 0, 1, 0][..], ())));
303        assert_eq!(iter.next().transpose().unwrap(), None);
304        drop(iter);
305
306        wtxn.abort();
307    }
308
309    #[test]
310    fn prefix_iter_last() {
311        use crate::types::*;
312        use crate::EnvOpenOptions;
313
314        let dir = tempfile::tempdir().unwrap();
315        let env = unsafe {
316            EnvOpenOptions::new()
317                .map_size(10 * 1024 * 1024) // 10MB
318                .max_dbs(3000)
319                .open(dir.path())
320                .unwrap()
321        };
322
323        let mut wtxn = env.write_txn().unwrap();
324        let db = env.create_database::<Bytes, Unit>(&mut wtxn, None).unwrap();
325        wtxn.commit().unwrap();
326
327        // Create an ordered list of keys...
328        let mut wtxn = env.write_txn().unwrap();
329        db.put(&mut wtxn, &[0, 0, 0, 254, 119, 111, 114, 108, 100], &()).unwrap();
330        db.put(&mut wtxn, &[0, 0, 0, 255, 104, 101, 108, 108, 111], &()).unwrap();
331        db.put(&mut wtxn, &[0, 0, 0, 255, 119, 111, 114, 108, 100], &()).unwrap();
332        db.put(&mut wtxn, &[0, 0, 1, 0, 119, 111, 114, 108, 100], &()).unwrap();
333
334        // Lets check that we properly get the last entry.
335        let iter = db.prefix_iter(&wtxn, &[0, 0, 0]).unwrap();
336        assert_eq!(
337            iter.last().transpose().unwrap(),
338            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], ()))
339        );
340
341        let mut iter = db.prefix_iter(&wtxn, &[0, 0, 0]).unwrap();
342        assert_eq!(
343            iter.next().transpose().unwrap(),
344            Some((&[0, 0, 0, 254, 119, 111, 114, 108, 100][..], ()))
345        );
346        assert_eq!(
347            iter.next().transpose().unwrap(),
348            Some((&[0, 0, 0, 255, 104, 101, 108, 108, 111][..], ()))
349        );
350        assert_eq!(
351            iter.last().transpose().unwrap(),
352            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], ()))
353        );
354
355        let mut iter = db.prefix_iter(&wtxn, &[0, 0, 0]).unwrap();
356        assert_eq!(
357            iter.next().transpose().unwrap(),
358            Some((&[0, 0, 0, 254, 119, 111, 114, 108, 100][..], ()))
359        );
360        assert_eq!(
361            iter.next().transpose().unwrap(),
362            Some((&[0, 0, 0, 255, 104, 101, 108, 108, 111][..], ()))
363        );
364        assert_eq!(
365            iter.next().transpose().unwrap(),
366            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], ()))
367        );
368        assert_eq!(iter.last().transpose().unwrap(), None);
369
370        let iter = db.prefix_iter(&wtxn, &[0, 0, 1]).unwrap();
371        assert_eq!(
372            iter.last().transpose().unwrap(),
373            Some((&[0, 0, 1, 0, 119, 111, 114, 108, 100][..], ()))
374        );
375
376        let mut iter = db.prefix_iter(&wtxn, &[0, 0, 1]).unwrap();
377        assert_eq!(
378            iter.next().transpose().unwrap(),
379            Some((&[0, 0, 1, 0, 119, 111, 114, 108, 100][..], ()))
380        );
381        assert_eq!(iter.last().transpose().unwrap(), None);
382
383        wtxn.abort();
384    }
385
386    #[test]
387    fn rev_prefix_iter_last() {
388        use crate::types::*;
389        use crate::EnvOpenOptions;
390
391        let dir = tempfile::tempdir().unwrap();
392        let env = unsafe {
393            EnvOpenOptions::new()
394                .map_size(10 * 1024 * 1024) // 10MB
395                .max_dbs(3000)
396                .open(dir.path())
397                .unwrap()
398        };
399
400        let mut wtxn = env.write_txn().unwrap();
401        let db = env.create_database::<Bytes, Unit>(&mut wtxn, None).unwrap();
402        wtxn.commit().unwrap();
403
404        // Create an ordered list of keys...
405        let mut wtxn = env.write_txn().unwrap();
406        db.put(&mut wtxn, &[0, 0, 0, 254, 119, 111, 114, 108, 100], &()).unwrap();
407        db.put(&mut wtxn, &[0, 0, 0, 255, 104, 101, 108, 108, 111], &()).unwrap();
408        db.put(&mut wtxn, &[0, 0, 0, 255, 119, 111, 114, 108, 100], &()).unwrap();
409        db.put(&mut wtxn, &[0, 0, 1, 0, 119, 111, 114, 108, 100], &()).unwrap();
410
411        // Lets check that we properly get the last entry.
412        let iter = db.rev_prefix_iter(&wtxn, &[0, 0, 0]).unwrap();
413        assert_eq!(
414            iter.last().transpose().unwrap(),
415            Some((&[0, 0, 0, 254, 119, 111, 114, 108, 100][..], ()))
416        );
417
418        let mut iter = db.rev_prefix_iter(&wtxn, &[0, 0, 0]).unwrap();
419        assert_eq!(
420            iter.next().transpose().unwrap(),
421            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], ()))
422        );
423        assert_eq!(
424            iter.next().transpose().unwrap(),
425            Some((&[0, 0, 0, 255, 104, 101, 108, 108, 111][..], ()))
426        );
427        assert_eq!(
428            iter.last().transpose().unwrap(),
429            Some((&[0, 0, 0, 254, 119, 111, 114, 108, 100][..], ()))
430        );
431
432        let mut iter = db.rev_prefix_iter(&wtxn, &[0, 0, 0]).unwrap();
433        assert_eq!(
434            iter.next().transpose().unwrap(),
435            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], ()))
436        );
437        assert_eq!(
438            iter.next().transpose().unwrap(),
439            Some((&[0, 0, 0, 255, 104, 101, 108, 108, 111][..], ()))
440        );
441        assert_eq!(
442            iter.next().transpose().unwrap(),
443            Some((&[0, 0, 0, 254, 119, 111, 114, 108, 100][..], ()))
444        );
445        assert_eq!(iter.last().transpose().unwrap(), None);
446
447        let iter = db.rev_prefix_iter(&wtxn, &[0, 0, 1]).unwrap();
448        assert_eq!(
449            iter.last().transpose().unwrap(),
450            Some((&[0, 0, 1, 0, 119, 111, 114, 108, 100][..], ()))
451        );
452
453        let mut iter = db.rev_prefix_iter(&wtxn, &[0, 0, 1]).unwrap();
454        assert_eq!(
455            iter.next().transpose().unwrap(),
456            Some((&[0, 0, 1, 0, 119, 111, 114, 108, 100][..], ()))
457        );
458        assert_eq!(iter.last().transpose().unwrap(), None);
459
460        wtxn.abort();
461    }
462
463    #[test]
464    fn rev_prefix_iter_last_with_byte_255() {
465        use crate::types::*;
466        use crate::EnvOpenOptions;
467
468        let dir = tempfile::tempdir().unwrap();
469        let env = unsafe {
470            EnvOpenOptions::new()
471                .map_size(10 * 1024 * 1024) // 10MB
472                .max_dbs(3000)
473                .open(dir.path())
474                .unwrap()
475        };
476
477        let mut wtxn = env.write_txn().unwrap();
478        let db = env.create_database::<Bytes, Unit>(&mut wtxn, None).unwrap();
479        wtxn.commit().unwrap();
480
481        // Create an ordered list of keys...
482        let mut wtxn = env.write_txn().unwrap();
483        db.put(&mut wtxn, &[0, 0, 0, 254, 119, 111, 114, 108, 100], &()).unwrap();
484        db.put(&mut wtxn, &[0, 0, 0, 255, 104, 101, 108, 108, 111], &()).unwrap();
485        db.put(&mut wtxn, &[0, 0, 0, 255, 119, 111, 114, 108, 100], &()).unwrap();
486        db.put(&mut wtxn, &[0, 0, 1, 0, 119, 111, 114, 108, 100], &()).unwrap();
487
488        db.put(&mut wtxn, &[255, 255, 0, 254, 119, 111, 114, 108, 100], &()).unwrap();
489        db.put(&mut wtxn, &[255, 255, 0, 255, 104, 101, 108, 108, 111], &()).unwrap();
490        db.put(&mut wtxn, &[255, 255, 0, 255, 119, 111, 114, 108, 100], &()).unwrap();
491        db.put(&mut wtxn, &[255, 255, 1, 0, 119, 111, 114, 108, 100], &()).unwrap();
492
493        // Lets check that we can get last entry on that sequence ending with the key "255".
494        let iter = db.rev_prefix_iter(&wtxn, &[0, 0, 0, 255]).unwrap();
495        assert_eq!(
496            iter.last().transpose().unwrap(),
497            Some((&[0, 0, 0, 255, 104, 101, 108, 108, 111][..], ()))
498        );
499
500        // Lets check that we can prefix_iter on that sequence ending with the key "255".
501        let mut iter = db.rev_prefix_iter(&wtxn, &[0, 0, 0, 255]).unwrap();
502        assert_eq!(
503            iter.next().transpose().unwrap(),
504            Some((&[0, 0, 0, 255, 119, 111, 114, 108, 100][..], ()))
505        );
506        assert_eq!(
507            iter.next().transpose().unwrap(),
508            Some((&[0, 0, 0, 255, 104, 101, 108, 108, 111][..], ()))
509        );
510        assert_eq!(iter.last().transpose().unwrap(), None);
511
512        let mut iter = db.rev_prefix_iter(&wtxn, &[255, 255]).unwrap();
513        assert_eq!(
514            iter.next().transpose().unwrap(),
515            Some((&[255, 255, 1, 0, 119, 111, 114, 108, 100][..], ()))
516        );
517        assert_eq!(
518            iter.next().transpose().unwrap(),
519            Some((&[255, 255, 0, 255, 119, 111, 114, 108, 100][..], ()))
520        );
521        assert_eq!(
522            iter.next().transpose().unwrap(),
523            Some((&[255, 255, 0, 255, 104, 101, 108, 108, 111][..], ()))
524        );
525        assert_eq!(
526            iter.next().transpose().unwrap(),
527            Some((&[255, 255, 0, 254, 119, 111, 114, 108, 100][..], ()))
528        );
529        assert_eq!(iter.last().transpose().unwrap(), None);
530
531        wtxn.abort();
532    }
533
534    #[test]
535    fn rev_range_iter_last() {
536        use crate::byteorder::BigEndian;
537        use crate::types::*;
538        use crate::EnvOpenOptions;
539
540        let dir = tempfile::tempdir().unwrap();
541        let env = unsafe {
542            EnvOpenOptions::new()
543                .map_size(10 * 1024 * 1024) // 10MB
544                .max_dbs(3000)
545                .open(dir.path())
546                .unwrap()
547        };
548
549        let mut wtxn = env.write_txn().unwrap();
550        let db = env.create_database::<BEI32, Unit>(&mut wtxn, None).unwrap();
551        wtxn.commit().unwrap();
552
553        type BEI32 = I32<BigEndian>;
554
555        // Create an ordered list of keys...
556        let mut wtxn = env.write_txn().unwrap();
557        db.put(&mut wtxn, &1, &()).unwrap();
558        db.put(&mut wtxn, &2, &()).unwrap();
559        db.put(&mut wtxn, &3, &()).unwrap();
560        db.put(&mut wtxn, &4, &()).unwrap();
561
562        // Lets check that we properly get the last entry.
563        let iter = db.rev_range(&wtxn, &(1..=3)).unwrap();
564        assert_eq!(iter.last().transpose().unwrap(), Some((1, ())));
565
566        let mut iter = db.rev_range(&wtxn, &(0..4)).unwrap();
567        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
568        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
569        assert_eq!(iter.last().transpose().unwrap(), Some((1, ())));
570
571        let mut iter = db.rev_range(&wtxn, &(0..=5)).unwrap();
572        assert_eq!(iter.next().transpose().unwrap(), Some((4, ())));
573        assert_eq!(iter.next().transpose().unwrap(), Some((3, ())));
574        assert_eq!(iter.next().transpose().unwrap(), Some((2, ())));
575        assert_eq!(iter.next().transpose().unwrap(), Some((1, ())));
576        assert_eq!(iter.last().transpose().unwrap(), None);
577
578        let iter = db.rev_range(&wtxn, &(0..=5)).unwrap();
579        assert_eq!(iter.last().transpose().unwrap(), Some((1, ())));
580
581        let mut iter = db.rev_range(&wtxn, &(4..=4)).unwrap();
582        assert_eq!(iter.next().transpose().unwrap(), Some((4, ())));
583        assert_eq!(iter.last().transpose().unwrap(), None);
584
585        wtxn.abort();
586    }
587
588    #[test]
589    fn rev_range_iter_last_with_byte_255() {
590        use crate::types::*;
591        use crate::EnvOpenOptions;
592
593        let dir = tempfile::tempdir().unwrap();
594        let env = unsafe {
595            EnvOpenOptions::new()
596                .map_size(10 * 1024 * 1024) // 10MB
597                .max_dbs(3000)
598                .open(dir.path())
599                .unwrap()
600        };
601
602        let mut wtxn = env.write_txn().unwrap();
603        let db = env.create_database::<Bytes, Unit>(&mut wtxn, None).unwrap();
604        wtxn.commit().unwrap();
605
606        // Create an ordered list of keys...
607        let mut wtxn = env.write_txn().unwrap();
608        db.put(&mut wtxn, &[0, 0, 0], &()).unwrap();
609        db.put(&mut wtxn, &[0, 0, 0, 1], &()).unwrap();
610        db.put(&mut wtxn, &[0, 0, 0, 2], &()).unwrap();
611        db.put(&mut wtxn, &[0, 0, 1, 0], &()).unwrap();
612
613        // Lets check that we properly get the last entry.
614        let iter = db
615            .rev_range(
616                &wtxn,
617                &(ops::Bound::Excluded(&[0, 0, 0][..]), ops::Bound::Included(&[0, 0, 1, 0][..])),
618            )
619            .unwrap();
620        assert_eq!(iter.last().transpose().unwrap(), Some((&[0, 0, 0, 1][..], ())));
621
622        // Lets check that we can range_iter on that sequence with the key "255".
623        let mut iter = db
624            .rev_range(
625                &wtxn,
626                &(ops::Bound::Excluded(&[0, 0, 0][..]), ops::Bound::Included(&[0, 0, 1, 0][..])),
627            )
628            .unwrap();
629        assert_eq!(iter.next().transpose().unwrap(), Some((&[0, 0, 1, 0][..], ())));
630        assert_eq!(iter.next().transpose().unwrap(), Some((&[0, 0, 0, 2][..], ())));
631        assert_eq!(iter.next().transpose().unwrap(), Some((&[0, 0, 0, 1][..], ())));
632        assert_eq!(iter.next().transpose().unwrap(), None);
633        drop(iter);
634
635        wtxn.abort();
636    }
637}