redis:auto-complete

“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 strings = conn.zrangeByLex(key, "(" + min, "(" + max);

        System.out.println(strings);
    }

你可能感兴趣的:(redis:auto-complete)