1 module fdb.rangeinfo; 2 3 import 4 std.array, 5 std.exception; 6 7 import 8 fdb.fdb_c, 9 fdb.fdb_c_options; 10 11 struct Selector 12 { 13 Key key; 14 bool orEqual; 15 int offset; 16 } 17 18 struct RangeInfo 19 { 20 Selector begin; 21 Selector end; 22 int limit; 23 StreamingMode mode; 24 int iteration; 25 bool reverse; 26 } 27 28 /* 29 * #define FDB_KEYSEL_LAST_LESS_THAN(k, l) k, l, 0, 0 30 * #define FDB_KEYSEL_LAST_LESS_OR_EQUAL(k, l) k, l, 1, 0 31 * #define FDB_KEYSEL_FIRST_GREATER_THAN(k, l) k, l, 1, 1 32 * #define FDB_KEYSEL_FIRST_GREATER_OR_EQUAL(k, l) k, l, 0, 1 33 */ 34 35 auto lastLessThan(const Key key) 36 { 37 return Selector(key.dup, false, 0); 38 } 39 40 auto lastLessOrEqual(const Key key) 41 { 42 return Selector(key.dup, true, 0); 43 } 44 45 auto firstGreaterThan(const Key key) 46 { 47 return Selector(key.dup, true, 1); 48 } 49 50 auto firstGreaterOrEqual(const Key key) 51 { 52 return Selector(key.dup, false, 1); 53 } 54 55 auto createRangeInfo( 56 const Key begin, 57 const Key end = null, 58 const int limit = 0, 59 const StreamingMode mode = StreamingMode.ITERATOR, 60 const bool reverse = false, 61 const int iteration = 1) 62 { 63 auto sanBegin = sanitizeKey(begin, [ 0x00 ]); 64 auto sanEnd = sanitizeKey(end, sanBegin.getEndPrefix); 65 66 auto beginSel = sanBegin.firstGreaterOrEqual; 67 auto endSel = sanEnd.firstGreaterOrEqual; 68 69 auto rangeInfo = RangeInfo( 70 beginSel, endSel, limit, mode, iteration, reverse); 71 return rangeInfo; 72 } 73 74 auto createRangeInfoInclusive( 75 const Key begin, 76 const Key end = null, 77 const int limit = 0, 78 const StreamingMode mode = StreamingMode.ITERATOR, 79 const bool reverse = false, 80 const int iteration = 1) 81 { 82 auto sanBegin = sanitizeKey(begin, [ 0x00 ]); 83 auto sanEnd = sanitizeKey(end, sanBegin.getEndPrefix); 84 85 auto beginSel = sanBegin.firstGreaterOrEqual; 86 auto endSel = sanEnd.firstGreaterThan; 87 88 auto rangeInfo = RangeInfo( 89 beginSel, endSel, limit, mode, iteration, reverse); 90 return rangeInfo; 91 } 92 93 auto createRangeInfo( 94 Selector beginSel, 95 Selector endSel, 96 const int limit = 0, 97 const StreamingMode mode = StreamingMode.ITERATOR, 98 const bool reverse = false, 99 const int iteration = 1) 100 { 101 auto rangeInfo = RangeInfo( 102 beginSel, endSel, limit, mode, iteration, reverse); 103 return rangeInfo; 104 } 105 106 alias range = createRangeInfo; 107 alias rangeInclusive = createRangeInfoInclusive; 108 109 auto sanitizeKey(const Key key, lazy Key fallback) pure 110 { 111 if (key is null || key.empty) 112 return fallback; 113 return key; 114 } 115 116 auto getEndPrefix(const Key prefix) pure 117 in 118 { 119 enforce(prefix !is null); 120 enforce(prefix.length > 0); 121 } 122 body 123 { 124 ulong i = prefix.length; 125 if (i == 1) return [ cast(ubyte) 0xff ]; 126 127 do --i; 128 while (i != 0 && prefix[i] == 0xff); 129 130 enforce(prefix[i] != 0xff, "All prefix bytes cannot equal 0xff"); 131 132 auto endPrefix = prefix[0 .. i + 1].dup; 133 ++endPrefix[i]; 134 return endPrefix; 135 }