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