use std::marker::PhantomData;
use std::slice::Iter;
use std::time::Instant;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ColumnId(pub u32);
impl std::hash::Hash for ColumnId {
fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
hasher.write_u32(self.0)
}
}
impl nohash_hasher::IsEnabled for ColumnId {}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ColumnTicket(pub usize);
#[derive(Clone, Debug, PartialEq)]
pub struct Column<ColumnType> {
pub id: ColumnId,
pub data: ColumnType,
}
pub struct ColumnPool<ColumnType, FilterType> {
local_column_counter: u32,
columns: Vec<Column<ColumnType>>,
phantom: PhantomData<FilterType>,
}
impl<ColumnType, FilterType> ColumnPool<ColumnType, FilterType> {
pub fn new() -> Self {
ColumnPool {
local_column_counter: 0,
columns: Vec::new(),
phantom: PhantomData,
}
}
}
pub trait ColumnPoolFilter<ColumnType, FilterType> {
fn get_columns(&self, filters: &[FilterType], ticket : Option<ColumnTicket>) -> (ColumnTicket, Vec<&Column<ColumnType>>);
}
impl<ColumnType, FilterType> ColumnPool<ColumnType, FilterType> {
pub fn count(&self) -> usize {
self.columns.len()
}
pub fn get_column(&self, id: ColumnId) -> &Column<ColumnType> {
let column_at_index = &self.columns[id.0 as usize];
debug_assert_eq!(column_at_index.id.0, id.0);
column_at_index
}
pub fn get_all_columns(&self) -> (ColumnTicket,Iter<Column<ColumnType>>) {
(ColumnTicket(self.columns.len()), self.columns.iter())
}
pub fn add_column(&mut self, column_data: ColumnType, column_ticket: ColumnTicket) -> bool
where
ColumnType: PartialEq,
{
let existing_column = self
.columns
.iter()
.enumerate() .skip(column_ticket.0)
.filter_map(|( i ,c)| if c.data == column_data { Some(i)} else { None})
.next();
if let Some(column) = existing_column {
return false;
} else {
#[cfg(feature = "validity_assertions")]
{
let existing_columns = self
.columns
.iter()
.filter(|c| c.data == column_data)
.next();
assert!(existing_columns.is_none());
}
let column = Column {
id: ColumnId(self.local_column_counter),
data: column_data,
};
self.local_column_counter += 1;
self.columns.push(column);
return true
}
}
}
impl<ColumnType, FilterType> Clone for ColumnPool<ColumnType, FilterType>
where
ColumnType: Clone,
{
fn clone(&self) -> Self {
Self {
local_column_counter: self.local_column_counter,
columns: self.columns.clone(),
phantom: PhantomData,
}
}
}