summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKornel <kornel@geekhood.net>2020-03-01 14:17:19 +0000
committerKornel <kornel@geekhood.net>2020-03-01 14:18:02 +0000
commita38758e88c390600fef6a2eda243296bf8a198f6 (patch)
tree2111a0274e7c2f237a12eeb456a3c11e50b9c379
parent039a482c021c639e249db1a59bb9f2e54483006d (diff)
Configurable key type
-rw-r--r--docs_rs_client/src/lib_docs_rs_client.rs2
-rw-r--r--simple_cache/src/kv.rs35
2 files changed, 19 insertions, 18 deletions
diff --git a/docs_rs_client/src/lib_docs_rs_client.rs b/docs_rs_client/src/lib_docs_rs_client.rs
index 9e91caf..09b9093 100644
--- a/docs_rs_client/src/lib_docs_rs_client.rs
+++ b/docs_rs_client/src/lib_docs_rs_client.rs
@@ -28,7 +28,7 @@ impl DocsRsClient {
pub async fn build_status(&self, crate_name: &str, version: &str) -> Result<Option<Vec<BuildStatus>>, Error> {
let key = format!("{}-{}", crate_name, version);
- if let Some(cached) = self.cache.get(&key)? {
+ if let Some(cached) = self.cache.get(key.as_str())? {
return Ok(cached);
}
let url = format!("https://docs.rs/crate/{}/{}/builds.json", crate_name, version);
diff --git a/simple_cache/src/kv.rs b/simple_cache/src/kv.rs
index c382839..5e57110 100644
--- a/simple_cache/src/kv.rs
+++ b/simple_cache/src/kv.rs
@@ -1,3 +1,4 @@
+use std::hash::Hash;
use crate::error::Error;
use crate::SimpleCache;
use flate2::read::DeflateDecoder;
@@ -21,21 +22,21 @@ use std::collections::hash_map::Entry;
type FxHashMap<K, V> = std::collections::HashMap<K, V, ahash::RandomState>;
-struct Inner {
- data: Option<FxHashMap<Box<str>, Box<[u8]>>>,
+struct Inner<K> {
+ data: Option<FxHashMap<K, Box<[u8]>>>,
writes: usize,
next_autosave: usize,
}
-pub struct TempCache<T: Serialize + DeserializeOwned + Clone + Send> {
+pub struct TempCache<T: Serialize + DeserializeOwned + Clone + Send, K: Serialize + DeserializeOwned + Clone + Send + Eq + Hash = Box<str>> {
path: PathBuf,
- data: RwLock<Inner>,
+ data: RwLock<Inner<K>>,
_ty: PhantomData<T>,
pub cache_only: bool,
sem: tokio::sync::Semaphore,
}
-impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
+impl<T: Serialize + DeserializeOwned + Clone + Send, K: Serialize + DeserializeOwned + Clone + Send + Eq + Hash> TempCache<T, K> {
pub fn new(path: impl Into<PathBuf>) -> Result<Self, Error> {
let path = path.into().with_extension("rmpz");
let data = if path.exists() {
@@ -58,11 +59,11 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
}
#[inline]
- pub fn set(&self, key: impl Into<String>, value: impl Borrow<T>) -> Result<(), Error> {
- self.set_(key.into().into_boxed_str(), value.borrow())
+ pub fn set(&self, key: impl Into<K>, value: impl Borrow<T>) -> Result<(), Error> {
+ self.set_(key.into(), value.borrow())
}
- fn lock_for_write(&self) -> Result<RwLockWriteGuard<'_, Inner>, Error> {
+ fn lock_for_write(&self) -> Result<RwLockWriteGuard<'_, Inner<K>>, Error> {
let mut inner = self.data.write();
if inner.data.is_none() {
inner.data = Some(self.load_data()?);
@@ -70,7 +71,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
Ok(inner)
}
- fn lock_for_read(&self) -> Result<RwLockReadGuard<'_, Inner>, Error> {
+ fn lock_for_read(&self) -> Result<RwLockReadGuard<'_, Inner<K>>, Error> {
loop {
let inner = self.data.read();
if inner.data.is_some() {
@@ -81,7 +82,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
}
}
- fn load_data(&self) -> Result<FxHashMap<Box<str>, Box<[u8]>>, Error> {
+ fn load_data(&self) -> Result<FxHashMap<K, Box<[u8]>>, Error> {
let mut f = BufReader::new(File::open(&self.path)?);
Ok(rmp_serde::from_read(&mut f).map_err(|e| {
eprintln!("File {} is broken: {}", self.path.display(), e);
@@ -89,7 +90,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
})?)
}
- pub fn set_(&self, key: Box<str>, value: &T) -> Result<(), Error> {
+ pub fn set_(&self, key: K, value: &T) -> Result<(), Error> {
let mut e = DeflateEncoder::new(Vec::new(), Compression::best());
rmp_serde::encode::write_named(&mut e, value)?;
let compr = e.finish()?;
@@ -118,7 +119,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
Ok(())
}
- pub fn delete(&self, key: &str) -> Result<(), Error> {
+ pub fn delete<Q>(&self, key: &Q) -> Result<(), Error> where K: Borrow<Q>, Q: Eq + Hash + ?Sized {
let mut d = self.lock_for_write()?;
if d.data.as_mut().unwrap().remove(key).is_some() {
d.writes += 1;
@@ -126,7 +127,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
Ok(())
}
- pub fn get(&self, key: &str) -> Result<Option<T>, Error> {
+ pub fn get<Q>(&self, key: &Q) -> Result<Option<T>, Error> where K: Borrow<Q>, Q: Eq + Hash + std::fmt::Display + ?Sized {
let kw = self.lock_for_read()?;
Ok(match kw.data.as_ref().unwrap().get(key) {
Some(gz) => Some(Self::ungz(gz).map_err(|e| {
@@ -153,7 +154,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
Ok(())
}
- fn save_unlocked(&self, d: &Inner) -> Result<(), Error> {
+ fn save_unlocked(&self, d: &Inner<K>) -> Result<(), Error> {
if let Some(data) = d.data.as_ref() {
let tmp_path = NamedTempFile::new_in(self.path.parent().expect("tmp"))?;
let mut file = BufWriter::new(File::create(&tmp_path)?);
@@ -164,8 +165,8 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
}
#[inline]
- pub async fn get_json<B>(&self, key: &str, url: impl AsRef<str>, on_miss: impl FnOnce(B) -> Option<T>) -> Result<Option<T>, Error>
- where B: for<'a> Deserialize<'a> {
+ pub async fn get_json<Q, B>(&self, key: &Q, url: impl AsRef<str>, on_miss: impl FnOnce(B) -> Option<T>) -> Result<Option<T>, Error>
+ where B: for<'a> Deserialize<'a>, K: Borrow<Q> + for<'a> From<&'a Q>, Q: Eq + Hash + std::fmt::Display + ?Sized {
if let Some(res) = self.get(key)? {
return Ok(Some(res));
}
@@ -189,7 +190,7 @@ impl<T: Serialize + DeserializeOwned + Clone + Send> TempCache<T> {
}
}
-impl<T: Serialize + DeserializeOwned + Clone + Send> Drop for TempCache<T> {
+impl<T: Serialize + DeserializeOwned + Clone + Send, K: Serialize + DeserializeOwned + Clone + Send + Eq + Hash> Drop for TempCache<T, K> {
fn drop(&mut self) {
let d = self.data.read();
if d.writes > 0 {