Skip to content

Commit 2cba4f1

Browse files
committed
Add AscendKeysRange and DescendKeysRange functions to support key iteration within a specified range
1 parent 0b2637b commit 2cba4f1

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

db.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,40 @@ func (db *DB) AscendKeys(pattern []byte, filterExpired bool, handleFn func(k []b
476476
})
477477
}
478478

479+
// AscendKeysRange calls handleFn for keys within a range in the db in ascending order.
480+
// Since our expiry time is stored in the value, if you want to filter expired keys,
481+
// you need to set parameter filterExpired to true. But the performance will be affected.
482+
// Because we need to read the value of each key to determine if it is expired.
483+
func (db *DB) AscendKeysRange(startKey, endKey, pattern []byte, filterExpired bool, handleFn func(k []byte) (bool, error)) {
484+
db.mu.RLock()
485+
defer db.mu.RUnlock()
486+
487+
var reg *regexp.Regexp
488+
if len(pattern) > 0 {
489+
reg = regexp.MustCompile(string(pattern))
490+
}
491+
492+
db.index.AscendRange(startKey, endKey, func(key []byte, pos *wal.ChunkPosition) (bool, error) {
493+
if reg == nil || reg.Match(key) {
494+
var invalid bool
495+
if filterExpired {
496+
chunk, err := db.dataFiles.Read(pos)
497+
if err != nil {
498+
return false, err
499+
}
500+
if value := db.checkValue(chunk); value == nil {
501+
invalid = true
502+
}
503+
}
504+
if invalid {
505+
return true, nil
506+
}
507+
return handleFn(key)
508+
}
509+
return true, nil
510+
})
511+
}
512+
479513
// Descend calls handleFn for each key/value pair in the db in descending order.
480514
func (db *DB) Descend(handleFn func(k []byte, v []byte) (bool, error)) {
481515
db.mu.RLock()
@@ -561,6 +595,40 @@ func (db *DB) DescendKeys(pattern []byte, filterExpired bool, handleFn func(k []
561595
})
562596
}
563597

598+
// DescendKeysRange calls handleFn for keys within a range in the db in descending order.
599+
// Since our expiry time is stored in the value, if you want to filter expired keys,
600+
// you need to set parameter filterExpired to true. But the performance will be affected.
601+
// Because we need to read the value of each key to determine if it is expired.
602+
func (db *DB) DescendKeysRange(startKey, endKey, pattern []byte, filterExpired bool, handleFn func(k []byte) (bool, error)) {
603+
db.mu.RLock()
604+
defer db.mu.RUnlock()
605+
606+
var reg *regexp.Regexp
607+
if len(pattern) > 0 {
608+
reg = regexp.MustCompile(string(pattern))
609+
}
610+
611+
db.index.DescendRange(startKey, endKey, func(key []byte, pos *wal.ChunkPosition) (bool, error) {
612+
if reg == nil || reg.Match(key) {
613+
var invalid bool
614+
if filterExpired {
615+
chunk, err := db.dataFiles.Read(pos)
616+
if err != nil {
617+
return false, err
618+
}
619+
if value := db.checkValue(chunk); value == nil {
620+
invalid = true
621+
}
622+
}
623+
if invalid {
624+
return true, nil
625+
}
626+
return handleFn(key)
627+
}
628+
return true, nil
629+
})
630+
}
631+
564632
func (db *DB) checkValue(chunk []byte) []byte {
565633
record := decodeLogRecord(chunk)
566634
now := time.Now().UnixNano()

0 commit comments

Comments
 (0)