use crate::queries::secondary_index::KeySet;
use crate::traits::idxset::IdxSet;
use crate::traits::record::Record;
use crate::traits::valid_key::{BorrowedKey, ValidKey};
use crate::types::chunk_storage::ChunkStorage;
use crate::types::storage::Storage;
use std::borrow::Borrow;
use std::borrow::Cow;
use std::fmt::Debug;
use std::rc::Rc;
use std::sync::Arc;
pub trait Query<ChunkKey, ItemKey, Element>
where
ChunkKey: BorrowedKey + ?Sized,
ChunkKey::Owned: ValidKey,
ItemKey: BorrowedKey + ?Sized,
ItemKey::Owned: ValidKey,
{
type ChunkIdxSet: IdxSet;
type ItemIdxSet: IdxSet;
fn chunk_idxs(&self, storage: &Storage<ChunkKey, ItemKey, Element>) -> Self::ChunkIdxSet;
fn item_idxs(
&self,
chunk_key: &ChunkKey,
chunk_storage: &ChunkStorage<ChunkKey, ItemKey, Element>,
) -> Self::ItemIdxSet;
fn test(&self, element: &Element) -> bool;
fn filter<F>(self, f: F) -> crate::queries::filter::Filter<Self, F>
where
Self: Sized,
F: Fn(&Element) -> bool + 'static,
{
crate::queries::filter::Filter::new(self, f)
}
fn matching<'a, IndexKeys, IndexKey>(
self,
secondary_index: &'a crate::queries::secondary_index::SecondaryIndex<
ChunkKey,
Element,
IndexKeys,
IndexKey,
>,
key: Cow<'a, IndexKey>,
) -> crate::queries::secondary_index::MatchingSecondaryIndex<
'a,
Self,
ChunkKey,
Element,
IndexKeys,
IndexKey,
>
where
Self: Sized,
IndexKey: BorrowedKey + ?Sized,
IndexKey::Owned: ValidKey,
Element: Record<ChunkKey, ItemKey>,
for<'k> IndexKeys: Clone + Debug + Default + Eq + KeySet<'k, IndexKey>,
{
crate::queries::secondary_index::MatchingSecondaryIndex::new(self, secondary_index, key)
}
}
impl<'a, Q, ChunkKey: ToOwned, ItemKey: ToOwned, Element> Query<ChunkKey, ItemKey, Element>
for &'a Q
where
Q: Query<ChunkKey, ItemKey, Element>,
ChunkKey: BorrowedKey + ?Sized,
ChunkKey::Owned: ValidKey,
ItemKey: BorrowedKey + ?Sized,
ItemKey::Owned: ValidKey,
{
type ChunkIdxSet = Q::ChunkIdxSet;
type ItemIdxSet = Q::ItemIdxSet;
fn chunk_idxs(&self, storage: &Storage<ChunkKey, ItemKey, Element>) -> Self::ChunkIdxSet {
Q::chunk_idxs(self, storage)
}
fn item_idxs(
&self,
chunk_key: &ChunkKey,
chunk_storage: &ChunkStorage<ChunkKey, ItemKey, Element>,
) -> Self::ItemIdxSet {
Q::item_idxs(self, chunk_key, chunk_storage)
}
fn test(&self, element: &Element) -> bool {
Q::test(self, element)
}
}
impl<Q, ChunkKey: ToOwned, ItemKey: ToOwned, Element> Query<ChunkKey, ItemKey, Element> for Rc<Q>
where
Q: Query<ChunkKey, ItemKey, Element>,
ChunkKey: BorrowedKey + ?Sized,
ChunkKey::Owned: ValidKey,
ItemKey: BorrowedKey + ?Sized,
ItemKey::Owned: ValidKey,
{
type ChunkIdxSet = Q::ChunkIdxSet;
type ItemIdxSet = Q::ItemIdxSet;
fn chunk_idxs(&self, storage: &Storage<ChunkKey, ItemKey, Element>) -> Self::ChunkIdxSet {
Q::chunk_idxs(Rc::as_ref(self), storage)
}
fn item_idxs(
&self,
chunk_key: &ChunkKey,
chunk_storage: &ChunkStorage<ChunkKey, ItemKey, Element>,
) -> Self::ItemIdxSet {
Q::item_idxs(Rc::as_ref(self), chunk_key, chunk_storage)
}
fn test(&self, element: &Element) -> bool {
Q::test(Rc::as_ref(self), element)
}
}
impl<Q, ChunkKey: ToOwned, ItemKey: ToOwned, Element> Query<ChunkKey, ItemKey, Element> for Arc<Q>
where
Q: Query<ChunkKey, ItemKey, Element>,
ChunkKey: BorrowedKey + ?Sized,
ChunkKey::Owned: ValidKey,
ItemKey: BorrowedKey + ?Sized,
ItemKey::Owned: ValidKey,
{
type ChunkIdxSet = Q::ChunkIdxSet;
type ItemIdxSet = Q::ItemIdxSet;
fn chunk_idxs(&self, storage: &Storage<ChunkKey, ItemKey, Element>) -> Self::ChunkIdxSet {
Q::chunk_idxs(Arc::as_ref(self), storage)
}
fn item_idxs(
&self,
chunk_key: &ChunkKey,
chunk_storage: &ChunkStorage<ChunkKey, ItemKey, Element>,
) -> Self::ItemIdxSet {
Q::item_idxs(Arc::as_ref(self), chunk_key, chunk_storage)
}
fn test(&self, element: &Element) -> bool {
Q::test(Arc::as_ref(self), element)
}
}
impl<'a, Q, ChunkKey, ItemKey, Element> Query<ChunkKey, ItemKey, Element> for Cow<'a, Q>
where
Q: Query<ChunkKey, ItemKey, Element> + Clone,
ChunkKey: BorrowedKey + ?Sized,
ChunkKey::Owned: ValidKey,
ItemKey: BorrowedKey + ?Sized,
ItemKey::Owned: ValidKey,
{
type ChunkIdxSet = Q::ChunkIdxSet;
type ItemIdxSet = Q::ItemIdxSet;
fn chunk_idxs(&self, storage: &Storage<ChunkKey, ItemKey, Element>) -> Self::ChunkIdxSet {
Q::chunk_idxs(Cow::borrow(self), storage)
}
fn item_idxs(
&self,
chunk_key: &ChunkKey,
chunk_storage: &ChunkStorage<ChunkKey, ItemKey, Element>,
) -> Self::ItemIdxSet {
Q::item_idxs(Cow::borrow(self), chunk_key, chunk_storage)
}
fn test(&self, element: &Element) -> bool {
Q::test(Cow::borrow(self), element)
}
}