#![cfg(feature = "storage")]
use core::num::NonZeroU32;
#[cfg(feature = "secondary-indexes")]
use pipecircuit::storage::warp_table::MutableSelectionRemoveFirstOutcome;
use pipecircuit::storage::warp_table::{
Capacity, WarpId, WarpTable, WarpTableEntry, WarpTableGetOutcome, WarpTableInsertAllOutcome,
WarpTableInsertOutcome, WarpTableInsertWithIdOutcome, WarpTableRemoveOutcome, WarpTableRow,
WarpTableUniqueGetOutcome, WarpTableUniqueUpdateOutcome, WarpTableUniqueUpdateWithOutcome,
WarpTableUpdateOutcome, WarpTableUpdateWithOutcome, WarpTableUpsertOutcome,
WarpTableVacantInsertOutcome,
};
#[cfg(feature = "secondary-indexes")]
use pipecircuit::storage::warp_table::{RangeIndexKey, WarpTableRowRelocation};
#[derive(WarpTableRow)]
struct Pet {
name: &'static str,
age: u8,
}
#[derive(WarpTableRow)]
#[index(primary = u64)]
struct GenericMessage<'payload, Value, const WIDTH: usize> {
payload: &'payload [Value; WIDTH],
}
enum PlayerSession {}
type PlayerSessionId = WarpId<PlayerSession>;
#[derive(Clone, Copy, Debug, Eq, WarpTableRow, PartialEq)]
#[index(primary = PlayerSessionId)]
struct PlayerSessionRecord {}
#[derive(Debug, Eq, WarpTableRow, PartialEq)]
#[index(primary = u64)]
struct ImportedPet {
name: &'static str,
}
#[derive(Debug, Eq, WarpTableRow, PartialEq)]
struct UniquelyNamedPet {
#[index(unique)]
name: u64,
age: u8,
}
#[derive(Debug, Eq, WarpTableRow, PartialEq)]
struct RegisteredPet {
#[index(unique)]
name: u64,
#[index(unique)]
registration: u64,
}
#[cfg(feature = "secondary-indexes")]
#[derive(WarpTableRow)]
struct CategorizedPet {
name: &'static str,
#[index(secondary, range)]
pub age: u8,
}
#[cfg(feature = "secondary-indexes")]
#[derive(WarpTableRow)]
#[index(primary = u64)]
struct ImportedCategorizedPet {
name: &'static str,
#[index(secondary)]
pub age: u8,
}
#[cfg(feature = "secondary-indexes")]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, RangeIndexKey)]
struct Age(u8);
#[cfg(feature = "secondary-indexes")]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, RangeIndexKey)]
struct Temperature {
degrees: i16,
}
#[cfg(feature = "secondary-indexes")]
#[derive(WarpTableRow)]
struct MeasuredPet {
name: &'static str,
#[index(range)]
age: Age,
#[index(range)]
temperature: Temperature,
}
#[cfg(feature = "secondary-indexes")]
#[derive(WarpTableRow)]
struct Owner {
name: &'static str,
}
#[cfg(feature = "secondary-indexes")]
#[derive(WarpTableRow)]
struct OwnedPet {
name: &'static str,
#[index(secondary)]
owner: WarpId<Owner>,
}
#[test]
fn generic_rows_with_borrowed_payloads_work_outside_the_library() -> Result<(), &'static str> {
let payload = [7_u16, 11_u16];
let capacity = Capacity::new(NonZeroU32::new(1).ok_or("capacity was zero")?);
let mut messages = WarpTable::<GenericMessage<'_, u16, 2>>::try_new(capacity)
.map_err(|_| "message storage was unavailable")?;
let WarpTableInsertWithIdOutcome::Inserted { id: 17, .. } =
messages.insert_with_id(17, GenericMessage { payload: &payload })
else {
return Err("generic message was not inserted");
};
let WarpTableGetOutcome::Present { row } = messages.get(17) else {
return Err("generic message was unavailable");
};
assert_eq!(row.payload[0], 7);
assert_eq!(row.payload[1], 11);
Ok(())
}
#[test]
fn identity_only_rows_need_no_placeholder_column() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut sessions = WarpTable::<PlayerSessionRecord>::try_new(capacity)
.map_err(|_| "session storage was unavailable")?;
assert_eq!(core::mem::size_of_val(sessions.columns()), 0);
let WarpTableInsertOutcome::Inserted {
id: first_id,
row: 0,
} = sessions.insert(PlayerSessionRecord {})
else {
return Err("first session was not inserted");
};
let WarpTableInsertOutcome::Inserted {
id: second_id,
row: 1,
} = sessions.insert(PlayerSessionRecord {})
else {
return Err("second session was not inserted");
};
assert_ne!(first_id, second_id);
assert_eq!(
sessions.insert(PlayerSessionRecord {}),
WarpTableInsertOutcome::Full {
rejected: PlayerSessionRecord {},
}
);
let WarpTableGetOutcome::Present { row } = sessions.get(second_id) else {
return Err("second session was unavailable");
};
assert_eq!(*row.id, second_id);
let WarpTableRemoveOutcome::Removed { id, removed, .. } = sessions.remove(first_id) else {
return Err("first session was not removed");
};
assert_eq!((id, removed), (first_id, PlayerSessionRecord {}));
let WarpTableGetOutcome::Present { row } = sessions.get(second_id) else {
return Err("relocated second session was unavailable");
};
assert_eq!(*row.id, second_id);
Ok(())
}
#[test]
fn default_ids_are_typed_generated_and_directly_available() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets =
WarpTable::<Pet>::try_new(capacity).map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id: luna_id, .. } = pets.insert(Pet {
name: "Luna",
age: 4,
}) else {
return Err("Luna could not be inserted");
};
assert_eq!(luna_id, WarpId::<Pet>::MIN);
let WarpTableGetOutcome::Present { row } = pets.get(luna_id) else {
return Err("Luna was unavailable");
};
assert_eq!(*row.id, luna_id);
assert_eq!(*row.name, "Luna");
assert_eq!(row.age, &4);
assert_eq!(
pets.update(luna_id, |mut pet| {
let previous = (*pet.name(), *pet.age());
*pet.name_mut() = "Luna II";
*pet.age_mut() = 5;
previous
}),
WarpTableUpdateOutcome::Updated {
id: luna_id,
row: 0,
output: ("Luna", 4),
}
);
let WarpTableGetOutcome::Present { row } = pets.get(luna_id) else {
return Err("updated Luna was unavailable");
};
assert_eq!((*row.name, *row.age), ("Luna II", 5));
Ok(())
}
#[test]
fn unique_indexes_reject_conflicts_and_follow_dense_row_relocation() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(3).ok_or("capacity was zero")?);
let mut pets = WarpTable::<UniquelyNamedPet>::try_new(capacity)
.map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted {
id: luna_id,
row: 0,
} = pets.insert(UniquelyNamedPet { name: 10, age: 4 })
else {
return Err("Luna could not be inserted");
};
let WarpTableInsertOutcome::UniqueConflict { conflict, rejected } =
pets.insert(UniquelyNamedPet { name: 10, age: 7 })
else {
return Err("duplicate name was accepted");
};
assert_eq!(
conflict,
UniquelyNamedPetUniqueConflict::NameAlreadyPresent {
value: 10,
existing_row: 0,
}
);
assert_eq!(rejected, UniquelyNamedPet { name: 10, age: 7 });
let WarpTableInsertOutcome::Inserted {
id: milo_id,
row: 1,
} = pets.insert(UniquelyNamedPet { name: 20, age: 5 })
else {
return Err("Milo could not be inserted");
};
let WarpTableUniqueGetOutcome::Present { key: 20, row } =
pets.query().get_by_name(20).map_err(|_| "lookup failed")?
else {
return Err("Milo was absent by unique name");
};
assert_eq!((*row.id, *row.name, *row.age), (milo_id, 20, 5));
assert!(matches!(
pets.replace(milo_id, UniquelyNamedPet { name: 10, age: 6 }),
pipecircuit::storage::warp_table::WarpTableReplaceOutcome::UniqueConflict {
conflict: UniquelyNamedPetUniqueConflict::NameAlreadyPresent {
value: 10,
existing_row: 0,
},
rejected: UniquelyNamedPet { name: 10, age: 6 },
..
}
));
assert!(matches!(
pets.update(milo_id, |mut pet| pet.set_name(10)),
WarpTableUpdateOutcome::Updated {
output: Err(UniquelyNamedPetUniqueConflict::NameAlreadyPresent {
value: 10,
existing_row: 0,
}),
..
}
));
assert_eq!(
pets.update(milo_id, |mut pet| pet.set_name(30)),
WarpTableUpdateOutcome::Updated {
id: milo_id,
row: 1,
output: Ok(20),
}
);
assert!(matches!(
pets.query().get_by_name(20).map_err(|_| "lookup failed")?,
WarpTableUniqueGetOutcome::Absent { key: 20 }
));
let WarpTableRemoveOutcome::Removed { .. } = pets.remove(luna_id) else {
return Err("Luna could not be removed");
};
let WarpTableUniqueGetOutcome::Present { key: 30, row } =
pets.query().get_by_name(30).map_err(|_| "lookup failed")?
else {
return Err("relocated Milo was absent by unique name");
};
assert_eq!((*row.id, *row.name), (milo_id, 30));
assert!(matches!(
pets.insert(UniquelyNamedPet { name: 10, age: 8 }),
WarpTableInsertOutcome::Inserted { row: 1, .. }
));
Ok(())
}
#[test]
fn multiple_unique_indexes_remain_independent() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets =
WarpTable::<RegisteredPet>::try_new(capacity).map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id, .. } = pets.insert(RegisteredPet {
name: 10,
registration: 20,
}) else {
return Err("registered pet could not be inserted");
};
assert!(matches!(
pets.insert(RegisteredPet {
name: 10,
registration: 30,
}),
WarpTableInsertOutcome::UniqueConflict {
conflict: RegisteredPetUniqueConflict::NameAlreadyPresent {
value: 10,
existing_row: 0,
},
..
}
));
assert!(matches!(
pets.insert(RegisteredPet {
name: 40,
registration: 20,
}),
WarpTableInsertOutcome::UniqueConflict {
conflict: RegisteredPetUniqueConflict::RegistrationAlreadyPresent {
value: 20,
existing_row: 0,
},
..
}
));
let WarpTableUniqueGetOutcome::Present { row, .. } = pets
.query()
.get_by_registration(20)
.map_err(|_| "registration lookup failed")?
else {
return Err("registered pet was unavailable");
};
assert_eq!(*row.id, id);
assert_eq!(
pets.query_mut()
.update_by_registration(20, |mut pet| pet.set_name(40))
.map_err(|_| "registration update lookup failed")?,
WarpTableUniqueUpdateOutcome::Updated {
key: 20,
id,
row: 0,
output: Ok(10),
}
);
assert!(matches!(
pets.query()
.get_by_name(40)
.map_err(|_| "updated name lookup failed")?,
WarpTableUniqueGetOutcome::Present { .. }
));
Ok(())
}
#[test]
fn unique_indexes_directly_update_their_one_row_and_preserve_absent_context()
-> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets = WarpTable::<UniquelyNamedPet>::try_new(capacity)
.map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id: luna_id, .. } =
pets.insert(UniquelyNamedPet { name: 10, age: 4 })
else {
return Err("Luna could not be inserted");
};
let WarpTableInsertOutcome::Inserted { id: milo_id, .. } =
pets.insert(UniquelyNamedPet { name: 20, age: 5 })
else {
return Err("Milo could not be inserted");
};
assert_eq!(
pets.query_mut()
.update_by_name(20, |mut pet| {
let previous = *pet.age();
*pet.age_mut() = 6;
previous
})
.map_err(|_| "unique update lookup failed")?,
WarpTableUniqueUpdateOutcome::Updated {
key: 20,
id: milo_id,
row: 1,
output: 5,
}
);
assert_eq!(
pets.query_mut()
.update_by_name(20, |mut pet| pet.set_name(10))
.map_err(|_| "conflicting unique update lookup failed")?,
WarpTableUniqueUpdateOutcome::Updated {
key: 20,
id: milo_id,
row: 1,
output: Err(UniquelyNamedPetUniqueConflict::NameAlreadyPresent {
value: 10,
existing_row: 0,
}),
}
);
assert_eq!(
pets.query_mut()
.update_by_name_with(20, 30, |mut pet, replacement| { pet.set_name(replacement) })
.map_err(|_| "contextual unique update lookup failed")?,
WarpTableUniqueUpdateWithOutcome::Updated {
key: 20,
id: milo_id,
row: 1,
output: Ok(20),
}
);
assert_eq!(
pets.query_mut()
.update_by_name_with(99, "unconsumed", |_, context| context)
.map_err(|_| "absent unique update lookup failed")?,
WarpTableUniqueUpdateWithOutcome::Absent {
key: 99,
context: "unconsumed",
}
);
let WarpTableUniqueGetOutcome::Present { row, .. } = pets
.query()
.get_by_name(30)
.map_err(|_| "updated unique lookup failed")?
else {
return Err("updated Milo was absent");
};
assert_eq!((*row.id, *row.age), (milo_id, 6));
let WarpTableUniqueGetOutcome::Present { row, .. } = pets
.query()
.get_by_name(10)
.map_err(|_| "unchanged unique lookup failed")?
else {
return Err("Luna was absent");
};
assert_eq!(*row.id, luna_id);
Ok(())
}
#[test]
fn contextual_updates_consume_present_context_and_preserve_absent_context()
-> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets =
WarpTable::<Pet>::try_new(capacity).map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id, .. } = pets.insert(Pet {
name: "Luna",
age: 4,
}) else {
return Err("Luna could not be inserted");
};
assert_eq!(
pets.update_with(id, "Luna II", |mut pet, replacement| {
let previous = *pet.name();
*pet.name_mut() = replacement;
previous
}),
WarpTableUpdateWithOutcome::Updated {
id,
row: 0,
output: "Luna",
}
);
let absent = WarpId::new(core::num::NonZeroU64::new(2).ok_or("identifier was zero")?);
assert_eq!(
pets.update_with(absent, "Milo", |_, _| ()),
WarpTableUpdateWithOutcome::Absent {
id: absent,
context: "Milo",
}
);
Ok(())
}
#[test]
fn an_existing_primary_id_slots_in_explicitly() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::MIN);
let mut pets = WarpTable::<ImportedPet>::try_new(capacity)
.map_err(|_| "imported pet storage was unavailable")?;
let WarpTableInsertWithIdOutcome::Inserted { id, .. } =
pets.insert_with_id(42, ImportedPet { name: "Milo" })
else {
return Err("Milo could not be inserted");
};
assert_eq!(id, 42);
let WarpTableGetOutcome::Present { row, .. } = pets.get(42) else {
return Err("Milo was unavailable");
};
assert_eq!(*row.name, "Milo");
Ok(())
}
#[test]
fn primary_entry_preserves_presence_or_vacancy_until_consumed() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets = WarpTable::<ImportedPet>::try_new(capacity)
.map_err(|_| "imported pet storage was unavailable")?;
let WarpTableEntry::Vacant { vacancy } = pets.entry(42) else {
return Err("unused ID was already present");
};
assert_eq!(vacancy.id(), 42);
assert_eq!(
vacancy.insert(ImportedPet { name: "Milo" }),
WarpTableVacantInsertOutcome::Inserted { id: 42, row: 0 }
);
let WarpTableEntry::Present { id, dense_row, row } = pets.entry(42) else {
return Err("inserted ID was vacant");
};
assert_eq!((id, dense_row, *row.name), (42, 0, "Milo"));
Ok(())
}
#[test]
fn vacant_entry_preserves_capacity_and_unique_conflicts() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::MIN);
let mut pets = WarpTable::<UniquelyNamedPet>::try_new(capacity)
.map_err(|_| "pet storage was unavailable")?;
let WarpTableEntry::Vacant { vacancy } = pets.entry(WarpId::MIN) else {
return Err("first generated ID was already present");
};
assert_eq!(
vacancy.insert(UniquelyNamedPet { name: 10, age: 4 }),
WarpTableVacantInsertOutcome::Inserted {
id: WarpId::MIN,
row: 0,
}
);
let second_id = WarpId::new(core::num::NonZeroU64::new(2).ok_or("identifier was zero")?);
let WarpTableEntry::Vacant { vacancy } = pets.entry(second_id) else {
return Err("second ID was already present");
};
assert_eq!(
vacancy.insert(UniquelyNamedPet { name: 10, age: 7 }),
WarpTableVacantInsertOutcome::Full {
id: second_id,
rejected: UniquelyNamedPet { name: 10, age: 7 },
}
);
let larger_capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets = WarpTable::<UniquelyNamedPet>::try_new(larger_capacity)
.map_err(|_| "larger pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { .. } =
pets.insert(UniquelyNamedPet { name: 10, age: 4 })
else {
return Err("first pet could not be inserted");
};
let WarpTableEntry::Vacant { vacancy } = pets.entry(second_id) else {
return Err("second ID was already present");
};
assert_eq!(
vacancy.insert(UniquelyNamedPet { name: 10, age: 7 }),
WarpTableVacantInsertOutcome::UniqueConflict {
id: second_id,
conflict: UniquelyNamedPetUniqueConflict::NameAlreadyPresent {
value: 10,
existing_row: 0,
},
rejected: UniquelyNamedPet { name: 10, age: 7 },
}
);
Ok(())
}
#[test]
fn upsert_inserts_replaces_at_capacity_and_returns_rejected_rows() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::MIN);
let mut pets = WarpTable::<ImportedPet>::try_new(capacity)
.map_err(|_| "imported pet storage was unavailable")?;
assert_eq!(
pets.upsert(42, ImportedPet { name: "Luna" }),
WarpTableUpsertOutcome::Inserted { id: 42, row: 0 }
);
assert_eq!(
pets.upsert(42, ImportedPet { name: "Luna II" }),
WarpTableUpsertOutcome::Replaced {
id: 42,
row: 0,
previous: ImportedPet { name: "Luna" },
}
);
assert_eq!(
pets.upsert(7, ImportedPet { name: "Milo" }),
WarpTableUpsertOutcome::Full {
id: 7,
rejected: ImportedPet { name: "Milo" },
}
);
let WarpTableGetOutcome::Present { row } = pets.get(42) else {
return Err("upserted pet was unavailable");
};
assert_eq!(*row.name, "Luna II");
Ok(())
}
#[cfg(feature = "secondary-indexes")]
#[test]
fn branded_ids_are_secondary_index_keys_across_tables() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::MIN);
let mut owners =
WarpTable::<Owner>::try_new(capacity).map_err(|_| "owner storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id: owner_id, .. } =
owners.insert(Owner { name: "Ken" })
else {
return Err("owner could not be inserted");
};
let mut pets =
WarpTable::<OwnedPet>::try_new(capacity).map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { .. } = pets.insert(OwnedPet {
name: "Luna",
owner: owner_id,
}) else {
return Err("pet could not be inserted");
};
let mut matches = pets.query().find_owner(owner_id).rows();
let Some(pet) = matches.next() else {
return Err("owned pet was unavailable");
};
assert_eq!((*pet.name, *pet.owner), ("Luna", owner_id));
assert!(matches.next().is_none());
Ok(())
}
#[cfg(feature = "secondary-indexes")]
#[test]
fn mutable_selections_remove_their_first_stable_member() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(3).ok_or("capacity was zero")?);
let mut pets = WarpTable::<CategorizedPet>::try_new(capacity)
.map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id: luna_id, .. } = pets.insert(CategorizedPet {
name: "Luna",
age: 4,
}) else {
return Err("Luna could not be inserted");
};
let WarpTableInsertOutcome::Inserted { id: milo_id, .. } = pets.insert(CategorizedPet {
name: "Milo",
age: 4,
}) else {
return Err("Milo could not be inserted");
};
let WarpTableInsertOutcome::Inserted { id: suki_id, .. } = pets.insert(CategorizedPet {
name: "Suki",
age: 7,
}) else {
return Err("Suki could not be inserted");
};
assert!(matches!(
pets.query_mut()
.find_age(4)
.and(|query| query.find_age(7))
.remove_first(),
MutableSelectionRemoveFirstOutcome::Empty
));
assert_eq!(pets.ids(), &[luna_id, milo_id, suki_id]);
assert!(!pets.query_mut().find_age(4).is_empty());
assert_eq!(pets.query_mut().find_age(4).len(), 2);
let MutableSelectionRemoveFirstOutcome::Removed {
id,
removed,
relocation,
} = pets.query_mut().find_age(4).remove_first()
else {
return Err("first age-four pet was unavailable");
};
assert_eq!((id, removed.name, removed.age), (luna_id, "Luna", 4));
assert_eq!(
relocation,
WarpTableRowRelocation::Relocated {
id: suki_id,
from: 2,
to: 0,
}
);
let MutableSelectionRemoveFirstOutcome::Removed {
id,
removed,
relocation,
} = pets.query_mut().find_age(4).remove_first()
else {
return Err("second age-four pet was unavailable");
};
assert_eq!((id, removed.name, removed.age), (milo_id, "Milo", 4));
assert_eq!(relocation, WarpTableRowRelocation::Stable);
assert!(matches!(
pets.query_mut().find_age(4).remove_first(),
MutableSelectionRemoveFirstOutcome::Empty
));
Ok(())
}
#[test]
fn bulk_insertion_observes_every_generated_id_and_rejected_row() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets =
WarpTable::<Pet>::try_new(capacity).map_err(|_| "pet storage was unavailable")?;
let mut inserted = Vec::new();
let mut rejected = Vec::new();
let outcome = pets.insert_all(
[
Pet {
name: "Luna",
age: 4,
},
Pet {
name: "Milo",
age: 7,
},
Pet {
name: "Suki",
age: 9,
},
],
|outcome| match outcome {
WarpTableInsertOutcome::Inserted { id, .. } => inserted.push(id),
WarpTableInsertOutcome::Full { rejected: pet }
| WarpTableInsertOutcome::IdentifiersExhausted { rejected: pet } => {
rejected.push(pet.name);
}
},
);
assert_eq!(outcome, WarpTableInsertAllOutcome::Completed);
assert_eq!(inserted.len(), 2);
assert_eq!(rejected, ["Suki"]);
assert_eq!(pets.len(), 2);
Ok(())
}
#[test]
fn bulk_caller_ids_preserve_duplicate_and_capacity_outcomes() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets = WarpTable::<ImportedPet>::try_new(capacity)
.map_err(|_| "imported pet storage was unavailable")?;
let mut inserted = Vec::new();
let mut rejected = Vec::new();
let outcome = pets.insert_all_with_id(
[
(42, ImportedPet { name: "Luna" }),
(42, ImportedPet { name: "Duplicate" }),
(7, ImportedPet { name: "Milo" }),
(9, ImportedPet { name: "Suki" }),
],
|outcome| match outcome {
WarpTableInsertWithIdOutcome::Inserted { id, .. } => inserted.push(id),
WarpTableInsertWithIdOutcome::AlreadyPresent {
id, rejected: pet, ..
}
| WarpTableInsertWithIdOutcome::Full { id, rejected: pet } => {
rejected.push((id, pet.name));
}
},
);
assert_eq!(outcome, WarpTableInsertAllOutcome::Completed);
assert_eq!(inserted, [42, 7]);
assert_eq!(rejected, [(42, "Duplicate"), (9, "Suki")]);
assert_eq!(pets.len(), 2);
Ok(())
}
#[test]
fn logical_rows_scan_in_dense_order_with_identity() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets =
WarpTable::<Pet>::try_new(capacity).map_err(|_| "pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id: luna_id, .. } = pets.insert(Pet {
name: "Luna",
age: 4,
}) else {
return Err("Luna could not be inserted");
};
let WarpTableInsertOutcome::Inserted { id: milo_id, .. } = pets.insert(Pet {
name: "Milo",
age: 7,
}) else {
return Err("Milo could not be inserted");
};
let mut rows = pets.rows();
assert_eq!(rows.len(), 2);
let Some(first) = rows.next() else {
return Err("first logical row was unavailable");
};
assert_eq!((*first.id, first.name, first.age), (luna_id, &"Luna", &4));
assert_eq!(rows.len(), 1);
let Some(second) = rows.next() else {
return Err("second logical row was unavailable");
};
assert_eq!(
(*second.id, second.name, second.age),
(milo_id, &"Milo", &7)
);
assert_eq!(rows.len(), 0);
assert!(rows.next().is_none());
assert!(rows.next().is_none());
Ok(())
}
#[cfg(feature = "secondary-indexes")]
#[test]
fn range_key_wrappers_preserve_their_inner_ordering() -> Result<(), &'static str> {
assert_eq!(Age::BITS, u8::BITS);
assert_eq!(Age(7).ordered_word(), 7);
assert!(Temperature { degrees: -1 }.ordered_word() < Temperature { degrees: 1 }.ordered_word());
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets = WarpTable::<MeasuredPet>::try_new(capacity)
.map_err(|_| "measured pet storage was unavailable")?;
for (name, age, degrees) in [("Luna", 4, -2), ("Milo", 7, 3)] {
let WarpTableInsertOutcome::Inserted { .. } = pets.insert(MeasuredPet {
name,
age: Age(age),
temperature: Temperature { degrees },
}) else {
return Err("measured pet could not be inserted");
};
}
let ages = pets
.query()
.find_age_in(Age(4)..=Age(6))
.map_err(|_| "age range was unavailable")?;
let Some(luna) = ages.rows().next() else {
return Err("Luna was absent from the wrapped range");
};
assert_eq!((*luna.name, *luna.age), ("Luna", Age(4)));
Ok(())
}
#[cfg(feature = "secondary-indexes")]
#[test]
fn a_secondary_field_generates_an_external_lookup_surface() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::MIN);
let mut pets = WarpTable::<CategorizedPet>::try_new(capacity)
.map_err(|_| "categorized pet storage was unavailable")?;
let WarpTableInsertOutcome::Inserted { id, row: dense_row } = pets.insert(CategorizedPet {
name: "Luna",
age: 4,
}) else {
return Err("categorized pet could not be inserted");
};
assert_eq!(dense_row, 0);
let selection = pets.query().find_age(4);
assert_eq!(selection.len(), 1);
assert!(!selection.is_empty());
let Some(row) = selection.rows().next() else {
return Err("age membership did not resolve to Luna");
};
assert_eq!(*row.id, id);
assert_eq!((row.name, row.age), (&"Luna", &4));
let ranged = pets
.query()
.find_age_in(3..5)
.map_err(|_| "age range index was inconsistent")?;
assert_eq!(ranged.len(), 1);
assert!(!ranged.is_empty());
let absent_range = pets
.query()
.find_age_in(8..10)
.map_err(|_| "absent age range index was inconsistent")?;
assert_eq!(absent_range.len(), 0);
assert!(absent_range.is_empty());
assert!(absent_range.rows().next().is_none());
let WarpTableGetOutcome::Present { row, .. } = pets.get(id) else {
return Err("Luna was unavailable by ID");
};
assert_eq!(row.name, &"Luna");
assert_eq!(row.age, &4);
Ok(())
}
#[cfg(feature = "secondary-indexes")]
#[test]
fn caller_owned_ids_flow_through_secondary_queries() -> Result<(), &'static str> {
let capacity = Capacity::new(NonZeroU32::new(2).ok_or("capacity was zero")?);
let mut pets = WarpTable::<ImportedCategorizedPet>::try_new(capacity)
.map_err(|_| "imported pet storage was unavailable")?;
for (id, name) in [(42, "Luna"), (9001, "Milo")] {
let WarpTableInsertWithIdOutcome::Inserted {
id: inserted_id, ..
} = pets.insert_with_id(id, ImportedCategorizedPet { name, age: 4 })
else {
return Err("imported pet could not be inserted");
};
assert_eq!(inserted_id, id);
}
let selection = pets.query().find_age(4);
let mut rows = selection.rows();
assert_eq!(rows.size_hint(), (2, Some(2)));
#[cfg(target_pointer_width = "64")]
assert_eq!(rows.len(), 2);
let Some(row) = rows.next_back() else {
return Err("last imported pet was unavailable");
};
assert_eq!((*row.id, row.name), (9001, &"Milo"));
assert_eq!(rows.size_hint(), (1, Some(1)));
#[cfg(target_pointer_width = "64")]
assert_eq!(rows.len(), 1);
let Some(row) = rows.next() else {
return Err("first imported pet was unavailable");
};
assert_eq!((*row.id, row.name), (42, &"Luna"));
assert!(rows.next().is_none());
assert!(rows.next_back().is_none());
assert!(matches!(
pets.remove(42),
WarpTableRemoveOutcome::Removed {
id: 42,
relocation: WarpTableRowRelocation::Relocated {
id: 9001,
from: 1,
to: 0,
},
..
}
));
let selection = pets.query().find_age(4);
let Some(row) = selection.rows().next() else {
return Err("relocated imported pet was unavailable");
};
assert_eq!((*row.id, row.name), (9001, &"Milo"));
Ok(())
}
#[cfg(feature = "secondary-indexes")]
#[test]
fn empty_query_results_obey_subset_and_disjointness_laws() -> Result<(), &'static str> {
let mut pets = WarpTable::<CategorizedPet>::try_new(Capacity::new(NonZeroU32::MIN))
.map_err(|_| "pet storage unavailable")?;
let WarpTableInsertOutcome::Inserted { .. } = pets.insert(CategorizedPet {
name: "Luna",
age: 4,
}) else {
return Err("pet insertion refused");
};
let present = || pets.query().find_age(4);
let absent = || pets.query().find_age(9);
let owned_empty = || present().and_not_selection(present());
assert!(owned_empty().is_empty());
assert!(owned_empty().is_subset(absent()));
assert!(owned_empty().is_subset(owned_empty()));
assert!(absent().is_subset(&absent()));
assert!(!present().is_disjoint(&present()));
assert!(present().is_disjoint(&absent()));
assert!(absent().is_disjoint(&present()));
assert!(absent().is_disjoint(&absent()));
assert!(!present().is_subset(&absent()));
assert!(!present().and_selection(present()).is_subset(absent()));
Ok(())
}