rkv/store/
integermulti.rs

1// Copyright 2018 Mozilla
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4// this file except in compliance with the License. You may obtain a copy of the
5// License at http://www.apache.org/licenses/LICENSE-2.0
6// Unless required by applicable law or agreed to in writing, software distributed
7// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
8// CONDITIONS OF ANY KIND, either express or implied. See the License for the
9// specific language governing permissions and limitations under the License.
10
11use std::marker::PhantomData;
12
13use crate::{
14    backend::{BackendDatabase, BackendIter, BackendRoCursor, BackendRwTransaction},
15    error::StoreError,
16    readwrite::{Readable, Writer},
17    store::{
18        keys::{Key, PrimitiveInt},
19        multi::{Iter, MultiStore},
20    },
21    value::Value,
22};
23
24type EmptyResult = Result<(), StoreError>;
25
26#[derive(Debug, Eq, PartialEq, Copy, Clone)]
27pub struct MultiIntegerStore<D, K> {
28    inner: MultiStore<D>,
29    phantom: PhantomData<K>,
30}
31
32impl<D, K> MultiIntegerStore<D, K>
33where
34    D: BackendDatabase,
35    K: PrimitiveInt,
36{
37    pub(crate) fn new(db: D) -> MultiIntegerStore<D, K> {
38        MultiIntegerStore {
39            inner: MultiStore::new(db),
40            phantom: PhantomData,
41        }
42    }
43
44    pub fn get<'r, R, I, C>(&self, reader: &'r R, k: K) -> Result<Iter<'r, I>, StoreError>
45    where
46        R: Readable<'r, Database = D, RoCursor = C>,
47        I: BackendIter<'r>,
48        C: BackendRoCursor<'r, Iter = I>,
49        K: 'r,
50    {
51        self.inner.get(reader, Key::new(&k)?)
52    }
53
54    pub fn get_first<'r, R>(&self, reader: &'r R, k: K) -> Result<Option<Value<'r>>, StoreError>
55    where
56        R: Readable<'r, Database = D>,
57    {
58        self.inner.get_first(reader, Key::new(&k)?)
59    }
60
61    pub fn put<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
62    where
63        T: BackendRwTransaction<Database = D>,
64    {
65        self.inner.put(writer, Key::new(&k)?, v)
66    }
67
68    pub fn put_with_flags<T>(
69        &self,
70        writer: &mut Writer<T>,
71        k: K,
72        v: &Value,
73        flags: T::Flags,
74    ) -> EmptyResult
75    where
76        T: BackendRwTransaction<Database = D>,
77    {
78        self.inner.put_with_flags(writer, Key::new(&k)?, v, flags)
79    }
80
81    pub fn delete_all<T>(&self, writer: &mut Writer<T>, k: K) -> EmptyResult
82    where
83        T: BackendRwTransaction<Database = D>,
84    {
85        self.inner.delete_all(writer, Key::new(&k)?)
86    }
87
88    pub fn delete<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
89    where
90        T: BackendRwTransaction<Database = D>,
91    {
92        self.inner.delete(writer, Key::new(&k)?, v)
93    }
94
95    pub fn clear<T>(&self, writer: &mut Writer<T>) -> EmptyResult
96    where
97        T: BackendRwTransaction<Database = D>,
98    {
99        self.inner.clear(writer)
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106    use crate::*;
107
108    use std::fs;
109
110    use tempfile::Builder;
111
112    #[test]
113    fn test_integer_keys() {
114        let root = Builder::new()
115            .prefix("test_integer_keys")
116            .tempdir()
117            .expect("tempdir");
118        fs::create_dir_all(root.path()).expect("dir created");
119
120        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
121        let s = k
122            .open_multi_integer("s", StoreOptions::create())
123            .expect("open");
124
125        macro_rules! test_integer_keys {
126            ($type:ty, $key:expr) => {{
127                let mut writer = k.write().expect("writer");
128
129                s.put(&mut writer, $key, &Value::Str("hello!"))
130                    .expect("write");
131                assert_eq!(
132                    s.get_first(&writer, $key).expect("read"),
133                    Some(Value::Str("hello!"))
134                );
135                writer.commit().expect("committed");
136
137                let reader = k.read().expect("reader");
138                assert_eq!(
139                    s.get_first(&reader, $key).expect("read"),
140                    Some(Value::Str("hello!"))
141                );
142            }};
143        }
144
145        test_integer_keys!(u32, std::u32::MIN);
146        test_integer_keys!(u32, std::u32::MAX);
147    }
148
149    #[test]
150    fn test_clear() {
151        let root = Builder::new()
152            .prefix("test_multi_integer_clear")
153            .tempdir()
154            .expect("tempdir");
155        fs::create_dir_all(root.path()).expect("dir created");
156
157        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
158        let s = k
159            .open_multi_integer("s", StoreOptions::create())
160            .expect("open");
161
162        {
163            let mut writer = k.write().expect("writer");
164            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
165            s.put(&mut writer, 1, &Value::Str("hello1!"))
166                .expect("write");
167            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
168            assert_eq!(
169                s.get_first(&writer, 1).expect("read"),
170                Some(Value::Str("hello!"))
171            );
172            assert_eq!(
173                s.get_first(&writer, 2).expect("read"),
174                Some(Value::Str("hello!"))
175            );
176            assert_eq!(s.get_first(&writer, 3).expect("read"), None);
177            writer.commit().expect("committed");
178        }
179
180        {
181            let mut writer = k.write().expect("writer");
182            s.clear(&mut writer).expect("cleared");
183            writer.commit().expect("committed");
184
185            let reader = k.read().expect("reader");
186            assert_eq!(s.get_first(&reader, 1).expect("read"), None);
187            assert_eq!(s.get_first(&reader, 2).expect("read"), None);
188            assert_eq!(s.get_first(&reader, 3).expect("read"), None);
189        }
190    }
191
192    #[test]
193    fn test_dup() {
194        let root = Builder::new()
195            .prefix("test_multi_integer_dup")
196            .tempdir()
197            .expect("tempdir");
198        fs::create_dir_all(root.path()).expect("dir created");
199
200        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
201        let s = k
202            .open_multi_integer("s", StoreOptions::create())
203            .expect("open");
204
205        {
206            let mut writer = k.write().expect("writer");
207            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
208            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
209            s.put(&mut writer, 1, &Value::Str("hello1!"))
210                .expect("write");
211            assert_eq!(
212                s.get_first(&writer, 1).expect("read"),
213                Some(Value::Str("hello!"))
214            );
215            assert_eq!(s.get_first(&writer, 2).expect("read"), None);
216            assert_eq!(s.get_first(&writer, 3).expect("read"), None);
217            writer.commit().expect("committed");
218        }
219
220        {
221            let mut writer = k.write().expect("writer");
222            s.clear(&mut writer).expect("cleared");
223            writer.commit().expect("committed");
224
225            let reader = k.read().expect("reader");
226            assert_eq!(s.get_first(&reader, 1).expect("read"), None);
227            assert_eq!(s.get_first(&reader, 2).expect("read"), None);
228            assert_eq!(s.get_first(&reader, 3).expect("read"), None);
229        }
230    }
231
232    #[test]
233    fn test_dup_2() {
234        let root = Builder::new()
235            .prefix("test_multi_integer_dup")
236            .tempdir()
237            .expect("tempdir");
238        fs::create_dir_all(root.path()).expect("dir created");
239
240        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
241        let s = k
242            .open_multi_integer("s", StoreOptions::create())
243            .expect("open");
244
245        {
246            let mut writer = k.write().expect("writer");
247            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
248            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
249            s.put(&mut writer, 1, &Value::Str("hello1!"))
250                .expect("write");
251
252            let mut iter = s.get(&writer, 1).expect("read");
253            assert_eq!(
254                iter.next().expect("first").expect("ok").1,
255                Value::Str("hello!")
256            );
257            assert_eq!(
258                iter.next().expect("second").expect("ok").1,
259                Value::Str("hello1!")
260            );
261            assert!(iter.next().is_none());
262        }
263    }
264
265    #[test]
266    fn test_del() {
267        let root = Builder::new()
268            .prefix("test_multi_integer_dup")
269            .tempdir()
270            .expect("tempdir");
271        fs::create_dir_all(root.path()).expect("dir created");
272
273        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
274        let s = k
275            .open_multi_integer("s", StoreOptions::create())
276            .expect("open");
277
278        {
279            let mut writer = k.write().expect("writer");
280            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
281            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
282            s.put(&mut writer, 1, &Value::Str("hello1!"))
283                .expect("write");
284            {
285                let mut iter = s.get(&writer, 1).expect("read");
286                assert_eq!(
287                    iter.next().expect("first").expect("ok").1,
288                    Value::Str("hello!")
289                );
290                assert_eq!(
291                    iter.next().expect("second").expect("ok").1,
292                    Value::Str("hello1!")
293                );
294                assert!(iter.next().is_none());
295            }
296            writer.commit().expect("committed");
297        }
298
299        {
300            let mut writer = k.write().expect("writer");
301            s.delete(&mut writer, 1, &Value::Str("hello!"))
302                .expect("deleted");
303            writer.commit().expect("committed");
304
305            let reader = k.read().expect("reader");
306            let mut iter = s.get(&reader, 1).expect("read");
307            assert_eq!(
308                iter.next().expect("first").expect("ok").1,
309                Value::Str("hello1!")
310            );
311            assert!(iter.next().is_none());
312        }
313
314        {
315            let mut writer = k.write().expect("writer");
316            s.delete(&mut writer, 1, &Value::Str("hello!"))
317                .expect_err("deleted");
318            writer.commit().expect("committed");
319
320            let reader = k.read().expect("reader");
321            let mut iter = s.get(&reader, 1).expect("read");
322            assert_eq!(
323                iter.next().expect("first").expect("ok").1,
324                Value::Str("hello1!")
325            );
326            assert!(iter.next().is_none());
327        }
328
329        {
330            let mut writer = k.write().expect("writer");
331            s.delete(&mut writer, 1, &Value::Str("hello1!"))
332                .expect("deleted");
333            writer.commit().expect("committed");
334
335            let reader = k.read().expect("reader");
336            let mut iter = s.get(&reader, 1).expect("read");
337            assert!(iter.next().is_none());
338        }
339
340        {
341            let mut writer = k.write().expect("writer");
342            s.delete(&mut writer, 1, &Value::Str("hello1!"))
343                .expect_err("deleted");
344            writer.commit().expect("committed");
345
346            let reader = k.read().expect("reader");
347            let mut iter = s.get(&reader, 1).expect("read");
348            assert!(iter.next().is_none());
349        }
350    }
351
352    #[test]
353    fn test_persist() {
354        let root = Builder::new()
355            .prefix("test_multi_integer_persist")
356            .tempdir()
357            .expect("tempdir");
358        fs::create_dir_all(root.path()).expect("dir created");
359
360        {
361            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
362            let s = k
363                .open_multi_integer("s", StoreOptions::create())
364                .expect("open");
365
366            let mut writer = k.write().expect("writer");
367            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
368            s.put(&mut writer, 1, &Value::Str("hello1!"))
369                .expect("write");
370            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
371            {
372                let mut iter = s.get(&writer, 1).expect("read");
373                assert_eq!(
374                    iter.next().expect("first").expect("ok").1,
375                    Value::Str("hello!")
376                );
377                assert_eq!(
378                    iter.next().expect("second").expect("ok").1,
379                    Value::Str("hello1!")
380                );
381                assert!(iter.next().is_none());
382            }
383            writer.commit().expect("committed");
384        }
385
386        {
387            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
388            let s = k
389                .open_multi_integer("s", StoreOptions::create())
390                .expect("open");
391
392            let reader = k.read().expect("reader");
393            let mut iter = s.get(&reader, 1).expect("read");
394            assert_eq!(
395                iter.next().expect("first").expect("ok").1,
396                Value::Str("hello!")
397            );
398            assert_eq!(
399                iter.next().expect("second").expect("ok").1,
400                Value::Str("hello1!")
401            );
402            assert!(iter.next().is_none());
403        }
404    }
405}
406
407#[cfg(test)]
408mod tests_safe {
409    use super::*;
410    use crate::*;
411
412    use std::fs;
413
414    use tempfile::Builder;
415
416    #[test]
417    fn test_integer_keys() {
418        let root = Builder::new()
419            .prefix("test_integer_keys")
420            .tempdir()
421            .expect("tempdir");
422        fs::create_dir_all(root.path()).expect("dir created");
423
424        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
425        let s = k
426            .open_multi_integer("s", StoreOptions::create())
427            .expect("open");
428
429        macro_rules! test_integer_keys {
430            ($type:ty, $key:expr) => {{
431                let mut writer = k.write().expect("writer");
432
433                s.put(&mut writer, $key, &Value::Str("hello!"))
434                    .expect("write");
435                assert_eq!(
436                    s.get_first(&writer, $key).expect("read"),
437                    Some(Value::Str("hello!"))
438                );
439                writer.commit().expect("committed");
440
441                let reader = k.read().expect("reader");
442                assert_eq!(
443                    s.get_first(&reader, $key).expect("read"),
444                    Some(Value::Str("hello!"))
445                );
446            }};
447        }
448
449        test_integer_keys!(u32, std::u32::MIN);
450        test_integer_keys!(u32, std::u32::MAX);
451    }
452
453    #[test]
454    fn test_clear() {
455        let root = Builder::new()
456            .prefix("test_multi_integer_clear")
457            .tempdir()
458            .expect("tempdir");
459        fs::create_dir_all(root.path()).expect("dir created");
460
461        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
462        let s = k
463            .open_multi_integer("s", StoreOptions::create())
464            .expect("open");
465
466        {
467            let mut writer = k.write().expect("writer");
468            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
469            s.put(&mut writer, 1, &Value::Str("hello1!"))
470                .expect("write");
471            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
472            assert_eq!(
473                s.get_first(&writer, 1).expect("read"),
474                Some(Value::Str("hello!"))
475            );
476            assert_eq!(
477                s.get_first(&writer, 2).expect("read"),
478                Some(Value::Str("hello!"))
479            );
480            assert_eq!(s.get_first(&writer, 3).expect("read"), None);
481            writer.commit().expect("committed");
482        }
483
484        {
485            let mut writer = k.write().expect("writer");
486            s.clear(&mut writer).expect("cleared");
487            writer.commit().expect("committed");
488
489            let reader = k.read().expect("reader");
490            assert_eq!(s.get_first(&reader, 1).expect("read"), None);
491            assert_eq!(s.get_first(&reader, 2).expect("read"), None);
492            assert_eq!(s.get_first(&reader, 3).expect("read"), None);
493        }
494    }
495
496    #[test]
497    fn test_dup() {
498        let root = Builder::new()
499            .prefix("test_multi_integer_dup")
500            .tempdir()
501            .expect("tempdir");
502        fs::create_dir_all(root.path()).expect("dir created");
503
504        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
505        let s = k
506            .open_multi_integer("s", StoreOptions::create())
507            .expect("open");
508
509        {
510            let mut writer = k.write().expect("writer");
511            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
512            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
513            s.put(&mut writer, 1, &Value::Str("hello1!"))
514                .expect("write");
515            assert_eq!(
516                s.get_first(&writer, 1).expect("read"),
517                Some(Value::Str("hello!"))
518            );
519            assert_eq!(s.get_first(&writer, 2).expect("read"), None);
520            assert_eq!(s.get_first(&writer, 3).expect("read"), None);
521            writer.commit().expect("committed");
522        }
523
524        {
525            let mut writer = k.write().expect("writer");
526            s.clear(&mut writer).expect("cleared");
527            writer.commit().expect("committed");
528
529            let reader = k.read().expect("reader");
530            assert_eq!(s.get_first(&reader, 1).expect("read"), None);
531            assert_eq!(s.get_first(&reader, 2).expect("read"), None);
532            assert_eq!(s.get_first(&reader, 3).expect("read"), None);
533        }
534    }
535
536    #[test]
537    fn test_dup_2() {
538        let root = Builder::new()
539            .prefix("test_multi_integer_dup")
540            .tempdir()
541            .expect("tempdir");
542        fs::create_dir_all(root.path()).expect("dir created");
543
544        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
545        let s = k
546            .open_multi_integer("s", StoreOptions::create())
547            .expect("open");
548
549        {
550            let mut writer = k.write().expect("writer");
551            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
552            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
553            s.put(&mut writer, 1, &Value::Str("hello1!"))
554                .expect("write");
555
556            let mut iter = s.get(&writer, 1).expect("read");
557            assert_eq!(
558                iter.next().expect("first").expect("ok").1,
559                Value::Str("hello!")
560            );
561            assert_eq!(
562                iter.next().expect("second").expect("ok").1,
563                Value::Str("hello1!")
564            );
565            assert!(iter.next().is_none());
566        }
567    }
568
569    #[test]
570    fn test_del() {
571        let root = Builder::new()
572            .prefix("test_multi_integer_dup")
573            .tempdir()
574            .expect("tempdir");
575        fs::create_dir_all(root.path()).expect("dir created");
576
577        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
578        let s = k
579            .open_multi_integer("s", StoreOptions::create())
580            .expect("open");
581
582        {
583            let mut writer = k.write().expect("writer");
584            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
585            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
586            s.put(&mut writer, 1, &Value::Str("hello1!"))
587                .expect("write");
588            {
589                let mut iter = s.get(&writer, 1).expect("read");
590                assert_eq!(
591                    iter.next().expect("first").expect("ok").1,
592                    Value::Str("hello!")
593                );
594                assert_eq!(
595                    iter.next().expect("second").expect("ok").1,
596                    Value::Str("hello1!")
597                );
598                assert!(iter.next().is_none());
599            }
600            writer.commit().expect("committed");
601        }
602
603        {
604            let mut writer = k.write().expect("writer");
605            s.delete(&mut writer, 1, &Value::Str("hello!"))
606                .expect("deleted");
607            writer.commit().expect("committed");
608
609            let reader = k.read().expect("reader");
610            let mut iter = s.get(&reader, 1).expect("read");
611            assert_eq!(
612                iter.next().expect("first").expect("ok").1,
613                Value::Str("hello1!")
614            );
615            assert!(iter.next().is_none());
616        }
617
618        {
619            let mut writer = k.write().expect("writer");
620            s.delete(&mut writer, 1, &Value::Str("hello!"))
621                .expect_err("deleted");
622            writer.commit().expect("committed");
623
624            let reader = k.read().expect("reader");
625            let mut iter = s.get(&reader, 1).expect("read");
626            assert_eq!(
627                iter.next().expect("first").expect("ok").1,
628                Value::Str("hello1!")
629            );
630            assert!(iter.next().is_none());
631        }
632
633        {
634            let mut writer = k.write().expect("writer");
635            s.delete(&mut writer, 1, &Value::Str("hello1!"))
636                .expect("deleted");
637            writer.commit().expect("committed");
638
639            let reader = k.read().expect("reader");
640            let mut iter = s.get(&reader, 1).expect("read");
641            assert!(iter.next().is_none());
642        }
643
644        {
645            let mut writer = k.write().expect("writer");
646            s.delete(&mut writer, 1, &Value::Str("hello1!"))
647                .expect_err("deleted");
648            writer.commit().expect("committed");
649
650            let reader = k.read().expect("reader");
651            let mut iter = s.get(&reader, 1).expect("read");
652            assert!(iter.next().is_none());
653        }
654    }
655
656    #[test]
657    fn test_persist() {
658        let root = Builder::new()
659            .prefix("test_multi_integer_persist")
660            .tempdir()
661            .expect("tempdir");
662        fs::create_dir_all(root.path()).expect("dir created");
663
664        {
665            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
666            let s = k
667                .open_multi_integer("s", StoreOptions::create())
668                .expect("open");
669
670            let mut writer = k.write().expect("writer");
671            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
672            s.put(&mut writer, 1, &Value::Str("hello1!"))
673                .expect("write");
674            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
675            {
676                let mut iter = s.get(&writer, 1).expect("read");
677                assert_eq!(
678                    iter.next().expect("first").expect("ok").1,
679                    Value::Str("hello!")
680                );
681                assert_eq!(
682                    iter.next().expect("second").expect("ok").1,
683                    Value::Str("hello1!")
684                );
685                assert!(iter.next().is_none());
686            }
687            writer.commit().expect("committed");
688        }
689
690        {
691            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
692            let s = k
693                .open_multi_integer("s", StoreOptions::create())
694                .expect("open");
695
696            let reader = k.read().expect("reader");
697            let mut iter = s.get(&reader, 1).expect("read");
698            assert_eq!(
699                iter.next().expect("first").expect("ok").1,
700                Value::Str("hello!")
701            );
702            assert_eq!(
703                iter.next().expect("second").expect("ok").1,
704                Value::Str("hello1!")
705            );
706            assert!(iter.next().is_none());
707        }
708    }
709}