Skip to content

Instantly share code, notes, and snippets.

@porjo
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porjo/10233179 to your computer and use it in GitHub Desktop.
Save porjo/10233179 to your computer and use it in GitHub Desktop.
Autocomplete using Redis backend. Handles UTF8 strings. See this blog post on how to load the Redis data http://oldblog.antirez.com/post/autocomplete-with-redis.html
import (
"strings"
u8 "code.google.com/p/go.exp/utf8string"
"github.com/garyburd/redigo/redis"
)
// Based on code by Salvatore Sanfilippo
// http://oldblog.antirez.com/post/autocomplete-with-redis.html
func RedisComplete(prefix string, count int) (results []string, err error) {
prefix = strings.Title(prefix)
rangelen := 50
start := 0
u8p := u8.NewString(prefix)
start, rerr := redis.Int(redisConn.Do("ZRANK", "compl", prefix))
if rerr != nil {
if rerr == redis.ErrNil {
return
}
return nil, rerr
}
for len(results) != count {
var rerr error
var elements []string
elements, rerr = redis.Strings(redisConn.Do("ZRANGE", "compl", start, start+rangelen-1))
if rerr != nil {
if rerr == redis.ErrNil {
break
}
return nil, rerr
}
start += rangelen
if len(elements) == 0 {
break
}
for _, v := range elements {
u8v := u8.NewString(v)
var minlen int
if u8v.RuneCount() <= u8p.RuneCount() {
minlen = u8v.RuneCount()
} else {
minlen = u8p.RuneCount()
}
if u8v.Slice(0, minlen) != u8p.Slice(0, minlen) {
count = len(results)
break
}
if u8v.At(u8v.RuneCount()-1) == '*' {
results = append(results, strings.TrimRight(v, "*"))
if len(results) == count {
break
}
}
}
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment