Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ fvm_ipld_encoding = "0.5.3"
fvm_shared2 = { package = "fvm_shared", version = "~2.11" }
fvm_shared3 = { package = "fvm_shared", version = "~3.13", features = ["proofs"] }
fvm_shared4 = { package = "fvm_shared", version = "~4.7", features = ["proofs"] }
get-size2 = { version = "0.5", features = ["derive"] }
gethostname = "1"
git-version = "0.3"
group = "0.13"
Expand Down
57 changes: 15 additions & 42 deletions src/db/blockstore_with_read_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@

use cid::Cid;
use fvm_ipld_blockstore::Blockstore;
use lru::LruCache;
use parking_lot::Mutex;
use std::{
num::NonZeroUsize,
sync::{
Arc,
atomic::{self, AtomicUsize},
},
use std::sync::{
Arc,
atomic::{self, AtomicUsize},
};

use crate::utils::{cache::SizeTrackingLruCache, get_size};

pub trait BlockstoreReadCache {
fn get(&self, k: &Cid) -> Option<Vec<u8>>;

Expand All @@ -23,50 +20,23 @@ pub trait BlockstoreReadCache {
fn size_in_bytes(&self) -> usize;
}

pub struct LruBlockstoreReadCache {
lru: Mutex<LruCache<Cid, Vec<u8>>>,
size_in_bytes: AtomicUsize,
}

impl LruBlockstoreReadCache {
pub fn new(cap: NonZeroUsize) -> Self {
Self {
lru: Mutex::new(LruCache::new(cap)),
size_in_bytes: AtomicUsize::default(),
}
}
}
pub type LruBlockstoreReadCache = SizeTrackingLruCache<get_size::CidWrapper, Vec<u8>>;

impl BlockstoreReadCache for LruBlockstoreReadCache {
impl BlockstoreReadCache for SizeTrackingLruCache<get_size::CidWrapper, Vec<u8>> {
fn get(&self, k: &Cid) -> Option<Vec<u8>> {
self.lru.lock().get(k).cloned()
self.get_cloned(&get_size::CidWrapper(*k))
}

fn put(&self, k: Cid, block: Vec<u8>) {
let block_size = block.len();
if let Some((_, old_block)) = self.lru.lock().push(k, block) {
let old_block_size = old_block.len();
if block_size >= old_block_size {
self.size_in_bytes
.fetch_add(block_size - old_block_size, atomic::Ordering::Relaxed);
} else {
self.size_in_bytes
.fetch_sub(old_block_size - block_size, atomic::Ordering::Relaxed);
}
} else {
self.size_in_bytes.fetch_add(
std::mem::size_of::<Cid>() + block_size,
atomic::Ordering::Relaxed,
);
}
self.push(k.into(), block);
}

fn len(&self) -> usize {
self.lru.lock().len()
self.len()
}

fn size_in_bytes(&self) -> usize {
self.size_in_bytes.load(atomic::Ordering::Relaxed)
self.size_in_bytes()
}
}

Expand Down Expand Up @@ -213,7 +183,10 @@ mod tests {
mem_db.put_keyed(&key, &record).unwrap();
records.push((key, record));
}
let cache = Arc::new(LruBlockstoreReadCache::new(CACHE_SIZE.try_into().unwrap()));
let cache = Arc::new(LruBlockstoreReadCache::new_without_metrics_registry(
"test_blockstore_read_cache".into(),
CACHE_SIZE.try_into().unwrap(),
));
let db = BlockstoreWithReadCache::new(
mem_db.clone(),
cache.clone(),
Expand Down
11 changes: 6 additions & 5 deletions src/rpc/methods/f3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use crate::{
chain::index::ResolveNullTipset,
chain_sync::TipsetValidator,
db::{
BlockstoreReadCache as _, BlockstoreReadCacheStats as _, BlockstoreWithReadCache,
DefaultBlockstoreReadCacheStats, LruBlockstoreReadCache,
BlockstoreReadCacheStats as _, BlockstoreWithReadCache, DefaultBlockstoreReadCacheStats,
LruBlockstoreReadCache,
},
libp2p::{NetRPCMethods, NetworkMessage},
lotus_json::HasLotusJson as _,
Expand Down Expand Up @@ -166,10 +166,11 @@ impl GetPowerTable {
) -> anyhow::Result<Vec<F3PowerEntry>> {
// The RAM overhead on mainnet is ~14MiB
const BLOCKSTORE_CACHE_CAP: usize = 65536;
static BLOCKSTORE_CACHE: LazyLock<Arc<LruBlockstoreReadCache>> = LazyLock::new(|| {
Arc::new(LruBlockstoreReadCache::new(
static BLOCKSTORE_CACHE: LazyLock<LruBlockstoreReadCache> = LazyLock::new(|| {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example of usage

LruBlockstoreReadCache::new_with_default_metrics_registry(
"get_powertable_cache".into(),
BLOCKSTORE_CACHE_CAP.try_into().expect("Infallible"),
))
)
});
let db = BlockstoreWithReadCache::new(
ctx.store_owned(),
Expand Down
Loading
Loading