# -*- coding: utf-8 -*- """ Created on 2018/12/14 1:05 PM --------- @summary: --------- @author: Boris @email: [email protected] """ from __future__ import absolute_import from feapder.db.redisdb import RedisDB class BitArray: def setall(self, value): pass def __repr__(self): raise ImportError("this method mush be implement") def set(self, offsets, values): """ 设置å符串æ°åæä¸ä½çå¼ï¼ è¿åä¹åçå¼ @param offsets: æ¯æå表æåä¸ªå¼ @param values: æ¯æå表æåä¸ªå¼ @return: list / åä¸ªå¼ """ raise ImportError("this method mush be implement") def get(self, offsets): """ åå符串æ°åæä¸ä½çå¼ @param offsets: æ¯æå表æåä¸ªå¼ @return: list / åä¸ªå¼ """ raise ImportError("this method mush be implement") def count(self, value=True): raise ImportError("this method mush be implement") class MemoryBitArray(BitArray): def __init__(self, num_bits): try: import bitarray except Exception as e: raise Exception( "éè¦å®è£ feapder宿´ç\ncommand: pip install feapder[all]\nè¥å®è£ åºéï¼åèï¼https://boris.org.cn/feapder/#/question/%E5%AE%89%E8%A3%85%E9%97%AE%E9%A2%98" ) self.num_bits = num_bits self.bitarray = bitarray.bitarray(num_bits, endian="little") self.setall(0) def __repr__(self): return "MemoryBitArray: {}".format(self.num_bits) def setall(self, value): self.bitarray.setall(value) def set(self, offsets, values): """ 设置å符串æ°åæä¸ä½çå¼ï¼ è¿åä¹åçå¼ @param offsets: æ¯æå表æåä¸ªå¼ @param values: æ¯æå表æåä¸ªå¼ @return: list / åä¸ªå¼ """ old_values = [] if isinstance(offsets, list): if not isinstance(values, list): values = [values] * len(offsets) else: assert len(offsets) == len(values), "offsetså¼è¦ä¸valueså¼ä¸ä¸å¯¹åº" for offset, value in zip(offsets, values): old_values.append(int(self.bitarray[offset])) self.bitarray[offset] = value else: old_values = int(self.bitarray[offsets]) self.bitarray[offsets] = values return old_values def get(self, offsets): """ åå符串æ°åæä¸ä½çå¼ @param offsets: æ¯æå表æåä¸ªå¼ @return: list / åä¸ªå¼ """ if isinstance(offsets, list): return [self.bitarray[offset] for offset in offsets] else: return self.bitarray[offsets] def count(self, value=True): return self.bitarray.count(value) class RedisBitArray(BitArray): """ 仿bitarray åºäºredis """ redis_db = None def __init__(self, name, redis_url=None): self.name = name self.count_cached_name = name + "_count_cached" if not self.__class__.redis_db: self.__class__.redis_db = RedisDB(url=redis_url) def __repr__(self): return "RedisBitArray: {}".format(self.name) def set(self, offsets, values): """ 设置å符串æ°åæä¸ä½çå¼ï¼ è¿åä¹åçå¼ @param offsets: æ¯æå表æåä¸ªå¼ @param values: æ¯æå表æåä¸ªå¼ @return: list / åä¸ªå¼ """ return self.redis_db.setbit(self.name, offsets, values) def get(self, offsets): return self.redis_db.getbit(self.name, offsets) def count(self, value=True): # å æ¥redisçç¼åï¼è¥æ²¡æ å¨ç»è®¡æ°é count = self.redis_db.strget(self.count_cached_name) if count: return int(count) else: count = self.redis_db.bitcount(self.name) self.redis_db.strset(self.count_cached_name, count, ex=1800) # åå°æ¶è¿æ return count