def __getitem__(self, item: str) -> Skiplist: """ Return the associated Skiplist to a key or an empty Skiplist if there's no mapping in the dictionary """ if item in self.dictionary: value = self.dictionary[item] self.post_file.seek(value.offset) return Skiplist(pickle.loads(self.post_file.read(value.size))) else: return Skiplist([])
def not_merge(l1: Skiplist, l2: Skiplist) -> Skiplist: """ Negated the l1 list given the total list of existing doc ids l2 Note: use the underlying list for performances *params* - l1 The first Skiplist - l2 The list of all of the doc ids *return* - The negated Skiplist l1 based on l2 """ out = [] i1, i2 = iter(l1.list), iter(l2.list) e1, e2 = next(i1, False), next(i2, False) while e1 and e2: if e1 == e2: e1, e2 = next(i1, False), next(i2, False) elif e1 < e2: e1 = next(i1, False) else: out.append(e2) e2 = next(i2, False) if e2: out.append(e2) for e in i2: out.append(e) return Skiplist(out)
def or_merge(l1: Skiplist, l2: Skiplist) -> Skiplist: """ Merge 2 Skiplists based on the OR boolean operator logic Note: use the underlying list for performances *params* - l1 The first Skiplist - l2 The second Skiplist *return* - The merged Skiplist """ out = [] i1, i2 = iter(l1.list), iter(l2.list) e1, e2 = next(i1, False), next(i2, False) while e1 and e2: if e1 == e2: out.append(e1) e1, e2 = next(i1, False), next(i2, False) elif e1 < e2: out.append(e1) e1 = next(i1, False) else: out.append(e2) e2 = next(i2, False) if e1: out.append(e1) for e in i1: out.append(e) elif e2: out.append(e2) for e in i2: out.append(e) return Skiplist(out)
def and_not_merge(l1: Skiplist, l2: Skiplist) -> Skiplist: """ Merge 2 Skiplists based on the AND NOT logic: l1 AND **NOT** l2 *params* - l1 The first Skiplist - l2 The second Skiplist (being *negated*) *return* - The merged Skiplist """ out = [] i1, i2 = iter(l1.list), iter(l2.list) e1, e2 = next(i1, False), next(i2, False) while e1 and e2: if e1 == e2: e1, e2 = next(i1, False), next(i2, False) elif e1 < e2: out.append(e1) e1 = next(i1, False) else: e2 = next(i2, False) if e1: out.append(e1) for e in i1: out.append(e) return Skiplist(out)
def and_merge(l1: Skiplist, l2: Skiplist) -> Skiplist: """ Merge 2 Skiplists based on the AND boolean operator logic using Skip pointers whenever possible *params* - l1 The first Skiplist - l2 The second Skiplist *return* - The merged Skiplist """ out = [] i1, i2 = iter(l1), iter(l2) try: e1, e2 = next(i1, False), next(i2, False) while e1 and e2: if e1 == e2: out.append(e1) e1, e2 = next(i1, False), next(i2, False) elif e1 < e2: e1 = i1.__next__(e2) else: e2 = i2.__next__(e1) except StopIteration: pass return Skiplist(out)
def test_remove(): sklist = Skiplist() sklist.add(1) sklist.add(2) assert sklist.remove(1) == True assert sklist.remove(1) == False assert sklist.remove(2) == True
def test_find_predecessor(): sklist = Skiplist() sklist.add(1) sklist.add(2) sklist.add(3) sklist.add(4) sklist.add(5) assert sklist.find_predecessor(6)[0].data == 5 assert sklist.find_predecessor(4.5)[0].data == 4 assert sklist.find_predecessor(2.9)[0].data == 2 assert sklist.find_predecessor(1.1)[0].data == 1 assert sklist.find_predecessor(0.9)[0] == None
def test_add(): sklist = Skiplist() assert sklist.add(10) == True assert sklist.add(20) == True assert sklist.add(10) == False
def test_find(): sklist = Skiplist() sklist.add(1) sklist.add(2) sklist.add(3) assert sklist.find(1) == 1 assert sklist.find(0) == 1 assert sklist.find(2) == 2 assert sklist.find(10) == None assert sklist.find(1.5) == 2 assert sklist.find(3) == 3
def test_find_predecessor(): sklist = Skiplist() sklist.add(1) sklist.add(2) sklist.add(3)
def __init__(self, limit=100): Skiplist.__init__(self, limit) self.stack = list() # a list of tuples