diff --git a/foyer-common/src/code.rs b/foyer-common/src/code.rs index ae4826e6..fb47b794 100644 --- a/foyer-common/src/code.rs +++ b/foyer-common/src/code.rs @@ -25,13 +25,23 @@ impl Key for T {} impl Value for T {} /// Key trait for the disk cache. -pub trait StorageKey: Key + Serialize + DeserializeOwned {} -impl StorageKey for T where T: Key + Serialize + DeserializeOwned {} +pub trait StorageKey: Key + Serialize + DeserializeOwned + Hint {} +impl StorageKey for T where T: Key + Serialize + DeserializeOwned + Hint {} /// Value trait for the disk cache. -pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned {} -impl StorageValue for T where T: Value + Serialize + DeserializeOwned {} +pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned + Hint {} +impl StorageValue for T where T: Value + Serialize + DeserializeOwned + Hint {} /// Hash builder trait. pub trait HashBuilder: BuildHasher + Send + Sync + 'static {} impl HashBuilder for T where T: BuildHasher + Send + Sync + 'static {} + +/// Hint functions collection. +pub trait Hint { + /// Size hint for serialization. + fn serialized_size_hint(&self) -> usize { + 0 + } +} + +impl Hint for T {} diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index 89642226..93a87f38 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -94,6 +94,17 @@ impl EntrySerializer { Ok(KvInfo { key_len, value_len }) } + + pub fn size_hint<'a, K, V>(key: &'a K, value: &'a V, compression: &'a Compression) -> usize + where + K: StorageKey, + V: StorageValue, + { + match compression { + Compression::Zstd | Compression::Lz4 => 0, + Compression::None => key.serialized_size_hint() + value.serialized_size_hint(), + } + } } #[derive(Debug)] diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 5c9d804a..5293e1ad 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -144,7 +144,8 @@ where self.inner.write_runtime_handle.spawn(async move { if force || this.pick(entry.key()) { - let mut buffer = IoBytesMut::new(); + let mut buffer = + IoBytesMut::with_capacity(EntrySerializer::size_hint(entry.key(), entry.value(), &compression)); match EntrySerializer::serialize( entry.key(), entry.value(),