use branch numbers to detect branch subsumption

This commit is contained in:
Mark Thom
2025-12-09 23:14:24 -08:00
parent 16dc10ee96
commit 9089f9ddb4
6 changed files with 218 additions and 181 deletions

View File

@@ -18,9 +18,11 @@ use indexmap::{IndexMap, IndexSet};
use ordered_float::OrderedFloat;
use std::cell::Cell;
use std::cmp::Ordering;
use std::collections::VecDeque;
use std::convert::TryFrom;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::{AddAssign, Deref, DerefMut};
use std::path::PathBuf;
@@ -128,10 +130,86 @@ impl ChunkType {
}
}
#[derive(Debug, Clone)] //, PartialOrd, PartialEq, Eq, Hash)]
pub(crate) struct BranchNumber {
pub(crate) branch_num: Rational,
pub(crate) delta: Rational,
}
impl Default for BranchNumber {
fn default() -> Self {
Self {
branch_num: Rational::from(0),
delta: Rational::from(1u64 << 31),
}
}
}
impl PartialEq<BranchNumber> for BranchNumber {
#[inline]
fn eq(&self, rhs: &BranchNumber) -> bool {
self.branch_num == rhs.branch_num
}
}
impl Eq for BranchNumber {}
impl Hash for BranchNumber {
#[inline(always)]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.branch_num.hash(hasher)
}
}
impl PartialOrd<BranchNumber> for BranchNumber {
#[inline]
fn partial_cmp(&self, rhs: &BranchNumber) -> Option<Ordering> {
self.branch_num.partial_cmp(&rhs.branch_num)
}
}
impl BranchNumber {
pub(crate) fn has_as_subbranch(&self, other: &Self) -> bool {
let delta_ratio = &self.delta / &other.delta;
if !delta_ratio.denominator().is_one() {
return false;
}
other.branch_num >= self.branch_num && other.branch_num < &self.branch_num + &self.delta
}
pub(crate) fn split(&self) -> BranchNumber {
BranchNumber {
branch_num: self.branch_num.clone() + &self.delta / Rational::from(2),
delta: &self.delta / Rational::from(4),
}
}
pub(crate) fn incr_by_delta(&self) -> BranchNumber {
BranchNumber {
branch_num: self.branch_num.clone() + &self.delta,
delta: self.delta.clone(),
}
}
pub(crate) fn halve_delta(&self) -> BranchNumber {
BranchNumber {
branch_num: self.branch_num.clone(),
delta: &self.delta / Rational::from(2),
}
}
}
#[derive(Debug)]
pub enum ChunkedTerms {
Branch(Vec<VecDeque<ChunkedTerms>>),
Chunk { terms: VecDeque<QueryTerm> },
Branch {
branch_nums: Vec<BranchNumber>,
arms: Vec<VecDeque<ChunkedTerms>>,
},
Chunk {
terms: VecDeque<QueryTerm>,
},
}
#[derive(Debug)]
@@ -165,21 +243,22 @@ impl ChunkedTermVec {
}
pub fn reserve_branch(&mut self, capacity: usize) {
self.chunk_vec
.push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity)));
self.chunk_vec.push_back(ChunkedTerms::Branch {
branch_nums: Vec::with_capacity(capacity),
arms: Vec::with_capacity(capacity),
});
}
#[inline]
pub fn add_chunk(&mut self) {
let chunk = ChunkedTerms::Chunk {
self.chunk_vec.push_back(ChunkedTerms::Chunk {
terms: VecDeque::from(vec![]),
};
self.chunk_vec.push_back(chunk);
});
}
pub fn push_chunk_term(&mut self, term: QueryTerm) {
match self.chunk_vec.back_mut() {
Some(ChunkedTerms::Branch(_)) => {
Some(ChunkedTerms::Branch { .. }) => {
let chunk = ChunkedTerms::Chunk {
terms: VecDeque::from(vec![term]),
};