#[cfg(feature = "protobuf")]
use super::*;
#[cfg(feature = "protobuf")]
impl Keyspace {
pub fn proto_set(
&mut self,
key: String,
type_name: String,
data: Bytes,
expire: Option<Duration>,
) -> SetResult {
let has_expiry = expire.is_some();
let new_value = Value::Proto { type_name, data };
let new_size = memory::entry_size(&key, &new_value);
let old_size = self
.entries
.get(key.as_str())
.map(|e| e.entry_size(&key))
.unwrap_or(0);
let net_increase = new_size.saturating_sub(old_size);
if !self.enforce_memory_limit(net_increase) {
return SetResult::OutOfMemory;
}
if let Some(old_entry) = self.entries.get(key.as_str()) {
self.memory.replace(&key, &old_entry.value, &new_value);
let had_expiry = old_entry.expires_at_ms != 0;
match (had_expiry, has_expiry) {
(false, true) => self.expiry_count += 1,
(true, false) => self.expiry_count = self.expiry_count.saturating_sub(1),
_ => {}
}
} else {
self.memory.add(&key, &new_value);
if has_expiry {
self.expiry_count += 1;
}
}
let entry = Entry::new(new_value, expire);
self.entries
.insert(CompactString::from(key.as_str()), entry);
self.bump_version(&key);
SetResult::Ok
}
pub fn proto_get(
&mut self,
key: &str,
) -> Result<Option<(String, Bytes, Option<Duration>)>, WrongType> {
if self.remove_if_expired(key) {
return Ok(None);
}
match self.entries.get_mut(key) {
Some(e) => {
if let Value::Proto { type_name, data } = &e.value {
let remaining = if e.expires_at_ms == 0 {
None
} else {
let now = time::now_ms();
Some(Duration::from_millis(e.expires_at_ms.saturating_sub(now)))
};
let result = (type_name.clone(), data.clone(), remaining);
e.touch(self.track_access);
Ok(Some(result))
} else {
Err(WrongType)
}
}
None => Ok(None),
}
}
pub fn proto_type(&mut self, key: &str) -> Result<Option<String>, WrongType> {
if self.remove_if_expired(key) {
return Ok(None);
}
match self.entries.get(key) {
Some(e) => match &e.value {
Value::Proto { type_name, .. } => Ok(Some(type_name.clone())),
_ => Err(WrongType),
},
None => Ok(None),
}
}
}