Prevent needless key/value copies in database methods

Signed-off-by: Victor Porof <victor.porof@gmail.com>
without.crypto
Victor Porof 5 years ago
parent 7717f49841
commit 3fe8f2eccc
  1. 3
      Cargo.toml
  2. 45
      src/backend/impl_safe/database.rs

@ -16,7 +16,7 @@ exclude = ["/tests/envs/*"]
[features]
default = ["with-safe-mode"]
backtrace = ["failure/backtrace", "failure/std"]
with-safe-mode = ["id-arena", "log", "serde/derive", "serde/rc"]
with-safe-mode = ["hashbrown/serde", "id-arena", "log", "serde/derive", "serde/rc"]
with-asan = ["lmdb-rkv/with-asan"]
with-fuzzer = ["lmdb-rkv/with-fuzzer"]
with-fuzzer-no-link = ["lmdb-rkv/with-fuzzer-no-link"]
@ -26,6 +26,7 @@ arrayref = "0.3"
bincode = "1.0"
bitflags = "1"
byteorder = "1"
hashbrown = { version = "0.6", optional = true }
id-arena = { version = "2.2", optional = true }
lazy_static = "1.0"
lmdb-rkv = "0.12.3"

@ -8,12 +8,11 @@
// 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::{
BTreeSet,
HashMap,
};
use std::collections::BTreeSet;
use std::sync::Arc;
use hashbrown::hash_map::RawEntryMut;
use hashbrown::HashMap;
use id_arena::Id;
use serde_derive::{
Deserialize,
@ -75,35 +74,49 @@ impl Snapshot {
pub(crate) fn put_one(&mut self, key: &[u8], value: &[u8]) {
let map = Arc::make_mut(&mut self.map);
let values = map.entry(Box::from(key)).or_insert_with(BTreeSet::new);
values.clear();
let entry = map.raw_entry_mut().from_key(key);
let (_, values) = entry.and_modify(|_, v| v.clear()).or_insert_with(|| (Box::from(key), BTreeSet::new()));
values.insert(Box::from(value));
}
pub(crate) fn put_dup(&mut self, key: &[u8], value: &[u8]) {
let map = Arc::make_mut(&mut self.map);
let values = map.entry(Box::from(key)).or_insert_with(BTreeSet::new);
let entry = map.raw_entry_mut().from_key(key);
let (_, values) = entry.or_insert_with(|| (Box::from(key), BTreeSet::new()));
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);
let values = map.entry(Box::from(key)).or_insert_with(BTreeSet::new);
let was_removed = values.remove(value);
Some(()).filter(|_| was_removed)
let entry = map.raw_entry_mut().from_key(key);
match entry {
RawEntryMut::Vacant(_) => None,
RawEntryMut::Occupied(mut entry) => {
let values = entry.get_mut();
let was_removed = values.remove(value);
Some(()).filter(|_| was_removed)
},
}
}
pub(crate) fn del_all(&mut self, key: &[u8]) -> Option<()> {
let map = Arc::make_mut(&mut self.map);
let values = map.entry(Box::from(key)).or_insert_with(BTreeSet::new);
let was_empty = values.is_empty();
values.clear();
Some(()).filter(|_| !was_empty)
let entry = map.raw_entry_mut().from_key(key);
match entry {
RawEntryMut::Vacant(_) => None,
RawEntryMut::Occupied(mut entry) => {
let values = entry.get_mut();
let was_empty = values.is_empty();
values.clear();
Some(()).filter(|_| !was_empty)
},
}
}
pub(crate) fn clear(&mut self) {
let map = Arc::make_mut(&mut self.map);
map.clear();
self.map = Default::default();
}
pub(crate) fn iter(&self) -> impl Iterator<Item = (&[u8], &[u8])> {

Loading…
Cancel
Save