Skip to content

Commit 26b47c5

Browse files
KrzysFRabdullin
authored andcommitted
Decouple KeyRange from the key encoders by representing them as a (Slice, Slice) tuple internally
- Add implicit cast between KeyRange and (Slice, Slice) to make this invisible to users
1 parent f6c09b0 commit 26b47c5

File tree

5 files changed

+133
-109
lines changed

5 files changed

+133
-109
lines changed

FoundationDB.Client/KeyRange.cs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace FoundationDB.Client
3838

3939
/// <summary>Represents a pair of keys defining the range 'Begin &lt;= key &gt; End'</summary>
4040
[DebuggerDisplay("Begin={Begin}, End={End}")]
41-
public readonly struct KeyRange : IEquatable<KeyRange>, IComparable<KeyRange>
41+
public readonly struct KeyRange : IEquatable<KeyRange>, IComparable<KeyRange>, IEquatable<(Slice Begin, Slice End)>, IComparable<(Slice Begin, Slice End)>
4242
{
4343

4444
/// <summary>Start of the range</summary>
@@ -50,11 +50,11 @@ namespace FoundationDB.Client
5050
/// <summary>Create a new range of keys</summary>
5151
/// <param name="begin">Start of range (usually included)</param>
5252
/// <param name="end">End of range (usually excluded)</param>
53+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
5354
public KeyRange(Slice begin, Slice end)
5455
{
5556
this.Begin = begin;
5657
this.End = end;
57-
5858
Contract.Ensures(this.Begin <= this.End, "The range is inverted");
5959
}
6060

@@ -122,21 +122,26 @@ public static KeyRange FromKey(Slice key)
122122

123123
public override bool Equals(object obj)
124124
{
125-
return obj is KeyRange range && Equals(range);
125+
if (obj is KeyRange range) return Equals(range);
126+
if (obj is ValueTuple<Slice, Slice> tuple) return Equals(tuple);
127+
return false;
126128
}
127129

128130
public override int GetHashCode()
129131
{
130-
// ReSharper disable NonReadonlyMemberInGetHashCode
131132
return HashCodes.Combine(this.Begin.GetHashCode(), this.End.GetHashCode());
132-
// ReSharper restore NonReadonlyMemberInGetHashCode
133133
}
134134

135135
public bool Equals(KeyRange other)
136136
{
137137
return this.Begin.Equals(other.Begin) && this.End.Equals(other.End);
138138
}
139139

140+
public bool Equals((Slice Begin, Slice End) other)
141+
{
142+
return this.Begin.Equals(other.Begin) && this.End.Equals(other.End);
143+
}
144+
140145
public static bool operator ==(KeyRange left, KeyRange right)
141146
{
142147
return left.Begin.Equals(right.Begin) && left.End.Equals(right.End);
@@ -154,6 +159,25 @@ public int CompareTo(KeyRange other)
154159
return c;
155160
}
156161

162+
public int CompareTo((Slice Begin, Slice End) other)
163+
{
164+
int c = this.Begin.CompareTo(other.Begin);
165+
if (c == 0) c = this.End.CompareTo(other.End);
166+
return c;
167+
}
168+
169+
[Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]
170+
public static implicit operator KeyRange((Slice Begin, Slice End) range)
171+
{
172+
return new KeyRange(range.Begin, range.End);
173+
}
174+
175+
[Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]
176+
public static implicit operator (Slice Begin, Slice End)(KeyRange range)
177+
{
178+
return (range.Begin, range.End);
179+
}
180+
157181
/// <summary>Combine another range with the current range, to produce a range that includes both (and all keys in between it the ranges are disjoint)</summary>
158182
/// <param name="other">Range to merge with the current range</param>
159183
/// <returns>New range where the Begin key is the smallest bound and the End key is the largest bound of both ranges.</returns>

FoundationDB.Client/Shared/TypeSystem/Encoders/DynamicKeyEncoderBase.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public abstract class DynamicKeyEncoderBase : IDynamicKeyEncoder
3838

3939
public abstract IKeyEncoding Encoding { get; }
4040

41-
public virtual KeyRange ToRange(Slice prefix)
41+
public virtual (Slice Begin, Slice End) ToRange(Slice prefix)
4242
{
4343
return KeyRange.StartsWith(prefix);
4444
}
@@ -127,49 +127,49 @@ public virtual STuple<T1, T2, T3, T4, T5, T6> DecodeKey<T1, T2, T3, T4, T5, T6>(
127127
return UnpackKey(packed).With((T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) => STuple.Create(a, b, c, d, e, f));
128128
}
129129

130-
public virtual KeyRange ToRange(Slice prefix, ITuple items)
130+
public virtual (Slice Begin, Slice End) ToRange(Slice prefix, ITuple items)
131131
{
132132
var writer = new SliceWriter(prefix, 16);
133133
PackKey(ref writer, items);
134134
return ToRange(writer.ToSlice());
135135
}
136136

137-
public virtual KeyRange ToKeyRange<T1>(Slice prefix, T1 item1)
137+
public virtual (Slice Begin, Slice End) ToKeyRange<T1>(Slice prefix, T1 item1)
138138
{
139139
return ToRange(prefix, STuple.Create(item1));
140140
}
141141

142-
public virtual KeyRange ToKeyRange<T1, T2>(Slice prefix, T1 item1, T2 item2)
142+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2>(Slice prefix, T1 item1, T2 item2)
143143
{
144144
return ToRange(prefix, STuple.Create(item1, item2));
145145
}
146146

147-
public virtual KeyRange ToKeyRange<T1, T2, T3>(Slice prefix, T1 item1, T2 item2, T3 item3)
147+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2, T3>(Slice prefix, T1 item1, T2 item2, T3 item3)
148148
{
149149
return ToRange(prefix, STuple.Create(item1, item3, item3));
150150
}
151151

152-
public virtual KeyRange ToKeyRange<T1, T2, T3, T4>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4)
152+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4)
153153
{
154154
return ToRange(prefix, STuple.Create(item1, item3, item3, item4));
155155
}
156156

157-
public virtual KeyRange ToKeyRange<T1, T2, T3, T4, T5>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
157+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
158158
{
159159
return ToRange(prefix, STuple.Create(item1, item3, item3, item4, item5));
160160
}
161161

162-
public virtual KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
162+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
163163
{
164164
return ToRange(prefix, STuple.Create(item1, item3, item3, item4, item5, item6));
165165
}
166166

167-
public virtual KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6, T7>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
167+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6, T7>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
168168
{
169169
return ToRange(prefix, STuple.Create(item1, item3, item3, item4, item5, item6, item7));
170170
}
171171

172-
public virtual KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6, T7, T8>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
172+
public virtual (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6, T7, T8>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
173173
{
174174
return ToRange(prefix, STuple.Create(item1, item3, item3, item4, item5, item6, item7, item8));
175175
}

FoundationDB.Client/Shared/TypeSystem/Encoders/IDynamicKeyEncoder.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,26 +231,26 @@ public interface IDynamicKeyEncoder
231231
/// <param name="prefix">Optional binary prefix</param>
232232
/// <returns>Key range which derives from the semantic of the current encoding</returns>
233233
/// <remarks>For example, the Tuple encoding will produce ranges of the form "(Key + \x00) &lt;= x &lt; (Key + \xFF)", while a binary-based encoding would produce ranges of the form "Key &lt;= x &lt; Increment(Key)"</remarks>
234-
KeyRange ToRange(Slice prefix = default(Slice));
234+
(Slice Begin, Slice End) ToRange(Slice prefix = default(Slice));
235235

236236
/// <summary>Return a key range using a tuple as a prefix</summary>
237237
/// <param name="prefix">Optional binary prefix that should be added before encoding the key</param>
238238
/// <param name="items">Tuple of any size (0 to N)</param>
239-
KeyRange ToRange(Slice prefix, ITuple items);
239+
(Slice Begin, Slice End) ToRange(Slice prefix, ITuple items);
240240

241241
/// <summary>Return a key range using a single element as a prefix</summary>
242242
/// <typeparam name="T1">Type of the element</typeparam>
243243
/// <param name="prefix">Optional binary prefix that should be added before encoding the key</param>
244244
/// <param name="item1">Element to encode</param>
245-
KeyRange ToKeyRange<T1>(Slice prefix, T1 item1);
245+
(Slice Begin, Slice End) ToKeyRange<T1>(Slice prefix, T1 item1);
246246

247247
/// <summary>Return a key range using two elements as a prefix</summary>
248248
/// <typeparam name="T1">Type of the first element</typeparam>
249249
/// <typeparam name="T2">Type of the second element</typeparam>
250250
/// <param name="prefix">Optional binary prefix that should be added before encoding the key</param>
251251
/// <param name="item1">First element to encode</param>
252252
/// <param name="item2">Second element to encode</param>
253-
KeyRange ToKeyRange<T1, T2>(Slice prefix, T1 item1, T2 item2);
253+
(Slice Begin, Slice End) ToKeyRange<T1, T2>(Slice prefix, T1 item1, T2 item2);
254254

255255
/// <summary>Return a key range using three elements as a prefix</summary>
256256
/// <typeparam name="T1">Type of the first element</typeparam>
@@ -260,7 +260,7 @@ public interface IDynamicKeyEncoder
260260
/// <param name="item1">First element to encode</param>
261261
/// <param name="item2">Second element to encode</param>
262262
/// <param name="item3">Third element to encode</param>
263-
KeyRange ToKeyRange<T1, T2, T3>(Slice prefix, T1 item1, T2 item2, T3 item3);
263+
(Slice Begin, Slice End) ToKeyRange<T1, T2, T3>(Slice prefix, T1 item1, T2 item2, T3 item3);
264264

265265
/// <summary>Return a key range using four elements as a prefix</summary>
266266
/// <typeparam name="T1">Type of the first element</typeparam>
@@ -272,7 +272,7 @@ public interface IDynamicKeyEncoder
272272
/// <param name="item2">Second element to encode</param>
273273
/// <param name="item3">Third element to encode</param>
274274
/// <param name="item4">Fourth element to encode</param>
275-
KeyRange ToKeyRange<T1, T2, T3, T4>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4);
275+
(Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4);
276276

277277
/// <summary>Return a key range using five elements as a prefix</summary>
278278
/// <typeparam name="T1">Type of the first element</typeparam>
@@ -286,7 +286,7 @@ public interface IDynamicKeyEncoder
286286
/// <param name="item3">Third element to encode</param>
287287
/// <param name="item4">Fourth element to encode</param>
288288
/// <param name="item5">Fifth element to encode</param>
289-
KeyRange ToKeyRange<T1, T2, T3, T4, T5>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5);
289+
(Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5);
290290

291291
/// <summary>Return a key range using six elements as a prefix</summary>
292292
/// <typeparam name="T1">Type of the first element</typeparam>
@@ -302,7 +302,7 @@ public interface IDynamicKeyEncoder
302302
/// <param name="item4">Fourth element to encode</param>
303303
/// <param name="item5">Fifth element to encode</param>
304304
/// <param name="item6">Sixth element to encode</param>
305-
KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6);
305+
(Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6);
306306

307307
/// <summary>Return a key range using seven elements as a prefix</summary>
308308
/// <typeparam name="T1">Type of the first element</typeparam>
@@ -320,7 +320,7 @@ public interface IDynamicKeyEncoder
320320
/// <param name="item5">Fifth element to encode</param>
321321
/// <param name="item6">Sixth element to encode</param>
322322
/// <param name="item7">Seventh element to encode</param>
323-
KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6, T7>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7);
323+
(Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6, T7>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7);
324324

325325
/// <summary>Return a key range using eight elements as a prefix</summary>
326326
/// <typeparam name="T1">Type of the first element</typeparam>
@@ -340,7 +340,7 @@ public interface IDynamicKeyEncoder
340340
/// <param name="item6">Sixth element to encode</param>
341341
/// <param name="item7">Seventh element to encode</param>
342342
/// <param name="item8">Eighth element to encode</param>
343-
KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6, T7, T8>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8);
343+
(Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6, T7, T8>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8);
344344

345345
//note: I will be billing $999.99 to anyone who wants up to T11 !!! :(
346346

FoundationDB.Client/Tuples/Encoding/TupleKeyEncoder.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,52 +182,52 @@ public STuple<T1, T2, T3, T4, T5, T6> DecodeKey<T1, T2, T3, T4, T5, T6>(Slice pa
182182
return TuPack.DecodeKey<T1, T2, T3, T4, T5, T6>(packed);
183183
}
184184

185-
public KeyRange ToRange(Slice prefix)
185+
public (Slice Begin, Slice End) ToRange(Slice prefix)
186186
{
187187
return TuPack.ToRange(prefix);
188188
}
189189

190-
public KeyRange ToRange(Slice prefix, ITuple items)
190+
public (Slice Begin, Slice End) ToRange(Slice prefix, ITuple items)
191191
{
192192
return TuPack.ToPrefixedKeyRange(prefix, items);
193193
}
194194

195-
public KeyRange ToKeyRange<T1>(Slice prefix, T1 item1)
195+
public (Slice Begin, Slice End) ToKeyRange<T1>(Slice prefix, T1 item1)
196196
{
197197
return TuPack.ToPrefixedKeyRange(prefix, item1);
198198
}
199199

200-
public KeyRange ToKeyRange<T1, T2>(Slice prefix, T1 item1, T2 item2)
200+
public (Slice Begin, Slice End) ToKeyRange<T1, T2>(Slice prefix, T1 item1, T2 item2)
201201
{
202202
return TuPack.ToPrefixedKeyRange(prefix, item1, item2);
203203
}
204204

205-
public KeyRange ToKeyRange<T1, T2, T3>(Slice prefix, T1 item1, T2 item2, T3 item3)
205+
public (Slice Begin, Slice End) ToKeyRange<T1, T2, T3>(Slice prefix, T1 item1, T2 item2, T3 item3)
206206
{
207207
return TuPack.ToPrefixedKeyRange(prefix, item1, item2, item3);
208208
}
209209

210-
public KeyRange ToKeyRange<T1, T2, T3, T4>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4)
210+
public (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4)
211211
{
212212
return TuPack.ToPrefixedKeyRange(prefix, item1, item2, item3, item4);
213213
}
214214

215-
public KeyRange ToKeyRange<T1, T2, T3, T4, T5>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
215+
public (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
216216
{
217217
return TuPack.ToPrefixedKeyRange(prefix, item1, item2, item3, item4, item5);
218218
}
219219

220-
public KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
220+
public (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
221221
{
222222
return TuPack.ToPrefixedKeyRange(prefix, item1, item2, item3, item4, item5, item6);
223223
}
224224

225-
public KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6, T7>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
225+
public (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6, T7>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
226226
{
227227
return TuPack.ToPrefixedKeyRange(prefix, item1, item2, item3, item4, item5, item6, item7);
228228
}
229229

230-
public KeyRange ToKeyRange<T1, T2, T3, T4, T5, T6, T7, T8>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
230+
public (Slice Begin, Slice End) ToKeyRange<T1, T2, T3, T4, T5, T6, T7, T8>(Slice prefix, T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
231231
{
232232
return TuPack.ToPrefixedKeyRange(prefix, item1, item2, item3, item4, item5, item6, item7, item8);
233233
}

0 commit comments

Comments
 (0)