rkv/store/
integer.rs

1// Copyright 2018-2019 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, BackendRwTransaction},
15    error::StoreError,
16    readwrite::{Readable, Writer},
17    store::{
18        keys::{Key, PrimitiveInt},
19        single::SingleStore,
20    },
21    value::Value,
22};
23
24type EmptyResult = Result<(), StoreError>;
25
26#[derive(Debug, Eq, PartialEq, Copy, Clone)]
27pub struct IntegerStore<D, K> {
28    inner: SingleStore<D>,
29    phantom: PhantomData<K>,
30}
31
32impl<D, K> IntegerStore<D, K>
33where
34    D: BackendDatabase,
35    K: PrimitiveInt,
36{
37    pub(crate) fn new(db: D) -> IntegerStore<D, K> {
38        IntegerStore {
39            inner: SingleStore::new(db),
40            phantom: PhantomData,
41        }
42    }
43
44    pub fn get<'r, R>(&self, reader: &'r R, k: K) -> Result<Option<Value<'r>>, StoreError>
45    where
46        R: Readable<'r, Database = D>,
47    {
48        self.inner.get(reader, Key::new(&k)?)
49    }
50
51    pub fn put<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
52    where
53        T: BackendRwTransaction<Database = D>,
54    {
55        self.inner.put(writer, Key::new(&k)?, v)
56    }
57
58    pub fn delete<T>(&self, writer: &mut Writer<T>, k: K) -> EmptyResult
59    where
60        T: BackendRwTransaction<Database = D>,
61    {
62        self.inner.delete(writer, Key::new(&k)?)
63    }
64
65    pub fn clear<T>(&self, writer: &mut Writer<T>) -> EmptyResult
66    where
67        T: BackendRwTransaction<Database = D>,
68    {
69        self.inner.clear(writer)
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use crate::*;
77
78    use std::fs;
79
80    use tempfile::Builder;
81
82    #[test]
83    fn test_integer_keys() {
84        let root = Builder::new()
85            .prefix("test_integer_keys")
86            .tempdir()
87            .expect("tempdir");
88        fs::create_dir_all(root.path()).expect("dir created");
89
90        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
91        let s = k.open_integer("s", StoreOptions::create()).expect("open");
92
93        macro_rules! test_integer_keys {
94            ($type:ty, $key:expr) => {{
95                let mut writer = k.write().expect("writer");
96
97                s.put(&mut writer, $key, &Value::Str("hello!"))
98                    .expect("write");
99                assert_eq!(
100                    s.get(&writer, $key).expect("read"),
101                    Some(Value::Str("hello!"))
102                );
103                writer.commit().expect("committed");
104
105                let reader = k.read().expect("reader");
106                assert_eq!(
107                    s.get(&reader, $key).expect("read"),
108                    Some(Value::Str("hello!"))
109                );
110            }};
111        }
112
113        test_integer_keys!(u32, std::u32::MIN);
114        test_integer_keys!(u32, std::u32::MAX);
115    }
116
117    #[test]
118    fn test_clear() {
119        let root = Builder::new()
120            .prefix("test_integer_clear")
121            .tempdir()
122            .expect("tempdir");
123        fs::create_dir_all(root.path()).expect("dir created");
124
125        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
126        let s = k.open_integer("s", StoreOptions::create()).expect("open");
127
128        {
129            let mut writer = k.write().expect("writer");
130            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
131            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
132            s.put(&mut writer, 3, &Value::Str("hello!")).expect("write");
133            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
134            assert_eq!(s.get(&writer, 2).expect("read"), Some(Value::Str("hello!")));
135            assert_eq!(s.get(&writer, 3).expect("read"), Some(Value::Str("hello!")));
136            writer.commit().expect("committed");
137        }
138
139        {
140            let mut writer = k.write().expect("writer");
141            s.clear(&mut writer).expect("cleared");
142            writer.commit().expect("committed");
143
144            let reader = k.read().expect("reader");
145            assert_eq!(s.get(&reader, 1).expect("read"), None);
146            assert_eq!(s.get(&reader, 2).expect("read"), None);
147            assert_eq!(s.get(&reader, 3).expect("read"), None);
148        }
149    }
150
151    #[test]
152    fn test_dup() {
153        let root = Builder::new()
154            .prefix("test_integer_dup")
155            .tempdir()
156            .expect("tempdir");
157        fs::create_dir_all(root.path()).expect("dir created");
158
159        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
160        let s = k.open_integer("s", StoreOptions::create()).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("foo!")).expect("write");
166            s.put(&mut writer, 1, &Value::Str("bar!")).expect("write");
167            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("bar!")));
168            assert_eq!(s.get(&writer, 2).expect("read"), None);
169            assert_eq!(s.get(&writer, 3).expect("read"), None);
170            writer.commit().expect("committed");
171        }
172
173        {
174            let mut writer = k.write().expect("writer");
175            s.clear(&mut writer).expect("cleared");
176            writer.commit().expect("committed");
177
178            let reader = k.read().expect("reader");
179            assert_eq!(s.get(&reader, 1).expect("read"), None);
180            assert_eq!(s.get(&reader, 2).expect("read"), None);
181            assert_eq!(s.get(&reader, 3).expect("read"), None);
182        }
183    }
184
185    #[test]
186    fn test_del() {
187        let root = Builder::new()
188            .prefix("test_integer_del")
189            .tempdir()
190            .expect("tempdir");
191        fs::create_dir_all(root.path()).expect("dir created");
192
193        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
194        let s = k.open_integer("s", StoreOptions::create()).expect("open");
195
196        {
197            let mut writer = k.write().expect("writer");
198            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
199            s.put(&mut writer, 1, &Value::Str("foo!")).expect("write");
200            s.put(&mut writer, 1, &Value::Str("bar!")).expect("write");
201            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("bar!")));
202            assert_eq!(s.get(&writer, 2).expect("read"), None);
203            assert_eq!(s.get(&writer, 3).expect("read"), None);
204            writer.commit().expect("committed");
205        }
206
207        {
208            let mut writer = k.write().expect("writer");
209            s.delete(&mut writer, 1).expect("deleted");
210            writer.commit().expect("committed");
211
212            let reader = k.read().expect("reader");
213            assert_eq!(s.get(&reader, 1).expect("read"), None);
214        }
215
216        {
217            let mut writer = k.write().expect("writer");
218            s.delete(&mut writer, 2).expect_err("not deleted");
219            writer.commit().expect("committed");
220
221            let reader = k.read().expect("reader");
222            assert_eq!(s.get(&reader, 2).expect("read"), None);
223        }
224
225        {
226            let mut writer = k.write().expect("writer");
227            s.delete(&mut writer, 3).expect_err("not deleted");
228            writer.commit().expect("committed");
229
230            let reader = k.read().expect("reader");
231            assert_eq!(s.get(&reader, 3).expect("read"), None);
232        }
233    }
234
235    #[test]
236    fn test_persist() {
237        let root = Builder::new()
238            .prefix("test_integer_persist")
239            .tempdir()
240            .expect("tempdir");
241        fs::create_dir_all(root.path()).expect("dir created");
242
243        {
244            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
245            let s = k.open_integer("s", StoreOptions::create()).expect("open");
246
247            let mut writer = k.write().expect("writer");
248            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
249            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
250            s.put(&mut writer, 3, &Value::Str("hello!")).expect("write");
251            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
252            assert_eq!(s.get(&writer, 2).expect("read"), Some(Value::Str("hello!")));
253            assert_eq!(s.get(&writer, 3).expect("read"), Some(Value::Str("hello!")));
254            writer.commit().expect("committed");
255        }
256
257        {
258            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
259            let s = k.open_integer("s", StoreOptions::create()).expect("open");
260
261            let reader = k.read().expect("reader");
262            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
263            assert_eq!(s.get(&reader, 2).expect("read"), Some(Value::Str("hello!")));
264            assert_eq!(s.get(&reader, 3).expect("read"), Some(Value::Str("hello!")));
265        }
266    }
267
268    #[test]
269    fn test_intertwine_read_write() {
270        let root = Builder::new()
271            .prefix("test_integer_intertwine_read_write")
272            .tempdir()
273            .expect("tempdir");
274        fs::create_dir_all(root.path()).expect("dir created");
275
276        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
277        let s = k.open_integer("s", StoreOptions::create()).expect("open");
278
279        {
280            let mut writer = k.write().expect("writer");
281            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
282            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
283            assert_eq!(s.get(&writer, 2).expect("read"), None);
284            assert_eq!(s.get(&writer, 3).expect("read"), None);
285            writer.commit().expect("committed");
286        }
287
288        let reader = k.read().expect("reader");
289        let mut writer = k.write().expect("writer");
290
291        {
292            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
293            assert_eq!(s.get(&reader, 2).expect("read"), None);
294            assert_eq!(s.get(&reader, 3).expect("read"), None);
295        }
296
297        {
298            s.put(&mut writer, 1, &Value::Str("goodbye!"))
299                .expect("write");
300            s.put(&mut writer, 2, &Value::Str("goodbye!"))
301                .expect("write");
302            s.put(&mut writer, 3, &Value::Str("goodbye!"))
303                .expect("write");
304            assert_eq!(
305                s.get(&writer, 1).expect("read"),
306                Some(Value::Str("goodbye!"))
307            );
308            assert_eq!(
309                s.get(&writer, 2).expect("read"),
310                Some(Value::Str("goodbye!"))
311            );
312            assert_eq!(
313                s.get(&writer, 3).expect("read"),
314                Some(Value::Str("goodbye!"))
315            );
316            writer.commit().expect("committed");
317        }
318
319        {
320            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
321            assert_eq!(s.get(&reader, 2).expect("read"), None);
322            assert_eq!(s.get(&reader, 3).expect("read"), None);
323        }
324
325        {
326            let mut writer = k.write().expect("writer");
327            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
328            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
329            assert_eq!(
330                s.get(&writer, 2).expect("read"),
331                Some(Value::Str("goodbye!"))
332            );
333            assert_eq!(
334                s.get(&writer, 3).expect("read"),
335                Some(Value::Str("goodbye!"))
336            );
337            writer.commit().expect("committed");
338        }
339
340        {
341            let reader = k.write().expect("reader");
342            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
343            assert_eq!(
344                s.get(&reader, 2).expect("read"),
345                Some(Value::Str("goodbye!"))
346            );
347            assert_eq!(
348                s.get(&reader, 3).expect("read"),
349                Some(Value::Str("goodbye!"))
350            );
351            reader.commit().expect("committed");
352        }
353    }
354}
355
356#[cfg(test)]
357mod tests_safe {
358    use super::*;
359    use crate::*;
360
361    use std::fs;
362
363    use tempfile::Builder;
364
365    #[test]
366    fn test_integer_keys() {
367        let root = Builder::new()
368            .prefix("test_integer_keys")
369            .tempdir()
370            .expect("tempdir");
371        fs::create_dir_all(root.path()).expect("dir created");
372
373        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
374        let s = k.open_integer("s", StoreOptions::create()).expect("open");
375
376        macro_rules! test_integer_keys {
377            ($type:ty, $key:expr) => {{
378                let mut writer = k.write().expect("writer");
379
380                s.put(&mut writer, $key, &Value::Str("hello!"))
381                    .expect("write");
382                assert_eq!(
383                    s.get(&writer, $key).expect("read"),
384                    Some(Value::Str("hello!"))
385                );
386                writer.commit().expect("committed");
387
388                let reader = k.read().expect("reader");
389                assert_eq!(
390                    s.get(&reader, $key).expect("read"),
391                    Some(Value::Str("hello!"))
392                );
393            }};
394        }
395
396        test_integer_keys!(u32, std::u32::MIN);
397        test_integer_keys!(u32, std::u32::MAX);
398    }
399
400    #[test]
401    fn test_clear() {
402        let root = Builder::new()
403            .prefix("test_integer_clear")
404            .tempdir()
405            .expect("tempdir");
406        fs::create_dir_all(root.path()).expect("dir created");
407
408        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
409        let s = k.open_integer("s", StoreOptions::create()).expect("open");
410
411        {
412            let mut writer = k.write().expect("writer");
413            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
414            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
415            s.put(&mut writer, 3, &Value::Str("hello!")).expect("write");
416            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
417            assert_eq!(s.get(&writer, 2).expect("read"), Some(Value::Str("hello!")));
418            assert_eq!(s.get(&writer, 3).expect("read"), Some(Value::Str("hello!")));
419            writer.commit().expect("committed");
420        }
421
422        {
423            let mut writer = k.write().expect("writer");
424            s.clear(&mut writer).expect("cleared");
425            writer.commit().expect("committed");
426
427            let reader = k.read().expect("reader");
428            assert_eq!(s.get(&reader, 1).expect("read"), None);
429            assert_eq!(s.get(&reader, 2).expect("read"), None);
430            assert_eq!(s.get(&reader, 3).expect("read"), None);
431        }
432    }
433
434    #[test]
435    fn test_dup() {
436        let root = Builder::new()
437            .prefix("test_integer_dup")
438            .tempdir()
439            .expect("tempdir");
440        fs::create_dir_all(root.path()).expect("dir created");
441
442        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
443        let s = k.open_integer("s", StoreOptions::create()).expect("open");
444
445        {
446            let mut writer = k.write().expect("writer");
447            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
448            s.put(&mut writer, 1, &Value::Str("foo!")).expect("write");
449            s.put(&mut writer, 1, &Value::Str("bar!")).expect("write");
450            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("bar!")));
451            assert_eq!(s.get(&writer, 2).expect("read"), None);
452            assert_eq!(s.get(&writer, 3).expect("read"), None);
453            writer.commit().expect("committed");
454        }
455
456        {
457            let mut writer = k.write().expect("writer");
458            s.clear(&mut writer).expect("cleared");
459            writer.commit().expect("committed");
460
461            let reader = k.read().expect("reader");
462            assert_eq!(s.get(&reader, 1).expect("read"), None);
463            assert_eq!(s.get(&reader, 2).expect("read"), None);
464            assert_eq!(s.get(&reader, 3).expect("read"), None);
465        }
466    }
467
468    #[test]
469    fn test_del() {
470        let root = Builder::new()
471            .prefix("test_integer_del")
472            .tempdir()
473            .expect("tempdir");
474        fs::create_dir_all(root.path()).expect("dir created");
475
476        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
477        let s = k.open_integer("s", StoreOptions::create()).expect("open");
478
479        {
480            let mut writer = k.write().expect("writer");
481            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
482            s.put(&mut writer, 1, &Value::Str("foo!")).expect("write");
483            s.put(&mut writer, 1, &Value::Str("bar!")).expect("write");
484            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("bar!")));
485            assert_eq!(s.get(&writer, 2).expect("read"), None);
486            assert_eq!(s.get(&writer, 3).expect("read"), None);
487            writer.commit().expect("committed");
488        }
489
490        {
491            let mut writer = k.write().expect("writer");
492            s.delete(&mut writer, 1).expect("deleted");
493            writer.commit().expect("committed");
494
495            let reader = k.read().expect("reader");
496            assert_eq!(s.get(&reader, 1).expect("read"), None);
497        }
498
499        {
500            let mut writer = k.write().expect("writer");
501            s.delete(&mut writer, 2).expect_err("not deleted");
502            writer.commit().expect("committed");
503
504            let reader = k.read().expect("reader");
505            assert_eq!(s.get(&reader, 2).expect("read"), None);
506        }
507
508        {
509            let mut writer = k.write().expect("writer");
510            s.delete(&mut writer, 3).expect_err("not deleted");
511            writer.commit().expect("committed");
512
513            let reader = k.read().expect("reader");
514            assert_eq!(s.get(&reader, 3).expect("read"), None);
515        }
516    }
517
518    #[test]
519    fn test_persist() {
520        let root = Builder::new()
521            .prefix("test_integer_persist")
522            .tempdir()
523            .expect("tempdir");
524        fs::create_dir_all(root.path()).expect("dir created");
525
526        {
527            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
528            let s = k.open_integer("s", StoreOptions::create()).expect("open");
529
530            let mut writer = k.write().expect("writer");
531            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
532            s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
533            s.put(&mut writer, 3, &Value::Str("hello!")).expect("write");
534            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
535            assert_eq!(s.get(&writer, 2).expect("read"), Some(Value::Str("hello!")));
536            assert_eq!(s.get(&writer, 3).expect("read"), Some(Value::Str("hello!")));
537            writer.commit().expect("committed");
538        }
539
540        {
541            let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
542            let s = k.open_integer("s", StoreOptions::create()).expect("open");
543
544            let reader = k.read().expect("reader");
545            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
546            assert_eq!(s.get(&reader, 2).expect("read"), Some(Value::Str("hello!")));
547            assert_eq!(s.get(&reader, 3).expect("read"), Some(Value::Str("hello!")));
548        }
549    }
550
551    #[test]
552    fn test_intertwine_read_write() {
553        let root = Builder::new()
554            .prefix("test_integer_intertwine_read_write")
555            .tempdir()
556            .expect("tempdir");
557        fs::create_dir_all(root.path()).expect("dir created");
558
559        let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded");
560        let s = k.open_integer("s", StoreOptions::create()).expect("open");
561
562        {
563            let mut writer = k.write().expect("writer");
564            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
565            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
566            assert_eq!(s.get(&writer, 2).expect("read"), None);
567            assert_eq!(s.get(&writer, 3).expect("read"), None);
568            writer.commit().expect("committed");
569        }
570
571        let reader = k.read().expect("reader");
572        let mut writer = k.write().expect("writer");
573
574        {
575            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
576            assert_eq!(s.get(&reader, 2).expect("read"), None);
577            assert_eq!(s.get(&reader, 3).expect("read"), None);
578        }
579
580        {
581            s.put(&mut writer, 1, &Value::Str("goodbye!"))
582                .expect("write");
583            s.put(&mut writer, 2, &Value::Str("goodbye!"))
584                .expect("write");
585            s.put(&mut writer, 3, &Value::Str("goodbye!"))
586                .expect("write");
587            assert_eq!(
588                s.get(&writer, 1).expect("read"),
589                Some(Value::Str("goodbye!"))
590            );
591            assert_eq!(
592                s.get(&writer, 2).expect("read"),
593                Some(Value::Str("goodbye!"))
594            );
595            assert_eq!(
596                s.get(&writer, 3).expect("read"),
597                Some(Value::Str("goodbye!"))
598            );
599            writer.commit().expect("committed");
600        }
601
602        {
603            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
604            assert_eq!(s.get(&reader, 2).expect("read"), None);
605            assert_eq!(s.get(&reader, 3).expect("read"), None);
606        }
607
608        {
609            let mut writer = k.write().expect("writer");
610            s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
611            assert_eq!(s.get(&writer, 1).expect("read"), Some(Value::Str("hello!")));
612            assert_eq!(
613                s.get(&writer, 2).expect("read"),
614                Some(Value::Str("goodbye!"))
615            );
616            assert_eq!(
617                s.get(&writer, 3).expect("read"),
618                Some(Value::Str("goodbye!"))
619            );
620            writer.commit().expect("committed");
621        }
622
623        {
624            let reader = k.write().expect("reader");
625            assert_eq!(s.get(&reader, 1).expect("read"), Some(Value::Str("hello!")));
626            assert_eq!(
627                s.get(&reader, 2).expect("read"),
628                Some(Value::Str("goodbye!"))
629            );
630            assert_eq!(
631                s.get(&reader, 3).expect("read"),
632                Some(Value::Str("goodbye!"))
633            );
634            reader.commit().expect("committed");
635        }
636    }
637}