Browse Source

fix range listing

pull/7178/head
chrislu 1 month ago
parent
commit
e15c5eb64e
  1. 80
      weed/filer/foundationdb/foundationdb_store.go

80
weed/filer/foundationdb/foundationdb_store.go

@ -4,7 +4,6 @@
package foundationdb package foundationdb
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"strings" "strings"
@ -25,37 +24,6 @@ const (
FDB_TRANSACTION_SIZE_LIMIT = 10 * 1024 * 1024 FDB_TRANSACTION_SIZE_LIMIT = 10 * 1024 * 1024
) )
// Helper function to create prefix range (tries idiomatic approach first, falls back to custom)
func prefixRange(prefix fdb.Key) fdb.KeyRange {
// Try to use idiomatic FoundationDB PrefixRange if available
// Note: This may not be available in older Go bindings, so we provide fallback
begin := prefix
end := prefixEndFallback(prefix)
return fdb.KeyRange{Begin: begin, End: end}
}
// Fallback implementation for prefix end calculation
func prefixEndFallback(prefix fdb.Key) fdb.Key {
if len(prefix) == 0 {
return fdb.Key("\xff")
}
// Create a copy and increment the last byte
end := make([]byte, len(prefix))
copy(end, prefix)
// Find the last byte that can be incremented
for i := len(end) - 1; i >= 0; i-- {
if end[i] < 0xff {
end[i]++
return fdb.Key(end[:i+1])
}
}
// All bytes are 0xff, append 0x00
return fdb.Key(append(end, 0x00))
}
func init() { func init() {
filer.Stores = append(filer.Stores, &FoundationDBStore{}) filer.Stores = append(filer.Stores, &FoundationDBStore{})
} }
@ -297,18 +265,22 @@ func (store *FoundationDBStore) DeleteEntry(ctx context.Context, fullpath util.F
} }
func (store *FoundationDBStore) DeleteFolderChildren(ctx context.Context, fullpath util.FullPath) error { func (store *FoundationDBStore) DeleteFolderChildren(ctx context.Context, fullpath util.FullPath) error {
directoryPrefix := store.genDirectoryKeyPrefix(string(fullpath), "")
// Construct tuple-aware range for all children in this directory
// Use FDBRangeKeys for proper tuple-encoded range
beginKey, endKey := tuple.Tuple{string(fullpath)}.FDBRangeKeys()
// Pack with directory subspace
startKey := store.seaweedfsDir.Pack(beginKey)
endKeyPacked := store.seaweedfsDir.Pack(endKey)
kr := fdb.KeyRange{Begin: startKey, End: endKeyPacked}
// Check if there's a transaction in context // Check if there's a transaction in context
if tx, exists := store.getTransactionFromContext(ctx); exists { if tx, exists := store.getTransactionFromContext(ctx); exists {
kr := prefixRange(directoryPrefix)
tx.ClearRange(kr) tx.ClearRange(kr)
return nil return nil
} }
// Execute in a new transaction if not in an existing one // Execute in a new transaction if not in an existing one
_, err := store.database.Transact(func(tr fdb.Transaction) (interface{}, error) { _, err := store.database.Transact(func(tr fdb.Transaction) (interface{}, error) {
kr := prefixRange(directoryPrefix)
tr.ClearRange(kr) tr.ClearRange(kr)
return nil, nil return nil, nil
}) })
@ -329,30 +301,37 @@ func (store *FoundationDBStore) ListDirectoryPrefixedEntries(ctx context.Context
limit = 1000 limit = 1000
} }
// Construct tight range based on directory and prefix
directoryPrefix := store.genDirectoryKeyPrefix(string(dirPath), prefix)
// Determine the actual start key
// For tuple-encoded keys, construct range using directory tuples
var startKey fdb.Key var startKey fdb.Key
var endKey fdb.Key
// Determine start key based on startFileName and prefix
if startFileName != "" { if startFileName != "" {
// Start from the specified file within the prefix range
startKey = store.genDirectoryKeyPrefix(string(dirPath), startFileName)
// Start from the specified file
startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), startFileName})
if !includeStartFile { if !includeStartFile {
// Append 0x00 to exclude the start key itself
startKey = append(startKey, 0x00) startKey = append(startKey, 0x00)
} }
// Ensure startKey is within the prefix range
if !bytes.HasPrefix(startKey, directoryPrefix) {
// If startFileName is before the prefix, start at prefix
if bytes.Compare(startKey, directoryPrefix) < 0 {
startKey = directoryPrefix
// 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})
} }
} }
} else if prefix != "" {
// Start from prefix
startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), prefix})
} else { } else {
startKey = directoryPrefix
// Start from beginning of directory
startKey = store.seaweedfsDir.Pack(tuple.Tuple{string(dirPath), ""})
} }
// End key is the prefix range end
endKey := prefixEndFallback(directoryPrefix)
// Compute the end key using tuple-aware range
// This ensures we stay within the directory bounds
beginTuple, endTuple := tuple.Tuple{string(dirPath)}.FDBRangeKeys()
endKey = store.seaweedfsDir.Pack(endTuple)
var kvs []fdb.KeyValue var kvs []fdb.KeyValue
var rangeErr error var rangeErr error
@ -385,8 +364,9 @@ func (store *FoundationDBStore) ListDirectoryPrefixedEntries(ctx context.Context
continue continue
} }
// Prefix filtering is now handled by the range scan, but double-check for safety
// Filter by prefix if specified
if prefix != "" && !strings.HasPrefix(fileName, prefix) { if prefix != "" && !strings.HasPrefix(fileName, prefix) {
glog.V(2).Infof("list %s: fileName %s does not match prefix %s", dirPath, fileName, prefix)
continue continue
} }

Loading…
Cancel
Save