// Copyright 2018-2019 Mozilla // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. use std::{ collections::{BTreeMap, BTreeSet}, sync::Arc, }; use serde_derive::{Deserialize, Serialize}; use super::DatabaseFlagsImpl; type Key = Box<[u8]>; type Value = Box<[u8]>; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Snapshot { flags: DatabaseFlagsImpl, #[cfg(not(feature = "db-dup-sort"))] map: Arc>, #[cfg(feature = "db-dup-sort")] map: Arc>>, } impl Snapshot { pub(crate) fn new(flags: Option) -> Snapshot { Snapshot { flags: flags.unwrap_or_default(), map: Default::default(), } } pub(crate) fn flags(&self) -> &DatabaseFlagsImpl { &self.flags } pub(crate) fn clear(&mut self) { self.map = Default::default(); } } #[cfg(not(feature = "db-dup-sort"))] impl Snapshot { pub(crate) fn get(&self, key: &[u8]) -> Option<&[u8]> { self.map.get(key).map(|value| value.as_ref()) } pub(crate) fn put(&mut self, key: &[u8], value: &[u8]) { let map = Arc::make_mut(&mut self.map); map.insert(Box::from(key), Box::from(value)); } pub(crate) fn del(&mut self, key: &[u8]) -> Option<()> { let map = Arc::make_mut(&mut self.map); map.remove(key).map(|_| ()) } pub(crate) fn iter(&self) -> impl Iterator { self.map .iter() .map(|(key, value)| (key.as_ref(), value.as_ref())) } } #[cfg(feature = "db-dup-sort")] impl Snapshot { pub(crate) fn get(&self, key: &[u8]) -> Option<&[u8]> { self.map .get(key) .and_then(|v| v.iter().next()) .map(|v| v.as_ref()) } pub(crate) fn put(&mut self, key: &[u8], value: &[u8]) { let map = Arc::make_mut(&mut self.map); match map.get_mut(key) { None => { let mut values = BTreeSet::new(); values.insert(Box::from(value)); map.insert(Box::from(key), values); } Some(values) => { values.clear(); values.insert(Box::from(value)); } } } pub(crate) fn del(&mut self, key: &[u8]) -> Option<()> { let map = Arc::make_mut(&mut self.map); match map.get_mut(key) { None => None, Some(values) => { let was_empty = values.is_empty(); values.clear(); Some(()).filter(|_| !was_empty) } } } pub(crate) fn iter(&self) -> impl Iterator)> { self.map .iter() .map(|(key, values)| (key.as_ref(), values.iter().map(|value| value.as_ref()))) } } #[cfg(feature = "db-dup-sort")] impl Snapshot { pub(crate) fn put_dup(&mut self, key: &[u8], value: &[u8]) { let map = Arc::make_mut(&mut self.map); match map.get_mut(key) { None => { let mut values = BTreeSet::new(); values.insert(Box::from(value)); map.insert(Box::from(key), values); } Some(values) => { values.insert(Box::from(value)); } } } pub(crate) fn del_exact(&mut self, key: &[u8], value: &[u8]) -> Option<()> { let map = Arc::make_mut(&mut self.map); match map.get_mut(key) { None => None, Some(values) => { let was_removed = values.remove(value); Some(()).filter(|_| was_removed) } } } }