@@ -19,25 +19,15 @@
//! The store owns the file; concurrent writers are not supported.
use indexmap::IndexMap;
-use serde::{Deserialize, Serialize, de::DeserializeOwned};
+use serde::{Serialize, de::DeserializeOwned};
use std::fs::{self, File, OpenOptions};
use std::hash::Hash;
use std::io::{self, BufWriter, ErrorKind, Read, Write};
use std::path::{Path, PathBuf};
const LEN_BYTES: usize = 4;
-
-#[derive(Serialize)]
-enum LogRef<'a, K, V> {
- Insert(&'a K, &'a V),
- Remove(&'a K),
-}
-
-#[derive(Deserialize)]
-enum LogOwned<K, V> {
- Insert(K, V),
- Remove(K),
-}
+const TAG_INSERT: u8 = 0;
+const TAG_REMOVE: u8 = 1;
/// Configuration for an [`IndexMapStore`].
#[derive(Clone, Debug)]
@@ -126,20 +116,27 @@
) as usize;
let payload_start = offset + LEN_BYTES;
let payload_end = payload_start + len;
- if payload_end > buf.len() {
+ if payload_end > buf.len() || len == 0 {
break;
}
- let rec: LogOwned<K, V> = match bincode::deserialize(&buf[payload_start..payload_end]) {
- Ok(r) => r,
- Err(_) => break,
- };
- match rec {
- LogOwned::Insert(k, v) => {
+ let tag = buf[payload_start];
+ let body = &buf[payload_start + 1..payload_end];
+ match tag {
+ TAG_INSERT => {
+ let (k, v): (K, V) = match bincode::deserialize(body) {
+ Ok(r) => r,
+ Err(_) => break,
+ };
map.insert(k, v);
}
- LogOwned::Remove(k) => {
+ TAG_REMOVE => {
+ let k: K = match bincode::deserialize(body) {
+ Ok(r) => r,
+ Err(_) => break,
+ };
map.shift_remove(&k);
}
+ _ => break,
}
valid_len += (LEN_BYTES + len) as u64;
total_records += 1;
@@ -220,7 +217,8 @@
pub fn insert(&mut self, k: K, v: V) -> io::Result<Option<V>> {
self.scratch.clear();
self.scratch.extend_from_slice(&[0u8; LEN_BYTES]);
- bincode::serialize_into(&mut self.scratch, &LogRef::Insert::<K, V>(&k, &v))
+ self.scratch.push(TAG_INSERT);
+ bincode::serialize_into(&mut self.scratch, &(&k, &v))
.map_err(serialize_err)?;
self.flush_scratch()?;
let prev = self.map.insert(k, v);
@@ -240,7 +238,8 @@
}
self.scratch.clear();
self.scratch.extend_from_slice(&[0u8; LEN_BYTES]);
- bincode::serialize_into(&mut self.scratch, &LogRef::Remove::<K, V>(k))
+ self.scratch.push(TAG_REMOVE);
+ bincode::serialize_into(&mut self.scratch, k)
.map_err(serialize_err)?;
self.flush_scratch()?;
let prev = self.map.shift_remove(k);
@@ -268,7 +267,8 @@
self.scratch.clear();
self.scratch.extend_from_slice(&[0u8; LEN_BYTES]);
- bincode::serialize_into(&mut self.scratch, &LogRef::Insert::<K, V>(k, v_ref))
+ self.scratch.push(TAG_INSERT);
+ bincode::serialize_into(&mut self.scratch, &(k, v_ref))
.map_err(serialize_err)?;
self.flush_scratch()?;
@@ -299,7 +299,8 @@
let mut buf = Vec::with_capacity(256);
for (k, v) in &self.map {
buf.clear();
- bincode::serialize_into(&mut buf, &LogRef::Insert::<K, V>(k, v))
+ buf.push(TAG_INSERT);
+ bincode::serialize_into(&mut buf, &(k, v))
.map_err(serialize_err)?;
writer.write_all(&(buf.len() as u32).to_le_bytes())?;
writer.write_all(&buf)?;