|
8 | 8 | """ |
9 | 9 | import os |
10 | 10 | import time |
| 11 | +from typing import Union, List |
11 | 12 |
|
12 | 13 | import redis |
13 | 14 | from redis.connection import Encoder as _Encoder |
@@ -743,27 +744,38 @@ def hget_count(self, table): |
743 | 744 | def hkeys(self, table): |
744 | 745 | return self._redis.hkeys(table) |
745 | 746 |
|
746 | | - def setbit(self, table, offsets, values): |
| 747 | + def setbit( |
| 748 | + self, table, offsets: Union[int, List[int]], values: Union[int, List[int]] |
| 749 | + ): |
747 | 750 | """ |
748 | | - 设置字符串数组某一位的值, 返回之前的值 |
749 | | - @param table: |
| 751 | + 设置字符串数组某一位的值,返回之前的值 |
| 752 | + @param table: Redis key |
750 | 753 | @param offsets: 支持列表或单个值 |
751 | 754 | @param values: 支持列表或单个值 |
752 | 755 | @return: list / 单个值 |
753 | 756 | """ |
754 | 757 | if isinstance(offsets, list): |
755 | | - if not isinstance(values, list): |
756 | | - values = [values] * len(offsets) |
| 758 | + if isinstance(values, int): |
| 759 | + # 使用lua脚本,数据是一起传给redis的,降低了网络开销,但redis会阻塞 |
| 760 | + script = """ |
| 761 | + local value = table.remove(ARGV, 1) |
| 762 | + local offsets = ARGV |
| 763 | + local results = {} |
| 764 | + for i, offset in ipairs(offsets) do |
| 765 | + results[i] = redis.call('SETBIT', KEYS[1], offset, value) |
| 766 | + end |
| 767 | + return results |
| 768 | + """ |
| 769 | + return self._redis.eval(script, 1, table, values, *offsets) |
757 | 770 | else: |
758 | 771 | assert len(offsets) == len(values), "offsets值要与values值一一对应" |
| 772 | + pipe = self._redis.pipeline() |
| 773 | + pipe.multi() |
759 | 774 |
|
760 | | - pipe = self._redis.pipeline() |
761 | | - pipe.multi() |
762 | | - |
763 | | - for offset, value in zip(offsets, values): |
764 | | - pipe.setbit(table, offset, value) |
| 775 | + for offset, value in zip(offsets, values): |
| 776 | + pipe.setbit(table, offset, value) |
765 | 777 |
|
766 | | - return pipe.execute() |
| 778 | + return pipe.execute() |
767 | 779 |
|
768 | 780 | else: |
769 | 781 | return self._redis.setbit(table, offsets, values) |
|
0 commit comments