예제 #1
0
class ConsistentHasher:
    def __init__(self):
        self.nodes = BST()
        self.id_to_node = dict()

    def hash(self, item, limit=4294967295):
        id_hash = hashlib.sha512(item.encode())
        id_hash_int = int.from_bytes(id_hash.digest(), 'big')
        final_id = id_hash_int % limit
        return final_id

    def add_node(self, node_name):
        hash_id = self.hash(node_name)
        self.nodes.insert(hash_id)
        self.id_to_node[hash_id] = node_name

    def remove_node(self, node_name):
        hash_id = self.hash(node_name)
        removed = self.nodes.remove(hash_id)
        print('Removed %s: %r' % (node_name, removed))
        return self.id_to_node.pop(hash_id, None)

    def assign_key_to_node(self, key):
        key_hash_id = self.hash(key)
        assigned_node_id = self.nodes.find_next_bigger_elem(key_hash_id)
        if assigned_node_id is None:
            print('Failed to assign key %s (hash = %d) to any node!' %
                  (key, key_hash_id))
            return
        # print('Key %s was hashed to value %d, and was assigned to node %s with id %d' % (key, key_hash_id, self.id_to_node[assigned_node_id], assigned_node_id))
        return self.id_to_node[assigned_node_id]
예제 #2
0
def test_contains():
    bst = BST()
    for i in range(1, 11):
        bst.insert(i)
    assert bst.contains(1)
    assert bst.contains(5)
    assert not bst.contains(15)
예제 #3
0
def test_depth():
    bst = BST()
    bst.insert(5)
    assert bst.depth(node=bst.root) == 1
    bst.insert(3)
    bst.insert(4)
    bst.insert(6)
    assert bst.depth(node=bst.root) == 3
예제 #4
0
def test_depth_collatz():
    bst = BST()
    for i in range(1, 11):
        if not i % 2:
            i /= 2
        else:
            i = i * 3 + 1
        bst.insert(i)
    assert bst.depth(bst.root) == 5
예제 #5
0
def test_depth_collatz():
    bst = BST()
    for i in range(1, 11):
        if not i % 2:
            i /= 2
        else:
            i = i * 3 + 1
        bst.insert(i)
    assert bst.depth(bst.root) == 5
예제 #6
0
def test_size():
    bst = BST()
    assert bst.size() == 0
    bst.insert(5)
    assert bst.size() == 1
    bst.insert(5)
    assert bst.size() == 1
예제 #7
0
def test_depth():
    bst = BST()
    bst.insert(5)
    assert bst.depth(node=bst.root) == 1
    bst.insert(3)
    bst.insert(4)
    bst.insert(6)
    assert bst.depth(node=bst.root) == 3
예제 #8
0
def test_size():
    bst = BST()
    assert bst.size() == 0
    bst.insert(5)
    assert bst.size() == 1
    bst.insert(5)
    assert bst.size() == 1
예제 #9
0
def test_insert():
    bst = BST()
    bst.insert(3)
    assert bst.root.value == 3
    bst.insert(5)
    assert bst.root.r_child.value == 5
    assert bst.root.r_child.parent is bst.root
    bst.insert(2)
    assert bst.root.l_child.value == 2
    assert bst.root.l_child.parent is bst.root
예제 #10
0
def test_left_balance():
    bst = BST()
    bst.insert(5)
    bst.insert(4)
    bst.insert(3)
    bst.insert(6)
    assert bst.balance() == 1
예제 #11
0
def test_right_balance():
    bst = BST()
    bst.insert(5)
    bst.insert(6)
    bst.insert(7)
    bst.insert(3)
    assert bst.balance() == -1
예제 #12
0
    def test_bst(self):
        numbers = [10, 15, 3, 6, 12, 20, 1, 0]
        bst = BST()
        for num in numbers:
            bst.insert(num)

        ordered_nums = bst.traverse_inorder()

        print(ordered_nums)

        for num in numbers:
            successor = bst.find_next_bigger_elem(num)
            if successor is not None:
                print('Successor of %d is %d' % (num, successor))
            else:
                print('Successor of %d is %s' % (num, 'None'))

            predecessor = bst.find_previous_smaller_elem(num)
            if predecessor is not None:
                print('Predecessor of %d is %d' % (num, predecessor))
            else:
                print('Predecessor of %d is %s' % (num, 'None'))

            print('\n')

        num = -1  # Does not exist in the list
        successor = bst.find_next_bigger_elem(num)
        if successor is not None:
            print('Successor of %d is %d' % (num, successor))
        else:
            print('Successor of %d is %s' % (num, 'None'))

        print('\n')

        num = 1
        removed = bst.remove(num)
        if removed is not None:
            print('%d removed from tree: %s' %
                  (num, " ".join(str(x) for x in bst.traverse_inorder())))
        else:
            print('%d was not found in the tree' % num)
예제 #13
0
def test_insert():
    bst = BST()
    bst.insert(3)
    assert bst.root.value == 3
    bst.insert(5)
    assert bst.root.r_child.value == 5
    assert bst.root.r_child.parent is bst.root
    bst.insert(2)
    assert bst.root.l_child.value == 2
    assert bst.root.l_child.parent is bst.root
예제 #14
0
def test_contains():
    bst = BST()
    for i in range(1, 11):
        bst.insert(i)
    assert bst.contains(1)
    assert bst.contains(5)
    assert not bst.contains(15)
예제 #15
0
def test_left_balance():
    bst = BST()
    bst.insert(5)
    bst.insert(4)
    bst.insert(3)
    bst.insert(6)
    assert bst.balance() == 1
예제 #16
0
def test_right_balance():
    bst = BST()
    bst.insert(5)
    bst.insert(6)
    bst.insert(7)
    bst.insert(3)
    assert bst.balance() == -1
예제 #17
0
class ConsistentHasher:
    def __init__(self):
        self.nodes = BST()
        self.id_to_node = dict()

    # Note: we need a deterministic hash function. Python hashlib's hash() is not deterministic, and will return
    # a different hash value on different runs.
    def hash(self, item, limit=4294967295):
        id_hash = hashlib.sha512(item.encode())
        id_hash_int = int.from_bytes(
            id_hash.digest(), 'big'
        )  # Uses explicit byteorder for system-agnostic reproducibility
        final_id = id_hash_int % limit

        return final_id

    def hash2(self, item):
        return zlib.adler32(str.encode(item)) & 0xffffffff

    def add_node(self, node_name):
        hash_id = self.hash(node_name)
        self.nodes.insert(hash_id)
        self.id_to_node[hash_id] = node_name

    def remove_node(self, node_name):
        hash_id = self.hash(node_name)
        removed = self.nodes.remove(hash_id)
        print('Removed %s: %r' % (node_name, removed))
        return self.id_to_node.pop(hash_id, None)

    def assign_key_to_node(self, key):
        key_hash_id = self.hash(key)
        assigned_node_id = self.nodes.find_next_bigger_elem(key_hash_id)
        if assigned_node_id is None:
            print('Failed to assign key %s (hash = %d) to any node!' %
                  (key, key_hash_id))
            return
        # print('Key %s was hashed to value %d, and was assigned to node %s with id %d' % (key, key_hash_id, self.id_to_node[assigned_node_id], assigned_node_id))
        return self.id_to_node[assigned_node_id]
예제 #18
0
 def __init__(self):
     self.nodes = BST()
     self.id_to_node = dict()
예제 #19
0
def make_bst():
    bst = BST()
    return bst
예제 #20
0
def test_depth_all_left():
    bst = BST()
    for i in range(110,10,-10):
        bst.insert(i)
    assert bst.depth(bst.root) == 10
예제 #21
0
def test_depth_all_left():
    bst = BST()
    for i in range(110, 10, -10):
        bst.insert(i)
    assert bst.depth(bst.root) == 10
예제 #22
0
def test_bst():
    assert BST() is not None