1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use super::{reader, Collection, FieldReader};
use crate::object;
use std::{marker::PhantomData, sync::Arc};

/// Result of a query predicate
pub enum QueryAction {
    /// Pull the current value into memory.
    Take,
    /// Skip the current value and deserialize the next one.
    Skip,
    /// Abort the query and _don't_ pull the current value to memory.
    Abort,
}

pub(crate) struct QueryIteratorOwned<T, F, R> {
    transaction: reader::Transaction,
    object: R,
    predicate: Arc<F>,
    _fieldtype: PhantomData<T>,
}

impl<T, K, R, F> QueryIteratorOwned<T, F, R>
where
    T: Collection<Key = K>,
    F: Fn(&K) -> QueryAction,
    R: object::Reader,
{
    pub fn new(
        mut transaction: reader::Transaction,
        mut object: R,
        predicate: Arc<F>,
        field: &mut T,
    ) -> Self {
        field.load_head(&mut transaction, &mut object);
        Self {
            transaction,
            object,
            predicate,
            _fieldtype: PhantomData,
        }
    }
}

impl<T, K, R, F> Iterator for QueryIteratorOwned<T, F, R>
where
    T: Collection<Key = K>,
    F: Fn(&K) -> QueryAction,
    R: object::Reader,
{
    type Item = <T as Collection>::Item;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        while let Ok(item) = self.transaction.read_next::<T::Serialized>() {
            use QueryAction::*;

            match (self.predicate)(T::key(&item)) {
                Take => return Some(T::load(item, &mut self.object)),
                Skip => continue,
                Abort => return None,
            }
        }

        None
    }
}

pub(crate) struct QueryIterator<'reader, T, F> {
    transaction: reader::Transaction,
    object: &'reader mut dyn object::Reader,
    predicate: Arc<F>,
    _fieldtype: PhantomData<T>,
}

impl<'reader, T, K, F> QueryIterator<'reader, T, F>
where
    T: Collection<Key = K>,
    F: Fn(&K) -> QueryAction,
{
    pub fn new(
        mut transaction: reader::Transaction,
        object: &'reader mut dyn object::Reader,
        predicate: Arc<F>,
        field: &mut T,
    ) -> Self {
        field.load_head(&mut transaction, object);
        Self {
            transaction,
            object,
            predicate,
            _fieldtype: PhantomData,
        }
    }
}

impl<'reader, T, K, F> Iterator for QueryIterator<'reader, T, F>
where
    T: Collection<Key = K>,
    F: Fn(&K) -> QueryAction,
{
    type Item = <T as Collection>::Item;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        while let Ok(item) = self.transaction.read_next::<T::Serialized>() {
            use QueryAction::*;

            match (self.predicate)(T::key(&item)) {
                Take => return Some(T::load(item, self.object)),
                Skip => continue,
                Abort => return None,
            }
        }

        None
    }
}