Skip to content

Commit 69cc468

Browse files
authored
Merge branch 'master' into ttl-set
2 parents 667d663 + feae89c commit 69cc468

File tree

10 files changed

+191
-39
lines changed

10 files changed

+191
-39
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ English | [简体中文](https://github.com/ByteStorage/flydb/blob/master/README
1717
You can install FlyDB using the Go command line tool:
1818

1919
```GO
20-
go get github.com/ByteStorage/FlyDB@v1.0.13
20+
go get github.com/ByteStorage/FlyDB@v1.1.0
2121
```
2222

2323
Or clone this project from github:

structure/hash.go

+28-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/ByteStorage/FlyDB/config"
88
"github.com/ByteStorage/FlyDB/engine"
99
_const "github.com/ByteStorage/FlyDB/lib/const"
10+
"regexp"
1011
"strconv"
1112
"time"
1213
)
@@ -1158,21 +1159,41 @@ func (hs *HashStructure) HTypes(k string, f interface{}) (string, error) {
11581159
//
11591160
// []string: A list of field names in the hash.
11601161
// error: An error if occurred during the operation, or nil on success.
1161-
func (hs *HashStructure) Keys() []string {
1162+
func (hs *HashStructure) Keys(regx string) ([]string, error) {
1163+
toRegexp := convertToRegexp(regx)
1164+
compile, err := regexp.Compile(toRegexp)
1165+
if err != nil {
1166+
return nil, err
1167+
}
11621168
// Get all the keys from the database
1163-
byte_keys := hs.db.GetListKeys()
1169+
byteKeys := hs.db.GetListKeys()
11641170

11651171
// Create a new slice of strings
11661172
keys := make([]string, 0)
11671173

1168-
for _, key := range byte_keys {
1169-
// Check if the key has the identifier suffix
1170-
if !keysIdentify(key) {
1171-
keys = append(keys, string(key))
1174+
for _, key := range byteKeys {
1175+
if compile.MatchString(string(key)) {
1176+
// Check if the key has the identifier suffix
1177+
if !keysIdentify(key) {
1178+
fields := hs.GetFields(string(key))
1179+
ok := true
1180+
for _, field := range fields {
1181+
_, err := hs.HGet(string(key), field)
1182+
if err != nil {
1183+
ok = false
1184+
break
1185+
}
1186+
}
1187+
if !ok {
1188+
continue
1189+
}
1190+
keys = append(keys, string(key))
1191+
}
11721192
}
1193+
11731194
}
11741195

1175-
return keys
1196+
return keys, nil
11761197
}
11771198

11781199
// GetFields returns a list of all field names in the hash stored at the specified key.

structure/hash_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,22 @@ func TestHashStructure_GetFields(t *testing.T) {
553553
fields2 := hash.GetFields("qqqqqq")
554554
assert.Equal(t, fields2, []string{"!qqq!1", "!qqq!2", "!qqq!3"})
555555

556+
keys, err := hash.Keys("*")
557+
assert.Nil(t, err)
558+
assert.Equal(t, keys, []string{"qqqqqq", "qweqwe"})
559+
560+
keys, err = hash.Keys("q*")
561+
assert.Nil(t, err)
562+
assert.Equal(t, keys, []string{"qqqqqq", "qweqwe"})
563+
564+
keys, err = hash.Keys("qq*")
565+
assert.Nil(t, err)
566+
assert.Equal(t, keys, []string{"qqqqqq"})
567+
568+
keys, err = hash.Keys("q?*")
569+
assert.Nil(t, err)
570+
assert.Equal(t, keys, []string{"qqqqqq", "qweqwe"})
571+
556572
}
557573

558574
func TestHashStructure_HGetAllFieldAndValue(t *testing.T) {

structure/list.go

+21-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"reflect"
8+
"regexp"
89
"time"
910

1011
"encoding/gob"
@@ -433,11 +434,27 @@ func (l *ListStructure) LIndex(key string, index int) (interface{}, error) {
433434
}
434435

435436
// Keys returns all the keys of the list structure.
436-
func (l *ListStructure) Keys() ([]string, error) {
437+
func (l *ListStructure) Keys(regx string) ([]string, error) {
438+
toRegexp := convertToRegexp(regx)
439+
compile, err := regexp.Compile(toRegexp)
440+
if err != nil {
441+
return nil, err
442+
}
437443
var keys []string
438-
byte_keys := l.db.GetListKeys()
439-
for _, key := range byte_keys {
440-
keys = append(keys, string(key))
444+
byteKeys := l.db.GetListKeys()
445+
for _, key := range byteKeys {
446+
// match prefix and key
447+
if compile.MatchString(string(key)) {
448+
// check if deleted
449+
db, _, err := l.getListFromDB(string(key), true)
450+
if err != nil {
451+
continue
452+
}
453+
if db.Length == 0 {
454+
continue
455+
}
456+
keys = append(keys, string(key))
457+
}
441458
}
442459
return keys, nil
443460
}

structure/list_test.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -379,16 +379,32 @@ func TestListStructure_Keys(t *testing.T) {
379379
list, _ := initList()
380380
defer list.db.Clean()
381381

382-
listErr = list.LPush("1", randkv.RandomValue(100), 0)
382+
listErr = list.LPush("111", randkv.RandomValue(100), 0)
383383
assert.Nil(t, listErr)
384384

385-
listErr = list.LPush("2", randkv.RandomValue(100), 0)
385+
listErr = list.LPush("122", randkv.RandomValue(100), 0)
386386
assert.Nil(t, listErr)
387387

388-
listErr = list.LPush("q", randkv.RandomValue(100), 0)
388+
listErr = list.LPush("123", randkv.RandomValue(100), 0)
389389
assert.Nil(t, listErr)
390390

391-
keys, err := list.Keys()
391+
keys, err := list.Keys("*")
392+
assert.Nil(t, err)
393+
assert.Equal(t, len(keys), 3)
394+
395+
keys, err = list.Keys("1*")
396+
assert.Nil(t, err)
397+
assert.Equal(t, len(keys), 3)
398+
399+
keys, err = list.Keys("12*")
400+
assert.Nil(t, err)
401+
assert.Equal(t, len(keys), 2)
402+
403+
keys, err = list.Keys("123")
404+
assert.Nil(t, err)
405+
assert.Equal(t, len(keys), 1)
406+
407+
keys, err = list.Keys("1?*")
392408
assert.Nil(t, err)
393409
assert.Equal(t, len(keys), 3)
394410
}

structure/set.go

+24-11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/ByteStorage/FlyDB/engine"
88
_const "github.com/ByteStorage/FlyDB/lib/const"
99
"github.com/ByteStorage/FlyDB/lib/encoding"
10+
"regexp"
1011
"time"
1112
)
1213

@@ -229,6 +230,27 @@ func (s *SetStructure) SDiff(keys ...string) ([]string, error) {
229230
return diffMembers, nil
230231
}
231232

233+
// Keys returns all the keys of the set structure
234+
func (s *SetStructure) Keys(regx string) ([]string, error) {
235+
toRegexp := convertToRegexp(regx)
236+
compile, err := regexp.Compile(toRegexp)
237+
if err != nil {
238+
return nil, err
239+
}
240+
var keys []string
241+
byteKeys := s.db.GetListKeys()
242+
for _, key := range byteKeys {
243+
if compile.MatchString(string(key)) {
244+
// check if deleted
245+
if !s.exists(string(key)) {
246+
continue
247+
}
248+
keys = append(keys, string(key))
249+
}
250+
}
251+
return keys, nil
252+
}
253+
232254
// SUnionStore calculates and stores the union of multiple sets
233255
// in a destination set.
234256
//
@@ -385,7 +407,7 @@ type FSetWithTTL struct {
385407

386408
// setSetToDB
387409
func (s *SetStructure) setSetToDB(key []byte, zSetValue *FSets, ttl time.Duration) error {
388-
// 创建新的结构体实例,包含zSetValue和TTL值
410+
// create a new zSetValueWithTTL struct
389411
var expire int64 = 0
390412

391413
if ttl != 0 {
@@ -398,7 +420,7 @@ func (s *SetStructure) setSetToDB(key []byte, zSetValue *FSets, ttl time.Duratio
398420
}
399421

400422
val := encoding.NewMessagePackEncoder()
401-
err := val.Encode(valueWithTTL) // 编码包含zSetValue和TTL的新的结构体
423+
err := val.Encode(valueWithTTL) // Encode the value along with TTL
402424
if err != nil {
403425
return err
404426
}
@@ -427,15 +449,6 @@ func (s *FSets) exists(member ...string) bool {
427449
return true
428450
}
429451

430-
func (s *SetStructure) Keys() ([]string, error) {
431-
var keys []string
432-
byte_keys := s.db.GetListKeys()
433-
for _, key := range byte_keys {
434-
keys = append(keys, string(key))
435-
}
436-
return keys, nil
437-
}
438-
439452
func (s *SetStructure) Stop() error {
440453
err := s.db.Close()
441454
return err

structure/set_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -1139,3 +1139,41 @@ func TestFSets_remove(t *testing.T) {
11391139
})
11401140
}
11411141
}
1142+
1143+
func TestSetStructure_Keys(t *testing.T) {
1144+
set, _ := initTestSetDb()
1145+
defer set.db.Clean()
1146+
1147+
err = set.SAdd("testKey11", "non1", 0)
1148+
assert.Nil(t, err)
1149+
1150+
err = set.SAdd("testKey12", "non1", 0)
1151+
assert.Nil(t, err)
1152+
1153+
err = set.SAdd("testKey3", "non1", 0)
1154+
assert.Nil(t, err)
1155+
1156+
err = set.SAdd("testKey4", "non1", 0)
1157+
assert.Nil(t, err)
1158+
1159+
keys, err := set.Keys("*")
1160+
assert.Nil(t, err)
1161+
assert.Equal(t, 4, len(keys))
1162+
1163+
keys, err = set.Keys("testKey*")
1164+
assert.Nil(t, err)
1165+
assert.Equal(t, 4, len(keys))
1166+
1167+
keys, err = set.Keys("testKey1*")
1168+
assert.Nil(t, err)
1169+
assert.Equal(t, 2, len(keys))
1170+
1171+
keys, err = set.Keys("testKey?*")
1172+
assert.Nil(t, err)
1173+
assert.Equal(t, 4, len(keys))
1174+
1175+
keys, err = set.Keys("testKey111?*")
1176+
assert.Nil(t, err)
1177+
assert.Equal(t, 0, len(keys))
1178+
1179+
}

structure/string.go

+13-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/ByteStorage/FlyDB/config"
88
"github.com/ByteStorage/FlyDB/engine"
99
_const "github.com/ByteStorage/FlyDB/lib/const"
10+
"regexp"
1011
"strconv"
1112
"time"
1213
)
@@ -311,20 +312,24 @@ func (s *StringStructure) DecrBy(key string, amount int, ttl int64) error {
311312
}
312313

313314
// Keys returns all keys matching pattern
314-
func (s *StringStructure) Keys() ([]string, error) {
315+
func (s *StringStructure) Keys(regx string) ([]string, error) {
316+
toRegexp := convertToRegexp(regx)
317+
compile, err := regexp.Compile(toRegexp)
318+
if err != nil {
319+
return nil, err
320+
}
315321
var keys []string
316322
byteKeys := s.db.GetListKeys()
317323
for _, key := range byteKeys {
318-
// check if key is expired
319-
_, err := s.Get(string(key))
320-
if err != nil {
321-
if errors.Is(err, _const.ErrKeyIsExpired) {
324+
if compile.MatchString(string(key)) {
325+
// check if key is expired
326+
_, err := s.Get(string(key))
327+
if err != nil {
322328
continue
323-
} else {
324-
return nil, err
325329
}
330+
keys = append(keys, string(key))
326331
}
327-
keys = append(keys, string(key))
332+
328333
}
329334
return keys, nil
330335
}

structure/string_test.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -425,13 +425,13 @@ func TestStringStructure_Keys(t *testing.T) {
425425
str, _ := initdb()
426426
defer str.db.Clean()
427427

428-
err = str.Set("1", randkv.RandomValue(100), 1)
428+
err = str.Set("11", randkv.RandomValue(100), 1)
429429
assert.Nil(t, err)
430430

431-
err = str.Set("2", randkv.RandomValue(100), 2)
431+
err = str.Set("21", randkv.RandomValue(100), 2)
432432
assert.Nil(t, err)
433433

434-
err = str.Set("3", randkv.RandomValue(100), 0)
434+
err = str.Set("31", randkv.RandomValue(100), 0)
435435
assert.Nil(t, err)
436436

437437
err = str.Set("hhh", randkv.RandomValue(100), 0)
@@ -442,9 +442,21 @@ func TestStringStructure_Keys(t *testing.T) {
442442

443443
time.Sleep(2 * time.Second)
444444

445-
keys, err := str.Keys()
445+
keys, err := str.Keys("*")
446446
assert.Nil(t, err)
447447
assert.Equal(t, len(keys), 3)
448+
449+
keys, err = str.Keys("1*")
450+
assert.Nil(t, err)
451+
assert.Equal(t, len(keys), 0)
452+
453+
keys, err = str.Keys("3*")
454+
assert.Nil(t, err)
455+
assert.Equal(t, len(keys), 1)
456+
457+
keys, err = str.Keys("*1")
458+
assert.Nil(t, err)
459+
assert.Equal(t, len(keys), 1)
448460
}
449461

450462
func TestStringStructure_TTL(t *testing.T) {

structure/types.go

+14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package structure
22

33
import (
44
"errors"
5+
"regexp"
56
"strconv"
7+
"strings"
68
)
79

810
type DataStructure = byte
@@ -189,3 +191,15 @@ func convertToFloat(Value interface{}) (float64, error) {
189191
return 0, errors.New("unsupported type")
190192
}
191193
}
194+
195+
func convertToRegexp(pattern string) string {
196+
// 转义正则特殊字符
197+
re := regexp.MustCompile(`([\[\]\(\)\{\}\^\$\.\+])`)
198+
pattern = re.ReplaceAllString(pattern, `\$1`)
199+
200+
// 将 * 和 ? 转换为对应的正则表达式
201+
pattern = strings.ReplaceAll(pattern, "*", ".*")
202+
pattern = strings.ReplaceAll(pattern, "?", ".")
203+
204+
return "^" + pattern + "$" // 添加 ^ 和 $ 以确保完全匹配
205+
}

0 commit comments

Comments
 (0)