def __init__(self, n, eps): q, r = ceil(log2(n)), ceil(log2(1 / eps)) if q + r > 32: assert False self.capacity = n self.bits = ceil(log2(1 / eps)) self.A = BitArray(n, self.bits) self.h = Hash(2**(q + r))
def test_add(a: BitArray, elements_list, to_print: bool = False): if to_print: print_data_index_list(elements_list) for bin_list, hash_index in elements_list: a.add(bin_list, hash_index) if to_print: print(a)
def test2(): n, bits, m = 4, 5, 2 l_to_print = [('11111', 1), ('00001', 1)] elements_list = [([1] * 5, 1), ([0] * 4 + [1], 1)] a = BitArray(n, bits) test_add(a, elements_list) tp_lookup(a, elements_list) print("Elements_list:", l_to_print) print("BitArray a:", a)
def sanity_lookup() -> bool: """ Initializing Empty BitArray, and checking if it contain any element. """ fp_list = [] n, bits = randint(10, 100), randint(4, 8) a = BitArray(n, bits) for i in range(32): data, index = random_data(bits), randint(0, n - 1) if a.lookup(data, index): fp_list.append((data, index)) if len(fp_list) == 0: print("No fn!", end=":") return False else: print(len(fp_list), "False positive: ", end="") print_data_index_list(fp_list) return True
def ts_2(add_print=False): a = BitArray(8, 5) l_to_print = [('10010', 1), ('00101', 2), ('01000', 6), ('01000', 6), ('11011', 7)] res = [ '0:11011|001', '1:10010|100', '2:00101|100', '3:00000|000', '4:00000|000', '5:00000|000', '6:01000|100', '7:01000|111' ] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] test_add(a, elements_list, add_print) check(a, res, l_to_print, elements_list, "ts_2")
class CQF: A: BitArray capacity: int bits: int h: Hash def __init__(self, n, eps): q, r = ceil(log2(n)), ceil(log2(1 / eps)) if q + r > 32: assert False self.capacity = n self.bits = ceil(log2(1 / eps)) self.A = BitArray(n, self.bits) self.h = Hash(2**(q + r)) def str_to_data_index(self, s: str): ans = self.h(s) data = ans % (2**self.bits) index = ans // (2**self.bits) # assert index.is_integer() index = int(index) temp_s = list(bin(data)[2:]) if len(temp_s) < self.bits: temp_s = [0] * (self.bits - len(temp_s)) + temp_s data_l = [int(i) for i in temp_s] return data_l, index def add(self, s: str): data, hash_index = self.str_to_data_index(s) self.A.add(data, hash_index) def lookup(self, s: str) -> bool: data, hash_index = self.str_to_data_index(s) return self.A.lookup(data, hash_index) def get_load_factor(self): load_factor = 0 for i in range(self.capacity): load_factor += self.A[i].get_occupied() return load_factor / self.capacity
def ts_1(add_print=False): # 1 False negative: [('00100', 0)] l_to_print = [('00100', 0), ('01100', 3), ('10001', 5), ('10111', 7), ('01110', 7)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] res = [ '0:10111|111', '1:00100|001', '2:00000|000', '3:01100|100', '4:00000|000', '5:10001|100', '6:00000|000', '7:01110|100' ] a = BitArray(8, 5) test_add(a, elements_list, add_print) check(a, res, l_to_print, elements_list, "ts_1")
def test1(): n, bits, m = 32, 5, 16 l_to_print = [('10101', 0), ('01100', 1), ('10000', 5), ('11010', 5), ('00000', 7), ('11000', 9), ('01001', 10), ('00100', 12), ('10110', 18), ('11011', 18), ('01010', 21), ('01110', 22), ('01000', 23), ('10111', 23), ('10100', 24), ('00110', 31)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] a = BitArray(n, bits) test_add(a, elements_list) tp_lookup(a, elements_list) print("Elements:", l_to_print) print(a)
def t7_3(to_print_add=False): n, bits = 7, 5 l_to_print = [('00011', 1), ('00100', 2), ('11111', 6), ('11111', 0), ('11000', 0), ('01111', 0)] res = [ '0:01111|100', '1:11000|111', '2:11111|111', '3:00011|001', '4:00100|001', '5:00000|000', '6:11111|100' ] a = BitArray(n, bits) elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] test_add(a, elements_list, to_print_add) check(a, res, l_to_print, elements_list, "t7_3")
def t5(to_print=False): """ lookup with soft collisions, checking boundaries :return: """ n, bits = 4, 5 l_to_print = [('11111', 1), ('01100', 1), ('10000', 1), ('11010', 1)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] a = BitArray(n, bits) test_add(a, elements_list, to_print) res = ['0:11111|011', '1:01100|100', '2:10000|011', '3:11010|011'] check(a, res, l_to_print, elements_list, "t5")
def ts_d(l_to_print, add_print=False, res=None): a = BitArray(8, 5) elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] test_add(a, elements_list, add_print) if res: check(a, res, l_to_print, elements_list, "ts_d") return if not tp_lookup(a, elements_list): print("Pass ts_d without res") return print_data_index_list(elements_list) print(a)
def test0(to_print_add=False): n, bits = 32, 5 l_to_print = [('11000', 9), ('01110', 9), ('10010', 14), ('00000', 19), ('10100', 19), ('11100', 19), ('01100', 20), ('01111', 21), ('11100', 26)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] a = BitArray(n, bits) print(a) print_data_index_list(elements_list) test_add(a, elements_list, to_print_add) print(a) print() print() tp_lookup(a, elements_list)
def test4(): n, bits = 8, 5 l_to_print = [('01110', 1), ('01000', 2), ('10111', 2), ('10100', 3)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] a = BitArray(n, bits) test_add(a, elements_list, True) tp_lookup(a, elements_list) print("Elements_list:", l_to_print) print(a) print([ '0:00000|000', '1:01110|100', '2:01000|100', '3:10111|111', '4:10100|001', '5:00000|000', '6:00000|000', '7:00000|000' ])
def t7(to_print_add=False): n, bits = 13, 5 l_to_print = [('00011', 1), ('00111', 1), ('11111', 4), ('11111', 6), ('11000', 6), ('01111', 6), ('00011', 7), ('00100', 8), ('11111', 12)] res = [ '0:00000|000', '1:00011|100', '2:00111|011', '3:00000|000', '4:11111|100', '5:00000|000', '6:01111|100', '7:11000|111', '8:11111|111', '9:00011|001', '10:00100|001', '11:00000|000', '12:11111|100' ] a = BitArray(n, bits) elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] test_add(a, elements_list, to_print_add) check(a, res, l_to_print, elements_list, "t7")
def t2(to_print: bool = False): """ lookup without any soft collision :return: """ n, bits = 5, 5 l_to_print = [('00000', 0), ('00001', 1), ('00010', 2), ('00011', 3), ('00100', 4)] res = [ '0:00000|100', '1:00001|100', '2:00010|100', '3:00011|100', '4:00100|100' ] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] a = BitArray(n, bits) test_add(a, elements_list) check(a, res, l_to_print, elements_list, "t2")
def t7_2(to_print_add=False): n, bits = 7, 5 l_to_print = [('00011', 1), ('00100', 2), ('11111', 6), ('11111', 0), ('11000', 0), ('01111', 0), ('00111', 2)] res = [ '0:01111|100', '1:11000|111', '2:11111|111', '3:00011|001', '4:00100|001', '5:00111|011', '6:11111|100' ] a = BitArray(n, bits) elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] test_add(a, elements_list, to_print_add) if str(a) == str(res): print("Pass t7_2") return print(a) print(res)
def t_random_lookup(to_print=False, n=8, bits=5, m=5): """ lookup random lookup :return: """ a = BitArray(n, bits) elements_list = [(random_data(bits), randint(0, a.capacity - 1)) for i in range(m)] test_add(a, elements_list, to_print) if not tp_lookup(a, elements_list, to_print): # print("Pass t_random_lookup") return print("Failed t_random_lookup:") print_data_index_list(elements_list) print(a)
def t3(): """ lookup with soft collisions, right order :return: """ n, bits = 5, 5 l_to_print = [('10101', 0), ('01100', 1), ('10000', 1), ('11010', 1)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] res = [ '0:10101|100', '1:01100|100', '2:10000|011', '3:11010|011', '4:00000|000' ] a = BitArray(n, bits) test_add(a, elements_list) check(a, res, l_to_print, elements_list, "t3")
def t8(add_print=False): """ Inserting element (the last) between existing runs, which create a new run expected problem : first element continuation bit will be set to True :param add_print: :return: """ a = BitArray(8, 5) l_to_print = [('11010', 0), ('01000', 6), ('11001', 6), ('10101', 6), ('11001', 7)] res = [ '0:11001|111', '1:11001|001', '2:11010|001', '3:00000|000', '4:00000|000', '5:00000|000', '6:01000|100', '7:10101|111' ] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] test_add(a, elements_list, add_print) check(a, res, l_to_print, elements_list, "t8")
def tp_lookup(a: BitArray, elements_list, to_print=True) -> bool: """ :param a: :param elements_list: :param to_print: :return: False if Pass! """ fp_list = [] for data, index in elements_list: if not (a.lookup(data, index)): fp_list.append((data, index)) if len(fp_list) == 0: if to_print: print("No FP!", end=":") return False else: print(len(fp_list), "False negative: ", end="") print_data_index_list(fp_list) return True
def t1(to_print: bool = False): """ adding elements without any soft collision :return: """ n, bits = 5, 5 l_to_print = [('00000', 0), ('00001', 1), ('00010', 2), ('00011', 3), ('00100', 4)] elements_list = [(bin_to_list(i[0]), i[1]) for i in l_to_print] a = BitArray(n, bits) test_add(a, elements_list) # tp_lookup(a, elements_list) res = [ '0:00000|100', '1:00001|100', '2:00010|100', '3:00011|100', '4:00100|100' ] if str(res) == str(a): print("Pass t1") if not to_print: return print("Elements_list:", l_to_print) print(a) print(res)
def init(n, bits): a = BitArray(n, bits) return a