diff --git a/internal/server/keys.go b/internal/server/keys.go index 06a73297..90b0cb2c 100644 --- a/internal/server/keys.go +++ b/internal/server/keys.go @@ -27,6 +27,10 @@ func (c *Server) cmdKeys(msg *Message) (res resp.Value, err error) { if msg.OutputType == JSON { wr.WriteString(`{"ok":true,"keys":[`) } + var wild bool + if strings.Contains(pattern, "*") { + wild = true + } var everything bool var greater bool var greaterPivot string @@ -58,30 +62,29 @@ func (c *Server) cmdKeys(msg *Message) (res resp.Value, err error) { case RESP: vals = append(vals, resp.StringValue(key)) } + + // If no more than one match is expected, stop searching + if !wild { + return false + } } return true } + + // TODO: This can be further optimized by using glob.Parse and limits if pattern == "*" { everything = true c.cols.Scan(iterator) - } else { - if strings.HasSuffix(pattern, "*") { - greaterPivot = pattern[:len(pattern)-1] - if glob.IsGlob(greaterPivot) { - greater = false - c.cols.Scan(iterator) - } else { - greater = true - c.cols.Ascend(greaterPivot, iterator) - } - } else if glob.IsGlob(pattern) { - greater = false + } else if strings.HasSuffix(pattern, "*") { + greaterPivot = pattern[:len(pattern)-1] + if glob.IsGlob(greaterPivot) { c.cols.Scan(iterator) } else { greater = true - greaterPivot = pattern c.cols.Ascend(greaterPivot, iterator) } + } else { + c.cols.Scan(iterator) } if msg.OutputType == JSON { wr.WriteString(`],"elapsed":"` + time.Now().Sub(start).String() + "\"}") diff --git a/tests/keys_test.go b/tests/keys_test.go index dcd87943..17ad6e51 100644 --- a/tests/keys_test.go +++ b/tests/keys_test.go @@ -149,14 +149,20 @@ func keys_KEYS_test(mc *mockServer) error { {"SET", "mykey11", "myid3", "OBJECT", `{"type":"Point","coordinates":[-110,25,-8]}`}, {"OK"}, {"SET", "mykey42", "myid2", "HASH", "9my5xp7"}, {"OK"}, {"SET", "mykey31", "myid4", "STRING", "value"}, {"OK"}, - {"KEYS", "*"}, {"[mykey11 mykey22 mykey31 mykey42]"}, - {"KEYS", "*key*"}, {"[mykey11 mykey22 mykey31 mykey42]"}, - {"KEYS", "mykey*"}, {"[mykey11 mykey22 mykey31 mykey42]"}, + {"SET", "mykey310", "myid5", "STRING", "value"}, {"OK"}, + {"KEYS", "*"}, {"[mykey11 mykey22 mykey31 mykey310 mykey42]"}, + {"KEYS", "*key*"}, {"[mykey11 mykey22 mykey31 mykey310 mykey42]"}, + {"KEYS", "mykey*"}, {"[mykey11 mykey22 mykey31 mykey310 mykey42]"}, {"KEYS", "mykey4*"}, {"[mykey42]"}, {"KEYS", "mykey*1"}, {"[mykey11 mykey31]"}, + {"KEYS", "mykey*1*"}, {"[mykey11 mykey31 mykey310]"}, + {"KEYS", "mykey*10"}, {"[mykey310]"}, {"KEYS", "mykey*2"}, {"[mykey22 mykey42]"}, {"KEYS", "*2"}, {"[mykey22 mykey42]"}, - {"KEYS", "*1*"}, {"[mykey11 mykey31]"}, + {"KEYS", "*1*"}, {"[mykey11 mykey31 mykey310]"}, + {"KEYS", "mykey"}, {"[]"}, + {"KEYS", "mykey31"}, {"[mykey31]"}, + {"KEYS", "mykey[^3]*"}, {"[mykey11 mykey22 mykey42]"}, }) } func keys_PERSIST_test(mc *mockServer) error {