use {
super::storage::{TestPartition, Test1Partition, TestPartitions, TestSortKey},
crate::{
ContentHash, Ident, Uri,
database::{
PartitionKey,
chunk::RecordWriter,
partitions::HasPartition,
storage::Partitions,
},
},
};
fn test_uri(path: &str) -> Uri {
Uri::parse(path).expect("valid test URI")
}
#[test]
fn partition_store_span_index_round_trip() {
let stores = TestPartitions::new_stores();
let store = <
<TestPartitions as Partitions>::Stores as HasPartition<TestPartition>
>::store(&stores);
let uri = test_uri("file:///test.gold");
let hash_a = ContentHash::new(&[1, 0, 0, 0]);
let hash_b = ContentHash::new(&[2, 0, 0, 0]);
store.span_index_apply(
&[],
vec![
("a".to_string(), uri.clone(), 0, 10, hash_a),
("b".to_string(), uri.clone(), 20, 5, hash_b),
],
);
assert_eq!(store.span_index_query(&uri, 5), Some(hash_a));
assert_eq!(store.span_index_query(&uri, 22), Some(hash_b));
assert_eq!(store.span_index_query(&uri, 15), None);
let other_uri = test_uri("file:///other.gold");
assert_eq!(store.span_index_query(&other_uri, 5), None);
}
#[test]
fn partition_store_span_index_reapply_same_key_overwrites() {
let stores = TestPartitions::new_stores();
let store = <
<TestPartitions as Partitions>::Stores as HasPartition<TestPartition>
>::store(&stores);
let uri = test_uri("file:///test.gold");
let hash_old = ContentHash::new(&[1, 0, 0, 0]);
let hash_new = ContentHash::new(&[2, 0, 0, 0]);
store.span_index_apply(&[], vec![("k".to_string(), uri.clone(), 0, 10, hash_old)]);
assert_eq!(store.span_index_query(&uri, 5), Some(hash_old));
store.span_index_apply(&[], vec![("k".to_string(), uri.clone(), 0, 10, hash_new)]);
assert_eq!(store.span_index_query(&uri, 5), Some(hash_new));
}
#[test]
fn partition_store_span_index_merge_keeps_prior_entries() {
let stores = TestPartitions::new_stores();
let store = <
<TestPartitions as Partitions>::Stores as HasPartition<TestPartition>
>::store(&stores);
let uri = test_uri("file:///test.gold");
let hash_a = ContentHash::new(&[1, 0, 0, 0]);
let hash_b = ContentHash::new(&[2, 0, 0, 0]);
store.span_index_apply(&[], vec![("a".to_string(), uri.clone(), 0, 10, hash_a)]);
store.span_index_apply(&[], vec![("b".to_string(), uri.clone(), 20, 5, hash_b)]);
assert_eq!(store.span_index_query(&uri, 5), Some(hash_a));
assert_eq!(store.span_index_query(&uri, 22), Some(hash_b));
}
#[test]
fn partition_store_span_index_removed_key_drops_only_that_entry() {
let stores = TestPartitions::new_stores();
let store = <
<TestPartitions as Partitions>::Stores as HasPartition<TestPartition>
>::store(&stores);
let uri = test_uri("file:///test.gold");
let hash_a = ContentHash::new(&[1, 0, 0, 0]);
let hash_b = ContentHash::new(&[2, 0, 0, 0]);
store.span_index_apply(
&[],
vec![
("a".to_string(), uri.clone(), 0, 10, hash_a),
("b".to_string(), uri.clone(), 20, 5, hash_b),
],
);
store.span_index_apply(&["a".to_string()], vec![]);
assert_eq!(store.span_index_query(&uri, 5), None);
assert_eq!(store.span_index_query(&uri, 22), Some(hash_b));
}
#[test]
fn partition_store_span_index_remove() {
let stores = TestPartitions::new_stores();
let store = <
<TestPartitions as Partitions>::Stores as HasPartition<TestPartition>
>::store(&stores);
let uri = test_uri("file:///test.gold");
let hash = ContentHash::new(&[1, 0, 0, 0]);
store.span_index_apply(&[], vec![("k".to_string(), uri.clone(), 0, 10, hash)]);
assert_eq!(store.span_index_query(&uri, 5), Some(hash));
store.span_index_remove(&uri);
assert_eq!(store.span_index_query(&uri, 5), None);
store.span_index_apply(&[], vec![("k".to_string(), uri.clone(), 0, 10, hash)]);
assert_eq!(store.span_index_query(&uri, 5), Some(hash));
}
#[test]
fn record_writer_index_span_stages_per_partition() {
let mut writer = RecordWriter::<TestPartitions>::new(Ident::new("task"));
let mut span_cache = crate::SpanCache::for_test(3, 0);
let span1 = span_cache.create_span(0, 10);
let span2 = span_cache.create_span(20, 5);
let span3 = span_cache.create_span(30, 5);
let hash1 = ContentHash::new(&[1, 0, 0, 0]);
let hash2 = ContentHash::new(&[2, 0, 0, 0]);
let hash3 = ContentHash::new(&[3, 0, 0, 0]);
writer.index_span::<TestPartition>("a".to_string(), span1, hash1);
writer.index_span::<TestPartition>("b".to_string(), span2, hash2);
writer.index_span::<Test1Partition>("c".to_string(), span3, hash3);
let chunk = writer.build();
let test_intervals = chunk.staged_intervals().get(&TestPartition::KEY);
assert!(test_intervals.is_some());
assert_eq!(test_intervals.map(|v| v.len()), Some(2));
let test1_intervals = chunk.staged_intervals().get(&Test1Partition::KEY);
assert!(test1_intervals.is_some());
assert_eq!(test1_intervals.map(|v| v.len()), Some(1));
}
#[test]
fn partitions_trait_span_index_dispatch() {
let stores = TestPartitions::new_stores();
let uri = test_uri("file:///dispatch.gold");
let hash = ContentHash::new(&[42, 0, 0, 0]);
TestPartitions::span_index_apply(
&stores,
TestPartition::KEY,
&[],
vec![(TestSortKey::Test("k".to_string()), uri.clone(), 0, 10, hash)],
);
let store = <
<TestPartitions as Partitions>::Stores as HasPartition<TestPartition>
>::store(&stores);
assert_eq!(store.span_index_query(&uri, 5), Some(hash));
TestPartitions::span_index_remove(&stores, TestPartition::KEY, &uri);
assert_eq!(store.span_index_query(&uri, 5), None);
}