use crate::{SeqNo, UserKey, ValueType};
#[derive(Clone, Eq)]
pub struct InternalKey {
pub user_key: UserKey,
pub seqno: SeqNo,
pub value_type: ValueType,
}
impl PartialEq for InternalKey {
fn eq(&self, other: &Self) -> bool {
self.user_key == other.user_key && self.seqno == other.seqno
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
impl std::fmt::Debug for InternalKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:?}:{}:{}",
self.user_key,
self.seqno,
match self.value_type {
ValueType::Value => "V",
ValueType::Tombstone => "T",
ValueType::WeakTombstone => "W",
ValueType::Indirection => "Vb",
},
)
}
}
impl InternalKey {
pub fn new<K: Into<UserKey>>(user_key: K, seqno: SeqNo, value_type: ValueType) -> Self {
let user_key = user_key.into();
assert!(
u16::try_from(user_key.len()).is_ok(),
"keys can be 65535 bytes in length",
);
Self {
user_key,
seqno,
value_type,
}
}
pub fn is_tombstone(&self) -> bool {
self.value_type.is_tombstone()
}
}
impl PartialOrd for InternalKey {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for InternalKey {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
(&self.user_key, other.seqno).cmp(&(&other.user_key, self.seqno))
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_log::test;
#[test]
fn key_order_smoke_test() {
use ValueType::Value as V;
let mut keys = [
InternalKey::new(b"d", 3, V),
InternalKey::new(b"a", 0, V),
InternalKey::new(b"b", 0, V),
InternalKey::new(b"a", 2, V),
InternalKey::new(b"b", 1, V),
InternalKey::new(b"a", 1, V),
InternalKey::new(b"c", 3, V),
];
keys.sort();
assert_eq!(
[
InternalKey::new(b"a", 2, V),
InternalKey::new(b"a", 1, V),
InternalKey::new(b"a", 0, V),
InternalKey::new(b"b", 1, V),
InternalKey::new(b"b", 0, V),
InternalKey::new(b"c", 3, V),
InternalKey::new(b"d", 3, V),
],
keys,
);
}
}