Last active
September 20, 2021 08:25
-
-
Save luw2007/692d4a615dd71aa2bfa42190ad6a12e3 to your computer and use it in GitHub Desktop.
Revisions
-
luw2007 revised this gist
May 23, 2017 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -19,10 +19,13 @@ func BitRange(str []byte, start int, offset int, size int) []int { bits := []int{} k := 0 for i, b := range str { // 按位,依次判断0-7下标每位是否为真 for j, num := range nums { if b&num != num { continue } // redis 存储offset 是从左向右存 // 下标位置 = 7 - 当前位 k = int(i*8 + 7 - j) if offset <= k && k < offset+size { bits = append(bits, start*8+k) -
luw2007 revised this gist
May 22, 2017 . No changes.There are no files selected for viewing
-
luw2007 revised this gist
May 12, 2017 . No changes.There are no files selected for viewing
-
luw2007 revised this gist
May 12, 2017 . 1 changed file with 8 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,12 +20,14 @@ func BitRange(str []byte, start int, offset int, size int) []int { k := 0 for i, b := range str { for j, num := range nums { if b&num != num { continue } k = int(i*8 + 7 - j) if offset <= k && k < offset+size { bits = append(bits, start*8+k) } } } return bits @@ -42,7 +44,7 @@ func (p *Pool) BitRange(key string, cur int, size int) ([]int, error) { end := (cur+size+7)/8 str, err := r.Bytes(p.ExecuteCMD("GETRANGE", key, start, end)) if err != nil { return nil, err } bits := BitRange(str, start, cur%8, size) return bits, nil -
luw2007 revised this gist
May 12, 2017 . No changes.There are no files selected for viewing
-
luw2007 revised this gist
May 12, 2017 . 4 changed files with 409 additions and 300 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,13 @@ package redis import ( r "github.com/garyburd/redigo/redis" ) type Pool struct { r.Pool } var nums = [8]uint8{1, 2, 4, 8, 16, 32, 64, 128} // BitRange 计算下标表 @@ -21,4 +29,21 @@ func BitRange(str []byte, start int, offset int, size int) []int { } } return bits } // GetBitRange 按位查询 返回bit位为1的下标 // client: redis的client // key: redis 存储的key // cur: 开始位置 // size: 查询个数 func (p *Pool) BitRange(key string, cur int, size int) ([]int, error) { start := cur / 8 // end必须按8取整 end := (cur+size+7)/8 str, err := r.Bytes(p.ExecuteCMD("GETRANGE", key, start, end)) if err != nil { return []int{}, err } bits := BitRange(str, start, cur%8, size) return bits, nil } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,24 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,296 +1,362 @@ # -*- coding: utf-8 -*- """ 业务中经常需要对redis执行一组连续的gitbit 以下通过getrange 方法来优化getbits的速度 empty key, times 10 git_bits 1: 0.508 get_bits_pipe 1: 0.604 git_bits 10: 0.543 get_bits_pipe 10: 1.159 git_bits 100: 0.587 get_bits_pipe 100: 3.477 git_bits 1000: 0.744 get_bits_pipe 1000: 34.866 git_bits 5000: 0.629 get_bits_pipe 5000: 120.348 all true, times 10 git_bits 1: 0.405 get_bits_pipe 1: 0.478 git_bits 10: 0.420 get_bits_pipe 10: 1.390 git_bits 100: 0.995 get_bits_pipe 100: 3.562 git_bits 1000: 1.615 get_bits_pipe 1000: 28.776 git_bits 5000: 4.770 get_bits_pipe 5000: 120.539 由此可见getrange 确实有效的提升了查询性能 """ import time import redis redis_bit_map = { "\x00": [], "\x01": [7], "\x02": [6], "\x03": [6, 7], "\x04": [5], "\x05": [5, 7], "\x06": [5, 6], "\x07": [5, 6, 7], "\x08": [4], "\t": [4, 7], "\n": [4, 6], "\x0b": [4, 6, 7], "\x0c": [4, 5], "\r": [4, 5, 7], "\x0e": [4, 5, 6], "\x0f": [4, 5, 6, 7], "\x10": [3], "\x11": [3, 7], "\x12": [3, 6], "\x13": [3, 6, 7], "\x14": [3, 5], "\x15": [3, 5, 7], "\x16": [3, 5, 6], "\x17": [3, 5, 6, 7], "\x18": [3, 4], "\x19": [3, 4, 7], "\x1a": [3, 4, 6], "\x1b": [3, 4, 6, 7], "\x1c": [3, 4, 5], "\x1d": [3, 4, 5, 7], "\x1e": [3, 4, 5, 6], "\x1f": [3, 4, 5, 6, 7], " ": [2], "!": [2, 7], """: [2, 6], "#": [2, 6, 7], "$": [2, 5], "%": [2, 5, 7], "&": [2, 5, 6], """: [2, 5, 6, 7], "(": [2, 4], ")": [2, 4, 7], "*": [2, 4, 6], "+": [2, 4, 6, 7], ",": [2, 4, 5], "-": [2, 4, 5, 7], ".": [2, 4, 5, 6], "/": [2, 4, 5, 6, 7], "0": [2, 3], "1": [2, 3, 7], "2": [2, 3, 6], "3": [2, 3, 6, 7], "4": [2, 3, 5], "5": [2, 3, 5, 7], "6": [2, 3, 5, 6], "7": [2, 3, 5, 6, 7], "8": [2, 3, 4], "9": [2, 3, 4, 7], ":": [2, 3, 4, 6], ";": [2, 3, 4, 6, 7], "<": [2, 3, 4, 5], "=": [2, 3, 4, 5, 7], ">": [2, 3, 4, 5, 6], "?": [2, 3, 4, 5, 6, 7], "@": [1], "A": [1, 7], "B": [1, 6], "C": [1, 6, 7], "D": [1, 5], "E": [1, 5, 7], "F": [1, 5, 6], "G": [1, 5, 6, 7], "H": [1, 4], "I": [1, 4, 7], "J": [1, 4, 6], "K": [1, 4, 6, 7], "L": [1, 4, 5], "M": [1, 4, 5, 7], "N": [1, 4, 5, 6], "O": [1, 4, 5, 6, 7], "P": [1, 3], "Q": [1, 3, 7], "R": [1, 3, 6], "S": [1, 3, 6, 7], "T": [1, 3, 5], "U": [1, 3, 5, 7], "V": [1, 3, 5, 6], "W": [1, 3, 5, 6, 7], "X": [1, 3, 4], "Y": [1, 3, 4, 7], "Z": [1, 3, 4, 6], "[": [1, 3, 4, 6, 7], "\\": [1, 3, 4, 5], "]": [1, 3, 4, 5, 7], "^": [1, 3, 4, 5, 6], "_": [1, 3, 4, 5, 6, 7], "`": [1, 2], "a": [1, 2, 7], "b": [1, 2, 6], "c": [1, 2, 6, 7], "d": [1, 2, 5], "e": [1, 2, 5, 7], "f": [1, 2, 5, 6], "g": [1, 2, 5, 6, 7], "h": [1, 2, 4], "i": [1, 2, 4, 7], "j": [1, 2, 4, 6], "k": [1, 2, 4, 6, 7], "l": [1, 2, 4, 5], "m": [1, 2, 4, 5, 7], "n": [1, 2, 4, 5, 6], "o": [1, 2, 4, 5, 6, 7], "p": [1, 2, 3], "q": [1, 2, 3, 7], "r": [1, 2, 3, 6], "s": [1, 2, 3, 6, 7], "t": [1, 2, 3, 5], "u": [1, 2, 3, 5, 7], "v": [1, 2, 3, 5, 6], "w": [1, 2, 3, 5, 6, 7], "x": [1, 2, 3, 4], "y": [1, 2, 3, 4, 7], "z": [1, 2, 3, 4, 6], "{": [1, 2, 3, 4, 6, 7], "|": [1, 2, 3, 4, 5], "}": [1, 2, 3, 4, 5, 7], "~": [1, 2, 3, 4, 5, 6], "\x7f": [1, 2, 3, 4, 5, 6, 7], "\x80": [0], "\x81": [0, 7], "\x82": [0, 6], "\x83": [0, 6, 7], "\x84": [0, 5], "\x85": [0, 5, 7], "\x86": [0, 5, 6], "\x87": [0, 5, 6, 7], "\x88": [0, 4], "\x89": [0, 4, 7], "\x8a": [0, 4, 6], "\x8b": [0, 4, 6, 7], "\x8c": [0, 4, 5], "\x8d": [0, 4, 5, 7], "\x8e": [0, 4, 5, 6], "\x8f": [0, 4, 5, 6, 7], "\x90": [0, 3], "\x91": [0, 3, 7], "\x92": [0, 3, 6], "\x93": [0, 3, 6, 7], "\x94": [0, 3, 5], "\x95": [0, 3, 5, 7], "\x96": [0, 3, 5, 6], "\x97": [0, 3, 5, 6, 7], "\x98": [0, 3, 4], "\x99": [0, 3, 4, 7], "\x9a": [0, 3, 4, 6], "\x9b": [0, 3, 4, 6, 7], "\x9c": [0, 3, 4, 5], "\x9d": [0, 3, 4, 5, 7], "\x9e": [0, 3, 4, 5, 6], "\x9f": [0, 3, 4, 5, 6, 7], "\xa0": [0, 2], "\xa1": [0, 2, 7], "\xa2": [0, 2, 6], "\xa3": [0, 2, 6, 7], "\xa4": [0, 2, 5], "\xa5": [0, 2, 5, 7], "\xa6": [0, 2, 5, 6], "\xa7": [0, 2, 5, 6, 7], "\xa8": [0, 2, 4], "\xa9": [0, 2, 4, 7], "\xaa": [0, 2, 4, 6], "\xab": [0, 2, 4, 6, 7], "\xac": [0, 2, 4, 5], "\xad": [0, 2, 4, 5, 7], "\xae": [0, 2, 4, 5, 6], "\xaf": [0, 2, 4, 5, 6, 7], "\xb0": [0, 2, 3], "\xb1": [0, 2, 3, 7], "\xb2": [0, 2, 3, 6], "\xb3": [0, 2, 3, 6, 7], "\xb4": [0, 2, 3, 5], "\xb5": [0, 2, 3, 5, 7], "\xb6": [0, 2, 3, 5, 6], "\xb7": [0, 2, 3, 5, 6, 7], "\xb8": [0, 2, 3, 4], "\xb9": [0, 2, 3, 4, 7], "\xba": [0, 2, 3, 4, 6], "\xbb": [0, 2, 3, 4, 6, 7], "\xbc": [0, 2, 3, 4, 5], "\xbd": [0, 2, 3, 4, 5, 7], "\xbe": [0, 2, 3, 4, 5, 6], "\xbf": [0, 2, 3, 4, 5, 6, 7], "\xc0": [0, 1], "\xc1": [0, 1, 7], "\xc2": [0, 1, 6], "\xc3": [0, 1, 6, 7], "\xc4": [0, 1, 5], "\xc5": [0, 1, 5, 7], "\xc6": [0, 1, 5, 6], "\xc7": [0, 1, 5, 6, 7], "\xc8": [0, 1, 4], "\xc9": [0, 1, 4, 7], "\xca": [0, 1, 4, 6], "\xcb": [0, 1, 4, 6, 7], "\xcc": [0, 1, 4, 5], "\xcd": [0, 1, 4, 5, 7], "\xce": [0, 1, 4, 5, 6], "\xcf": [0, 1, 4, 5, 6, 7], "\xd0": [0, 1, 3], "\xd1": [0, 1, 3, 7], "\xd2": [0, 1, 3, 6], "\xd3": [0, 1, 3, 6, 7], "\xd4": [0, 1, 3, 5], "\xd5": [0, 1, 3, 5, 7], "\xd6": [0, 1, 3, 5, 6], "\xd7": [0, 1, 3, 5, 6, 7], "\xd8": [0, 1, 3, 4], "\xd9": [0, 1, 3, 4, 7], "\xda": [0, 1, 3, 4, 6], "\xdb": [0, 1, 3, 4, 6, 7], "\xdc": [0, 1, 3, 4, 5], "\xdd": [0, 1, 3, 4, 5, 7], "\xde": [0, 1, 3, 4, 5, 6], "\xdf": [0, 1, 3, 4, 5, 6, 7], "\xe0": [0, 1, 2], "\xe1": [0, 1, 2, 7], "\xe2": [0, 1, 2, 6], "\xe3": [0, 1, 2, 6, 7], "\xe4": [0, 1, 2, 5], "\xe5": [0, 1, 2, 5, 7], "\xe6": [0, 1, 2, 5, 6], "\xe7": [0, 1, 2, 5, 6, 7], "\xe8": [0, 1, 2, 4], "\xe9": [0, 1, 2, 4, 7], "\xea": [0, 1, 2, 4, 6], "\xeb": [0, 1, 2, 4, 6, 7], "\xec": [0, 1, 2, 4, 5], "\xed": [0, 1, 2, 4, 5, 7], "\xee": [0, 1, 2, 4, 5, 6], "\xef": [0, 1, 2, 4, 5, 6, 7], "\xf0": [0, 1, 2, 3], "\xf1": [0, 1, 2, 3, 7], "\xf2": [0, 1, 2, 3, 6], "\xf3": [0, 1, 2, 3, 6, 7], "\xf4": [0, 1, 2, 3, 5], "\xf5": [0, 1, 2, 3, 5, 7], "\xf6": [0, 1, 2, 3, 5, 6], "\xf7": [0, 1, 2, 3, 5, 6, 7], "\xf8": [0, 1, 2, 3, 4], "\xf9": [0, 1, 2, 3, 4, 7], "\xfa": [0, 1, 2, 3, 4, 6], "\xfb": [0, 1, 2, 3, 4, 6, 7], "\xfc": [0, 1, 2, 3, 4, 5], "\xfd": [0, 1, 2, 3, 4, 5, 7], "\xfe": [0, 1, 2, 3, 4, 5, 6], "\xff": [0, 1, 2, 3, 4, 5, 6, 7], } def find_bit(bits): """ 位计算为真的下标 >>> find_bit(b"\x80") [0] >>> find_bit("@") [1] >>> find_bit(b"\xff\xff") [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] >>> find_bit(b"\x11") [3, 7] >>> find_bit(b"\x01\x01") [7, 15] >>> find_bit(b"\x11\x11") [3, 7, 11, 15] """ return [no * 8 + j for no, i in enumerate(bits) for j in redis_bit_map[i]] def git_bits(redis_client, key, cur, num=10): """ 按位查询 返回bit位为1的下标 :param cur: 开始位置 :param num: 查询个数 :return: [] """ start, offset = divmod(cur, 8) # end 必须按8取整 end = (cur + num + 7) / 8 return [start * 8 + _id for _id in find_bit(redis_client.getrange(key, start, end)) if offset <= _id <= offset + num] def get_bits_pipe(pipe, key, cur, num=10): """ 使用pipeline gitbit""" for i in xrange(num + 1): pipe.getbit(key, cur + i) return [cur + i for i, v in enumerate(pipe.execute()) if v] def bench(func, *a, **kw): """压力测试""" s = time.time() times = kw.pop("times", 1) res = None for _ in range(times): res = func(*a, **kw) e = time.time() print("%s %d: %.3f" % (func.func_name, kw["num"], (e - s) * 1000 / times)) if __name__ == "__main__": key = "bench_bits" r = redis.Redis() Times = 10 print("empty key, times %d" % Times) r.delete(key) pipe = r.pipeline(transaction=False) for MAX in (1, 10, 100, 1000, 5000): bench(git_bits, r, key, 0, num=MAX, times=Times) bench(get_bits_pipe, pipe, key, 0, num=MAX, times=Times) for i in range(MAX): r.setbit(key, i, 1) print("all true, times %d" % Times) for MAX in (1, 10, 100, 1000, 5000): bench(git_bits, r, key, 0, num=MAX, times=Times) bench(get_bits_pipe, pipe, key, 0, num=MAX, times=Times) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,42 @@ package redis import ( r "github.com/garyburd/redigo/redis" "fmt" ) var ( key = "bits" p = &Pool{r.Pool{ Dial: func() (r.Conn, error) { return r.Dial("tcp", "127.0.0.1:6379") }, }} ) func ExamplePool_GetBitRange() { p.ExecuteCMD("DEL", key) p.ExecuteCMD("SETBIT", key, 1, 1) bits, _ := p.GetBitRange(key, 0, 8) fmt.Println(bits) // Output: [1] } func TestPool_GetBitRange(t *testing.T) { // 测试边界 11 [12 13] 14 p.ExecuteCMD("SETBIT", key, 11, 1) p.ExecuteCMD("SETBIT", key, 12, 1) p.ExecuteCMD("SETBIT", key, 14, 1) bits, _ := p.GetBitRange(key, 12, 2) if intInSlice(11, bits) && intInSlice(14, bits) && !intInSlice(12, bits) { t.Error("error in test TestGetBitRange") } } // intInSlice 数字是否在数组中 func intInSlice(a int, list []int) bool { for _, i := range list { if i == a { return true } } return false } -
luw2007 created this gist
May 12, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,24 @@ package redis var nums = [8]uint8{1, 2, 4, 8, 16, 32, 64, 128} // BitRange 计算下标表 // str: 计算的字符串 // start: 开始的座标 // offset: 偏移值 // size: 查询个数 func BitRange(str []byte, start int, offset int, size int) []int { bits := []int{} k := 0 for i, b := range str { for j, num := range nums { if b&num == num { k = int(i*8 + 7 - j) if offset <= k && k < offset+size { bits = append(bits, start*8+k) } } } } return bits } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,24 @@ package redis import ( r "github.com/garyburd/redigo/redis" ) type Pool struct { r.Pool } // GetBitRange 按位查询 返回bit位为1的下标 // client: redis的client // key: redis 存储的key // cur: 开始位置 // size: 查询个数 func (p *Pool) BitRange(key string, cur int, size int) ([]int, error) { start := cur / 8 // end必须按8取整 end := (cur+size+7)/8 str, err := r.Bytes(p.ExecuteCMD("GETRANGE", key, start, end)) if err != nil { return []int{}, err } bits := BitRange(str, start, cur%8, size) return bits, nil } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,296 @@ import itertools import time redis_bit_map = { '\x00': [], '\x01': [7], '\x02': [6], '\x03': [6, 7], '\x04': [5], '\x05': [5, 7], '\x06': [5, 6], '\x07': [5, 6, 7], '\x08': [4], '\t': [4, 7], '\n': [4, 6], '\x0b': [4, 6, 7], '\x0c': [4, 5], '\r': [4, 5, 7], '\x0e': [4, 5, 6], '\x0f': [4, 5, 6, 7], '\x10': [3], '\x11': [3, 7], '\x12': [3, 6], '\x13': [3, 6, 7], '\x14': [3, 5], '\x15': [3, 5, 7], '\x16': [3, 5, 6], '\x17': [3, 5, 6, 7], '\x18': [3, 4], '\x19': [3, 4, 7], '\x1a': [3, 4, 6], '\x1b': [3, 4, 6, 7], '\x1c': [3, 4, 5], '\x1d': [3, 4, 5, 7], '\x1e': [3, 4, 5, 6], '\x1f': [3, 4, 5, 6, 7], ' ': [2], '!': [2, 7], '"': [2, 6], '#': [2, 6, 7], '$': [2, 5], '%': [2, 5, 7], '&': [2, 5, 6], "'": [2, 5, 6, 7], '(': [2, 4], ')': [2, 4, 7], '*': [2, 4, 6], '+': [2, 4, 6, 7], ',': [2, 4, 5], '-': [2, 4, 5, 7], '.': [2, 4, 5, 6], '/': [2, 4, 5, 6, 7], '0': [2, 3], '1': [2, 3, 7], '2': [2, 3, 6], '3': [2, 3, 6, 7], '4': [2, 3, 5], '5': [2, 3, 5, 7], '6': [2, 3, 5, 6], '7': [2, 3, 5, 6, 7], '8': [2, 3, 4], '9': [2, 3, 4, 7], ':': [2, 3, 4, 6], ';': [2, 3, 4, 6, 7], '<': [2, 3, 4, 5], '=': [2, 3, 4, 5, 7], '>': [2, 3, 4, 5, 6], '?': [2, 3, 4, 5, 6, 7], '@': [1], 'A': [1, 7], 'B': [1, 6], 'C': [1, 6, 7], 'D': [1, 5], 'E': [1, 5, 7], 'F': [1, 5, 6], 'G': [1, 5, 6, 7], 'H': [1, 4], 'I': [1, 4, 7], 'J': [1, 4, 6], 'K': [1, 4, 6, 7], 'L': [1, 4, 5], 'M': [1, 4, 5, 7], 'N': [1, 4, 5, 6], 'O': [1, 4, 5, 6, 7], 'P': [1, 3], 'Q': [1, 3, 7], 'R': [1, 3, 6], 'S': [1, 3, 6, 7], 'T': [1, 3, 5], 'U': [1, 3, 5, 7], 'V': [1, 3, 5, 6], 'W': [1, 3, 5, 6, 7], 'X': [1, 3, 4], 'Y': [1, 3, 4, 7], 'Z': [1, 3, 4, 6], '[': [1, 3, 4, 6, 7], '\\': [1, 3, 4, 5], ']': [1, 3, 4, 5, 7], '^': [1, 3, 4, 5, 6], '_': [1, 3, 4, 5, 6, 7], '`': [1, 2], 'a': [1, 2, 7], 'b': [1, 2, 6], 'c': [1, 2, 6, 7], 'd': [1, 2, 5], 'e': [1, 2, 5, 7], 'f': [1, 2, 5, 6], 'g': [1, 2, 5, 6, 7], 'h': [1, 2, 4], 'i': [1, 2, 4, 7], 'j': [1, 2, 4, 6], 'k': [1, 2, 4, 6, 7], 'l': [1, 2, 4, 5], 'm': [1, 2, 4, 5, 7], 'n': [1, 2, 4, 5, 6], 'o': [1, 2, 4, 5, 6, 7], 'p': [1, 2, 3], 'q': [1, 2, 3, 7], 'r': [1, 2, 3, 6], 's': [1, 2, 3, 6, 7], 't': [1, 2, 3, 5], 'u': [1, 2, 3, 5, 7], 'v': [1, 2, 3, 5, 6], 'w': [1, 2, 3, 5, 6, 7], 'x': [1, 2, 3, 4], 'y': [1, 2, 3, 4, 7], 'z': [1, 2, 3, 4, 6], '{': [1, 2, 3, 4, 6, 7], '|': [1, 2, 3, 4, 5], '}': [1, 2, 3, 4, 5, 7], '~': [1, 2, 3, 4, 5, 6], '\x7f': [1, 2, 3, 4, 5, 6, 7], '\x80': [0], '\x81': [0, 7], '\x82': [0, 6], '\x83': [0, 6, 7], '\x84': [0, 5], '\x85': [0, 5, 7], '\x86': [0, 5, 6], '\x87': [0, 5, 6, 7], '\x88': [0, 4], '\x89': [0, 4, 7], '\x8a': [0, 4, 6], '\x8b': [0, 4, 6, 7], '\x8c': [0, 4, 5], '\x8d': [0, 4, 5, 7], '\x8e': [0, 4, 5, 6], '\x8f': [0, 4, 5, 6, 7], '\x90': [0, 3], '\x91': [0, 3, 7], '\x92': [0, 3, 6], '\x93': [0, 3, 6, 7], '\x94': [0, 3, 5], '\x95': [0, 3, 5, 7], '\x96': [0, 3, 5, 6], '\x97': [0, 3, 5, 6, 7], '\x98': [0, 3, 4], '\x99': [0, 3, 4, 7], '\x9a': [0, 3, 4, 6], '\x9b': [0, 3, 4, 6, 7], '\x9c': [0, 3, 4, 5], '\x9d': [0, 3, 4, 5, 7], '\x9e': [0, 3, 4, 5, 6], '\x9f': [0, 3, 4, 5, 6, 7], '\xa0': [0, 2], '\xa1': [0, 2, 7], '\xa2': [0, 2, 6], '\xa3': [0, 2, 6, 7], '\xa4': [0, 2, 5], '\xa5': [0, 2, 5, 7], '\xa6': [0, 2, 5, 6], '\xa7': [0, 2, 5, 6, 7], '\xa8': [0, 2, 4], '\xa9': [0, 2, 4, 7], '\xaa': [0, 2, 4, 6], '\xab': [0, 2, 4, 6, 7], '\xac': [0, 2, 4, 5], '\xad': [0, 2, 4, 5, 7], '\xae': [0, 2, 4, 5, 6], '\xaf': [0, 2, 4, 5, 6, 7], '\xb0': [0, 2, 3], '\xb1': [0, 2, 3, 7], '\xb2': [0, 2, 3, 6], '\xb3': [0, 2, 3, 6, 7], '\xb4': [0, 2, 3, 5], '\xb5': [0, 2, 3, 5, 7], '\xb6': [0, 2, 3, 5, 6], '\xb7': [0, 2, 3, 5, 6, 7], '\xb8': [0, 2, 3, 4], '\xb9': [0, 2, 3, 4, 7], '\xba': [0, 2, 3, 4, 6], '\xbb': [0, 2, 3, 4, 6, 7], '\xbc': [0, 2, 3, 4, 5], '\xbd': [0, 2, 3, 4, 5, 7], '\xbe': [0, 2, 3, 4, 5, 6], '\xbf': [0, 2, 3, 4, 5, 6, 7], '\xc0': [0, 1], '\xc1': [0, 1, 7], '\xc2': [0, 1, 6], '\xc3': [0, 1, 6, 7], '\xc4': [0, 1, 5], '\xc5': [0, 1, 5, 7], '\xc6': [0, 1, 5, 6], '\xc7': [0, 1, 5, 6, 7], '\xc8': [0, 1, 4], '\xc9': [0, 1, 4, 7], '\xca': [0, 1, 4, 6], '\xcb': [0, 1, 4, 6, 7], '\xcc': [0, 1, 4, 5], '\xcd': [0, 1, 4, 5, 7], '\xce': [0, 1, 4, 5, 6], '\xcf': [0, 1, 4, 5, 6, 7], '\xd0': [0, 1, 3], '\xd1': [0, 1, 3, 7], '\xd2': [0, 1, 3, 6], '\xd3': [0, 1, 3, 6, 7], '\xd4': [0, 1, 3, 5], '\xd5': [0, 1, 3, 5, 7], '\xd6': [0, 1, 3, 5, 6], '\xd7': [0, 1, 3, 5, 6, 7], '\xd8': [0, 1, 3, 4], '\xd9': [0, 1, 3, 4, 7], '\xda': [0, 1, 3, 4, 6], '\xdb': [0, 1, 3, 4, 6, 7], '\xdc': [0, 1, 3, 4, 5], '\xdd': [0, 1, 3, 4, 5, 7], '\xde': [0, 1, 3, 4, 5, 6], '\xdf': [0, 1, 3, 4, 5, 6, 7], '\xe0': [0, 1, 2], '\xe1': [0, 1, 2, 7], '\xe2': [0, 1, 2, 6], '\xe3': [0, 1, 2, 6, 7], '\xe4': [0, 1, 2, 5], '\xe5': [0, 1, 2, 5, 7], '\xe6': [0, 1, 2, 5, 6], '\xe7': [0, 1, 2, 5, 6, 7], '\xe8': [0, 1, 2, 4], '\xe9': [0, 1, 2, 4, 7], '\xea': [0, 1, 2, 4, 6], '\xeb': [0, 1, 2, 4, 6, 7], '\xec': [0, 1, 2, 4, 5], '\xed': [0, 1, 2, 4, 5, 7], '\xee': [0, 1, 2, 4, 5, 6], '\xef': [0, 1, 2, 4, 5, 6, 7], '\xf0': [0, 1, 2, 3], '\xf1': [0, 1, 2, 3, 7], '\xf2': [0, 1, 2, 3, 6], '\xf3': [0, 1, 2, 3, 6, 7], '\xf4': [0, 1, 2, 3, 5], '\xf5': [0, 1, 2, 3, 5, 7], '\xf6': [0, 1, 2, 3, 5, 6], '\xf7': [0, 1, 2, 3, 5, 6, 7], '\xf8': [0, 1, 2, 3, 4], '\xf9': [0, 1, 2, 3, 4, 7], '\xfa': [0, 1, 2, 3, 4, 6], '\xfb': [0, 1, 2, 3, 4, 6, 7], '\xfc': [0, 1, 2, 3, 4, 5], '\xfd': [0, 1, 2, 3, 4, 5, 7], '\xfe': [0, 1, 2, 3, 4, 5, 6], '\xff': [0, 1, 2, 3, 4, 5, 6, 7], } DEFAULT_EXPIRE_TIME = 30 * 3600 * 24 def find_bit(bits): ''' 浣嶈绠椾负鐪熺殑涓嬫爣 :param bytes: :return: >>> find_bit(b'\x80') [0] >>> find_bit('@') [1] >>> find_bit(b'\xff\xff') [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] >>> find_bit(b'\x11') [3, 7] >>> find_bit(b'\x01\x01') [7, 15] >>> find_bit(b'\x11\x11') [3, 7, 11, 15] ''' return [no * 8 + j for no, i in enumerate(bits) for j in redis_bit_map[i]] def bit_range(redis_client, cur, num): '''按位查询 返回bit位为1的下标 :param cur: 开始位置 :param num: 查询个数 :return: [] ''' start, offset = divmod(cur, 8) # end 必须按8取整 end = (cur + num + 7) / 8 return [start * 8 + _id for _id in find_bit(redis_client.getrange(start, end)) if offset <= _id <= offset + num]