use std::path::Path;
use crate::Result;
mod big;
mod bti;
mod descriptor;
pub use big::BigVersionGates;
pub use bti::BtiVersionGates;
pub use descriptor::{SsTableDescriptor, SsTableFormat};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VersionGates {
Big(BigVersionGates),
Bti(BtiVersionGates),
}
impl VersionGates {
pub fn from_descriptor(desc: &SsTableDescriptor) -> Result<Self> {
match desc.format {
SsTableFormat::Big => BigVersionGates::from_version(&desc.version).map(Self::Big),
SsTableFormat::Bti => BtiVersionGates::from_version(&desc.version).map(Self::Bti),
}
}
pub fn from_path(path: &Path) -> Result<Self> {
let desc = SsTableDescriptor::parse(path)?;
Self::from_descriptor(&desc)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Error;
use std::path::PathBuf;
#[test]
fn test_version_gates_from_path_nb() {
let path = PathBuf::from("nb-1-big-Data.db");
let gates = VersionGates::from_path(&path).unwrap();
match gates {
VersionGates::Big(g) => assert_eq!(g.version, "nb"),
VersionGates::Bti(_) => panic!("Expected Big"),
}
}
#[test]
fn test_version_gates_from_path_oa() {
let path = PathBuf::from("oa-1-big-Data.db");
let gates = VersionGates::from_path(&path).unwrap();
match gates {
VersionGates::Big(g) => {
assert_eq!(g.version, "oa");
assert!(g.has_uint_deletion_time);
}
VersionGates::Bti(_) => panic!("Expected Big"),
}
}
#[test]
fn test_version_gates_from_descriptor_rejects_unknown_bti() {
for v in &["db", "ea", "dz", "zz"] {
let desc = SsTableDescriptor {
version: v.to_string(),
sstable_id: "1".to_string(),
format: SsTableFormat::Bti,
component: "Data.db".to_string(),
};
match VersionGates::from_descriptor(&desc) {
Err(Error::UnsupportedVersion { version, floor }) => {
assert_eq!(version, *v, "error must name the offending BTI version");
assert_eq!(floor, "da", "error must name the da floor");
}
other => panic!("{}: expected UnsupportedVersion, got {:?}", v, other),
}
}
let da_desc = SsTableDescriptor {
version: "da".to_string(),
sstable_id: "1".to_string(),
format: SsTableFormat::Bti,
component: "Data.db".to_string(),
};
assert!(matches!(
VersionGates::from_descriptor(&da_desc),
Ok(VersionGates::Bti(_))
));
}
#[test]
fn test_version_gates_from_descriptor_rejects_unknown_big() {
let desc = SsTableDescriptor {
version: "nc".to_string(),
sstable_id: "1".to_string(),
format: SsTableFormat::Big,
component: "Data.db".to_string(),
};
assert!(matches!(
VersionGates::from_descriptor(&desc),
Err(Error::UnsupportedVersion { .. })
));
}
#[test]
fn test_version_gates_from_path_da() {
let path = PathBuf::from("da-1-bti-Partitions.db");
let gates = VersionGates::from_path(&path).unwrap();
match gates {
VersionGates::Bti(g) => assert_eq!(g.version, "da"),
VersionGates::Big(_) => panic!("Expected Bti"),
}
}
#[test]
fn test_version_gates_from_statistics_component_path() {
let nb = VersionGates::from_path(&PathBuf::from("nb-1-big-Statistics.db")).unwrap();
assert!(matches!(nb, VersionGates::Big(g) if g.version == "nb"));
let da = VersionGates::from_path(&PathBuf::from("da-1-bti-Statistics.db")).unwrap();
assert!(matches!(da, VersionGates::Bti(g) if g.version == "da"));
}
#[test]
fn test_version_gates_from_corpus_filename() {
let path = PathBuf::from("nb-6aa08200a25111f0a3fef1a551383fb9-big-Data.db");
let gates = VersionGates::from_path(&path).unwrap();
match gates {
VersionGates::Big(g) => {
assert_eq!(g.version, "nb");
assert!(!g.has_improved_min_max);
assert!(!g.has_uint_deletion_time);
}
VersionGates::Bti(_) => panic!("Expected Big"),
}
}
#[test]
fn test_gates_docker_oa_fixture() {
let gates = VersionGates::from_path(&PathBuf::from("oa-2-big-Data.db")).unwrap();
match gates {
VersionGates::Big(g) => {
assert_eq!(g.version, "oa");
assert!(g.has_improved_min_max, "oa fixture: hasImprovedMinMax");
assert!(
g.has_partition_level_deletion_presence_marker,
"oa fixture: hasPartitionLevelDeletionPresenceMarker"
);
assert!(g.has_key_range, "oa fixture: hasKeyRange");
assert!(g.has_uint_deletion_time, "oa fixture: hasUIntDeletionTime");
assert!(
g.has_token_space_coverage,
"oa fixture: hasTokenSpaceCoverage"
);
assert!(
!g.has_accurate_min_max,
"oa fixture: hasAccurateMinMax deprecated"
);
assert!(
!g.has_legacy_min_max,
"oa fixture: hasLegacyMinMax deprecated"
);
}
VersionGates::Bti(_) => panic!("Expected Big gates for oa-2-big-Data.db"),
}
}
#[test]
fn test_gates_docker_da_fixture() {
let gates = VersionGates::from_path(&PathBuf::from("da-2-bti-Data.db")).unwrap();
match gates {
VersionGates::Bti(g) => {
assert_eq!(g.version, "da");
assert!(g.has_improved_min_max, "da: hasImprovedMinMax");
assert!(g.has_key_range, "da: hasKeyRange");
assert!(g.has_uint_deletion_time, "da: hasUIntDeletionTime");
assert!(g.has_token_space_coverage, "da: hasTokenSpaceCoverage");
assert!(
g.has_partition_level_deletion_presence_marker,
"da: hasPartitionLevelDeletionPresenceMarker"
);
assert!(!g.has_old_bf_format, "da: !hasOldBfFormat");
assert!(g.has_originating_host_id, "da: hasOriginatingHostId");
assert!(g.has_accurate_min_max, "da: hasAccurateMinMax");
assert!(!g.has_legacy_min_max, "da: !hasLegacyMinMax");
}
VersionGates::Big(_) => panic!("Expected Bti gates for da-2-bti-Data.db"),
}
}
}