|
@@ -45,7 +45,7 @@ pub struct WrapperIterator<'a> {
|
|
pub limit: Option<usize>,
|
|
pub limit: Option<usize>,
|
|
pub returned: usize,
|
|
pub returned: usize,
|
|
|
|
|
|
- pub current_event_by_prefix: Option<CurrentEventByPrefixFuture<'a>>,
|
|
|
|
|
|
+ pub future_event: Option<CurrentEventByPrefixFuture<'a>>,
|
|
}
|
|
}
|
|
|
|
|
|
impl<'a> WrapperIterator<'a> {
|
|
impl<'a> WrapperIterator<'a> {
|
|
@@ -53,6 +53,7 @@ impl<'a> WrapperIterator<'a> {
|
|
/// secondary index. If no prefix is available from prefixes the functions
|
|
/// secondary index. If no prefix is available from prefixes the functions
|
|
/// return None, signalling upstream the are no more results
|
|
/// return None, signalling upstream the are no more results
|
|
fn select_next_prefix_using_secondary_index(&mut self) -> Option<()> {
|
|
fn select_next_prefix_using_secondary_index(&mut self) -> Option<()> {
|
|
|
|
+ self.secondary_index_iterator = None;
|
|
let prefix = self.prefixes.pop_front()?;
|
|
let prefix = self.prefixes.pop_front()?;
|
|
self.secondary_index_iterator = Some(
|
|
self.secondary_index_iterator = Some(
|
|
self.db
|
|
self.db
|
|
@@ -62,6 +63,37 @@ impl<'a> WrapperIterator<'a> {
|
|
self.current_prefix = prefix;
|
|
self.current_prefix = prefix;
|
|
Some(())
|
|
Some(())
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ fn handle_future_call(&mut self, cx: &mut Context<'_>) -> FutureStatus {
|
|
|
|
+ if let Some(mut future_event) = self.future_event.take() {
|
|
|
|
+ match future_event.poll_unpin(cx) {
|
|
|
|
+ Poll::Ready(Ok(None)) => FutureStatus::FoundNotMatch,
|
|
|
|
+ Poll::Ready(Ok(Some(event))) => {
|
|
|
|
+ // event is ready, apply the neccesary filters
|
|
|
|
+ if let Some(filter) = &self.filter {
|
|
|
|
+ if filter.check_event(&event) {
|
|
|
|
+ FutureStatus::Found(Ok(event))
|
|
|
|
+ } else {
|
|
|
|
+ FutureStatus::FoundNotMatch
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ FutureStatus::Found(Ok(event))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Poll::Ready(Err(error)) => return FutureStatus::Found(Err(error)),
|
|
|
|
+ Poll::Pending => FutureStatus::Pending,
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ FutureStatus::Ended
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+enum FutureStatus {
|
|
|
|
+ Found(Result<Event, Error>),
|
|
|
|
+ Pending,
|
|
|
|
+ Ended,
|
|
|
|
+ FoundNotMatch,
|
|
}
|
|
}
|
|
|
|
|
|
impl<'a> Stream for WrapperIterator<'a> {
|
|
impl<'a> Stream for WrapperIterator<'a> {
|
|
@@ -79,64 +111,60 @@ impl<'a> Stream for WrapperIterator<'a> {
|
|
let this = Pin::into_inner(self);
|
|
let this = Pin::into_inner(self);
|
|
let db = this.db;
|
|
let db = this.db;
|
|
|
|
|
|
- if let Some(mut current_event_filter) = this.current_event_by_prefix.take() {
|
|
|
|
- match current_event_filter.poll_unpin(cx) {
|
|
|
|
- Poll::Ready(Ok(Some(event))) => {
|
|
|
|
- // event is ready, apply the neccesary filters
|
|
|
|
- if let Some(filter) = &this.filter {
|
|
|
|
- if filter.check_event(&event) {
|
|
|
|
- this.returned += 1;
|
|
|
|
- return Poll::Ready(Some(Ok(event)));
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- this.returned += 1;
|
|
|
|
- return Poll::Ready(Some(Ok(event)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- Poll::Ready(Err(x)) => return Poll::Ready(Some(Err(x))),
|
|
|
|
- Poll::Pending => {
|
|
|
|
- // add it back
|
|
|
|
- this.current_event_by_prefix = Some(current_event_filter);
|
|
|
|
- return Poll::Pending;
|
|
|
|
- }
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
|
|
+ match this.handle_future_call(cx) {
|
|
|
|
+ FutureStatus::Found(event) => return Poll::Ready(Some(event)),
|
|
|
|
+ FutureStatus::Pending => return Poll::Pending,
|
|
|
|
+ FutureStatus::FoundNotMatch | FutureStatus::Ended => {}
|
|
}
|
|
}
|
|
- let secondary_index = if let Some(iterator) = this.secondary_index_iterator.as_mut() {
|
|
|
|
- iterator
|
|
|
|
- } else {
|
|
|
|
- return Poll::Ready(None);
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- match secondary_index.next() {
|
|
|
|
- Some(Ok((key, value))) => {
|
|
|
|
- if !key.starts_with(&this.current_prefix) {
|
|
|
|
- if this.select_next_prefix_using_secondary_index().is_none() {
|
|
|
|
- return Poll::Ready(None);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- // query the database to get the record
|
|
|
|
- this.current_event_by_prefix = Some(db.get_event(value));
|
|
|
|
- }
|
|
|
|
|
|
|
|
- Poll::Pending
|
|
|
|
- }
|
|
|
|
- Some(Err(err)) => Poll::Ready(Some(Err(Error::Internal(err.to_string())))),
|
|
|
|
- None => {
|
|
|
|
|
|
+ loop {
|
|
|
|
+ let secondary_index = if let Some(iterator) = this.secondary_index_iterator.as_mut() {
|
|
|
|
+ iterator
|
|
|
|
+ } else {
|
|
if this.namespace.is_some() {
|
|
if this.namespace.is_some() {
|
|
- if this.select_next_prefix_using_secondary_index().is_none() {
|
|
|
|
|
|
+ let _ = this.select_next_prefix_using_secondary_index();
|
|
|
|
+ if let Some(iterator) = this.secondary_index_iterator.as_mut() {
|
|
|
|
+ iterator
|
|
|
|
+ } else {
|
|
return Poll::Ready(None);
|
|
return Poll::Ready(None);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
// No secondary index is used to query, this means the query is
|
|
// No secondary index is used to query, this means the query is
|
|
// using the ID filter, so it is more efficient to use the
|
|
// using the ID filter, so it is more efficient to use the
|
|
// primary index to prefetch events that may satisfy the query
|
|
// primary index to prefetch events that may satisfy the query
|
|
- let current_event_by_prefix =
|
|
|
|
- this.prefixes.pop_front().map(|prefix| db.get_event(prefix));
|
|
|
|
- this.current_event_by_prefix = current_event_by_prefix;
|
|
|
|
|
|
+ return if let Some(prefix) = this.prefixes.pop_front() {
|
|
|
|
+ this.future_event = Some(db.get_event(prefix));
|
|
|
|
+ match this.handle_future_call(cx) {
|
|
|
|
+ FutureStatus::Found(event) => Poll::Ready(Some(event)),
|
|
|
|
+ FutureStatus::Pending => Poll::Pending,
|
|
|
|
+ FutureStatus::FoundNotMatch | FutureStatus::Ended => continue,
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ Poll::Ready(None)
|
|
|
|
+ };
|
|
}
|
|
}
|
|
- Poll::Pending
|
|
|
|
- }
|
|
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return match secondary_index.next() {
|
|
|
|
+ Some(Ok((key, value))) => {
|
|
|
|
+ if !key.starts_with(&this.current_prefix) {
|
|
|
|
+ let _ = this.select_next_prefix_using_secondary_index();
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.future_event = Some(db.get_event(value));
|
|
|
|
+ match this.handle_future_call(cx) {
|
|
|
|
+ FutureStatus::Found(event) => Poll::Ready(Some(event)),
|
|
|
|
+ FutureStatus::Pending => Poll::Pending,
|
|
|
|
+ FutureStatus::FoundNotMatch | FutureStatus::Ended => continue,
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Some(Err(err)) => Poll::Ready(Some(Err(Error::Internal(err.to_string())))),
|
|
|
|
+ None => {
|
|
|
|
+ let _ = this.select_next_prefix_using_secondary_index();
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|