“Redis IN Action” 這本書的中的實(shí)現(xiàn)思路
理論基礎(chǔ),以下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
繼續(xù)擴(kuò)展范圍, 構(gòu)成 username 的 字符范圍 擴(kuò)展整個(gè) unicode: BMP
unicode:BMP
指代unicode code points在
U+0000 to U+FFFF
范圍內(nèi)的字符垢粮。
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);
}