|
|
@ -14,29 +14,47 @@ pub struct StoreSearchIter<'a, T: ?Sized>(&'a Store, Option<Range<'a, String, Ar
|
|
|
|
// Accessing
|
|
|
|
// Accessing
|
|
|
|
impl Store
|
|
|
|
impl Store
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
//TODO: Parallelize this with futures::Stream ver to do the `tag_search` lookups in parallel.
|
|
|
|
|
|
|
|
pub fn tag_search_all<'a, T: ?Sized + Ord + 'a>(&'a self, tags: impl IntoIterator<Item= &'a T>) -> impl Iterator<Item = &'a Entry> + 'a
|
|
|
|
|
|
|
|
where String: Borrow<T>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let tags: SmallVec<[_; 5]> = tags.into_iter().collect();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tags.iter().flat_map(|&tag| self.tag_search(tag)).dedup_ref()
|
|
|
|
|
|
|
|
.filter(|x| x.tags.iter().map(|x| x.borrow()).filter(|tx| !tags.contains(tx)).count() == 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO: get rid of this ,replace `impl Iterator` return with its own type. */ .collect::<Vec<_>>().into_iter()
|
|
|
|
|
|
|
|
}
|
|
|
|
/// Search for all entries with *any* of these provided tags.
|
|
|
|
/// Search for all entries with *any* of these provided tags.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Notes
|
|
|
|
/// # Notes
|
|
|
|
/// This is allowed to produce duplicate entries.
|
|
|
|
/// This is allowed to produce duplicate entries, if either:
|
|
|
|
pub fn tag_search_many<T: Ord>(&self, tags: impl IntoIterator<Item= T>) -> StoreSearchIter<'_, T>
|
|
|
|
/// * An entry has multiple of the same tag set
|
|
|
|
|
|
|
|
/// * An entry has multiple of the tags provided to this function set
|
|
|
|
|
|
|
|
pub fn tag_search_any<'a, T: ?Sized + Ord + 'a>(&self, tags: impl IntoIterator<Item= &'a T>) -> StoreSearchIter<'_, T>
|
|
|
|
where String: Borrow<T>
|
|
|
|
where String: Borrow<T>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let mut sorted: SmallVec<[_; 5]> = tags.into_iter().collect();
|
|
|
|
let mut sorted: SmallVec<[_; 5]> = tags.into_iter().collect();
|
|
|
|
sorted.sort();
|
|
|
|
sorted.sort();
|
|
|
|
StoreSearchIter(self, Some(match (sorted.first(), sorted.last()) {
|
|
|
|
StoreSearchIter(self, Some(match (sorted.first(), sorted.last()) {
|
|
|
|
(Some(low), Some(high)) => self.tags.range(low..=high),
|
|
|
|
(Some(&low), Some(&high)) => self.tags.range::<T, _>((std::ops::Bound::Included(low), std::ops::Bound::Included(high))),
|
|
|
|
_ => return StoreSearchIter(self, None, Default::default(), PhantomData),
|
|
|
|
_ => return StoreSearchIter(self, None, Default::default(), PhantomData),
|
|
|
|
}), VecDeque::new(), PhantomData)
|
|
|
|
}), VecDeque::new(), PhantomData)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Search for all items with this provided tag.
|
|
|
|
/// Search for all items with this provided tag.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Notes
|
|
|
|
/// # Notes
|
|
|
|
/// This is allowed to produce duplicate entries, if an entry has two of the same tags.
|
|
|
|
/// This is allowed to produce duplicate entries, if an entry has two of the same tags set.
|
|
|
|
pub fn tag_search<'a, T: Ord>(&'a self, tag: T) -> StoreSearchIter<'a, T>
|
|
|
|
pub fn tag_search<'a, T: ?Sized + Ord>(&'a self, tag: &T) -> StoreSearchIter<'a, T>
|
|
|
|
where String: Borrow<T>
|
|
|
|
where String: Borrow<T>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let tag = &tag;
|
|
|
|
let r= (std::ops::Bound::Included(tag), std::ops::Bound::Included(tag));
|
|
|
|
StoreSearchIter(self, Some(self.tags.range(tag..=tag)), VecDeque::new(), PhantomData)
|
|
|
|
StoreSearchIter(self, Some(self.tags.range::<T, _>(r)), VecDeque::new(), PhantomData)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn _assert_test_search(&self)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let _x: Vec<_> = self.tag_search_any(vec!["hello", "one", "two"]).dedup_ref().collect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|