blob: 77f08136e6517caee9a0ff3f6685e656c6b5d6a6 [file]
// Copyright 2025 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cache
import (
"k8s.io/utils/third_party/forked/golang/btree"
"go.etcd.io/etcd/api/v3/mvccpb"
)
// snapshot captures a full, point-in-time view of the KV state at rev.
type snapshot struct {
rev int64
tree *btree.BTree[*kvItem]
}
func newClonedSnapshot(rev int64, t *btree.BTree[*kvItem]) *snapshot {
return &snapshot{rev: rev, tree: t.Clone()}
}
func (s *snapshot) Range(startKey, endKey []byte) []*mvccpb.KeyValue {
var out []*mvccpb.KeyValue
switch {
case len(endKey) == 0:
if item, ok := s.tree.Get(probeItemFromKey(startKey)); ok {
out = append(out, item.kv)
}
case isPrefixScan(endKey):
s.tree.AscendGreaterOrEqual(probeItemFromKey(startKey), func(item *kvItem) bool {
out = append(out, item.kv)
return true
})
default:
s.tree.AscendRange(
probeItemFromKey(startKey),
probeItemFromKey(endKey),
func(item *kvItem) bool {
out = append(out, item.kv)
return true
},
)
}
return out
}
func isPrefixScan(endKey []byte) bool {
return len(endKey) == 1 && endKey[0] == 0
}
func probeItemFromKey(key []byte) *kvItem { return &kvItem{key: string(key)} }