diff --git a/weed/filer/foundationdb/foundationdb_store.go b/weed/filer/foundationdb/foundationdb_store.go index 25628db85..babf382a5 100644 --- a/weed/filer/foundationdb/foundationdb_store.go +++ b/weed/filer/foundationdb/foundationdb_store.go @@ -307,47 +307,52 @@ func (store *FoundationDBStore) ListDirectoryPrefixedEntries(ctx context.Context return "", fmt.Errorf("creating prefix range for %s: %v", dirPath, err) } - // Determine start key based on startFileName and prefix + // Determine start key and selector based on startFileName and prefix var startKey fdb.Key + var beginSelector fdb.KeySelector + if startFileName != "" { // Start from the specified file - if !includeStartFile { - // Use next possible tuple to exclude start key (append \x00 to fileName in tuple, not to packed bytes) - startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), startFileName + "\x00"}) + startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), startFileName}) + // Use KeySelector for idiomatic FDB range scanning + if includeStartFile { + beginSelector = fdb.FirstGreaterOrEqual(startKey) } else { - startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), startFileName}) + beginSelector = fdb.FirstGreaterThan(startKey) } // If prefix is specified and startFileName doesn't match, adjust if prefix != "" && !strings.HasPrefix(startFileName, prefix) { if startFileName < prefix { // Start from prefix if startFileName is before it startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), prefix}) + beginSelector = fdb.FirstGreaterOrEqual(startKey) } } } else if prefix != "" { // Start from prefix startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), prefix}) + beginSelector = fdb.FirstGreaterOrEqual(startKey) } else { // Start from beginning of directory - startKey = dirRange.Begin + beginSelector = fdb.FirstGreaterOrEqual(dirRange.Begin) } - // End key is from the directory range - endKey := dirRange.End + // End selector is from the directory range + endSelector := fdb.FirstGreaterOrEqual(dirRange.End) var kvs []fdb.KeyValue var rangeErr error // Check if there's a transaction in context if tx, exists := store.getTransactionFromContext(ctx); exists { - kr := fdb.KeyRange{Begin: startKey, End: endKey} - kvs, rangeErr = tx.GetRange(kr, fdb.RangeOptions{Limit: int(limit)}).GetSliceWithError() + sr := fdb.SelectorRange{Begin: beginSelector, End: endSelector} + kvs, rangeErr = tx.GetRange(sr, fdb.RangeOptions{Limit: int(limit)}).GetSliceWithError() if rangeErr != nil { return "", fmt.Errorf("scanning %s: %v", dirPath, rangeErr) } } else { result, err := store.database.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) { - kr := fdb.KeyRange{Begin: startKey, End: endKey} - kvSlice, err := rtr.GetRange(kr, fdb.RangeOptions{Limit: int(limit)}).GetSliceWithError() + sr := fdb.SelectorRange{Begin: beginSelector, End: endSelector} + kvSlice, err := rtr.GetRange(sr, fdb.RangeOptions{Limit: int(limit)}).GetSliceWithError() if err != nil { return nil, err }