func applyRange(txnID int64, kv mvcc.KV, r *etcdserverpb.RangeRequest) (*etcdserverpb.RangeResponse, error) { resp := &etcdserverpb.RangeResponse{} resp.Header = &etcdserverpb.ResponseHeader{} var ( kvs []mvccpb.KeyValue rev int64 err error ) if isGteRange(r.RangeEnd) { r.RangeEnd = []byte{} } limit := r.Limit if r.SortOrder != etcdserverpb.RangeRequest_NONE { // fetch everything; sort and truncate afterwards limit = 0 } if limit > 0 { // fetch one extra for 'more' flag limit = limit + 1 } if txnID != noTxn { kvs, rev, err = kv.TxnRange(txnID, r.Key, r.RangeEnd, limit, r.Revision) if err != nil { return nil, err } } else { kvs, rev, err = kv.Range(r.Key, r.RangeEnd, limit, r.Revision) if err != nil { return nil, err } } if r.SortOrder != etcdserverpb.RangeRequest_NONE { var sorter sort.Interface switch { case r.SortTarget == etcdserverpb.RangeRequest_KEY: sorter = &kvSortByKey{&kvSort{kvs}} case r.SortTarget == etcdserverpb.RangeRequest_VERSION: sorter = &kvSortByVersion{&kvSort{kvs}} case r.SortTarget == etcdserverpb.RangeRequest_CREATE: sorter = &kvSortByCreate{&kvSort{kvs}} case r.SortTarget == etcdserverpb.RangeRequest_MOD: sorter = &kvSortByMod{&kvSort{kvs}} case r.SortTarget == etcdserverpb.RangeRequest_VALUE: sorter = &kvSortByValue{&kvSort{kvs}} } switch { case r.SortOrder == etcdserverpb.RangeRequest_ASCEND: sort.Sort(sorter) case r.SortOrder == etcdserverpb.RangeRequest_DESCEND: sort.Sort(sort.Reverse(sorter)) } } if r.Limit > 0 && len(kvs) > int(r.Limit) { kvs = kvs[:r.Limit] resp.More = true } resp.Header.Revision = rev for i := range kvs { resp.Kvs = append(resp.Kvs, &kvs[i]) } return resp, nil }