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