aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-06-02 18:11:32 +0200
committerAlex Auvolat <alex@adnab.me>2022-06-02 18:11:32 +0200
commitf29b91232fbacc0c552fbbec52f5b2cf20cdcf8d (patch)
treed022409e23a6eaefb1960396d1b5bd231fc6c0a7
parentfbd5b64ff3c0da95a2ae96b1f830d2ed7dc4c5a8 (diff)
downloadgarage-f29b91232fbacc0c552fbbec52f5b2cf20cdcf8d.tar.gz
garage-f29b91232fbacc0c552fbbec52f5b2cf20cdcf8d.zip
Use Cell instead of ArcSwap
-rw-r--r--Cargo.lock1
-rw-r--r--src/db/Cargo.toml1
-rw-r--r--src/db/lib.rs28
-rw-r--r--src/db/sled_adapter.rs40
4 files changed, 27 insertions, 43 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f1063c3b..05f48c37 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -991,7 +991,6 @@ dependencies = [
name = "garage_db"
version = "0.8.0"
dependencies = [
- "arc-swap",
"err-derive 0.3.1",
"mktemp",
"sled",
diff --git a/src/db/Cargo.toml b/src/db/Cargo.toml
index 025016d5..ae6cb45f 100644
--- a/src/db/Cargo.toml
+++ b/src/db/Cargo.toml
@@ -15,7 +15,6 @@ path = "lib.rs"
[dependencies]
err-derive = "0.3"
-arc-swap = "1.0"
sled = "0.34"
diff --git a/src/db/lib.rs b/src/db/lib.rs
index c3e89ba4..2b9b6bd7 100644
--- a/src/db/lib.rs
+++ b/src/db/lib.rs
@@ -6,9 +6,9 @@ pub mod test;
use core::ops::{Bound, RangeBounds};
use std::borrow::Cow;
+use std::cell::Cell;
use std::sync::Arc;
-use arc_swap::ArcSwapOption;
use err_derive::Error;
#[derive(Clone)]
@@ -25,7 +25,7 @@ pub type ValueIter<'a> =
Box<dyn std::iter::Iterator<Item = Result<(Value<'a>, Value<'a>)>> + Send + Sync + 'a>;
pub type Exporter<'a> =
- Box<dyn std::iter::Iterator<Item=Result<(String, ValueIter<'a>)>> + Send + Sync + 'a>;
+ Box<dyn std::iter::Iterator<Item = Result<(String, ValueIter<'a>)>> + Send + Sync + 'a>;
// ----
@@ -59,30 +59,26 @@ impl Db {
pub fn transaction<R, E, F>(&self, fun: F) -> TxResult<R, E>
where
F: Fn(Transaction<'_>) -> TxResult<R, E>,
- R: Send + Sync,
- E: Send + Sync,
{
let f = TxFn {
function: fun,
- result: ArcSwapOption::new(None),
+ result: Cell::new(None),
};
match self.0.transaction(&f) {
Err(TxError::Db(e)) => Err(TxError::Db(e)),
Err(TxError::Abort(())) => {
- let r_arc = f
+ let r = f
.result
.into_inner()
.expect("Transaction did not store result");
- let r = Arc::try_unwrap(r_arc).ok().expect("Many refs");
assert!(matches!(r, Err(TxError::Abort(_))));
r
}
Ok(()) => {
- let r_arc = f
+ let r = f
.result
.into_inner()
.expect("Transaction did not store result");
- let r = Arc::try_unwrap(r_arc).ok().expect("Many refs");
assert!(matches!(r, Ok(_)));
r
}
@@ -186,18 +182,12 @@ impl<'a> Transaction<'a> {
#[must_use]
pub fn abort<R, E>(self, e: E) -> TxResult<R, E>
- where
- R: Send + Sync,
- E: Send + Sync,
{
Err(TxError::Abort(e))
}
#[must_use]
pub fn commit<R, E>(self, r: R) -> TxResult<R, E>
- where
- R: Send + Sync,
- E: Send + Sync,
{
Ok(r)
}
@@ -270,18 +260,14 @@ enum TxFnResult {
struct TxFn<F, R, E>
where
F: Fn(Transaction<'_>) -> TxResult<R, E>,
- R: Send + Sync,
- E: Send + Sync,
{
function: F,
- result: ArcSwapOption<TxResult<R, E>>,
+ result: Cell<Option<TxResult<R, E>>>,
}
impl<F, R, E> ITxFn for TxFn<F, R, E>
where
F: Fn(Transaction<'_>) -> TxResult<R, E>,
- R: Send + Sync,
- E: Send + Sync,
{
fn try_on<'a>(&'a self, tx: &'a dyn ITx<'a>) -> TxFnResult {
let res = (self.function)(Transaction(tx));
@@ -290,7 +276,7 @@ where
Err(TxError::Abort(_)) => TxFnResult::Abort,
Err(TxError::Db(_)) => TxFnResult::Err,
};
- self.result.store(Some(Arc::new(res)));
+ self.result.set(Some(res));
retval
}
}
diff --git a/src/db/sled_adapter.rs b/src/db/sled_adapter.rs
index 9ee9ea58..3942317c 100644
--- a/src/db/sled_adapter.rs
+++ b/src/db/sled_adapter.rs
@@ -1,16 +1,17 @@
use core::ops::Bound;
+use std::cell::Cell;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
-use arc_swap::ArcSwapOption;
-
use sled::transaction::{
ConflictableTransactionError, TransactionError, Transactional, TransactionalTree,
UnabortableTransactionError,
};
-use crate::{Db, Error, IDb, ITx, ITxFn, Result, TxError, TxFnResult, TxResult, Value, ValueIter, Exporter};
+use crate::{
+ Db, Error, Exporter, IDb, ITx, ITxFn, Result, TxError, TxFnResult, TxResult, Value, ValueIter,
+};
pub use sled;
@@ -47,20 +48,20 @@ impl SledDb {
pub fn export<'a>(&'a self) -> Result<Exporter<'a>> {
let mut trees = vec![];
for name in self.db.tree_names() {
- let name = std::str::from_utf8(&name).map_err(|e| Error(format!("{}", e).into()))?.to_string();
+ let name = std::str::from_utf8(&name)
+ .map_err(|e| Error(format!("{}", e).into()))?
+ .to_string();
let tree = self.open_tree(&name)?;
let tree = self.trees.read().unwrap().0.get(tree).unwrap().clone();
trees.push((name, tree));
}
- let trees_exporter: Exporter<'a> = Box::new(trees
- .into_iter()
- .map(|(name, tree)| {
- let iter: ValueIter<'a> = Box::new(tree.iter().map(|v| {
- v.map(|(x, y)| (x.to_vec().into(), y.to_vec().into()))
- .map_err(Into::into)
- }));
- Ok((name.to_string(), iter))
+ let trees_exporter: Exporter<'a> = Box::new(trees.into_iter().map(|(name, tree)| {
+ let iter: ValueIter<'a> = Box::new(tree.iter().map(|v| {
+ v.map(|(x, y)| (x.to_vec().into(), y.to_vec().into()))
+ .map_err(Into::into)
}));
+ Ok((name.to_string(), iter))
+ }));
Ok(trees_exporter)
}
@@ -172,7 +173,7 @@ impl IDb for SledDb {
let res = trees.0.transaction(|txtrees| {
let tx = SledTx {
trees: txtrees,
- err: ArcSwapOption::new(None),
+ err: Cell::new(None),
};
match f.try_on(&tx) {
TxFnResult::Ok => {
@@ -184,11 +185,10 @@ impl IDb for SledDb {
Err(ConflictableTransactionError::Abort(()))
}
TxFnResult::Err => {
- let err_arc = tx
+ let err = tx
.err
.into_inner()
.expect("Transaction did not store error");
- let err = Arc::try_unwrap(err_arc).ok().expect("Many refs");
Err(err.into())
}
}
@@ -205,14 +205,14 @@ impl IDb for SledDb {
struct SledTx<'a> {
trees: &'a [TransactionalTree],
- err: ArcSwapOption<UnabortableTransactionError>,
+ err: Cell<Option<UnabortableTransactionError>>,
}
impl<'a> SledTx<'a> {
fn get_tree(&self, i: usize) -> Result<&TransactionalTree> {
- self.trees
- .get(i)
- .ok_or(Error("invalid tree id (it might have been openned after the transaction started)".into()))
+ self.trees.get(i).ok_or(Error(
+ "invalid tree id (it might have been openned after the transaction started)".into(),
+ ))
}
fn save_error<R>(&self, v: std::result::Result<R, UnabortableTransactionError>) -> Result<R> {
@@ -220,7 +220,7 @@ impl<'a> SledTx<'a> {
Ok(x) => Ok(x),
Err(e) => {
let txt = format!("{}", e);
- self.err.store(Some(Arc::new(e)));
+ self.err.set(Some(e));
Err(Error(txt.into()))
}
}