@@ -446,34 +446,70 @@ func (db *DB) AscendGreaterOrEqual(key []byte, handleFn func(k []byte, v []byte)
446446// Since our expiry time is stored in the value, if you want to filter expired keys,
447447// you need to set parameter filterExpired to true. But the performance will be affected.
448448// Because we need to read the value of each key to determine if it is expired.
449- func (db * DB ) AscendKeys (pattern []byte , filterExpired bool , handleFn func (k []byte ) (bool , error )) {
449+ func (db * DB ) AscendKeys (pattern []byte , filterExpired bool , handleFn func (k []byte ) (bool , error )) error {
450450 db .mu .RLock ()
451451 defer db .mu .RUnlock ()
452452
453453 var reg * regexp.Regexp
454454 if len (pattern ) > 0 {
455- reg = regexp .MustCompile (string (pattern ))
455+ var err error
456+ reg , err = regexp .Compile (string (pattern ))
457+ if err != nil {
458+ return err
459+ }
456460 }
457461
458462 db .index .Ascend (func (key []byte , pos * wal.ChunkPosition ) (bool , error ) {
459- if reg == nil || reg .Match (key ) {
460- var invalid bool
461- if filterExpired {
462- chunk , err := db .dataFiles .Read (pos )
463- if err != nil {
464- return false , err
465- }
466- if value := db .checkValue (chunk ); value == nil {
467- invalid = true
468- }
463+ if reg != nil && ! reg .Match (key ) {
464+ return true , nil
465+ }
466+ if filterExpired {
467+ chunk , err := db .dataFiles .Read (pos )
468+ if err != nil {
469+ return false , err
469470 }
470- if invalid {
471+ if value := db . checkValue ( chunk ); value == nil {
471472 return true , nil
472473 }
473- return handleFn (key )
474474 }
475- return true , nil
475+ return handleFn ( key )
476476 })
477+ return nil
478+ }
479+
480+ // AscendKeysRange calls handleFn for keys within a range in the db in ascending order.
481+ // Since our expiry time is stored in the value, if you want to filter expired keys,
482+ // you need to set parameter filterExpired to true. But the performance will be affected.
483+ // Because we need to read the value of each key to determine if it is expired.
484+ func (db * DB ) AscendKeysRange (startKey , endKey , pattern []byte , filterExpired bool , handleFn func (k []byte ) (bool , error )) error {
485+ db .mu .RLock ()
486+ defer db .mu .RUnlock ()
487+
488+ var reg * regexp.Regexp
489+ if len (pattern ) > 0 {
490+ var err error
491+ reg , err = regexp .Compile (string (pattern ))
492+ if err != nil {
493+ return err
494+ }
495+ }
496+
497+ db .index .AscendRange (startKey , endKey , func (key []byte , pos * wal.ChunkPosition ) (bool , error ) {
498+ if reg != nil && ! reg .Match (key ) {
499+ return true , nil
500+ }
501+ if filterExpired {
502+ chunk , err := db .dataFiles .Read (pos )
503+ if err != nil {
504+ return false , err
505+ }
506+ if value := db .checkValue (chunk ); value == nil {
507+ return true , nil
508+ }
509+ }
510+ return handleFn (key )
511+ })
512+ return nil
477513}
478514
479515// Descend calls handleFn for each key/value pair in the db in descending order.
@@ -531,34 +567,70 @@ func (db *DB) DescendLessOrEqual(key []byte, handleFn func(k []byte, v []byte) (
531567// Since our expiry time is stored in the value, if you want to filter expired keys,
532568// you need to set parameter filterExpired to true. But the performance will be affected.
533569// Because we need to read the value of each key to determine if it is expired.
534- func (db * DB ) DescendKeys (pattern []byte , filterExpired bool , handleFn func (k []byte ) (bool , error )) {
570+ func (db * DB ) DescendKeys (pattern []byte , filterExpired bool , handleFn func (k []byte ) (bool , error )) error {
535571 db .mu .RLock ()
536572 defer db .mu .RUnlock ()
537573
538574 var reg * regexp.Regexp
539575 if len (pattern ) > 0 {
540- reg = regexp .MustCompile (string (pattern ))
576+ var err error
577+ reg , err = regexp .Compile (string (pattern ))
578+ if err != nil {
579+ return err
580+ }
541581 }
542582
543583 db .index .Descend (func (key []byte , pos * wal.ChunkPosition ) (bool , error ) {
544- if reg == nil || reg .Match (key ) {
545- var invalid bool
546- if filterExpired {
547- chunk , err := db .dataFiles .Read (pos )
548- if err != nil {
549- return false , err
550- }
551- if value := db .checkValue (chunk ); value == nil {
552- invalid = true
553- }
584+ if reg != nil && ! reg .Match (key ) {
585+ return true , nil
586+ }
587+ if filterExpired {
588+ chunk , err := db .dataFiles .Read (pos )
589+ if err != nil {
590+ return false , err
554591 }
555- if invalid {
592+ if value := db . checkValue ( chunk ); value == nil {
556593 return true , nil
557594 }
558- return handleFn (key )
559595 }
560- return true , nil
596+ return handleFn ( key )
561597 })
598+ return nil
599+ }
600+
601+ // DescendKeysRange calls handleFn for keys within a range in the db in descending order.
602+ // Since our expiry time is stored in the value, if you want to filter expired keys,
603+ // you need to set parameter filterExpired to true. But the performance will be affected.
604+ // Because we need to read the value of each key to determine if it is expired.
605+ func (db * DB ) DescendKeysRange (startKey , endKey , pattern []byte , filterExpired bool , handleFn func (k []byte ) (bool , error )) error {
606+ db .mu .RLock ()
607+ defer db .mu .RUnlock ()
608+
609+ var reg * regexp.Regexp
610+ if len (pattern ) > 0 {
611+ var err error
612+ reg , err = regexp .Compile (string (pattern ))
613+ if err != nil {
614+ return err
615+ }
616+ }
617+
618+ db .index .DescendRange (startKey , endKey , func (key []byte , pos * wal.ChunkPosition ) (bool , error ) {
619+ if reg != nil && ! reg .Match (key ) {
620+ return true , nil
621+ }
622+ if filterExpired {
623+ chunk , err := db .dataFiles .Read (pos )
624+ if err != nil {
625+ return false , err
626+ }
627+ if value := db .checkValue (chunk ); value == nil {
628+ return true , nil
629+ }
630+ }
631+ return handleFn (key )
632+ })
633+ return nil
562634}
563635
564636func (db * DB ) checkValue (chunk []byte ) []byte {
0 commit comments