Skip to content

Commit

Permalink
closes #1
Browse files Browse the repository at this point in the history
  • Loading branch information
marvin-j97 committed Jun 9, 2024
1 parent 03c74ab commit 0c8e8ad
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Generic value log implementation for key-value separated storage, inspired by Ro
- 100% safe & stable Rust
- Supports generic KV-index structures (LSM-tree, ...)
- Built-in per-blob compression (LZ4)
- In-memory blob cache for hot data
- In-memory blob cache for hot data, that can be shared between multiple value logs

Keys are limited to 65536 bytes, values are limited to 2^32 bytes.

Expand Down
28 changes: 21 additions & 7 deletions src/blob_cache.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
use crate::{value::UserValue, ValueHandle};
use quick_cache::{sync::Cache, Weighter};
use crate::{value::UserValue, value_log::ValueLogId, ValueHandle};
use quick_cache::{sync::Cache, Equivalent, Weighter};

type CacheKey = ValueHandle;
type Item = UserValue;

#[derive(Eq, std::hash::Hash, PartialEq)]
pub struct CacheKey(ValueLogId, ValueHandle);

impl Equivalent<CacheKey> for (ValueLogId, ValueHandle) {
fn equivalent(&self, key: &CacheKey) -> bool {
self.0 == key.0 && self.1 == key.1
}
}

impl From<(ValueLogId, ValueHandle)> for CacheKey {
fn from((vid, handle): (ValueLogId, ValueHandle)) -> Self {
Self(vid, handle)
}
}

#[derive(Clone)]
struct BlobWeighter;

Expand Down Expand Up @@ -42,15 +56,15 @@ impl BlobCache {
}
}

pub(crate) fn insert(&self, handle: CacheKey, value: UserValue) {
pub(crate) fn insert(&self, key: CacheKey, value: UserValue) {
if self.capacity > 0 {
self.data.insert(handle, value);
self.data.insert(key, value);
}
}

pub(crate) fn get(&self, handle: &CacheKey) -> Option<Item> {
pub(crate) fn get(&self, key: &CacheKey) -> Option<Item> {
if self.capacity > 0 {
self.data.get(handle)
self.data.get(key)
} else {
None
}
Expand Down
5 changes: 4 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ impl Default for Config {
impl Config {
/// Sets the blob cache.
///
/// Defaults to a blob cache with 16 MiB of capacity.
/// You can create a global [`BlobCache`] and share it between multiple
/// value logs to cap global cache memory usage.
///
/// Defaults to a blob cache with 16 MiB of capacity *per value log*.
#[must_use]
pub fn blob_cache(mut self, blob_cache: Arc<BlobCache>) -> Self {
self.blob_cache = blob_cache;
Expand Down
21 changes: 18 additions & 3 deletions src/value_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,19 @@ use std::{
fs::File,
io::{BufReader, Read, Seek},
path::PathBuf,
sync::{Arc, Mutex},
sync::{atomic::AtomicU64, Arc, Mutex},
};

/// Unique value log ID
#[allow(clippy::module_name_repetitions)]
pub type ValueLogId = u64;

/// Hands out a unique (monotonically increasing) value log ID
pub fn get_next_vlog_id() -> ValueLogId {
static VLOG_ID_COUNTER: AtomicU64 = AtomicU64::new(0);
VLOG_ID_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
}

/// A disk-resident value log
#[derive(Clone)]
pub struct ValueLog(Arc<ValueLogInner>);
Expand All @@ -32,6 +42,8 @@ impl std::ops::Deref for ValueLog {

#[allow(clippy::module_name_repetitions)]
pub struct ValueLogInner {
id: u64,

config: Config,

path: PathBuf,
Expand Down Expand Up @@ -100,6 +112,7 @@ impl ValueLog {
let manifest = SegmentManifest::create_new(&path)?;

Ok(Self(Arc::new(ValueLogInner {
id: get_next_vlog_id(),
config,
path,
blob_cache,
Expand Down Expand Up @@ -138,6 +151,7 @@ impl ValueLog {
.unwrap_or_default();

Ok(Self(Arc::new(ValueLogInner {
id: get_next_vlog_id(),
config,
path,
blob_cache,
Expand Down Expand Up @@ -172,7 +186,7 @@ impl ValueLog {
return Ok(None);
};

if let Some(value) = self.blob_cache.get(handle) {
if let Some(value) = self.blob_cache.get(&((self.id, handle.clone()).into())) {
return Ok(Some(value));
}

Expand All @@ -193,7 +207,8 @@ impl ValueLog {

let val: UserValue = val.into();

self.blob_cache.insert(handle.clone(), val.clone());
self.blob_cache
.insert((self.id, handle.clone()).into(), val.clone());

Ok(Some(val))
}
Expand Down

0 comments on commit 0c8e8ad

Please sign in to comment.