aboutsummaryrefslogtreecommitdiffstats
path: root/log_db/src/common.rs
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2025-01-06 15:51:45 +0200
committerJan Tuomi <jan@jantuomi.fi>2025-01-06 15:51:45 +0200
commitb5abd6dfea8b26b73cc9b489695ffdd6de6fe1cd (patch)
treecb3ae25796dd1a0ebccbc5796a7374a7ff9ab8ff /log_db/src/common.rs
parent4f80ddfccc4339b12c97648a1a00b72b4dfa3ef0 (diff)
Implement remove
Diffstat (limited to 'log_db/src/common.rs')
-rw-r--r--log_db/src/common.rs64
1 files changed, 40 insertions, 24 deletions
diff --git a/log_db/src/common.rs b/log_db/src/common.rs
index 4be2b39..a4f253c 100644
--- a/log_db/src/common.rs
+++ b/log_db/src/common.rs
@@ -26,6 +26,16 @@ pub const INIT_LOCK_FILENAME: &str = "init_lock";
pub const DEFAULT_READ_BUF_SIZE: usize = 1024 * 1024; // 1 MB
pub const TEST_RESOURCES_DIR: &str = "tests/resources";
+// Serialized value tags
+pub const B_NULL: u8 = 0x0;
+pub const B_INT: u8 = 0x1;
+pub const B_FLOAT: u8 = 0x2;
+pub const B_STRING: u8 = 0x3;
+pub const B_BYTES: u8 = 0x4;
+// Tombstone marker tags
+pub const B_LIVE: u8 = 0x0;
+pub const B_TOMBSTONE: u8 = 0xFF;
+
pub fn metadata_filename(num: u16) -> String {
format!("metadata.{}", num)
}
@@ -42,6 +52,14 @@ pub enum DBError {
IOError(#[from] io::Error),
}
+#[derive(Debug, Error)]
+pub enum LogKeySetError {
+ #[error("log key not found in set")]
+ NotFoundError,
+ #[error("attempted to remove last element of non-empty set")]
+ RemovingLastElementError,
+}
+
/// LogKey is a packed struct that contains:
/// - a log segment number (16 bits)
/// - a log index within the segment (48 bits)
@@ -102,6 +120,10 @@ impl LogKeySet {
self.set.iter()
}
+ pub fn contains(&self, key: &LogKey) -> bool {
+ self.set.contains(key)
+ }
+
/// The number of LogKeys in the set.
pub fn len(&self) -> usize {
self.set.len()
@@ -113,22 +135,16 @@ impl LogKeySet {
}
/// Remove a LogKey from the set. Return Ok(()) if the key was found and removed.
- /// Return io::Error::InvalidInput if trying to remove the last element.
- /// Return io::Error::NotFound if the key was not found.
- pub fn remove(&mut self, key: &LogKey) -> Result<(), io::Error> {
+ /// Return `LogKeySetError::RemovingLastElementError` if trying to remove the last element.
+ /// Return `LogKeySetError::NotFoundError` if the key was not found.
+ pub fn remove(&mut self, key: &LogKey) -> Result<(), LogKeySetError> {
if self.set.len() == 1 {
- return Err(io::Error::new(
- io::ErrorKind::InvalidInput,
- "Cannot remove the last element from LogKeySet",
- ));
+ return Err(LogKeySetError::RemovingLastElementError);
}
let removed = self.set.remove(key);
if !removed {
- return Err(io::Error::new(
- io::ErrorKind::NotFound,
- "LogKey not found in LogKeySet",
- ));
+ return Err(LogKeySetError::NotFoundError);
}
assert!(
@@ -309,27 +325,27 @@ impl Value {
pub fn serialize(&self) -> Vec<u8> {
match self {
Value::Null => {
- vec![0] // Tag for Null
+ vec![B_NULL]
}
Value::Int(i) => {
- let mut bytes = vec![1]; // Tag for Int
+ let mut bytes = vec![B_INT];
bytes.extend(&i.to_be_bytes());
bytes
}
Value::Float(f) => {
- let mut bytes = vec![2]; // Tag for Float
+ let mut bytes = vec![B_FLOAT];
bytes.extend(&f.to_be_bytes());
bytes
}
Value::String(s) => {
- let mut bytes = vec![3]; // Tag for String
+ let mut bytes = vec![B_STRING];
let length = s.len() as u64;
bytes.extend(&length.to_be_bytes());
bytes.extend(s.as_bytes());
bytes
}
Value::Bytes(b) => {
- let mut bytes = vec![4]; // Tag for Bytes
+ let mut bytes = vec![B_BYTES];
let length = b.len() as u64;
bytes.extend(&length.to_be_bytes());
bytes.extend(b);
@@ -342,18 +358,18 @@ impl Value {
/// Returns the deserialized Value and the number of bytes consumed.
pub fn deserialize(bytes: &[u8]) -> (Value, usize) {
match bytes[0] {
- 0 => (Value::Null, 1),
- 1 => {
+ B_NULL => (Value::Null, 1),
+ B_INT => {
let mut int_bytes = [0; 8];
int_bytes.copy_from_slice(&bytes[1..1 + 8]);
(Value::Int(i64::from_be_bytes(int_bytes)), 1 + 8)
}
- 2 => {
+ B_FLOAT => {
let mut float_bytes = [0; 8];
float_bytes.copy_from_slice(&bytes[1..1 + 8]);
(Value::Float(f64::from_be_bytes(float_bytes)), 1 + 8)
}
- 3 => {
+ B_STRING => {
let length_bytes = &bytes[1..1 + 8];
let length = u64::from_be_bytes(length_bytes.try_into().unwrap()) as usize;
(
@@ -363,7 +379,7 @@ impl Value {
1 + 8 + length,
)
}
- 4 => {
+ B_BYTES => {
let length_bytes = &bytes[1..1 + 8];
let length = u64::from_be_bytes(length_bytes.try_into().unwrap()) as usize;
(
@@ -395,9 +411,9 @@ impl Record {
let mut bytes = Vec::new();
if self.tombstone {
- bytes.extend(&[0xFF]);
+ bytes.extend(&[B_TOMBSTONE]);
} else {
- bytes.extend(&[0]);
+ bytes.extend(&[B_LIVE]);
}
for value in &self.values {
@@ -409,7 +425,7 @@ impl Record {
pub fn deserialize(bytes: &[u8]) -> Record {
let mut values = Vec::new();
- let tombstone = bytes[0] == 0xFF;
+ let tombstone = bytes[0] == B_TOMBSTONE;
let mut start = 1;
while start < bytes.len() {