use std::cmp::Ordering;
use std::iter as StdIter;
use std::mem as StdMem;
use super::{INITIAL_CAPACITY, InlineSuffixBag, PermutationProvider, SuffixBag, SuffixSidecar};
use crate::permuter::Permuter15;
#[test]
fn test_new_suffix_bag() {
let bag: SuffixBag = SuffixBag::new();
assert_eq!(bag.count(), 0);
assert!(bag.capacity() >= INITIAL_CAPACITY);
assert_eq!(bag.used(), 0);
}
#[test]
fn test_with_capacity() {
let bag: SuffixBag = SuffixBag::with_capacity(256);
assert!(bag.capacity() >= 256);
assert_eq!(bag.count(), 0);
}
#[test]
fn test_default() {
let bag: SuffixBag = SuffixBag::default();
assert_eq!(bag.count(), 0);
}
#[test]
fn test_assign_and_get() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
bag.assign(5, b"world");
bag.assign(10, b"!");
assert_eq!(bag.get(0), Some(b"hello".as_slice()));
assert_eq!(bag.get(5), Some(b"world".as_slice()));
assert_eq!(bag.get(10), Some(b"!".as_slice()));
assert_eq!(bag.get(1), None);
assert_eq!(bag.count(), 3);
}
#[test]
fn test_empty_suffix() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"");
assert_eq!(bag.get(0), Some(b"".as_slice()));
assert!(bag.has_suffix(0));
}
#[test]
fn test_get_or_empty() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
assert_eq!(bag.get_or_empty(0), b"hello".as_slice());
assert_eq!(bag.get_or_empty(1), b"".as_slice());
}
#[test]
fn test_overwrite_suffix() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
assert_eq!(bag.get(0), Some(b"hello".as_slice()));
bag.assign(0, b"goodbye");
assert_eq!(bag.get(0), Some(b"goodbye".as_slice()));
assert!(bag.used() >= "hello".len() + "goodbye".len());
}
#[test]
fn test_clear_suffix() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
assert!(bag.has_suffix(0));
bag.clear(0);
assert!(!bag.has_suffix(0));
assert_eq!(bag.get(0), None);
}
#[test]
fn test_clear_already_empty() {
let mut bag: SuffixBag = SuffixBag::new();
bag.clear(0);
assert!(!bag.has_suffix(0));
}
#[test]
fn test_compact() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"aaaa");
bag.assign(1, b"bbbb");
bag.assign(2, b"cccc");
bag.assign(3, b"dddd");
let before: usize = bag.used();
assert_eq!(before, 16);
let reclaimed: usize = bag.compact([0, 2].into_iter());
assert!(reclaimed > 0);
assert_eq!(bag.get(0), Some(b"aaaa".as_slice()));
assert_eq!(bag.get(2), Some(b"cccc".as_slice()));
assert_eq!(bag.get(1), None);
assert_eq!(bag.get(3), None);
assert_eq!(bag.used(), 8);
}
#[test]
fn test_compact_empty() {
let mut bag: SuffixBag = SuffixBag::new();
let reclaimed: usize = bag.compact(StdIter::empty());
assert_eq!(reclaimed, 0);
assert_eq!(bag.count(), 0);
}
#[test]
fn test_compact_all() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"test");
bag.assign(1, b"data");
let reclaimed: usize = bag.compact([0, 1].into_iter());
assert_eq!(reclaimed, 0);
assert_eq!(bag.get(0), Some(b"test".as_slice()));
assert_eq!(bag.get(1), Some(b"data".as_slice()));
}
#[test]
fn test_compact_with_permuter() {
struct MockPerm {
slots: Vec<usize>,
}
impl PermutationProvider for MockPerm {
fn size(&self) -> usize {
self.slots.len()
}
fn get(&self, i: usize) -> usize {
self.slots[i]
}
}
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"keep0");
bag.assign(1, b"drop1");
bag.assign(2, b"keep2");
let perm = MockPerm {
slots: vec![0, 2], };
bag.compact_with_permuter(&perm, None);
assert_eq!(bag.get(0), Some(b"keep0".as_slice()));
assert_eq!(bag.get(1), None);
assert_eq!(bag.get(2), Some(b"keep2".as_slice()));
}
#[test]
fn test_compact_with_exclude() {
struct MockPerm {
slots: Vec<usize>,
}
impl PermutationProvider for MockPerm {
fn size(&self) -> usize {
self.slots.len()
}
fn get(&self, i: usize) -> usize {
self.slots[i]
}
}
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"keep");
bag.assign(1, b"exclude");
bag.assign(2, b"keep2");
let perm = MockPerm {
slots: vec![0, 1, 2],
};
bag.compact_with_permuter(&perm, Some(1));
assert_eq!(bag.get(0), Some(b"keep".as_slice()));
assert_eq!(bag.get(1), None); assert_eq!(bag.get(2), Some(b"keep2".as_slice()));
}
#[test]
fn test_growth() {
let mut bag: SuffixBag = SuffixBag::with_capacity(16);
for i in 0..15 {
bag.assign(i, b"12345678"); }
assert!(bag.capacity() > 16);
assert_eq!(bag.used(), 120);
for i in 0..15 {
assert_eq!(bag.get(i), Some(b"12345678".as_slice()));
}
}
#[test]
fn test_long_suffix() {
let mut bag: SuffixBag = SuffixBag::new();
let long_suffix: Vec<u8> = vec![b'x'; 1000];
bag.assign(0, &long_suffix);
assert_eq!(bag.get(0), Some(long_suffix.as_slice()));
}
#[test]
fn test_suffix_equals() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
assert!(bag.suffix_equals(0, b"hello"));
assert!(!bag.suffix_equals(0, b"world"));
assert!(!bag.suffix_equals(0, b"hell"));
assert!(!bag.suffix_equals(1, b"hello")); }
#[test]
fn test_suffix_compare() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
assert_eq!(bag.suffix_compare(0, b"hello"), Some(Ordering::Equal));
assert_eq!(bag.suffix_compare(0, b"hella"), Some(Ordering::Greater));
assert_eq!(bag.suffix_compare(0, b"hellz"), Some(Ordering::Less));
assert_eq!(bag.suffix_compare(1, b"hello"), None);
}
#[test]
fn test_clone() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
bag.assign(5, b"world");
let cloned: SuffixBag = bag.clone();
assert_eq!(cloned.get(0), Some(b"hello".as_slice()));
assert_eq!(cloned.get(5), Some(b"world".as_slice()));
assert_eq!(cloned.count(), 2);
}
#[test]
fn test_try_assign_in_place_fresh_bag() {
let mut bag: SuffixBag = SuffixBag::new();
assert!(bag.try_assign_in_place(0, b"hello"));
assert_eq!(bag.get(0), Some(b"hello".as_slice()));
}
#[test]
fn test_try_assign_in_place_reuse_slot() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello world");
let used_before: usize = bag.used();
assert!(bag.try_assign_in_place(0, b"hi"));
assert_eq!(bag.get(0), Some(b"hi".as_slice()));
assert_eq!(bag.used(), used_before);
}
#[test]
fn test_try_assign_in_place_append() {
let mut bag: SuffixBag = SuffixBag::new();
assert!(bag.try_assign_in_place(0, b"first"));
assert!(bag.try_assign_in_place(1, b"second"));
assert_eq!(bag.get(0), Some(b"first".as_slice()));
assert_eq!(bag.get(1), Some(b"second".as_slice()));
}
#[test]
fn test_try_assign_in_place_fails_when_full() {
let mut bag: SuffixBag = SuffixBag::with_capacity(10);
assert!(bag.try_assign_in_place(0, b"12345"));
assert!(!bag.try_assign_in_place(1, b"678901234567890"));
assert_eq!(bag.get(0), Some(b"12345".as_slice()));
assert_eq!(bag.get(1), None);
}
#[test]
fn test_try_assign_in_place_same_length() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
let used_before: usize = bag.used();
assert!(bag.try_assign_in_place(0, b"world"));
assert_eq!(bag.get(0), Some(b"world".as_slice()));
assert_eq!(bag.used(), used_before);
}
#[test]
fn test_try_assign_in_place_longer_suffix_needs_append() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hi");
let used_before: usize = bag.used();
assert!(bag.try_assign_in_place(0, b"hello world"));
assert_eq!(bag.get(0), Some(b"hello world".as_slice()));
assert!(bag.used() > used_before);
}
#[test]
fn test_try_assign_in_place_mixed_usage() {
let mut bag: SuffixBag = SuffixBag::new();
for i in 0..5 {
assert!(bag.try_assign_in_place(i, b"test"));
}
assert!(bag.try_assign_in_place(2, b"ab"));
assert_eq!(bag.get(2), Some(b"ab".as_slice()));
assert_eq!(bag.get(0), Some(b"test".as_slice()));
assert_eq!(bag.get(1), Some(b"test".as_slice()));
assert_eq!(bag.get(3), Some(b"test".as_slice()));
assert_eq!(bag.get(4), Some(b"test".as_slice()));
}
#[test]
fn test_inline_new() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
#[cfg(not(feature = "small-suffix-capacity"))]
{
assert_eq!(bag.capacity(), 512);
assert_eq!(bag.remaining(), 512);
}
#[cfg(feature = "small-suffix-capacity")]
{
assert_eq!(bag.capacity(), 256);
assert_eq!(bag.remaining(), 256);
}
assert_eq!(bag.used(), 0);
assert_eq!(bag.count(), 0);
}
#[test]
fn test_inline_default() {
let bag: InlineSuffixBag = InlineSuffixBag::default();
assert_eq!(bag.count(), 0);
assert_eq!(bag.used(), 0);
}
#[test]
fn test_inline_try_assign_basic() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
assert!(bag.try_assign(0, b"hello"));
assert!(bag.try_assign(5, b"world"));
assert_eq!(bag.get(0), Some(b"hello".as_slice()));
assert_eq!(bag.get(5), Some(b"world".as_slice()));
assert_eq!(bag.get(1), None);
assert_eq!(bag.count(), 2);
assert_eq!(bag.used(), 10);
}
#[test]
fn test_inline_try_assign_reuse_slot() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
assert!(bag.try_assign(0, b"hello world"));
let used_before = bag.used();
assert!(bag.try_assign(0, b"hi"));
assert_eq!(bag.get(0), Some(b"hi".as_slice()));
assert_eq!(bag.used(), used_before);
}
#[test]
fn test_inline_try_assign_append() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
assert!(bag.try_assign(0, b"first"));
assert!(bag.try_assign(1, b"second"));
assert_eq!(bag.used(), 11); assert_eq!(bag.get(0), Some(b"first".as_slice()));
assert_eq!(bag.get(1), Some(b"second".as_slice()));
}
#[test]
fn test_inline_clear() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
assert!(bag.has_suffix(0));
bag.clear(0);
assert!(!bag.has_suffix(0));
assert_eq!(bag.get(0), None);
assert_eq!(bag.used(), 5);
}
#[test]
fn test_inline_clear_all() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
bag.try_assign(1, b"world");
bag.clear_all();
assert_eq!(bag.count(), 0);
assert_eq!(bag.used(), 0);
assert!(!bag.has_suffix(0));
assert!(!bag.has_suffix(1));
}
#[test]
fn test_inline_get_or_empty() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
assert_eq!(bag.get_or_empty(0), b"hello".as_slice());
assert_eq!(bag.get_or_empty(1), b"".as_slice());
}
#[test]
fn test_inline_suffix_equals() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
assert!(bag.suffix_equals(0, b"hello"));
assert!(!bag.suffix_equals(0, b"world"));
assert!(!bag.suffix_equals(1, b"hello"));
}
#[test]
fn test_inline_suffix_compare() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
assert_eq!(bag.suffix_compare(0, b"hello"), Some(Ordering::Equal));
assert_eq!(bag.suffix_compare(0, b"hella"), Some(Ordering::Greater));
assert_eq!(bag.suffix_compare(1, b"hello"), None);
}
#[test]
fn test_inline_drain_to_external() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"suffix0");
bag.try_assign(1, b"suffix1");
bag.try_assign(2, b"suffix2");
let perm = Permuter15::make_sorted(3);
let external = bag.drain_to_external(&perm, 3, b"new_suffix");
assert_eq!(bag.count(), 3);
assert_eq!(external.get(0), Some(b"suffix0".as_slice()));
assert_eq!(external.get(1), Some(b"suffix1".as_slice()));
assert_eq!(external.get(2), Some(b"suffix2".as_slice()));
assert_eq!(external.get(3), Some(b"new_suffix".as_slice()));
}
#[test]
fn test_inline_drain_replaces_slot() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"old_suffix");
bag.try_assign(1, b"keep_this");
let perm = Permuter15::make_sorted(2);
let external = bag.drain_to_external(&perm, 0, b"new_suffix");
assert_eq!(external.get(0), Some(b"new_suffix".as_slice()));
assert_eq!(external.get(1), Some(b"keep_this".as_slice()));
}
#[test]
fn test_inline_drain_to_external_init() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"suffix_0");
bag.try_assign(1, b"suffix_1");
bag.try_assign(2, b"suffix_2");
let external = bag.drain_to_external_init(3, b"new_suffix_3");
assert_eq!(bag.count(), 3);
assert_eq!(external.get(0), Some(b"suffix_0".as_slice()));
assert_eq!(external.get(1), Some(b"suffix_1".as_slice()));
assert_eq!(external.get(2), Some(b"suffix_2".as_slice()));
assert_eq!(external.get(3), Some(b"new_suffix_3".as_slice()));
}
#[test]
fn test_inline_drain_to_external_init_replaces_slot() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"keep_this");
bag.try_assign(1, b"old_suffix");
let external = bag.drain_to_external_init(1, b"new_suffix");
assert_eq!(external.get(0), Some(b"keep_this".as_slice()));
assert_eq!(external.get(1), Some(b"new_suffix".as_slice()));
}
#[test]
fn test_inline_clone() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
bag.try_assign(5, b"world");
let cloned = bag.clone();
assert_eq!(cloned.get(0), Some(b"hello".as_slice()));
assert_eq!(cloned.get(5), Some(b"world".as_slice()));
assert_eq!(cloned.count(), 2);
assert_eq!(cloned.used(), bag.used());
}
#[test]
fn test_inline_empty_suffix() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
assert!(bag.try_assign(0, b""));
assert_eq!(bag.get(0), Some(b"".as_slice()));
assert!(bag.has_suffix(0));
assert_eq!(bag.used(), 0);
}
#[test]
fn test_inline_size_calculation() {
#[cfg(not(feature = "small-suffix-capacity"))]
assert_eq!(StdMem::size_of::<InlineSuffixBag>(), 576);
#[cfg(feature = "small-suffix-capacity")]
assert_eq!(StdMem::size_of::<InlineSuffixBag>(), 320);
}
#[test]
fn test_suffix_count_assign_clear() {
let mut bag: SuffixBag = SuffixBag::new();
assert_eq!(bag.count(), 0);
bag.assign(0, b"hello");
assert_eq!(bag.count(), 1);
bag.assign(1, b"world");
assert_eq!(bag.count(), 2);
bag.assign(0, b"hi");
assert_eq!(bag.count(), 2);
bag.clear(0);
assert_eq!(bag.count(), 1);
bag.clear(1);
assert_eq!(bag.count(), 0);
bag.clear(0);
assert_eq!(bag.count(), 0);
}
#[test]
fn test_suffix_count_try_assign_in_place() {
let mut bag: SuffixBag = SuffixBag::new();
assert_eq!(bag.count(), 0);
assert!(bag.try_assign_in_place(0, b"hello"));
assert_eq!(bag.count(), 1);
assert!(bag.try_assign_in_place(1, b"world"));
assert_eq!(bag.count(), 2);
assert!(bag.try_assign_in_place(0, b"hi"));
assert_eq!(bag.count(), 2);
assert!(bag.try_assign_in_place(1, b"hello world"));
assert_eq!(bag.count(), 2);
}
#[test]
fn test_suffix_count_after_compact() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
bag.assign(1, b"world");
bag.assign(2, b"test");
assert_eq!(bag.count(), 3);
bag.clear(1);
assert_eq!(bag.count(), 2);
bag.compact([0, 2].into_iter());
assert_eq!(bag.count(), 2);
bag.compact(StdIter::once(0));
assert_eq!(bag.count(), 1);
bag.compact(StdIter::empty());
assert_eq!(bag.count(), 0);
}
#[test]
fn test_suffix_count_clone() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"hello");
bag.assign(1, b"world");
bag.clear(1);
let cloned = bag.clone();
assert_eq!(cloned.count(), 1);
assert_eq!(cloned.get(0), Some(b"hello".as_slice()));
assert_eq!(cloned.get(1), None);
assert_eq!(cloned.used(), 5); }
#[test]
fn test_inline_suffix_count_try_assign() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
assert_eq!(bag.count(), 0);
assert!(bag.try_assign(0, b"hello"));
assert_eq!(bag.count(), 1);
assert!(bag.try_assign(1, b"world"));
assert_eq!(bag.count(), 2);
assert!(bag.try_assign(0, b"hi"));
assert_eq!(bag.count(), 2);
}
#[test]
fn test_inline_suffix_count_clear() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
bag.try_assign(1, b"world");
assert_eq!(bag.count(), 2);
bag.clear(0);
assert_eq!(bag.count(), 1);
bag.clear(1);
assert_eq!(bag.count(), 0);
bag.clear(0);
assert_eq!(bag.count(), 0);
}
#[test]
fn test_inline_suffix_count_clear_all() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
bag.try_assign(0, b"hello");
bag.try_assign(1, b"world");
assert_eq!(bag.count(), 2);
bag.clear_all();
assert_eq!(bag.count(), 0);
}
#[test]
fn test_try_assign_compacts_before_grow() {
let mut bag: SuffixBag = SuffixBag::with_capacity(INITIAL_CAPACITY);
for i in 0..12 {
bag.assign(i, b"1234567890"); }
for i in (0..12).step_by(2) {
bag.clear(i);
}
let old_used: usize = bag.used();
assert_eq!(old_used, 120);
let _did_not_grow: bool = bag.try_assign(12, b"newdata!!!");
assert!(bag.used() < old_used); assert_eq!(bag.count(), 7);
assert_eq!(bag.get(12), Some(b"newdata!!!".as_slice()));
assert_eq!(bag.get(1), Some(b"1234567890".as_slice()));
}
#[test]
fn test_try_assign_grows_when_compact_insufficient() {
let mut bag: SuffixBag = SuffixBag::with_capacity(16);
bag.assign(0, b"12345678"); bag.assign(1, b"12345678");
let old_capacity = bag.capacity();
let did_grow: bool = !bag.try_assign(2, b"newdata!");
assert!(did_grow);
assert!(bag.capacity() > old_capacity);
assert_eq!(bag.count(), 3);
}
#[test]
fn test_clone_compacts_garbage() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"aaaaaaaaaa"); bag.assign(1, b"bbbbbbbbbb"); bag.assign(2, b"cccccccccc"); bag.assign(0, b"ddddd"); bag.clear(1);
let original_used: usize = bag.used();
assert!(original_used >= 35);
let cloned: SuffixBag = bag.clone();
assert_eq!(cloned.used(), 15); assert_eq!(cloned.count(), 2);
assert_eq!(cloned.get(0), Some(b"ddddd".as_slice()));
assert_eq!(cloned.get(1), None);
assert_eq!(cloned.get(2), Some(b"cccccccccc".as_slice()));
}
#[test]
fn test_clone_empty_bag() {
let bag: SuffixBag = SuffixBag::new();
let cloned: SuffixBag = bag;
assert_eq!(cloned.count(), 0);
assert_eq!(cloned.used(), 0);
}
#[test]
fn test_compact_dedup_duplicates() {
let mut bag: SuffixBag = SuffixBag::new();
bag.assign(0, b"aaaa");
bag.assign(1, b"bbbb");
bag.assign(2, b"cccc");
assert_eq!(bag.count(), 3);
let reclaimed: usize = bag.compact([0, 0, 2, 2].into_iter());
assert!(reclaimed > 0);
assert_eq!(bag.count(), 2);
assert_eq!(bag.get(0), Some(b"aaaa".as_slice()));
assert_eq!(bag.get(1), None);
assert_eq!(bag.get(2), Some(b"cccc".as_slice()));
}
#[test]
fn test_inline_drain_to_external_with_vec_reserves_enough() {
let bag: InlineSuffixBag = InlineSuffixBag::new();
assert!(bag.try_assign(0, b"suffix0"));
assert!(bag.try_assign(1, b"suffix1_long"));
assert!(bag.try_assign(2, b"suffix2"));
let perm: Permuter15 = Permuter15::make_sorted(3);
let new_slot: usize = 3;
let new_suffix: &[u8] = b"new_suffix";
let required_capacity: usize =
b"suffix0".len() + b"suffix1_long".len() + b"suffix2".len() + new_suffix.len();
let buffer: Vec<u8> = Vec::with_capacity(16);
let external: SuffixBag = bag.drain_to_external_with_vec(&perm, new_slot, new_suffix, buffer);
assert!(external.capacity() >= required_capacity);
assert_eq!(external.get(0), Some(b"suffix0".as_slice()));
assert_eq!(external.get(1), Some(b"suffix1_long".as_slice()));
assert_eq!(external.get(2), Some(b"suffix2".as_slice()));
assert_eq!(external.get(3), Some(new_suffix));
}
#[test]
fn test_sidecar_drop_inline_only() {
let sidecar: SuffixSidecar = SuffixSidecar::new();
sidecar.inline.try_assign(0, b"hello");
sidecar.inline.try_assign(1, b"world");
sidecar.inline.try_assign(2, b"test");
assert!(sidecar.has_suffix(0));
assert!(sidecar.has_suffix(1));
assert!(sidecar.has_suffix(2));
assert!(!sidecar.has_suffix(3));
assert_eq!(sidecar.get(0), Some(b"hello".as_slice()));
assert_eq!(sidecar.get(1), Some(b"world".as_slice()));
}
#[test]
fn test_sidecar_drop_with_external() {
let sidecar: SuffixSidecar = SuffixSidecar::new();
let external_bag = unsafe { sidecar.ensure_external() };
external_bag.assign(0, b"external_suffix_0");
external_bag.assign(1, b"external_suffix_1");
assert!(
!sidecar
.external
.load(std::sync::atomic::Ordering::Relaxed)
.is_null()
);
assert_eq!(sidecar.get(0), Some(b"external_suffix_0".as_slice()));
assert_eq!(sidecar.get(1), Some(b"external_suffix_1".as_slice()));
}
#[test]
fn test_sidecar_drop_mixed_inline_external() {
let sidecar: SuffixSidecar = SuffixSidecar::new();
sidecar.inline.try_assign(0, b"inline_0");
sidecar.inline.try_assign(1, b"inline_1");
let external_bag = unsafe { sidecar.ensure_external() };
external_bag.assign(5, b"external_5");
external_bag.assign(10, b"external_10");
assert_eq!(sidecar.get(0), Some(b"inline_0".as_slice()));
assert_eq!(sidecar.get(1), Some(b"inline_1".as_slice()));
assert_eq!(sidecar.get(5), Some(b"external_5".as_slice()));
assert_eq!(sidecar.get(10), Some(b"external_10".as_slice()));
}
#[test]
fn test_sidecar_default() {
let s1: SuffixSidecar = SuffixSidecar::new();
let s2: SuffixSidecar = SuffixSidecar::default();
assert!(
s1.external
.load(std::sync::atomic::Ordering::Relaxed)
.is_null()
);
assert!(
s2.external
.load(std::sync::atomic::Ordering::Relaxed)
.is_null()
);
assert_eq!(s1.inline.count(), 0);
assert_eq!(s2.inline.count(), 0);
}
#[test]
fn test_sidecar_ensure_external_idempotent() {
let sidecar: SuffixSidecar = SuffixSidecar::new();
let ptr1: *const SuffixBag = unsafe { sidecar.ensure_external() };
let ptr2: *const SuffixBag = unsafe { sidecar.ensure_external() };
let ptr3: *const SuffixBag = unsafe { sidecar.ensure_external() };
assert_eq!(ptr1, ptr2);
assert_eq!(ptr2, ptr3);
assert!(!ptr1.is_null());
}