@@ -302,6 +302,53 @@ func (c *Client) Scan(startKey, endKey []byte, limit int) (keys [][]byte, values
302
302
return
303
303
}
304
304
305
+ // ReverseScan queries continuous kv pairs in range [endKey, startKey), up to limit pairs.
306
+ // Direction is different from Scan, upper to lower.
307
+ // If endKey is empty, it means unbounded.
308
+ // If you want to include the startKey or exclude the endKey, append a '\0' to the key. For example, to scan
309
+ // (endKey, startKey], you can write:
310
+ // `ReverseScan(append(startKey, '\0'), append(endKey, '\0'), limit)`.
311
+ // It doesn't support Scanning from "", because locating the last Region is not yet implemented.
312
+ func (c * Client ) ReverseScan (startKey , endKey []byte , limit int ) (keys [][]byte , values [][]byte , err error ) {
313
+ start := time .Now ()
314
+ defer func () {
315
+ metrics .RawkvCmdHistogram .WithLabelValues ("raw_reverse_scan" ).Observe (time .Since (start ).Seconds ())
316
+ }()
317
+
318
+ if limit > config .MaxRawKVScanLimit {
319
+ return nil , nil , errors .WithStack (ErrMaxScanLimitExceeded )
320
+ }
321
+
322
+ for len (keys ) < limit {
323
+ req := & rpc.Request {
324
+ Type : rpc .CmdRawScan ,
325
+ RawScan : & kvrpcpb.RawScanRequest {
326
+ StartKey : startKey ,
327
+ EndKey : endKey ,
328
+ Limit : uint32 (limit - len (keys )),
329
+ Reverse : true ,
330
+ },
331
+ }
332
+ resp , loc , err := c .sendReq (startKey , req )
333
+ if err != nil {
334
+ return nil , nil , err
335
+ }
336
+ cmdResp := resp .RawScan
337
+ if cmdResp == nil {
338
+ return nil , nil , errors .WithStack (rpc .ErrBodyMissing )
339
+ }
340
+ for _ , pair := range cmdResp .Kvs {
341
+ keys = append (keys , pair .Key )
342
+ values = append (values , pair .Value )
343
+ }
344
+ startKey = loc .EndKey
345
+ if len (startKey ) == 0 {
346
+ break
347
+ }
348
+ }
349
+ return
350
+ }
351
+
305
352
func (c * Client ) sendReq (key []byte , req * rpc.Request ) (* rpc.Response , * locate.KeyLocation , error ) {
306
353
bo := retry .NewBackoffer (context .Background (), retry .RawkvMaxBackoff )
307
354
sender := rpc .NewRegionRequestSender (c .regionCache , c .rpcClient )
0 commit comments