Revision control
Copy as Markdown
Other Tools
// 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
// 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<BTreeMap<Key, Value>>,
#[cfg(feature = "db-dup-sort")]
map: Arc<BTreeMap<Key, BTreeSet<Value>>>,
}
impl Snapshot {
pub(crate) fn new(flags: Option<DatabaseFlagsImpl>) -> 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<Item = (&[u8], &[u8])> {
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<Item = (&[u8], impl Iterator<Item = &[u8]>)> {
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)
}
}
}
}