@@ -152,32 +152,45 @@ func Range(ctx context.Context, lg *zap.Logger, kv mvcc.KV, r *pb.RangeRequest)
152
152
func executeRange (ctx context.Context , lg * zap.Logger , txnRead mvcc.TxnRead , r * pb.RangeRequest ) (* pb.RangeResponse , error ) {
153
153
trace := traceutil .Get (ctx )
154
154
155
- resp := & pb.RangeResponse {}
156
- resp .Header = & pb.ResponseHeader {}
155
+ limit := rangeLimit (r )
156
+ ro := mvcc.RangeOptions {
157
+ Limit : limit ,
158
+ Rev : r .Revision ,
159
+ Count : r .CountOnly ,
160
+ }
161
+
162
+ rr , err := txnRead .Range (ctx , r .Key , mkGteRange (r .RangeEnd ), ro )
163
+ if err != nil {
164
+ return nil , err
165
+ }
166
+
167
+ filterRangeResults (rr , r )
168
+ sortRangeResults (rr , r , lg )
169
+ trace .Step ("filter and sort the key-value pairs" )
170
+
171
+ resp := asembleRangeResponse (rr , r )
172
+ trace .Step ("assemble the response" )
173
+
174
+ return resp , nil
175
+ }
157
176
177
+ func rangeLimit (r * pb.RangeRequest ) int64 {
158
178
limit := r .Limit
159
179
if r .SortOrder != pb .RangeRequest_NONE ||
160
180
r .MinModRevision != 0 || r .MaxModRevision != 0 ||
161
181
r .MinCreateRevision != 0 || r .MaxCreateRevision != 0 {
162
182
// fetch everything; sort and truncate afterwards
163
183
limit = 0
164
184
}
185
+
165
186
if limit > 0 {
166
187
// fetch one extra for 'more' flag
167
188
limit = limit + 1
168
189
}
190
+ return limit
191
+ }
169
192
170
- ro := mvcc.RangeOptions {
171
- Limit : limit ,
172
- Rev : r .Revision ,
173
- Count : r .CountOnly ,
174
- }
175
-
176
- rr , err := txnRead .Range (ctx , r .Key , mkGteRange (r .RangeEnd ), ro )
177
- if err != nil {
178
- return nil , err
179
- }
180
-
193
+ func filterRangeResults (rr * mvcc.RangeResult , r * pb.RangeRequest ) {
181
194
if r .MaxModRevision != 0 {
182
195
f := func (kv * mvccpb.KeyValue ) bool { return kv .ModRevision > r .MaxModRevision }
183
196
pruneKVs (rr , f )
@@ -194,7 +207,9 @@ func executeRange(ctx context.Context, lg *zap.Logger, txnRead mvcc.TxnRead, r *
194
207
f := func (kv * mvccpb.KeyValue ) bool { return kv .CreateRevision < r .MinCreateRevision }
195
208
pruneKVs (rr , f )
196
209
}
210
+ }
197
211
212
+ func sortRangeResults (rr * mvcc.RangeResult , r * pb.RangeRequest , lg * zap.Logger ) {
198
213
sortOrder := r .SortOrder
199
214
if r .SortTarget != pb .RangeRequest_KEY && sortOrder == pb .RangeRequest_NONE {
200
215
// Since current mvcc.Range implementation returns results
@@ -207,46 +222,55 @@ func executeRange(ctx context.Context, lg *zap.Logger, txnRead mvcc.TxnRead, r *
207
222
// don't re-sort when target is 'KEY' and order is ASCEND
208
223
sortOrder = pb .RangeRequest_NONE
209
224
}
210
- if sortOrder != pb .RangeRequest_NONE {
211
- var sorter sort.Interface
212
- switch {
213
- case r .SortTarget == pb .RangeRequest_KEY :
214
- sorter = & kvSortByKey {& kvSort {rr .KVs }}
215
- case r .SortTarget == pb .RangeRequest_VERSION :
216
- sorter = & kvSortByVersion {& kvSort {rr .KVs }}
217
- case r .SortTarget == pb .RangeRequest_CREATE :
218
- sorter = & kvSortByCreate {& kvSort {rr .KVs }}
219
- case r .SortTarget == pb .RangeRequest_MOD :
220
- sorter = & kvSortByMod {& kvSort {rr .KVs }}
221
- case r .SortTarget == pb .RangeRequest_VALUE :
222
- sorter = & kvSortByValue {& kvSort {rr .KVs }}
223
- default :
224
- lg .Panic ("unexpected sort target" , zap .Int32 ("sort-target" , int32 (r .SortTarget )))
225
- }
226
- switch {
227
- case sortOrder == pb .RangeRequest_ASCEND :
228
- sort .Sort (sorter )
229
- case sortOrder == pb .RangeRequest_DESCEND :
230
- sort .Sort (sort .Reverse (sorter ))
231
- }
225
+
226
+ if sortOrder == pb .RangeRequest_NONE {
227
+ return
232
228
}
233
229
230
+ var sorter sort.Interface
231
+ switch r .SortTarget {
232
+ case pb .RangeRequest_KEY :
233
+ sorter = & kvSortByKey {& kvSort {rr .KVs }}
234
+ case pb .RangeRequest_VERSION :
235
+ sorter = & kvSortByVersion {& kvSort {rr .KVs }}
236
+ case pb .RangeRequest_CREATE :
237
+ sorter = & kvSortByCreate {& kvSort {rr .KVs }}
238
+ case pb .RangeRequest_MOD :
239
+ sorter = & kvSortByMod {& kvSort {rr .KVs }}
240
+ case pb .RangeRequest_VALUE :
241
+ sorter = & kvSortByValue {& kvSort {rr .KVs }}
242
+ default :
243
+ // This should ideally not happen if request validation is done prior.
244
+ lg .Panic ("unexpected sort target" , zap .Int32 ("sort-target" , int32 (r .SortTarget )))
245
+ return // Defensive return after panic, though panic will stop execution.
246
+ }
247
+
248
+ switch sortOrder {
249
+ case pb .RangeRequest_ASCEND :
250
+ sort .Sort (sorter )
251
+ case pb .RangeRequest_DESCEND :
252
+ sort .Sort (sort .Reverse (sorter ))
253
+ }
254
+ }
255
+
256
+ func asembleRangeResponse (rr * mvcc.RangeResult , r * pb.RangeRequest ) * pb.RangeResponse {
257
+ resp := & pb.RangeResponse {Header : & pb.ResponseHeader {}}
234
258
if r .Limit > 0 && len (rr .KVs ) > int (r .Limit ) {
235
259
rr .KVs = rr .KVs [:r .Limit ]
236
260
resp .More = true
237
261
}
238
- trace . Step ( "filter and sort the key-value pairs" )
262
+
239
263
resp .Header .Revision = rr .Rev
240
264
resp .Count = int64 (rr .Count )
265
+
241
266
resp .Kvs = make ([]* mvccpb.KeyValue , len (rr .KVs ))
242
267
for i := range rr .KVs {
243
268
if r .KeysOnly {
244
269
rr .KVs [i ].Value = nil
245
270
}
246
271
resp .Kvs [i ] = & rr .KVs [i ]
247
272
}
248
- trace .Step ("assemble the response" )
249
- return resp , nil
273
+ return resp
250
274
}
251
275
252
276
func Txn (ctx context.Context , lg * zap.Logger , rt * pb.TxnRequest , txnModeWriteWithSharedBuffer bool , kv mvcc.KV , lessor lease.Lessor ) (* pb.TxnResponse , * traceutil.Trace , error ) {
0 commit comments