示例#1
0
 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")
示例#6
0
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