diff --git a/proxy/httpproxy/handler.go b/proxy/httpproxy/handler.go index 99261f1ed2..ad3f93961a 100644 --- a/proxy/httpproxy/handler.go +++ b/proxy/httpproxy/handler.go @@ -35,6 +35,7 @@ func NewHTTPProxyHandler() http.Handler { router.HandleFunc("/rawkv/client/{id}/batch-delete", rawkv.handlerFunc(rawkv.BatchDelete)) router.HandleFunc("/rawkv/client/{id}/delete-range", rawkv.handlerFunc(rawkv.DeleteRange)) router.HandleFunc("/rawkv/client/{id}/scan", rawkv.handlerFunc(rawkv.Scan)) + router.HandleFunc("/rawkv/client/{id}/reverse-scan", rawkv.handlerFunc(rawkv.ReverseScan)) txnkv := txnkvHandler{p: proxy.NewTxn()} router.HandleFunc("/txnkv/client/new", txnkv.handlerFunc(txnkv.New)) diff --git a/proxy/httpproxy/rawkv.go b/proxy/httpproxy/rawkv.go index 809ef537e6..797c6c0c60 100644 --- a/proxy/httpproxy/rawkv.go +++ b/proxy/httpproxy/rawkv.go @@ -126,6 +126,14 @@ func (h rawkvHandler) Scan(vars map[string]string, r *RawRequest) (*RawResponse, return &RawResponse{Keys: keys, Values: values}, http.StatusOK, nil } +func (h rawkvHandler) ReverseScan(vars map[string]string, r *RawRequest) (*RawResponse, int, error) { + keys, values, err := h.p.ReverseScan(proxy.UUID(vars["id"]), r.StartKey, r.EndKey, r.Limit) + if err != nil { + return nil, http.StatusInternalServerError, err + } + return &RawResponse{Keys: keys, Values: values}, http.StatusOK, nil +} + func (h rawkvHandler) handlerFunc(f func(map[string]string, *RawRequest) (*RawResponse, int, error)) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { data, err := ioutil.ReadAll(r.Body) diff --git a/proxy/rawkv.go b/proxy/rawkv.go index 7de0d658e9..6ede955198 100644 --- a/proxy/rawkv.go +++ b/proxy/rawkv.go @@ -127,3 +127,13 @@ func (p RawKVProxy) Scan(id UUID, startKey, endKey []byte, limit int) ([][]byte, } return client.(*rawkv.Client).Scan(startKey, endKey, limit) } + +// ReverseScan queries continuous kv pairs in range [endKey, startKey), up to limit pairs. +// Direction is different from Scan, upper to lower. +func (p RawKVProxy) ReverseScan(id UUID, startKey, endKey []byte, limit int) ([][]byte, [][]byte, error) { + client, ok := p.clients.Load(id) + if !ok { + return nil, nil, errors.WithStack(ErrClientNotFound) + } + return client.(*rawkv.Client).ReverseScan(startKey, endKey, limit) +}