Comments (5)
ah, i missed that. thanks a lot :)
from moka.
Hi. Thank you for using Moka.
It would not be necessary to expose these APIs. You can write your oun hasher, which simply pass-through the pre-calculated hash value. And then you can give the hasher to the cache. Here is an example:
use std::{
hash::{BuildHasherDefault, Hash, Hasher},
sync::Arc,
};
//
// Define a struct for the key, which holds the key and its hash value.
//
#[derive(Clone, PartialEq, Eq)]
pub struct MyKey {
_key: Arc<Box<[u8]>>,
hash_value: u64,
}
impl MyKey {
pub fn new(key: Box<[u8]>, hash_value: u64) -> Self {
Self {
_key: Arc::new(key),
hash_value,
}
}
}
// Implement Hash. We will only use the pre-calculated hash value.
impl Hash for MyKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.hash_value.hash(state);
}
}
//
// Create a Hasher, which just uses a single u64 value as the final hash.
//
#[derive(Default)]
struct PassthroughHasher(u64);
impl Hasher for PassthroughHasher {
fn write_u64(&mut self, i: u64) {
self.0 = i;
}
fn write(&mut self, _bytes: &[u8]) {
unimplemented!()
}
fn finish(&self) -> u64 {
self.0
}
}
// Define a BuildHasher using our Hasher. We will give this to our cache.
type PassthroughBuildHasher = BuildHasherDefault<PassthroughHasher>;
fn main() {
let cache = moka::sync::Cache::builder()
.max_capacity(100)
// Give our build hasher to this cache.
.build_with_hasher(PassthroughBuildHasher::default());
let key1 = MyKey::new(b"key1".to_vec().into_boxed_slice(), 0);
let key2 = MyKey::new(b"key2".to_vec().into_boxed_slice(), 1);
cache.insert(key1.clone(), "value1");
cache.insert(key2.clone(), "value2");
assert_eq!(cache.get(&key1), Some("value1"));
assert_eq!(cache.get(&key2), Some("value2"));
}
Will this trick work for you?
from moka.
it would, but i would think it is perhaps more ergonomic to provide something similar to the raw_entry API from hashbrown https://docs.rs/hashbrown/latest/hashbrown/raw/struct.RawTable.html#method.insert, etc, especially if these functions are already implemented.
its a bit a question of API, i guess.
from moka.
Unfortunately, exposing sync::Cache
's get_with_hash
and insert_with_hash
does not solve your problem.
Like many other hash tables, Moka cache's internal hash table re-calculates hash values of existing keys when it resizes (reallocates) the storage area for growth. This operation is called rehashing. So even though, you use the pre-calculated hash when inserting and retrieving an entry, the cache will still re-calculate hashes from the keys when the cache grows. If you use a different hash function for pre-calculating the hash to the hash function that the cache is given at the build time, it will break; get_with_hash
will no longer be able to locate the key after growing.
On the other hand, the example code above with PassthroughHasher
ensures that the hash is never re-calculated from the key, at insertion, retrieval and rehashing times.
from moka.
Here is the rehash
method in Moka's internal hash table:
Line 396 in 915d9b0
and this is the line in rehash
that re-calculates hash from key.
Line 439 in 915d9b0
from moka.
Related Issues (20)
- Try `seize` as a replacement of `crossbeam-epoch`? HOT 4
- Refactoring: Cache policy implementations HOT 2
- Do not swallow the panic when the eviction listener is panicked
- Crash in iOS HOT 3
- Unable to use moka when miri testing HOT 3
- Inefficient size aware eviction when inserting new entries with larger size HOT 3
- Consider switching to TinyUFO HOT 2
- Pending `run_pending_tasks` may cause busy loop in `schedule_write_op` HOT 14
- Miri errors on the `timer_wheel` module. (Miri v0.1.0 8b2459c1 2024-04-09) HOT 1
- CI: Kani verifier v0.49.0 uses Rust `nightly-2024-03-29`, which cannot compile `[email protected]` HOT 2
- Should Moka work in WASM? HOT 2
- Size Aware Eviction: First-In-First-Out, or evicting largest items first? HOT 2
- Latest triomphe update breaks MSRV
- The `once_cell` dependency should be optional
- Update Key With One Evaluation of the `init` Future HOT 12
- Feature Request: Alternative compute API that skips if other thread/async task is already computing for the key
- Locking `triomphe` is the wrong approach to preserving MSRV HOT 2
- CI: Run Linux arm64 tests only once a week on `arm1.small` instance at AWS CodeBuild
- Use SIEVE as underlying LRU?
- Unexpected behavior with LRU HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from moka.