1 module fdb.range;
2 
3 import
4     std.array;
5 
6 import
7     fdb.fdb_c,
8     fdb.fdb_c_options,
9     fdb.rangeinfo,
10     fdb.transaction;
11 
12 struct Record
13 {
14     Key   key;
15     Value value;
16 
17     this(Key key, Value value) pure
18     {
19         this.key   = key;
20         this.value = value;
21     }
22 }
23 
24 struct RecordRange
25 {
26     private Record[]           records;
27     private RangeInfo          info;
28     private bool               _more;
29     private shared Transaction tr;
30     private Key                end;
31     private ulong              index;
32 
33     @property auto more() const pure @nogc
34     {
35         return _more;
36     }
37 
38     @property auto length() const pure @nogc
39     {
40         return records.length;
41     }
42 
43     this(
44         Record[]           records,
45         const bool         more,
46         RangeInfo          info,
47         shared Transaction tr)
48     {
49         this.records = records;
50         this._more   = more;
51         this.info    = info;
52         this.tr      = tr;
53 
54         if (!records.empty)
55             this.end = records.back.key.dup;
56     }
57 
58     @property bool empty() const pure @nogc
59     {
60         return records.empty;
61     }
62 
63     auto front() pure @nogc
64     {
65         return records[0];
66     }
67 
68     auto popFront()
69     {
70         records = records[1 .. $];
71         ++index;
72         if (empty && more)
73             fetchNextBatch;
74     }
75 
76     auto save() pure @nogc
77     {
78         return this;
79     }
80 
81     private void fetchNextBatch()
82     {
83         if (!end || index == info.limit)
84         {
85             _more = false;
86             return;
87         }
88 
89         if (info.limit > 0)
90             info.limit -= index;
91 
92         info.iteration++;
93 
94         auto batchInfo = info;
95         if (batchInfo.reverse)
96             batchInfo.end   = end.firstGreaterOrEqual;
97         else
98             batchInfo.begin = end.firstGreaterThan;
99 
100         auto future = tr.getRange(batchInfo);
101         auto batch  = cast(RecordRange)future.await;
102         records     = batch.records;
103         _more       = batch.more;
104 
105         if (!records.empty)
106             end     = records.back.key.dup;
107         else
108             end     = null;
109     }
110 }