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 
11 use std::{
12     fmt::{
13         Debug,
14         Display,
15     },
16     path::{
17         Path,
18         PathBuf,
19     },
20 };
21 
22 use crate::{
23     backend::common::{
24         DatabaseFlags,
25         EnvironmentFlags,
26         WriteFlags,
27     },
28     error::StoreError,
29 };
30 
31 pub trait BackendError: Debug + Display + Into<StoreError> {}
32 
33 pub trait BackendDatabase: Debug + Eq + PartialEq + Copy + Clone {}
34 
35 pub trait BackendFlags: Debug + Eq + PartialEq + Copy + Clone + Default {
empty() -> Self36     fn empty() -> Self;
37 }
38 
39 pub trait BackendEnvironmentFlags: BackendFlags {
set(&mut self, flag: EnvironmentFlags, value: bool)40     fn set(&mut self, flag: EnvironmentFlags, value: bool);
41 }
42 
43 pub trait BackendDatabaseFlags: BackendFlags {
set(&mut self, flag: DatabaseFlags, value: bool)44     fn set(&mut self, flag: DatabaseFlags, value: bool);
45 }
46 
47 pub trait BackendWriteFlags: BackendFlags {
set(&mut self, flag: WriteFlags, value: bool)48     fn set(&mut self, flag: WriteFlags, value: bool);
49 }
50 
51 pub trait BackendStat {
page_size(&self) -> usize52     fn page_size(&self) -> usize;
53 
depth(&self) -> usize54     fn depth(&self) -> usize;
55 
branch_pages(&self) -> usize56     fn branch_pages(&self) -> usize;
57 
leaf_pages(&self) -> usize58     fn leaf_pages(&self) -> usize;
59 
overflow_pages(&self) -> usize60     fn overflow_pages(&self) -> usize;
61 
entries(&self) -> usize62     fn entries(&self) -> usize;
63 }
64 
65 pub trait BackendInfo {
map_size(&self) -> usize66     fn map_size(&self) -> usize;
67 
last_pgno(&self) -> usize68     fn last_pgno(&self) -> usize;
69 
last_txnid(&self) -> usize70     fn last_txnid(&self) -> usize;
71 
max_readers(&self) -> usize72     fn max_readers(&self) -> usize;
73 
num_readers(&self) -> usize74     fn num_readers(&self) -> usize;
75 }
76 
77 pub trait BackendEnvironmentBuilder<'b>: Debug + Eq + PartialEq + Copy + Clone {
78     type Error: BackendError;
79     type Environment: BackendEnvironment<'b>;
80     type Flags: BackendEnvironmentFlags;
81 
new() -> Self82     fn new() -> Self;
83 
set_flags<T>(&mut self, flags: T) -> &mut Self where T: Into<Self::Flags>84     fn set_flags<T>(&mut self, flags: T) -> &mut Self
85     where
86         T: Into<Self::Flags>;
87 
set_max_dbs(&mut self, max_dbs: u32) -> &mut Self88     fn set_max_dbs(&mut self, max_dbs: u32) -> &mut Self;
89 
set_max_readers(&mut self, max_readers: u32) -> &mut Self90     fn set_max_readers(&mut self, max_readers: u32) -> &mut Self;
91 
set_map_size(&mut self, size: usize) -> &mut Self92     fn set_map_size(&mut self, size: usize) -> &mut Self;
93 
set_make_dir_if_needed(&mut self, make_dir_if_needed: bool) -> &mut Self94     fn set_make_dir_if_needed(&mut self, make_dir_if_needed: bool) -> &mut Self;
95 
set_discard_if_corrupted(&mut self, discard_if_corrupted: bool) -> &mut Self96     fn set_discard_if_corrupted(&mut self, discard_if_corrupted: bool) -> &mut Self;
97 
open(&self, path: &Path) -> Result<Self::Environment, Self::Error>98     fn open(&self, path: &Path) -> Result<Self::Environment, Self::Error>;
99 }
100 
101 pub trait BackendEnvironment<'e>: Debug {
102     type Error: BackendError;
103     type Database: BackendDatabase;
104     type Flags: BackendDatabaseFlags;
105     type Stat: BackendStat;
106     type Info: BackendInfo;
107     type RoTransaction: BackendRoCursorTransaction<'e, Database = Self::Database>;
108     type RwTransaction: BackendRwCursorTransaction<'e, Database = Self::Database>;
109 
get_dbs(&self) -> Result<Vec<Option<String>>, Self::Error>110     fn get_dbs(&self) -> Result<Vec<Option<String>>, Self::Error>;
111 
open_db(&self, name: Option<&str>) -> Result<Self::Database, Self::Error>112     fn open_db(&self, name: Option<&str>) -> Result<Self::Database, Self::Error>;
113 
create_db(&self, name: Option<&str>, flags: Self::Flags) -> Result<Self::Database, Self::Error>114     fn create_db(&self, name: Option<&str>, flags: Self::Flags) -> Result<Self::Database, Self::Error>;
115 
begin_ro_txn(&'e self) -> Result<Self::RoTransaction, Self::Error>116     fn begin_ro_txn(&'e self) -> Result<Self::RoTransaction, Self::Error>;
117 
begin_rw_txn(&'e self) -> Result<Self::RwTransaction, Self::Error>118     fn begin_rw_txn(&'e self) -> Result<Self::RwTransaction, Self::Error>;
119 
sync(&self, force: bool) -> Result<(), Self::Error>120     fn sync(&self, force: bool) -> Result<(), Self::Error>;
121 
stat(&self) -> Result<Self::Stat, Self::Error>122     fn stat(&self) -> Result<Self::Stat, Self::Error>;
123 
info(&self) -> Result<Self::Info, Self::Error>124     fn info(&self) -> Result<Self::Info, Self::Error>;
125 
freelist(&self) -> Result<usize, Self::Error>126     fn freelist(&self) -> Result<usize, Self::Error>;
127 
load_ratio(&self) -> Result<Option<f32>, Self::Error>128     fn load_ratio(&self) -> Result<Option<f32>, Self::Error>;
129 
set_map_size(&self, size: usize) -> Result<(), Self::Error>130     fn set_map_size(&self, size: usize) -> Result<(), Self::Error>;
131 
get_files_on_disk(&self) -> Vec<PathBuf>132     fn get_files_on_disk(&self) -> Vec<PathBuf>;
133 }
134 
135 pub trait BackendRoTransaction: Debug {
136     type Error: BackendError;
137     type Database: BackendDatabase;
138 
get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>139     fn get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>;
140 
abort(self)141     fn abort(self);
142 }
143 
144 pub trait BackendRwTransaction: Debug {
145     type Error: BackendError;
146     type Database: BackendDatabase;
147     type Flags: BackendWriteFlags;
148 
get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>149     fn get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>;
150 
put(&mut self, db: &Self::Database, key: &[u8], value: &[u8], flags: Self::Flags) -> Result<(), Self::Error>151     fn put(&mut self, db: &Self::Database, key: &[u8], value: &[u8], flags: Self::Flags) -> Result<(), Self::Error>;
152 
153     #[cfg(not(feature = "db-dup-sort"))]
del(&mut self, db: &Self::Database, key: &[u8]) -> Result<(), Self::Error>154     fn del(&mut self, db: &Self::Database, key: &[u8]) -> Result<(), Self::Error>;
155 
156     #[cfg(feature = "db-dup-sort")]
del(&mut self, db: &Self::Database, key: &[u8], value: Option<&[u8]>) -> Result<(), Self::Error>157     fn del(&mut self, db: &Self::Database, key: &[u8], value: Option<&[u8]>) -> Result<(), Self::Error>;
158 
clear_db(&mut self, db: &Self::Database) -> Result<(), Self::Error>159     fn clear_db(&mut self, db: &Self::Database) -> Result<(), Self::Error>;
160 
commit(self) -> Result<(), Self::Error>161     fn commit(self) -> Result<(), Self::Error>;
162 
abort(self)163     fn abort(self);
164 }
165 
166 pub trait BackendRoCursorTransaction<'t>: BackendRoTransaction {
167     type RoCursor: BackendRoCursor<'t>;
168 
open_ro_cursor(&'t self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error>169     fn open_ro_cursor(&'t self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error>;
170 }
171 
172 pub trait BackendRwCursorTransaction<'t>: BackendRwTransaction {
173     type RoCursor: BackendRoCursor<'t>;
174 
open_ro_cursor(&'t self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error>175     fn open_ro_cursor(&'t self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error>;
176 }
177 
178 pub trait BackendRoCursor<'c>: Debug {
179     type Iter: BackendIter<'c>;
180 
into_iter(self) -> Self::Iter181     fn into_iter(self) -> Self::Iter;
182 
into_iter_from<K>(self, key: K) -> Self::Iter where K: AsRef<[u8]> + 'c183     fn into_iter_from<K>(self, key: K) -> Self::Iter
184     where
185         K: AsRef<[u8]> + 'c;
186 
into_iter_dup_of<K>(self, key: K) -> Self::Iter where K: AsRef<[u8]> + 'c187     fn into_iter_dup_of<K>(self, key: K) -> Self::Iter
188     where
189         K: AsRef<[u8]> + 'c;
190 }
191 
192 pub trait BackendIter<'i> {
193     type Error: BackendError;
194 
195     #[allow(clippy::type_complexity)]
next(&mut self) -> Option<Result<(&'i [u8], &'i [u8]), Self::Error>>196     fn next(&mut self) -> Option<Result<(&'i [u8], &'i [u8]), Self::Error>>;
197 }
198