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 }