@@ -152,9 +152,6 @@ 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 {}
157
-
158
155
limit := r .Limit
159
156
if r .SortOrder != pb .RangeRequest_NONE ||
160
157
r .MinModRevision != 0 || r .MaxModRevision != 0 ||
@@ -167,17 +164,41 @@ func executeRange(ctx context.Context, lg *zap.Logger, txnRead mvcc.TxnRead, r *
167
164
limit = limit + 1
168
165
}
169
166
167
+ // Combining r.CountOnly and any of { r.MaxModRevision, r.MinModRevision, r.MaxCreateRevision, r.MinCreateRevision }
168
+ // means "give me the count for the result of the filtering I asked for".
169
+ filtering := r .MaxModRevision != 0 || r .MinModRevision != 0 || r .MaxCreateRevision != 0 || r .MinCreateRevision != 0
170
+ var noKvsToProcess bool
171
+ if filtering {
172
+ noKvsToProcess = false
173
+ } else {
174
+ noKvsToProcess = r .CountOnly
175
+ }
176
+
170
177
ro := mvcc.RangeOptions {
171
178
Limit : limit ,
172
179
Rev : r .Revision ,
173
- Count : r . CountOnly ,
180
+ Count : noKvsToProcess ,
174
181
}
175
182
176
183
rr , err := txnRead .Range (ctx , r .Key , mkGteRange (r .RangeEnd ), ro )
177
184
if err != nil {
178
185
return nil , err
179
186
}
187
+ resp := & pb.RangeResponse {Header : & pb.ResponseHeader {Revision : rr .Rev }}
188
+
189
+ if noKvsToProcess {
190
+ resp .Count = int64 (rr .Count )
191
+ resp .Kvs = make ([]* mvccpb.KeyValue , 0 )
192
+ } else {
193
+ processKvsInRange (r , rr , resp , trace , lg )
194
+ }
195
+
196
+ trace .Step ("assemble the response" )
197
+ return resp , nil
198
+ }
180
199
200
+ func processKvsInRange (r * pb.RangeRequest , rr * mvcc.RangeResult , resp * pb.RangeResponse , trace * traceutil.Trace , lg * zap.Logger ) {
201
+ trace .Step ("filter and sort the key-value pairs" )
181
202
if r .MaxModRevision != 0 {
182
203
f := func (kv * mvccpb.KeyValue ) bool { return kv .ModRevision > r .MaxModRevision }
183
204
pruneKVs (rr , f )
@@ -195,6 +216,16 @@ func executeRange(ctx context.Context, lg *zap.Logger, txnRead mvcc.TxnRead, r *
195
216
pruneKVs (rr , f )
196
217
}
197
218
219
+ // No more prunning after this point; we can count now.
220
+ resp .Count = int64 (len (rr .KVs ))
221
+ // If r.CountOnly was specified:
222
+ // * r.SortOrder is useless and ignored.
223
+ // * r.Limit is useless and ignored.
224
+ if r .CountOnly {
225
+ resp .Kvs = make ([]* mvccpb.KeyValue , 0 )
226
+ return
227
+ }
228
+
198
229
sortOrder := r .SortOrder
199
230
if r .SortTarget != pb .RangeRequest_KEY && sortOrder == pb .RangeRequest_NONE {
200
231
// Since current mvcc.Range implementation returns results
@@ -235,18 +266,13 @@ func executeRange(ctx context.Context, lg *zap.Logger, txnRead mvcc.TxnRead, r *
235
266
rr .KVs = rr .KVs [:r .Limit ]
236
267
resp .More = true
237
268
}
238
- trace .Step ("filter and sort the key-value pairs" )
239
- resp .Header .Revision = rr .Rev
240
- resp .Count = int64 (rr .Count )
241
269
resp .Kvs = make ([]* mvccpb.KeyValue , len (rr .KVs ))
242
270
for i := range rr .KVs {
243
271
if r .KeysOnly {
244
272
rr .KVs [i ].Value = nil
245
273
}
246
274
resp .Kvs [i ] = & rr .KVs [i ]
247
275
}
248
- trace .Step ("assemble the response" )
249
- return resp , nil
250
276
}
251
277
252
278
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