leveldb/database/
snapshots.rs1use cruzbit_leveldb_sys::*;
6
7use super::bytes::Bytes;
8use super::db::{Database, DatabaseReader};
9use super::error::Error;
10use super::iterator::{Iterable, Iterator, KeyIterator, ValueIterator};
11use super::key::IntoLevelDBKey;
12use super::options::{c_readoptions, ReadOptions};
13use libc::{c_char, size_t};
14use std::ptr;
15
16#[allow(missing_docs)]
17struct RawSnapshot {
18 db_ptr: *mut leveldb_t,
19 ptr: *mut leveldb_snapshot_t,
20}
21
22impl Drop for RawSnapshot {
23 fn drop(&mut self) {
24 unsafe { leveldb_release_snapshot(self.db_ptr, self.ptr) };
25 }
26}
27
28pub struct Snapshot<'a> {
33 raw: RawSnapshot,
34 database: &'a Database,
35}
36
37impl<'a> Snapshot<'a> {
38 pub fn get(
43 &self,
44 options: &ReadOptions,
45 key: &dyn IntoLevelDBKey,
46 ) -> Result<Option<Vec<u8>>, Error> {
47 key.as_u8_slice_for_get(&|k| self.get_u8(options, k))
48 }
49
50 pub fn get_u8(&self, options: &ReadOptions, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
53 unsafe {
54 let mut error = ptr::null_mut();
55 let mut length: size_t = 0;
56 let c_readoptions = c_readoptions(options);
57
58 leveldb_readoptions_set_snapshot(c_readoptions, self.raw_ptr());
60
61 let result = leveldb_get(
62 self.database.database.ptr,
63 c_readoptions,
64 key.as_ptr() as *mut c_char,
65 key.len() as size_t,
66 &mut length,
67 &mut error,
68 );
69
70 leveldb_readoptions_destroy(c_readoptions);
71
72 if error.is_null() {
73 let bytes_opt = Bytes::from_raw(result as *mut u8, length);
74
75 Ok(bytes_opt.map(|val| val.into()))
76 } else {
77 Err(Error::new_from_char(error))
78 }
79 }
80 }
81
82 #[inline]
83 #[allow(missing_docs)]
84 pub fn raw_ptr(&self) -> *mut leveldb_snapshot_t {
85 self.raw.ptr
86 }
87}
88
89pub trait Snapshots {
92 fn snapshot(&self) -> Snapshot;
95}
96
97impl Snapshots for Database {
98 fn snapshot(&self) -> Snapshot {
99 let db_str = self.database.ptr;
100 let snap = unsafe { leveldb_create_snapshot(db_str) };
101
102 let raw = RawSnapshot {
103 db_ptr: db_str,
104 ptr: snap,
105 };
106
107 Snapshot {
108 raw,
109 database: self,
110 }
111 }
112}
113
114impl<'a> Iterable<'a> for Snapshot<'a> {
115 fn iter(&'a self, options: &ReadOptions) -> Iterator<'a> {
116 Iterator::new(self.database, options, Some(self))
117 }
118
119 fn keys_iter(&'a self, options: &ReadOptions) -> KeyIterator<'a> {
120 KeyIterator::new(self.database, options, Some(self))
121 }
122
123 fn value_iter(&'a self, options: &ReadOptions) -> ValueIterator<'a> {
124 ValueIterator::new(self.database, options, Some(self))
125 }
126}
127
128impl DatabaseReader for Snapshot<'_> {
129 fn get(
130 &self,
131 options: &ReadOptions,
132 key: &dyn IntoLevelDBKey,
133 ) -> Result<Option<Vec<u8>>, Error> {
134 self.get(options, key)
135 }
136
137 fn get_u8(
138 &self,
139 options: &ReadOptions,
140 key: &[u8],
141 ) -> Result<Option<Vec<u8>>, Error> {
142 self.get_u8(options, key)
143 }
144}