use crate::annotationdata::AnnotationData;
use crate::annotationdataset::AnnotationDataSet;
use crate::api::*;
use crate::datakey::DataKey;
use crate::datavalue::DataOperator;
use crate::store::*;
use crate::substore::AnnotationSubStore;
use rayon::iter::IntoParallelIterator;
impl<'store> FullHandle<AnnotationDataSet> for ResultItem<'store, AnnotationDataSet> {
fn fullhandle(&self) -> <AnnotationDataSet as Storable>::FullHandleType {
self.handle()
}
}
impl<'store> ResultItem<'store, AnnotationDataSet> {
pub fn data(&self) -> ResultIter<impl Iterator<Item = ResultItem<'store, AnnotationData>>> {
let store = self.as_ref();
let rootstore = self.rootstore();
ResultIter::new_sorted(
self.as_ref()
.data()
.map(|data| data.as_resultitem(store, rootstore)),
)
}
pub fn keys(&self) -> ResultIter<impl Iterator<Item = ResultItem<'store, DataKey>>> {
let store = self.as_ref();
let rootstore = self.rootstore();
ResultIter::new_sorted(
self.as_ref()
.keys()
.map(|item| item.as_resultitem(store, rootstore)),
)
}
pub fn key(&self, key: impl Request<DataKey>) -> Option<ResultItem<'store, DataKey>> {
self.as_ref()
.get(key)
.map(|x| x.as_resultitem(self.as_ref(), self.rootstore()))
.ok()
}
pub fn annotationdata(
&self,
annotationdata: impl Request<AnnotationData>,
) -> Option<ResultItem<'store, AnnotationData>> {
self.as_ref()
.get(annotationdata)
.map(|x| x.as_resultitem(self.as_ref(), self.rootstore()))
.ok()
}
pub fn annotations(&self) -> ResultIter<impl Iterator<Item = ResultItem<'store, Annotation>>> {
let store = self.store();
if let Some(annotations) = self.store().annotations_by_dataset_metadata(self.handle()) {
ResultIter::new_sorted(FromHandles::new(annotations.iter().copied(), store))
} else {
ResultIter::new_empty()
}
}
pub fn find_data<'q>(
&self,
key: impl Request<DataKey>,
value: DataOperator<'q>,
) -> Box<dyn Iterator<Item = ResultItem<'store, AnnotationData>> + 'store>
where
'q: 'store,
{
if !key.any() {
if let Some(key) = self.key(key) {
if let DataOperator::Any = value {
return Box::new(key.data());
} else {
return Box::new(key.data().filter_value(value));
}
} else {
return Box::new(std::iter::empty());
}
};
if let DataOperator::Any = value {
Box::new(self.data())
} else {
Box::new(self.data().filter_value(value))
}
}
pub fn test_data<'a>(&self, key: impl Request<DataKey>, value: DataOperator<'a>) -> bool {
self.find_data(key, value).next().is_some()
}
pub fn test(&self, other: impl Request<AnnotationDataSet>) -> bool {
Some(self.handle()) == other.to_handle(self.store())
}
pub fn substores<'a>(
&'a self,
) -> ResultIter<impl Iterator<Item = ResultItem<'a, AnnotationSubStore>>> {
let handle = self.handle();
let store = self.store();
ResultIter::new_sorted(
store
.dataset_substore_map
.get(handle)
.into_iter()
.flatten()
.map(|substorehandle| store.substore(*substorehandle).expect("handle must exist")),
)
}
}
pub type AnnotationDataSets<'store> = Handles<'store, AnnotationDataSet>;
impl<'store, I> FullHandleToResultItem<'store, AnnotationDataSet>
for FromHandles<'store, AnnotationDataSet, I>
where
I: Iterator<Item = AnnotationDataSetHandle>,
{
fn get_item(
&self,
handle: AnnotationDataSetHandle,
) -> Option<ResultItem<'store, AnnotationDataSet>> {
self.store.dataset(handle)
}
}
impl<'store, I> FullHandleToResultItem<'store, AnnotationDataSet>
for FilterAllIter<'store, AnnotationDataSet, I>
where
I: Iterator<Item = ResultItem<'store, AnnotationDataSet>>,
{
fn get_item(
&self,
handle: AnnotationDataSetHandle,
) -> Option<ResultItem<'store, AnnotationDataSet>> {
self.store.dataset(handle)
}
}
pub trait DataSetIterator<'store>: Iterator<Item = ResultItem<'store, AnnotationDataSet>>
where
Self: Sized,
{
fn parallel(self) -> rayon::vec::IntoIter<ResultItem<'store, AnnotationDataSet>> {
let datasets: Vec<_> = self.collect();
datasets.into_par_iter()
}
fn filter_handle(self, set: AnnotationDataSetHandle) -> FilteredDataSets<'store, Self> {
FilteredDataSets {
inner: self,
filter: Filter::AnnotationDataSet(set, SelectionQualifier::Normal),
}
}
fn filter_any(self, datasets: AnnotationDataSets<'store>) -> FilteredDataSets<'store, Self> {
FilteredDataSets {
inner: self,
filter: Filter::DataSets(datasets, FilterMode::Any, SelectionQualifier::Normal),
}
}
fn filter_any_byref(
self,
datasets: &'store AnnotationDataSets<'store>,
) -> FilteredDataSets<'store, Self> {
FilteredDataSets {
inner: self,
filter: Filter::BorrowedDataSets(datasets, FilterMode::Any, SelectionQualifier::Normal),
}
}
fn filter_all(
self,
datasets: AnnotationDataSets<'store>,
store: &'store AnnotationStore,
) -> FilterAllIter<'store, AnnotationDataSet, Self> {
FilterAllIter::new(self, datasets, store)
}
fn filter_one(
self,
data: &ResultItem<'store, AnnotationData>,
) -> FilteredDataSets<'store, Self> {
FilteredDataSets {
inner: self,
filter: Filter::AnnotationData(
data.set().handle(),
data.handle(),
SelectionQualifier::Normal,
),
}
}
fn filter_substore(
self,
substore: Option<ResultItem<'store, AnnotationSubStore>>,
) -> FilteredDataSets<'store, Self> {
if let Some(substore) = substore {
FilteredDataSets {
inner: self,
filter: Filter::AnnotationSubStore(Some(substore.handle())),
}
} else {
FilteredDataSets {
inner: self,
filter: Filter::AnnotationSubStore(None),
}
}
}
}
impl<'store, I> DataSetIterator<'store> for I
where
I: Iterator<Item = ResultItem<'store, AnnotationDataSet>>,
{
}
pub struct FilteredDataSets<'store, I>
where
I: Iterator<Item = ResultItem<'store, AnnotationDataSet>>,
{
inner: I,
filter: Filter<'store>,
}
impl<'store, I> Iterator for FilteredDataSets<'store, I>
where
I: Iterator<Item = ResultItem<'store, AnnotationDataSet>>,
{
type Item = ResultItem<'store, AnnotationDataSet>;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.inner.next() {
if self.test_filter(&item) {
return Some(item);
}
} else {
return None;
}
}
}
}
impl<'store, I> FilteredDataSets<'store, I>
where
I: Iterator<Item = ResultItem<'store, AnnotationDataSet>>,
{
fn test_filter(&self, dataset: &ResultItem<'store, AnnotationDataSet>) -> bool {
match &self.filter {
Filter::DataSets(_, FilterMode::All, _) => {
unreachable!("not handled by this iterator but by FilterAllIter")
}
Filter::BorrowedDataSets(_, FilterMode::All, _) => {
unreachable!("not handled by this iterator but by FilterAllIter")
}
Filter::AnnotationSubStore(substore) => {
if let Some(substore) = substore {
dataset.substores().any(|x| x.handle() == *substore)
} else {
dataset.substores().count() == 0
}
}
_ => unreachable!(
"Filter {:?} not implemented for FilteredDataSets",
self.filter
),
}
}
}