use std::collections::HashMap;
use std::fmt::Debug;
use std::hash::Hash;
use std::marker::PhantomData;
use variadics::variadic_collections::VariadicCollection;
use variadics::{
var_args, var_type, PartialEqVariadic, RefVariadic, Split, SplitBySuffix, VariadicExt,
};
pub mod colt;
pub mod lattice;
pub mod macros;
pub mod test;
pub trait GeneralizedHashTrieNode: Default {
type Schema: VariadicExt + Eq + Hash + Clone + SplitBySuffix<Self::SuffixSchema>;
type KeyType: VariadicExt + Eq + Hash + Clone;
type ValType: VariadicExt + Eq + Hash + Clone;
type Storage: VariadicCollection<Schema = Self::Schema>
+ Default
+ IntoIterator<Item = Self::Schema>;
type SuffixSchema: VariadicExt + Eq + Hash + Clone;
type Head: Eq + Hash + Clone;
fn new_from(input: impl IntoIterator<Item = Self::Schema>) -> Self;
fn merge_node(&mut self, other: Self) -> bool;
fn height(&self) -> usize {
Self::HEIGHT
}
const HEIGHT: usize;
fn insert(&mut self, row: Self::Schema) -> bool;
fn contains<'a>(&'a self, row: <Self::Schema as VariadicExt>::AsRefVar<'a>) -> bool;
fn recursive_iter(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>>;
fn find_containing_leaf(
&self,
row: <Self::Schema as VariadicExt>::AsRefVar<'_>,
) -> Option<&'_ GhtLeaf<Self::Schema, Self::ValType, Self::Storage>>;
fn into_iter(self) -> Option<impl Iterator<Item = Self::Schema>>;
fn drain(&mut self) -> Option<impl Iterator<Item = Self::Schema>>;
}
#[derive(Debug, Clone)]
pub struct GhtInner<Head, Node>
where
Head: Clone,
Node: GeneralizedHashTrieNode,
{
pub(crate) children: HashMap<Head, Node>,
}
impl<Head, Node: GeneralizedHashTrieNode> Default for GhtInner<Head, Node>
where
Head: Clone,
Node: GeneralizedHashTrieNode,
{
fn default() -> Self {
let children = Default::default();
Self { children }
}
}
impl<Head, Node> GeneralizedHashTrieNode for GhtInner<Head, Node>
where
Head: 'static + Hash + Eq + Clone,
Node: 'static + GeneralizedHashTrieNode,
Node::Schema: SplitBySuffix<var_type!(Head, ...Node::SuffixSchema)>,
{
type Schema = Node::Schema;
type KeyType = Node::KeyType;
type ValType = Node::ValType;
type Storage = Node::Storage;
type SuffixSchema = var_type!(Head, ...Node::SuffixSchema);
type Head = Head;
fn new_from(input: impl IntoIterator<Item = Self::Schema>) -> Self {
let mut retval: Self = Default::default();
for row in input {
retval.insert(row);
}
retval
}
fn merge_node(&mut self, other: Self) -> bool {
let mut changed = false;
for (k, v) in other.children {
match self.children.entry(k) {
std::collections::hash_map::Entry::Occupied(mut occupied) => {
changed |= occupied.get_mut().merge_node(v)
}
std::collections::hash_map::Entry::Vacant(vacant) => {
vacant.insert(v);
changed = true
}
}
}
changed
}
const HEIGHT: usize = Node::HEIGHT + 1;
fn insert(&mut self, row: Self::Schema) -> bool {
let (_prefix, var_args!(head, ..._rest)) =
Self::Schema::split_by_suffix_ref(row.as_ref_var());
self.children.entry(head.clone()).or_default().insert(row)
}
fn contains<'a>(&'a self, row: <Self::Schema as VariadicExt>::AsRefVar<'a>) -> bool {
let (_prefix, var_args!(head, ..._rest)) = Self::Schema::split_by_suffix_ref(row);
if let Some(node) = self.children.get(head) {
node.contains(row)
} else {
false
}
}
fn recursive_iter(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>> {
self.children
.iter()
.flat_map(|(_k, vs)| vs.recursive_iter())
}
fn find_containing_leaf(
&self,
row: <Self::Schema as VariadicExt>::AsRefVar<'_>,
) -> Option<&'_ GhtLeaf<Self::Schema, Self::ValType, Self::Storage>> {
let (_prefix, var_args!(head, ..._rest)) = Self::Schema::split_by_suffix_ref(row);
self.children
.get(head)
.and_then(|child| child.find_containing_leaf(row))
}
fn into_iter(self) -> Option<impl Iterator<Item = Self::Schema>> {
None::<Box<dyn Iterator<Item = Self::Schema>>>
}
fn drain(&mut self) -> Option<impl Iterator<Item = Self::Schema>> {
None::<Box<dyn Iterator<Item = Self::Schema>>>
}
}
impl<Head, Node> FromIterator<Node::Schema> for GhtInner<Head, Node>
where
Head: 'static + Hash + Eq + Clone,
Node: 'static + GeneralizedHashTrieNode + Clone,
Node::Schema: SplitBySuffix<var_type!(Head, ...Node::SuffixSchema)>,
{
fn from_iter<Iter: IntoIterator<Item = Node::Schema>>(iter: Iter) -> Self {
let mut out = Self::default();
for row in iter {
out.insert(row);
}
out
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct GhtLeaf<Schema, ValType, Storage>
where
Schema: Eq + Hash,
Storage: VariadicCollection<Schema = Schema>,
{
pub(crate) elements: Storage,
pub(crate) forced: bool,
pub(crate) _suffix_schema: PhantomData<ValType>,
}
impl<Schema, ValType, Storage> Default for GhtLeaf<Schema, ValType, Storage>
where
Schema: Eq + Hash,
Storage: VariadicCollection<Schema = Schema> + Default,
{
fn default() -> Self {
let elements = Storage::default();
Self {
elements,
forced: false,
_suffix_schema: PhantomData,
}
}
}
impl<Schema, ValHead, ValRest, Storage> GeneralizedHashTrieNode
for GhtLeaf<Schema, var_type!(ValHead, ...ValRest), Storage>
where
Schema: 'static
+ Eq
+ VariadicExt
+ Hash
+ Clone
+ SplitBySuffix<var_type!(ValHead, ...ValRest)>
+ PartialEqVariadic,
ValHead: Clone + Eq + Hash,
var_type!(ValHead, ...ValRest): Clone + Eq + Hash + PartialEqVariadic,
<Schema as SplitBySuffix<var_type!(ValHead, ...ValRest)>>::Prefix: Eq + Hash + Clone,
Storage: VariadicCollection<Schema = Schema> + Default + IntoIterator<Item = Schema>,
{
type Schema = Schema;
type SuffixSchema = var_type!(ValHead, ...ValRest);
type ValType = var_type!(ValHead, ...ValRest);
type KeyType = <Schema as SplitBySuffix<var_type!(ValHead, ...ValRest)>>::Prefix;
type Head = ValHead;
type Storage = Storage;
fn new_from(input: impl IntoIterator<Item = Self::Schema>) -> Self {
let mut retval: Self = Default::default();
for i in input {
retval.insert(i);
}
retval
}
fn merge_node(&mut self, other: Self) -> bool {
let old_len = self.elements.len();
self.elements.extend(other.elements);
self.elements.len() > old_len
}
const HEIGHT: usize = 0;
fn insert(&mut self, row: Self::Schema) -> bool {
self.elements.insert(row);
true
}
fn contains<'a>(&'a self, row: <Self::Schema as VariadicExt>::AsRefVar<'a>) -> bool {
self.elements.iter().any(|r| Schema::eq_ref(r, row))
}
fn recursive_iter(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>> {
self.elements.iter()
}
fn find_containing_leaf(
&self,
row: <Self::Schema as VariadicExt>::AsRefVar<'_>,
) -> Option<&'_ GhtLeaf<<Self as GeneralizedHashTrieNode>::Schema, Self::ValType, Self::Storage>>
{
if self
.elements
.iter()
.any(|x| <Schema as PartialEqVariadic>::eq_ref(row, x))
{
Some(self)
} else {
None
}
}
fn into_iter(self) -> Option<impl Iterator<Item = Self::Schema>> {
Some(self.elements.into_iter())
}
fn drain(&mut self) -> Option<impl Iterator<Item = Self::Schema>> {
Some(self.elements.drain())
}
}
impl<Schema, Storage> GeneralizedHashTrieNode for GhtLeaf<Schema, (), Storage>
where
Schema: 'static + Eq + VariadicExt + Hash + Clone + PartialEqVariadic,
Storage: VariadicCollection<Schema = Schema> + Default + IntoIterator<Item = Schema>,
{
type Schema = Schema;
type SuffixSchema = ();
type ValType = ();
type KeyType = Schema;
type Head = ();
type Storage = Storage;
fn new_from(input: impl IntoIterator<Item = Self::Schema>) -> Self {
let mut retval: Self = Default::default();
for i in input {
retval.insert(i);
}
retval
}
fn merge_node(&mut self, other: Self) -> bool {
let old_len = self.elements.len();
self.elements.extend(other.elements);
self.elements.len() > old_len
}
const HEIGHT: usize = 0;
fn insert(&mut self, row: Self::Schema) -> bool {
self.elements.insert(row);
true
}
fn contains<'a>(&'a self, row: <Self::Schema as VariadicExt>::AsRefVar<'a>) -> bool {
self.elements.iter().any(|r| Schema::eq_ref(r, row))
}
fn recursive_iter(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>> {
self.elements.iter()
}
fn find_containing_leaf(
&self,
row: <Self::Schema as VariadicExt>::AsRefVar<'_>,
) -> Option<&'_ GhtLeaf<<Self as GeneralizedHashTrieNode>::Schema, Self::ValType, Self::Storage>>
{
if self
.elements
.iter()
.any(|x| <Schema as PartialEqVariadic>::eq_ref(row, x))
{
Some(self)
} else {
None
}
}
fn into_iter(self) -> Option<impl Iterator<Item = Self::Schema>> {
Some(self.elements.into_iter())
}
fn drain(&mut self) -> Option<impl Iterator<Item = Self::Schema>> {
Some(self.elements.drain())
}
}
impl<Schema, ValType, Storage> FromIterator<Schema> for GhtLeaf<Schema, ValType, Storage>
where
Schema: Eq + Hash,
Storage: VariadicCollection<Schema = Schema> + Default + FromIterator<Schema>,
{
fn from_iter<Iter: IntoIterator<Item = Schema>>(iter: Iter) -> Self {
let elements = iter.into_iter().collect();
Self {
elements,
forced: false,
_suffix_schema: PhantomData,
}
}
}
pub trait GhtGet: GeneralizedHashTrieNode {
type Get: GeneralizedHashTrieNode<Schema = Self::Schema>;
fn get<'a>(&'a self, head: &Self::Head) -> Option<&'a Self::Get>;
fn get_mut<'a>(&'a mut self, head: &Self::Head) -> Option<&'a mut Self::Get>;
fn iter(&self) -> impl Iterator<Item = Self::Head>;
fn iter_tuples(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>>;
}
impl<Head, Node> GhtGet for GhtInner<Head, Node>
where
Head: 'static + Eq + Hash + Clone,
Node: 'static + GeneralizedHashTrieNode,
Node::Schema: SplitBySuffix<var_type!(Head, ...Node::SuffixSchema)>,
{
type Get = Node;
fn get<'a>(&'a self, head: &Self::Head) -> Option<&'a Self::Get> {
self.children.get(head)
}
fn get_mut<'a>(&'a mut self, head: &Self::Head) -> Option<&'a mut Self::Get> {
self.children.get_mut(head)
}
fn iter(&self) -> impl Iterator<Item = Self::Head> {
self.children.keys().cloned()
}
fn iter_tuples(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>> {
std::iter::empty()
}
}
impl<Schema, ValType, Storage> GhtGet for GhtLeaf<Schema, ValType, Storage>
where
Schema: 'static + Eq + Hash + Clone + PartialEqVariadic + SplitBySuffix<ValType>,
ValType: Eq + Hash + Clone + PartialEqVariadic,
<Schema as SplitBySuffix<ValType>>::Prefix: Eq + Hash + Clone,
GhtLeaf<Schema, ValType, Storage>: GeneralizedHashTrieNode<Schema = Schema>,
Storage: VariadicCollection<Schema = Schema>,
{
type Get = GhtLeaf<Schema, ValType, Storage>;
fn get<'a>(&'a self, _head: &Self::Head) -> Option<&'a Self::Get> {
None
}
fn get_mut<'a>(&'a mut self, _head: &Self::Head) -> Option<&'a mut Self::Get> {
None
}
fn iter(&self) -> impl Iterator<Item = Self::Head> {
std::iter::empty()
}
fn iter_tuples(&self) -> impl Iterator<Item = <Self::Schema as VariadicExt>::AsRefVar<'_>> {
self.elements.iter()
}
}
pub trait GhtPrefixIter<KeyPrefix> {
type Item: VariadicExt;
fn prefix_iter<'a>(
&'a self,
prefix: KeyPrefix,
) -> impl Iterator<Item = <Self::Item as VariadicExt>::AsRefVar<'a>>
where
Self::Item: 'a;
}
impl<'k, Head, Node, PrefixRest> GhtPrefixIter<var_type!(&'k Head, ...PrefixRest)>
for GhtInner<Head, Node>
where
Head: Eq + Hash + Clone,
Node: GeneralizedHashTrieNode + GhtPrefixIter<PrefixRest>,
{
type Item = <Node as GhtPrefixIter<PrefixRest>>::Item;
fn prefix_iter<'a>(
&'a self,
prefix: var_type!(&'k Head, ...PrefixRest),
) -> impl Iterator<Item = <Self::Item as VariadicExt>::AsRefVar<'a>>
where
Self::Item: 'a,
{
let var_args!(head, ...rest) = prefix;
self.children
.get(head)
.map(|node| node.prefix_iter(rest))
.into_iter()
.flatten()
}
}
impl<Head, Node> GhtPrefixIter<var_type!()> for GhtInner<Head, Node>
where
Self: GeneralizedHashTrieNode,
Head: Eq + Hash + Clone,
Node: GeneralizedHashTrieNode,
{
type Item = <Self as GeneralizedHashTrieNode>::Schema;
fn prefix_iter<'a>(
&'a self,
_prefix: var_type!(),
) -> impl Iterator<Item = <Self::Item as VariadicExt>::AsRefVar<'a>>
where
Self::Item: 'a,
{
self.recursive_iter()
}
}
impl<KeyPrefixRef, Schema, ValType, Storage> GhtPrefixIter<KeyPrefixRef>
for GhtLeaf<Schema, ValType, Storage>
where
KeyPrefixRef: 'static + RefVariadic,
Schema: 'static + VariadicExt + Hash + Eq + SplitBySuffix<ValType>,
ValType: VariadicExt,
ValType: Split<KeyPrefixRef::UnRefVar>,
KeyPrefixRef::UnRefVar: PartialEqVariadic,
Storage: 'static + VariadicCollection<Schema = Schema>,
{
type Item = Schema;
fn prefix_iter<'a>(
&'a self,
prefix: KeyPrefixRef,
) -> impl Iterator<Item = <Self::Item as VariadicExt>::AsRefVar<'a>>
where
Self::Item: 'a,
{
self.elements.iter().filter(move |&row| {
let (_row_prefix, row_mid_suffix) =
<Schema as SplitBySuffix<ValType>>::split_by_suffix_ref(row);
let (row_mid, _row_suffix): (<KeyPrefixRef::UnRefVar as VariadicExt>::AsRefVar<'_>, _) =
<ValType as Split<KeyPrefixRef::UnRefVar>>::split_ref(row_mid_suffix);
<KeyPrefixRef::UnRefVar as PartialEqVariadic>::eq_ref(prefix.unref_ref(), row_mid)
})
}
}