typed_store/
test_db.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5#![allow(clippy::await_holding_lock)]
6
7use std::{
8    borrow::Borrow,
9    collections::{BTreeMap, HashMap, VecDeque, btree_map::Iter},
10    marker::PhantomData,
11    ops::RangeBounds,
12    sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
13};
14
15use bincode::Options;
16use collectable::TryExtend;
17use ouroboros::self_referencing;
18use rand::distributions::{Alphanumeric, DistString};
19use rocksdb::Direction;
20use serde::{Serialize, de::DeserializeOwned};
21
22use crate::{
23    Map, TypedStoreError,
24    rocks::{be_fix_int_ser, errors::typed_store_err_from_bcs_err},
25};
26
27/// An interface to a btree map backed sally database. This is mainly intended
28/// for tests and performing benchmark comparisons
29#[derive(Clone, Debug)]
30pub struct TestDB<K, V> {
31    pub rows: Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>,
32    pub name: String,
33    _phantom: PhantomData<fn(K) -> V>,
34}
35
36impl<K, V> TestDB<K, V> {
37    pub fn open() -> Self {
38        TestDB {
39            rows: Arc::new(RwLock::new(BTreeMap::new())),
40            name: Alphanumeric.sample_string(&mut rand::thread_rng(), 16),
41            _phantom: PhantomData,
42        }
43    }
44    pub fn batch(&self) -> TestDBWriteBatch {
45        TestDBWriteBatch::default()
46    }
47}
48
49#[self_referencing(pub_extras)]
50pub struct TestDBIter<'a, K, V> {
51    pub rows: RwLockReadGuard<'a, BTreeMap<Vec<u8>, Vec<u8>>>,
52    #[borrows(mut rows)]
53    #[covariant]
54    pub iter: Iter<'this, Vec<u8>, Vec<u8>>,
55    phantom: PhantomData<(K, V)>,
56    pub direction: Direction,
57}
58
59#[self_referencing(pub_extras)]
60pub struct TestDBKeys<'a, K> {
61    rows: RwLockReadGuard<'a, BTreeMap<Vec<u8>, Vec<u8>>>,
62    #[borrows(mut rows)]
63    #[covariant]
64    pub iter: Iter<'this, Vec<u8>, Vec<u8>>,
65    phantom: PhantomData<K>,
66}
67
68#[self_referencing(pub_extras)]
69pub struct TestDBValues<'a, V> {
70    rows: RwLockReadGuard<'a, BTreeMap<Vec<u8>, Vec<u8>>>,
71    #[borrows(mut rows)]
72    #[covariant]
73    pub iter: Iter<'this, Vec<u8>, Vec<u8>>,
74    phantom: PhantomData<V>,
75}
76
77impl<K: DeserializeOwned, V: DeserializeOwned> Iterator for TestDBIter<'_, K, V> {
78    type Item = Result<(K, V), TypedStoreError>;
79
80    fn next(&mut self) -> Option<Self::Item> {
81        let mut out: Option<Self::Item> = None;
82        let config = bincode::DefaultOptions::new()
83            .with_big_endian()
84            .with_fixint_encoding();
85        self.with_mut(|fields| {
86            let resp = match fields.direction {
87                Direction::Forward => fields.iter.next(),
88                Direction::Reverse => panic!("Reverse iteration not supported in test db"),
89            };
90            if let Some((raw_key, raw_value)) = resp {
91                let key: K = config.deserialize(raw_key).ok().unwrap();
92                let value: V = bcs::from_bytes(raw_value).ok().unwrap();
93                out = Some(Ok((key, value)));
94            }
95        });
96        out
97    }
98}
99
100impl<'a, K: Serialize, V> TestDBIter<'a, K, V> {
101    /// Skips all the elements that are smaller than the given key,
102    /// and either lands on the key or the first one greater than
103    /// the key.
104    pub fn skip_to(mut self, key: &K) -> Result<Self, TypedStoreError> {
105        self.with_mut(|fields| {
106            let serialized_key = be_fix_int_ser(key).expect("serialization failed");
107            let mut peekable = fields.iter.peekable();
108            let mut peeked = peekable.peek();
109            while peeked.is_some() {
110                let serialized = be_fix_int_ser(peeked.unwrap()).expect("serialization failed");
111                if serialized >= serialized_key {
112                    break;
113                } else {
114                    peekable.next();
115                    peeked = peekable.peek();
116                }
117            }
118        });
119        Ok(self)
120    }
121
122    /// Moves the iterator to the element given or
123    /// the one prior to it if it does not exist. If there is
124    /// no element prior to it, it returns an empty iterator.
125    pub fn skip_prior_to(mut self, key: &K) -> Result<Self, TypedStoreError> {
126        self.with_mut(|fields| {
127            let serialized_key = be_fix_int_ser(key).expect("serialization failed");
128            let mut peekable = fields.iter.peekable();
129            let mut peeked = peekable.peek();
130            while peeked.is_some() {
131                let serialized = be_fix_int_ser(peeked.unwrap()).expect("serialization failed");
132                if serialized > serialized_key {
133                    break;
134                } else {
135                    peekable.next();
136                    peeked = peekable.peek();
137                }
138            }
139        });
140        Ok(self)
141    }
142
143    /// Seeks to the last key in the database (at this column family).
144    pub fn skip_to_last(mut self) -> Self {
145        self.with_mut(|fields| {
146            // `last` instead of `next_back` because we actually want to consume `iter`
147            #[expect(clippy::double_ended_iterator_last)]
148            fields.iter.last();
149        });
150        self
151    }
152
153    /// Will make the direction of the iteration reverse and will
154    /// create a new `RevIter` to consume. Every call to `next` method
155    /// will give the next element from the end.
156    pub fn reverse(mut self) -> TestDBRevIter<'a, K, V> {
157        self.with_mut(|fields| {
158            *fields.direction = Direction::Reverse;
159        });
160        TestDBRevIter::new(self)
161    }
162}
163
164/// An iterator with a reverted direction to the original. The `RevIter`
165/// is hosting an iteration which is consuming in the opposing direction.
166/// It's not possible to do further manipulation (ex re-reverse) to the
167/// iterator.
168pub struct TestDBRevIter<'a, K, V> {
169    iter: TestDBIter<'a, K, V>,
170}
171
172impl<'a, K, V> TestDBRevIter<'a, K, V> {
173    fn new(iter: TestDBIter<'a, K, V>) -> Self {
174        Self { iter }
175    }
176}
177
178impl<K: DeserializeOwned, V: DeserializeOwned> Iterator for TestDBRevIter<'_, K, V> {
179    type Item = Result<(K, V), TypedStoreError>;
180
181    /// Will give the next item backwards
182    fn next(&mut self) -> Option<Self::Item> {
183        self.iter.next()
184    }
185}
186
187impl<K: DeserializeOwned> Iterator for TestDBKeys<'_, K> {
188    type Item = Result<K, TypedStoreError>;
189
190    fn next(&mut self) -> Option<Self::Item> {
191        let mut out: Option<Self::Item> = None;
192        self.with_mut(|fields| {
193            let config = bincode::DefaultOptions::new()
194                .with_big_endian()
195                .with_fixint_encoding();
196            if let Some((raw_key, _)) = fields.iter.next() {
197                let key: K = config.deserialize(raw_key).ok().unwrap();
198                out = Some(Ok(key));
199            }
200        });
201        out
202    }
203}
204
205impl<V: DeserializeOwned> Iterator for TestDBValues<'_, V> {
206    type Item = Result<V, TypedStoreError>;
207
208    fn next(&mut self) -> Option<Self::Item> {
209        let mut out: Option<Self::Item> = None;
210        self.with_mut(|fields| {
211            if let Some((_, raw_value)) = fields.iter.next() {
212                let value: V = bcs::from_bytes(raw_value).ok().unwrap();
213                out = Some(Ok(value));
214            }
215        });
216        out
217    }
218}
219
220impl<'a, K, V> Map<'a, K, V> for TestDB<K, V>
221where
222    K: Serialize + DeserializeOwned,
223    V: Serialize + DeserializeOwned,
224{
225    type Error = TypedStoreError;
226    type Iterator = std::iter::Empty<(K, V)>;
227    type SafeIterator = TestDBIter<'a, K, V>;
228    type Keys = TestDBKeys<'a, K>;
229    type Values = TestDBValues<'a, V>;
230
231    fn contains_key(&self, key: &K) -> Result<bool, Self::Error> {
232        let raw_key = be_fix_int_ser(key)?;
233        let locked = self.rows.read().unwrap();
234        Ok(locked.contains_key(&raw_key))
235    }
236
237    fn get(&self, key: &K) -> Result<Option<V>, Self::Error> {
238        let raw_key = be_fix_int_ser(key)?;
239        let locked = self.rows.read().unwrap();
240        let res = locked.get(&raw_key);
241        Ok(res.map(|raw_value| bcs::from_bytes(raw_value).ok().unwrap()))
242    }
243
244    fn get_raw_bytes(&self, key: &K) -> Result<Option<Vec<u8>>, Self::Error> {
245        let raw_key = be_fix_int_ser(key)?;
246        let locked = self.rows.read().unwrap();
247        let res = locked.get(&raw_key);
248        Ok(res.cloned())
249    }
250
251    fn insert(&self, key: &K, value: &V) -> Result<(), Self::Error> {
252        let raw_key = be_fix_int_ser(key)?;
253        let raw_value = bcs::to_bytes(value).map_err(typed_store_err_from_bcs_err)?;
254        let mut locked = self.rows.write().unwrap();
255        locked.insert(raw_key, raw_value);
256        Ok(())
257    }
258
259    fn remove(&self, key: &K) -> Result<(), Self::Error> {
260        let raw_key = be_fix_int_ser(key)?;
261        let mut locked = self.rows.write().unwrap();
262        locked.remove(&raw_key);
263        Ok(())
264    }
265
266    fn unsafe_clear(&self) -> Result<(), Self::Error> {
267        let mut locked = self.rows.write().unwrap();
268        locked.clear();
269        Ok(())
270    }
271
272    fn delete_file_in_range(&self, from: &K, to: &K) -> Result<(), TypedStoreError> {
273        let mut locked = self.rows.write().unwrap();
274        locked
275            .retain(|k, _| k < &be_fix_int_ser(from).unwrap() || k >= &be_fix_int_ser(to).unwrap());
276        Ok(())
277    }
278
279    fn schedule_delete_all(&self) -> Result<(), TypedStoreError> {
280        let mut locked = self.rows.write().unwrap();
281        locked.clear();
282        Ok(())
283    }
284
285    fn is_empty(&self) -> bool {
286        let locked = self.rows.read().unwrap();
287        locked.is_empty()
288    }
289
290    fn unbounded_iter(&'a self) -> Self::Iterator {
291        unimplemented!("unimplemented API");
292    }
293
294    fn iter_with_bounds(
295        &'a self,
296        _lower_bound: Option<K>,
297        _upper_bound: Option<K>,
298    ) -> Self::Iterator {
299        unimplemented!("unimplemented API");
300    }
301
302    fn range_iter(&'a self, _range: impl RangeBounds<K>) -> Self::Iterator {
303        unimplemented!("unimplemented API");
304    }
305
306    fn safe_iter(&'a self) -> Self::SafeIterator {
307        TestDBIterBuilder {
308            rows: self.rows.read().unwrap(),
309            iter_builder: |rows: &mut RwLockReadGuard<'a, BTreeMap<Vec<u8>, Vec<u8>>>| rows.iter(),
310            phantom: PhantomData,
311            direction: Direction::Forward,
312        }
313        .build()
314    }
315
316    fn safe_iter_with_bounds(
317        &'a self,
318        _lower_bound: Option<K>,
319        _upper_bound: Option<K>,
320    ) -> Self::SafeIterator {
321        unimplemented!("unimplemented API");
322    }
323
324    fn safe_range_iter(&'a self, _range: impl RangeBounds<K>) -> Self::SafeIterator {
325        unimplemented!("unimplemented API");
326    }
327
328    fn keys(&'a self) -> Self::Keys {
329        TestDBKeysBuilder {
330            rows: self.rows.read().unwrap(),
331            iter_builder: |rows: &mut RwLockReadGuard<'a, BTreeMap<Vec<u8>, Vec<u8>>>| rows.iter(),
332            phantom: PhantomData,
333        }
334        .build()
335    }
336
337    fn values(&'a self) -> Self::Values {
338        TestDBValuesBuilder {
339            rows: self.rows.read().unwrap(),
340            iter_builder: |rows: &mut RwLockReadGuard<'a, BTreeMap<Vec<u8>, Vec<u8>>>| rows.iter(),
341            phantom: PhantomData,
342        }
343        .build()
344    }
345
346    fn try_catch_up_with_primary(&self) -> Result<(), Self::Error> {
347        Ok(())
348    }
349}
350
351impl<J, K, U, V> TryExtend<(J, U)> for TestDB<K, V>
352where
353    J: Borrow<K>,
354    U: Borrow<V>,
355    K: Serialize,
356    V: Serialize,
357{
358    type Error = TypedStoreError;
359
360    fn try_extend<T>(&mut self, iter: &mut T) -> Result<(), Self::Error>
361    where
362        T: Iterator<Item = (J, U)>,
363    {
364        let mut wb = self.batch();
365        wb.insert_batch(self, iter)?;
366        wb.write()
367    }
368
369    fn try_extend_from_slice(&mut self, slice: &[(J, U)]) -> Result<(), Self::Error> {
370        let slice_of_refs = slice.iter().map(|(k, v)| (k.borrow(), v.borrow()));
371        let mut wb = self.batch();
372        wb.insert_batch(self, slice_of_refs)?;
373        wb.write()
374    }
375}
376
377pub type DeleteBatchPayload = (
378    Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>,
379    String,
380    Vec<Vec<u8>>,
381);
382pub type DeleteRangePayload = (
383    Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>,
384    String,
385    (Vec<u8>, Vec<u8>),
386);
387pub type InsertBatchPayload = (
388    Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>,
389    String,
390    Vec<(Vec<u8>, Vec<u8>)>,
391);
392type DBAndName = (Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>, String);
393
394pub enum WriteBatchOp {
395    DeleteBatch(DeleteBatchPayload),
396    DeleteRange(DeleteRangePayload),
397    InsertBatch(InsertBatchPayload),
398}
399
400#[derive(Default)]
401pub struct TestDBWriteBatch {
402    pub ops: VecDeque<WriteBatchOp>,
403}
404
405#[self_referencing]
406pub struct DBLocked {
407    db: Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>,
408    #[borrows(db)]
409    #[covariant]
410    db_guard: RwLockWriteGuard<'this, BTreeMap<Vec<u8>, Vec<u8>>>,
411}
412
413impl TestDBWriteBatch {
414    pub fn write(self) -> Result<(), TypedStoreError> {
415        let mut dbs: Vec<DBAndName> = self
416            .ops
417            .iter()
418            .map(|op| match op {
419                WriteBatchOp::DeleteBatch((db, name, _)) => (db.clone(), name.clone()),
420                WriteBatchOp::DeleteRange((db, name, _)) => (db.clone(), name.clone()),
421                WriteBatchOp::InsertBatch((db, name, _)) => (db.clone(), name.clone()),
422            })
423            .collect();
424        dbs.sort_by_key(|(_k, v)| v.clone());
425        dbs.dedup_by_key(|(_k, v)| v.clone());
426        // lock all databases
427        let mut db_locks = HashMap::new();
428        dbs.iter().for_each(|(db, name)| {
429            if !db_locks.contains_key(name) {
430                db_locks.insert(
431                    name.clone(),
432                    DBLockedBuilder {
433                        db: db.clone(),
434                        db_guard_builder: |db: &Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>| {
435                            db.write().unwrap()
436                        },
437                    }
438                    .build(),
439                );
440            }
441        });
442        self.ops.iter().for_each(|op| match op {
443            WriteBatchOp::DeleteBatch((_, id, keys)) => {
444                let locked = db_locks.get_mut(id).unwrap();
445                locked.with_db_guard_mut(|db| {
446                    keys.iter().for_each(|key| {
447                        db.remove(key);
448                    });
449                });
450            }
451            WriteBatchOp::DeleteRange((_, id, (from, to))) => {
452                let locked = db_locks.get_mut(id).unwrap();
453                locked.with_db_guard_mut(|db| {
454                    db.retain(|k, _| k < from || k >= to);
455                });
456            }
457            WriteBatchOp::InsertBatch((_, id, key_values)) => {
458                let locked = db_locks.get_mut(id).unwrap();
459                locked.with_db_guard_mut(|db| {
460                    key_values.iter().for_each(|(k, v)| {
461                        db.insert(k.clone(), v.clone());
462                    });
463                });
464            }
465        });
466        // unlock in the reverse order
467        dbs.iter().rev().for_each(|(_db, id)| {
468            if db_locks.contains_key(id) {
469                db_locks.remove(id);
470            }
471        });
472        Ok(())
473    }
474    /// Deletes a set of keys given as an iterator
475    pub fn delete_batch<J: Borrow<K>, K: Serialize, V>(
476        &mut self,
477        db: &TestDB<K, V>,
478        purged_vals: impl IntoIterator<Item = J>,
479    ) -> Result<(), TypedStoreError> {
480        self.ops.push_back(WriteBatchOp::DeleteBatch((
481            db.rows.clone(),
482            db.name.clone(),
483            purged_vals
484                .into_iter()
485                .map(|key| be_fix_int_ser(&key.borrow()).unwrap())
486                .collect(),
487        )));
488        Ok(())
489    }
490    /// Deletes a range of keys between `from` (inclusive) and `to`
491    /// (non-inclusive)
492    pub fn delete_range<K: Serialize, V>(
493        &mut self,
494        db: &TestDB<K, V>,
495        from: &K,
496        to: &K,
497    ) -> Result<(), TypedStoreError> {
498        let raw_from = be_fix_int_ser(from).unwrap();
499        let raw_to = be_fix_int_ser(to).unwrap();
500        self.ops.push_back(WriteBatchOp::DeleteRange((
501            db.rows.clone(),
502            db.name.clone(),
503            (raw_from, raw_to),
504        )));
505        Ok(())
506    }
507    /// inserts a range of (key, value) pairs given as an iterator
508    pub fn insert_batch<J: Borrow<K>, K: Serialize, U: Borrow<V>, V: Serialize>(
509        &mut self,
510        db: &TestDB<K, V>,
511        new_vals: impl IntoIterator<Item = (J, U)>,
512    ) -> Result<(), TypedStoreError> {
513        self.ops.push_back(WriteBatchOp::InsertBatch((
514            db.rows.clone(),
515            db.name.clone(),
516            new_vals
517                .into_iter()
518                .map(|(key, value)| {
519                    (
520                        be_fix_int_ser(&key.borrow()).unwrap(),
521                        bcs::to_bytes(&value.borrow()).unwrap(),
522                    )
523                })
524                .collect(),
525        )));
526        Ok(())
527    }
528}
529
530#[cfg(test)]
531mod test {
532    use crate::{Map, test_db::TestDB};
533
534    #[test]
535    fn test_contains_key() {
536        let db = TestDB::open();
537        db.insert(&123456789, &"123456789".to_string())
538            .expect("Failed to insert");
539        assert!(
540            db.contains_key(&123456789)
541                .expect("Failed to call contains key")
542        );
543        assert!(
544            !db.contains_key(&000000000)
545                .expect("Failed to call contains key")
546        );
547    }
548
549    #[test]
550    fn test_get() {
551        let db = TestDB::open();
552        db.insert(&123456789, &"123456789".to_string())
553            .expect("Failed to insert");
554        assert_eq!(
555            Some("123456789".to_string()),
556            db.get(&123456789).expect("Failed to get")
557        );
558        assert_eq!(None, db.get(&000000000).expect("Failed to get"));
559    }
560
561    #[test]
562    fn test_get_raw() {
563        let db = TestDB::open();
564        db.insert(&123456789, &"123456789".to_string())
565            .expect("Failed to insert");
566
567        let val_bytes = db
568            .get_raw_bytes(&123456789)
569            .expect("Failed to get_raw_bytes")
570            .unwrap();
571
572        assert_eq!(bcs::to_bytes(&"123456789".to_string()).unwrap(), val_bytes);
573        assert_eq!(
574            None,
575            db.get_raw_bytes(&000000000)
576                .expect("Failed to get_raw_bytes")
577        );
578    }
579
580    #[test]
581    fn test_multi_get() {
582        let db = TestDB::open();
583        db.insert(&123, &"123".to_string())
584            .expect("Failed to insert");
585        db.insert(&456, &"456".to_string())
586            .expect("Failed to insert");
587
588        let result = db.multi_get([123, 456, 789]).expect("Failed to multi get");
589
590        assert_eq!(result.len(), 3);
591        assert_eq!(result[0], Some("123".to_string()));
592        assert_eq!(result[1], Some("456".to_string()));
593        assert_eq!(result[2], None);
594    }
595
596    #[test]
597    fn test_remove() {
598        let db = TestDB::open();
599        db.insert(&123456789, &"123456789".to_string())
600            .expect("Failed to insert");
601        assert!(db.get(&123456789).expect("Failed to get").is_some());
602
603        db.remove(&123456789).expect("Failed to remove");
604        assert!(db.get(&123456789).expect("Failed to get").is_none());
605    }
606
607    #[test]
608    fn test_iter() {
609        let db = TestDB::open();
610        db.insert(&123456789, &"123456789".to_string())
611            .expect("Failed to insert");
612
613        let mut iter = db.safe_iter();
614        assert_eq!(Some(Ok((123456789, "123456789".to_string()))), iter.next());
615        assert_eq!(None, iter.next());
616    }
617
618    #[test]
619    fn test_iter_reverse() {
620        let db = TestDB::open();
621        db.insert(&1, &"1".to_string()).expect("Failed to insert");
622        db.insert(&2, &"2".to_string()).expect("Failed to insert");
623        db.insert(&3, &"3".to_string()).expect("Failed to insert");
624        let mut iter = db.safe_iter();
625
626        assert_eq!(Some(Ok((1, "1".to_string()))), iter.next());
627        assert_eq!(Some(Ok((2, "2".to_string()))), iter.next());
628        assert_eq!(Some(Ok((3, "3".to_string()))), iter.next());
629        assert_eq!(None, iter.next());
630    }
631
632    #[test]
633    fn test_keys() {
634        let db = TestDB::open();
635
636        db.insert(&123456789, &"123456789".to_string())
637            .expect("Failed to insert");
638
639        let mut keys = db.keys();
640        assert_eq!(Some(Ok(123456789)), keys.next());
641        assert_eq!(None, keys.next());
642    }
643
644    #[test]
645    fn test_values() {
646        let db = TestDB::open();
647
648        db.insert(&123456789, &"123456789".to_string())
649            .expect("Failed to insert");
650
651        let mut values = db.values();
652        assert_eq!(Some(Ok("123456789".to_string())), values.next());
653        assert_eq!(None, values.next());
654    }
655
656    #[test]
657    fn test_insert_batch() {
658        let db = TestDB::open();
659        let keys_vals = (1..100).map(|i| (i, i.to_string()));
660        let mut wb = db.batch();
661        wb.insert_batch(&db, keys_vals.clone())
662            .expect("Failed to batch insert");
663        wb.write().expect("Failed to execute batch");
664        for (k, v) in keys_vals {
665            let val = db.get(&k).expect("Failed to get inserted key");
666            assert_eq!(Some(v), val);
667        }
668    }
669
670    #[test]
671    fn test_insert_batch_across_cf() {
672        let db_cf_1 = TestDB::open();
673        let keys_vals_1 = (1..100).map(|i| (i, i.to_string()));
674
675        let db_cf_2 = TestDB::open();
676        let keys_vals_2 = (1000..1100).map(|i| (i, i.to_string()));
677
678        let mut wb = db_cf_1.batch();
679        wb.insert_batch(&db_cf_1, keys_vals_1.clone())
680            .expect("Failed to batch insert");
681        wb.insert_batch(&db_cf_2, keys_vals_2.clone())
682            .expect("Failed to batch insert");
683        wb.write().expect("Failed to execute batch");
684        for (k, v) in keys_vals_1 {
685            let val = db_cf_1.get(&k).expect("Failed to get inserted key");
686            assert_eq!(Some(v), val);
687        }
688
689        for (k, v) in keys_vals_2 {
690            let val = db_cf_2.get(&k).expect("Failed to get inserted key");
691            assert_eq!(Some(v), val);
692        }
693    }
694
695    #[test]
696    fn test_delete_batch() {
697        let db: TestDB<i32, String> = TestDB::open();
698
699        let keys_vals = (1..100).map(|i| (i, i.to_string()));
700        let mut wb = db.batch();
701        wb.insert_batch(&db, keys_vals)
702            .expect("Failed to batch insert");
703
704        // delete the odd-index keys
705        let deletion_keys = (1..100).step_by(2);
706        wb.delete_batch(&db, deletion_keys)
707            .expect("Failed to batch delete");
708
709        wb.write().expect("Failed to execute batch");
710
711        for k in db.keys() {
712            assert_eq!(k.unwrap() % 2, 0);
713        }
714    }
715
716    #[test]
717    fn test_delete_range() {
718        let db: TestDB<i32, String> = TestDB::open();
719
720        // Note that the last element is (100, "100".to_owned()) here
721        let keys_vals = (0..101).map(|i| (i, i.to_string()));
722        let mut wb = db.batch();
723        wb.insert_batch(&db, keys_vals)
724            .expect("Failed to batch insert");
725
726        wb.delete_range(&db, &50, &100)
727            .expect("Failed to delete range");
728
729        wb.write().expect("Failed to execute batch");
730
731        for k in 0..50 {
732            assert!(db.contains_key(&k).expect("Failed to query legal key"),);
733        }
734        for k in 50..100 {
735            assert!(!db.contains_key(&k).expect("Failed to query legal key"));
736        }
737
738        // range operator is not inclusive of to
739        assert!(db.contains_key(&100).expect("Failed to query legal key"));
740    }
741
742    #[test]
743    fn test_clear() {
744        let db: TestDB<i32, String> = TestDB::open();
745
746        // Test clear of empty map
747        let _ = db.unsafe_clear();
748
749        let keys_vals = (0..101).map(|i| (i, i.to_string()));
750        let mut wb = db.batch();
751        wb.insert_batch(&db, keys_vals)
752            .expect("Failed to batch insert");
753
754        wb.write().expect("Failed to execute batch");
755
756        // Check we have multiple entries
757        assert!(db.safe_iter().count() > 1);
758        let _ = db.unsafe_clear();
759        assert_eq!(db.safe_iter().count(), 0);
760        // Clear again to ensure safety when clearing empty map
761        let _ = db.unsafe_clear();
762        assert_eq!(db.safe_iter().count(), 0);
763        // Clear with one item
764        let _ = db.insert(&1, &"e".to_string());
765        assert_eq!(db.safe_iter().count(), 1);
766        let _ = db.unsafe_clear();
767        assert_eq!(db.safe_iter().count(), 0);
768    }
769
770    #[test]
771    fn test_is_empty() {
772        let db: TestDB<i32, String> = TestDB::open();
773
774        // Test empty map is truly empty
775        assert!(db.is_empty());
776        let _ = db.unsafe_clear();
777        assert!(db.is_empty());
778
779        let keys_vals = (0..101).map(|i| (i, i.to_string()));
780        let mut wb = db.batch();
781        wb.insert_batch(&db, keys_vals)
782            .expect("Failed to batch insert");
783
784        wb.write().expect("Failed to execute batch");
785
786        // Check we have multiple entries and not empty
787        assert!(db.safe_iter().count() > 1);
788        assert!(!db.is_empty());
789
790        // Clear again to ensure empty works after clearing
791        let _ = db.unsafe_clear();
792        assert_eq!(db.safe_iter().count(), 0);
793        assert!(db.is_empty());
794    }
795
796    #[test]
797    fn test_multi_insert() {
798        // Init a DB
799        let db: TestDB<i32, String> = TestDB::open();
800
801        // Create kv pairs
802        let keys_vals = (0..101).map(|i| (i, i.to_string()));
803
804        db.multi_insert(keys_vals.clone())
805            .expect("Failed to multi-insert");
806
807        for (k, v) in keys_vals {
808            let val = db.get(&k).expect("Failed to get inserted key");
809            assert_eq!(Some(v), val);
810        }
811    }
812
813    #[test]
814    fn test_multi_remove() {
815        // Init a DB
816        let db: TestDB<i32, String> = TestDB::open();
817
818        // Create kv pairs
819        let keys_vals = (0..101).map(|i| (i, i.to_string()));
820
821        db.multi_insert(keys_vals.clone())
822            .expect("Failed to multi-insert");
823
824        // Check insertion
825        for (k, v) in keys_vals.clone() {
826            let val = db.get(&k).expect("Failed to get inserted key");
827            assert_eq!(Some(v), val);
828        }
829
830        // Remove 50 items
831        db.multi_remove(keys_vals.clone().map(|kv| kv.0).take(50))
832            .expect("Failed to multi-remove");
833        assert_eq!(db.safe_iter().count(), 101 - 50);
834
835        // Check that the remaining are present
836        for (k, v) in keys_vals.skip(50) {
837            let val = db.get(&k).expect("Failed to get inserted key");
838            assert_eq!(Some(v), val);
839        }
840    }
841}