1use 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}