unified-storage: use name instead of offset in kvstore continue token (#113560)
* unified-storage: use name instead of offset in kvstore continue token --------- Co-authored-by: Georges Chaudy <chaudyg@gmail.com>
This commit is contained in:
co-authored by
Georges Chaudy
parent
bdf529c545
commit
047e6d45fa
@@ -303,7 +303,7 @@ func (d *dataStore) GetResourceKeyAtRevision(ctx context.Context, key GetRequest
|
||||
|
||||
listKey := ListRequestKey(key)
|
||||
|
||||
iter := d.ListResourceKeysAtRevision(ctx, listKey, rv)
|
||||
iter := d.ListResourceKeysAtRevision(ctx, ListRequestOptions{Key: listKey, ResourceVersion: rv})
|
||||
for dataKey, err := range iter {
|
||||
if err != nil {
|
||||
return DataKey{}, err
|
||||
@@ -313,32 +313,77 @@ func (d *dataStore) GetResourceKeyAtRevision(ctx context.Context, key GetRequest
|
||||
return DataKey{}, ErrNotFound
|
||||
}
|
||||
|
||||
type ListRequestOptions struct {
|
||||
// Key defines the range to query (Group/Resource/Namespace/Name prefix).
|
||||
Key ListRequestKey
|
||||
// ContinueNamespace is the namespace to continue from.
|
||||
// Only used when Key.Namespace is empty (cross-namespace query).
|
||||
ContinueNamespace string
|
||||
// ContinueName is the name to continue from.
|
||||
ContinueName string
|
||||
ResourceVersion int64
|
||||
}
|
||||
|
||||
// Validate checks that the ListRequestOptions are valid.
|
||||
func (o ListRequestOptions) Validate() error {
|
||||
if err := o.Key.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid list request key: %w", err)
|
||||
}
|
||||
// ContinueNamespace is only valid for cross-namespace queries
|
||||
if o.ContinueNamespace != "" && o.Key.Namespace != "" {
|
||||
return fmt.Errorf("continue namespace %q not allowed when request namespace is set to %q", o.ContinueNamespace, o.Key.Namespace)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListLatestResourceKeys returns an iterator over the data keys for the latest versions of resources.
|
||||
// Only returns keys for resources that are not deleted.
|
||||
func (d *dataStore) ListLatestResourceKeys(ctx context.Context, key ListRequestKey) iter.Seq2[DataKey, error] {
|
||||
return d.ListResourceKeysAtRevision(ctx, key, 0)
|
||||
return d.ListResourceKeysAtRevision(ctx, ListRequestOptions{
|
||||
Key: key,
|
||||
})
|
||||
}
|
||||
|
||||
// ListResourceKeysAtRevision returns an iterator over data keys for resources at a specific revision.
|
||||
// If rv is 0, it returns the latest versions. Only returns keys for resources that are not deleted at the given revision.
|
||||
func (d *dataStore) ListResourceKeysAtRevision(ctx context.Context, key ListRequestKey, rv int64) iter.Seq2[DataKey, error] {
|
||||
if err := key.Validate(); err != nil {
|
||||
func (d *dataStore) ListResourceKeysAtRevision(ctx context.Context, options ListRequestOptions) iter.Seq2[DataKey, error] {
|
||||
if err := options.Validate(); err != nil {
|
||||
return func(yield func(DataKey, error) bool) {
|
||||
yield(DataKey{}, fmt.Errorf("invalid list request key: %w", err))
|
||||
yield(DataKey{}, err)
|
||||
}
|
||||
}
|
||||
|
||||
rv := options.ResourceVersion
|
||||
prefix := options.Key.Prefix()
|
||||
|
||||
startKey := prefix
|
||||
if options.ContinueName != "" {
|
||||
// Build the start key from the continue position
|
||||
continueKey := ListRequestKey{
|
||||
Group: options.Key.Group,
|
||||
Resource: options.Key.Resource,
|
||||
Namespace: options.Key.Namespace,
|
||||
Name: options.ContinueName,
|
||||
}
|
||||
// For cross-namespace queries, use the continue namespace
|
||||
if options.Key.Namespace == "" && options.ContinueNamespace != "" {
|
||||
continueKey.Namespace = options.ContinueNamespace
|
||||
}
|
||||
startKey = continueKey.Prefix()
|
||||
}
|
||||
|
||||
listOptions := ListOptions{
|
||||
StartKey: startKey,
|
||||
EndKey: PrefixRangeEnd(prefix),
|
||||
Sort: SortOrderAsc,
|
||||
}
|
||||
|
||||
if rv == 0 {
|
||||
rv = math.MaxInt64
|
||||
}
|
||||
|
||||
prefix := key.Prefix()
|
||||
// List all keys in the prefix.
|
||||
iter := d.kv.Keys(ctx, dataSection, ListOptions{
|
||||
StartKey: prefix,
|
||||
EndKey: PrefixRangeEnd(prefix),
|
||||
Sort: SortOrderAsc,
|
||||
})
|
||||
iter := d.kv.Keys(ctx, dataSection, listOptions)
|
||||
|
||||
return func(yield func(DataKey, error) bool) {
|
||||
var candidateKey *DataKey // The current candidate key we are iterating over
|
||||
|
||||
Reference in New Issue
Block a user