“Redis IN Action” 这本书的中的实现思路
理论基础,以下3篇文章:
jedis:向redis server提交bytes
redis:encoding
redis: lexicographic ordering
redis: Details on strings comparison
redis commands: zrangebylex
算法说明:
redis in action: 6.1.2 Address book autocomplete
简化问题, username 字符的取值范围是 [a,z]
用户输入: "abc"
查找以 “abc” 打头的usernames
确定下限:
“abb{”
确定上限:
“abc{”
范围在:
[ "abb{", "abc{" ]
我来解释下:
lexical order:
abb
abba
abbb
abbc
...
abb{
abc
abca
abcb
...
abc{
abd
所以,以"abc"打头的usernames都在 "abb{" 和 "abc{"之间。
Notes: 如果 为什么要用 { , 可以查看 unicode code points
继续扩展范围, 构成 username 的 字符范围 扩展整个 unicode: BMP
unicode:BMP
指代unicode code points在
U+0000 to U+FFFF
范围内的字符。
private static void autoCompleteBMP(Jedis conn, String key, String prefix) {
if (prefix == null || prefix.isEmpty()) {
return;
}
int len = prefix.length();
//1. header tail
String header = prefix;
String tail = prefix;
if (len > 1) {
header = prefix.substring(0, len - 1);
tail = prefix.substring(len - 1, len);
}
//2. min, max
int codePoint = tail.codePointAt(0);
String start = "\u0000";
if (Character.isValidCodePoint(codePoint - 1)) {
start = new String(new int[]{codePoint - 1}, 0, 1);
}
String min = start + "\uFFFF";
String max = tail + "\uFFFF";
if (len > 1) {
min = header + start + "\uFFFF";
max = header + tail + "\uFFFF";
}
// System.out.println("min: " + min + " ; " + "max: " + max);
//3. zrangebylex
Set<String> strings = conn.zrangeByLex(key, "(" + min, "(" + max);
System.out.println(strings);
}