Added backend options as features.
This commit is contained in:
@@ -24,6 +24,11 @@ utils = { path = "crates/utils" }
|
|||||||
tokio = { version = "1.23", features = ["full"] }
|
tokio = { version = "1.23", features = ["full"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["sqlite"]
|
||||||
|
sqlite = ["store/sqlite"]
|
||||||
|
foundationdb = ["store/foundation"]
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"crates/jmap",
|
"crates/jmap",
|
||||||
|
|||||||
@@ -33,13 +33,11 @@ num_cpus = { version = "1.15.0", optional = true }
|
|||||||
blake3 = "1.3.3"
|
blake3 = "1.3.3"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["foundation"]
|
rocks = ["rocksdb", "rayon", "is_sync", "backend"]
|
||||||
rocks = ["rocksdb", "rayon", "is_sync"]
|
sqlite = ["rusqlite", "rayon", "r2d2", "num_cpus", "is_sync", "backend"]
|
||||||
sqlite = ["rusqlite", "rayon", "r2d2", "num_cpus", "is_sync"]
|
foundation = ["foundationdb", "futures", "key_subspace", "backend"]
|
||||||
foundation = ["foundationdb", "futures", "is_async", "key_subspace"]
|
|
||||||
is_sync = ["maybe-async/is_sync", "lru-cache"]
|
is_sync = ["maybe-async/is_sync", "lru-cache"]
|
||||||
is_async = []
|
backend = []
|
||||||
key_subspace = []
|
key_subspace = []
|
||||||
test_mode = []
|
test_mode = []
|
||||||
|
|||||||
@@ -78,6 +78,17 @@ pub struct ReadTransaction<'x> {
|
|||||||
_p: std::marker::PhantomData<&'x ()>,
|
_p: std::marker::PhantomData<&'x ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "backend"))]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct Store {
|
||||||
|
blob: BlobStore,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "backend"))]
|
||||||
|
pub struct ReadTransaction<'x> {
|
||||||
|
_db: &'x [u8],
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Deserialize: Sized + Sync + Send {
|
pub trait Deserialize: Sized + Sync + Send {
|
||||||
fn deserialize(bytes: &[u8]) -> crate::Result<Self>;
|
fn deserialize(bytes: &[u8]) -> crate::Result<Self>;
|
||||||
}
|
}
|
||||||
@@ -218,3 +229,125 @@ pub const SUBSPACE_BITMAPS: u8 = b'b';
|
|||||||
pub const SUBSPACE_VALUES: u8 = b'v';
|
pub const SUBSPACE_VALUES: u8 = b'v';
|
||||||
pub const SUBSPACE_LOGS: u8 = b'l';
|
pub const SUBSPACE_LOGS: u8 = b'l';
|
||||||
pub const SUBSPACE_INDEXES: u8 = b'i';
|
pub const SUBSPACE_INDEXES: u8 = b'i';
|
||||||
|
|
||||||
|
#[cfg(not(feature = "backend"))]
|
||||||
|
impl Store {
|
||||||
|
pub async fn open(_config: &utils::config::Config) -> crate::Result<Self> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn purge_bitmaps(&self) -> crate::Result<()> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn purge_account(&self, _account_id: u32) -> crate::Result<()> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_transaction(&self) -> crate::Result<ReadTransaction<'_>> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn write(&self, _batch: write::Batch) -> crate::Result<()> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn assign_document_id(
|
||||||
|
&self,
|
||||||
|
_account_id: u32,
|
||||||
|
_collection: impl Into<u8>,
|
||||||
|
) -> crate::Result<u32> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn assign_change_id(&self, _account_id: u32) -> crate::Result<u64> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "test_mode")]
|
||||||
|
pub async fn destroy(&self) {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "test_mode")]
|
||||||
|
pub async fn assert_is_empty(&self) {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "backend"))]
|
||||||
|
impl ReadTransaction<'_> {
|
||||||
|
pub async fn get_value<U>(&self, _key: impl Key) -> crate::Result<Option<U>>
|
||||||
|
where
|
||||||
|
U: Deserialize,
|
||||||
|
{
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_bitmap<T: AsRef<[u8]>>(
|
||||||
|
&self,
|
||||||
|
_key: BitmapKey<T>,
|
||||||
|
) -> crate::Result<Option<roaring::RoaringBitmap>> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_bitmaps_intersection<T: AsRef<[u8]>>(
|
||||||
|
&self,
|
||||||
|
_keys: Vec<BitmapKey<T>>,
|
||||||
|
) -> crate::Result<Option<roaring::RoaringBitmap>> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_bitmaps_union<T: AsRef<[u8]>>(
|
||||||
|
&self,
|
||||||
|
_keys: Vec<BitmapKey<T>>,
|
||||||
|
) -> crate::Result<Option<roaring::RoaringBitmap>> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn range_to_bitmap(
|
||||||
|
&self,
|
||||||
|
_account_id: u32,
|
||||||
|
_collection: u8,
|
||||||
|
_field: u8,
|
||||||
|
_value: Vec<u8>,
|
||||||
|
_op: query::Operator,
|
||||||
|
) -> crate::Result<Option<roaring::RoaringBitmap>> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn sort_index(
|
||||||
|
&self,
|
||||||
|
_account_id: u32,
|
||||||
|
_collection: u8,
|
||||||
|
_field: u8,
|
||||||
|
_ascending: bool,
|
||||||
|
_cb: impl FnMut(&[u8], u32) -> bool,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn iterate<T>(
|
||||||
|
&self,
|
||||||
|
_acc: T,
|
||||||
|
_begin: impl Key,
|
||||||
|
_end: impl Key,
|
||||||
|
_first: bool,
|
||||||
|
_ascending: bool,
|
||||||
|
_cb: impl Fn(&mut T, &[u8], &[u8]) -> crate::Result<bool> + Sync + Send + 'static,
|
||||||
|
) -> crate::Result<T> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_last_change_id(
|
||||||
|
&self,
|
||||||
|
_account_id: u32,
|
||||||
|
_collection: u8,
|
||||||
|
) -> crate::Result<Option<u64>> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn refresh_if_old(&mut self) -> crate::Result<()> {
|
||||||
|
unimplemented!("No backend selected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ impl Store {
|
|||||||
filters: Vec<Filter>,
|
filters: Vec<Filter>,
|
||||||
) -> crate::Result<ResultSet> {
|
) -> crate::Result<ResultSet> {
|
||||||
let collection = collection.into();
|
let collection = collection.into();
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
self.read_transaction()
|
self.read_transaction()
|
||||||
.await?
|
.await?
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ impl Store {
|
|||||||
where
|
where
|
||||||
U: Deserialize + 'static,
|
U: Deserialize + 'static,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
self.read_transaction().await?.get_value(key).await
|
self.read_transaction().await?.get_value(key).await
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ impl Store {
|
|||||||
where
|
where
|
||||||
U: Deserialize + 'static,
|
U: Deserialize + 'static,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
let mut trx = self.read_transaction().await?;
|
let mut trx = self.read_transaction().await?;
|
||||||
let mut results = Vec::with_capacity(key.len());
|
let mut results = Vec::with_capacity(key.len());
|
||||||
@@ -81,7 +81,7 @@ impl Store {
|
|||||||
) -> crate::Result<Option<u64>> {
|
) -> crate::Result<Option<u64>> {
|
||||||
let collection = collection.into();
|
let collection = collection.into();
|
||||||
|
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
self.read_transaction()
|
self.read_transaction()
|
||||||
.await?
|
.await?
|
||||||
@@ -101,7 +101,7 @@ impl Store {
|
|||||||
&self,
|
&self,
|
||||||
key: BitmapKey<T>,
|
key: BitmapKey<T>,
|
||||||
) -> crate::Result<Option<RoaringBitmap>> {
|
) -> crate::Result<Option<RoaringBitmap>> {
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
self.read_transaction().await?.get_bitmap(key).await
|
self.read_transaction().await?.get_bitmap(key).await
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ impl Store {
|
|||||||
ascending: bool,
|
ascending: bool,
|
||||||
cb: impl Fn(&mut T, &[u8], &[u8]) -> crate::Result<bool> + Sync + Send + 'static,
|
cb: impl Fn(&mut T, &[u8], &[u8]) -> crate::Result<bool> + Sync + Send + 'static,
|
||||||
) -> crate::Result<T> {
|
) -> crate::Result<T> {
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
self.read_transaction()
|
self.read_transaction()
|
||||||
.await?
|
.await?
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ impl Store {
|
|||||||
(a, b) => std::cmp::min(a as usize, b),
|
(a, b) => std::cmp::min(a as usize, b),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "is_async")]
|
#[cfg(not(feature = "is_sync"))]
|
||||||
{
|
{
|
||||||
self.read_transaction()
|
self.read_transaction()
|
||||||
.await?
|
.await?
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["sqlite"]
|
||||||
|
sqlite = ["store/sqlite"]
|
||||||
|
foundationdb = ["store/foundation"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
store = { path = "../crates/store", features = ["test_mode"] }
|
store = { path = "../crates/store", features = ["test_mode"] }
|
||||||
jmap = { path = "../crates/jmap", features = ["test_mode"] }
|
jmap = { path = "../crates/jmap", features = ["test_mode"] }
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ use store::{write::BatchBuilder, Store};
|
|||||||
pub async fn test(db: Arc<Store>) {
|
pub async fn test(db: Arc<Store>) {
|
||||||
println!("Running Store ID assignment tests...");
|
println!("Running Store ID assignment tests...");
|
||||||
|
|
||||||
store::backend::foundationdb::write::ID_ASSIGNMENT_EXPIRY
|
/*store::backend::foundationdb::write::ID_ASSIGNMENT_EXPIRY
|
||||||
.store(2, std::sync::atomic::Ordering::Relaxed);
|
.store(2, std::sync::atomic::Ordering::Relaxed);*/
|
||||||
|
|
||||||
test_1(db.clone()).await;
|
test_1(db.clone()).await;
|
||||||
test_2(db.clone()).await;
|
test_2(db.clone()).await;
|
||||||
test_3(db.clone()).await;
|
test_3(db.clone()).await;
|
||||||
test_4(db).await;
|
test_4(db).await;
|
||||||
|
|
||||||
store::backend::foundationdb::write::ID_ASSIGNMENT_EXPIRY
|
/*store::backend::foundationdb::write::ID_ASSIGNMENT_EXPIRY
|
||||||
.store(60 * 60, std::sync::atomic::Ordering::Relaxed);
|
.store(60 * 60, std::sync::atomic::Ordering::Relaxed);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test_1(db: Arc<Store>) {
|
async fn test_1(db: Arc<Store>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user