コード例 #1
0
    def I_insert0(self, item):
        """
        Insert an item into the filter.

        :param item: Item to be inserted.
        :return: True if insert is successful; CuckooFilterFullException if
        filter is full.
        """
        fingerprint = hashutils_murmurhash.fingerprint(item,
                                                       self.fingerprint_size)
        i = self._get_index(item)
        j = self._get_alternate3_index(i, fingerprint)

        if self.buckets[i].insert(fingerprint) \
                or self.buckets[j].insert(fingerprint):
            self.size += 1
            return True

        eviction_index = random.choice([i, j])
        for _ in range(self.max_displacements):
            self.kicks += 1
            f = self.buckets[eviction_index].swap(fingerprint)
            eviction_index = self._get_alternate3_index(eviction_index, f)
            if self.buckets[eviction_index].insert(f):
                self.size += 1
                return True
            fingerprint = f  # 我自己感觉fingerprint没有改变,有问题,然后我加上了这行代码
        # Filter is full
        return self.size, self.kicks
コード例 #2
0
    def delete2(self, item):
        """
        Delete an item from the filter.

        To delete an item safely, it must have been previously inserted.
        Otherwise, deleting a non-inserted item might unintentionally remove
        a real, different item that happens to share the same fingerprint.

        :param item: Item to delete from the filter.
        :return: True, if item is found and deleted; False, otherwise.
        """
        fingerprint = hashutils_murmurhash.fingerprint(item)
        i = self._get_index(item)
        j = self._get_alternate1_index(i, fingerprint)
        x = self._get_alternate2_index(i, fingerprint)
        y = self._get_alternate3_index(i, fingerprint)

        if self.buckets[i].delete(fingerprint):
            return True
        elif self.buckets[y].delete(fingerprint):
            return True
        elif self.buckets[j].delete(fingerprint):
            return True
        elif self.buckets[x].delete(fingerprint):
            return True
        else:
            return False
コード例 #3
0
    def D_contains(self, item, threshold1, threshold2):
        """
        Check if the filter contains the item.

        :param item: Item to check its presence in the filter.
        :return: True, if item is in the filter; False, otherwise.
        """
        fingerprint = hashutils_murmurhash.fingerprint(item)
        if fingerprint >= threshold1 and fingerprint <= threshold2:
            i = self._get_index(item)
            j = self._get_alternate1_index(i, fingerprint)
            x = self._get_alternate2_index(i, fingerprint)
            y = self._get_alternate3_index(i, fingerprint)

            if fingerprint in self.buckets[i]:
                return True
            elif fingerprint in self.buckets[y]:
                return True
            elif fingerprint in self.buckets[j]:
                return True
            elif fingerprint in self.buckets[x]:
                return True
            else:
                return False

        else:
            i = self._get_index(item)
            j = self._get_alternate3_index(i, fingerprint)

            return fingerprint in self.buckets[
                i] or fingerprint in self.buckets[j]
コード例 #4
0
    def I_contains0(self, item):
        """
        Check if the filter contains the item.

        :param item: Item to check its presence in the filter.
        :return: True, if item is in the filter; False, otherwise.
        """
        fingerprint = hashutils_murmurhash.fingerprint(item)
        i = self._get_index(item)
        j = self._get_alternate3_index(i, fingerprint)

        return fingerprint in self.buckets[i] or fingerprint in self.buckets[j]
コード例 #5
0
    def D_insert(self, item, threshold1, threshold2):
        """
        Insert an item into the filter.

        :param item: Item to be inserted.
        :return: True if insert is successful; CuckooFilterFullException if
        filter is full.
        """
        # 处于阈值区间则采用4个候选桶进行存储,注意:threshold1不能小于255,threshold2不能大于65280
        fingerprint = hashutils_murmurhash.fingerprint(item)
        if fingerprint >= threshold1 and fingerprint <= threshold2:
            i = self._get_index(item)
            j = self._get_alternate1_index(i, fingerprint)
            x = self._get_alternate2_index(i, fingerprint)
            y = self._get_alternate3_index(i, fingerprint)

            if self.buckets[i].insert(fingerprint):
                self.size += 1
                return True
            elif self.buckets[y].insert(fingerprint):
                self.size += 1
                return True
            elif self.buckets[j].insert(fingerprint):
                self.size += 1
                return True
            elif self.buckets[x].insert(fingerprint):
                self.size += 1
                return True

            eviction_index = random.choice([i, j, x, y])
            for _ in range(self.max_displacements):
                self.kicks += 1
                f = self.buckets[eviction_index].swap(fingerprint)

                # 若交换得到的指纹值位于阈值区间,则4个桶
                if f >= threshold1 and f <= threshold2:
                    eviction_index1 = self._get_alternate1_index(
                        eviction_index, f)
                    eviction_index2 = self._get_alternate2_index(
                        eviction_index, f)
                    eviction_index3 = self._get_alternate3_index(
                        eviction_index, f)

                    if self.buckets[eviction_index3].insert(f):
                        self.size += 1
                        return True
                    elif self.buckets[eviction_index1].insert(f):
                        self.size += 1
                        return True
                    elif self.buckets[eviction_index2].insert(f):
                        self.size += 1
                        return True
                    eviction_index = random.choice(
                        [eviction_index1, eviction_index2, eviction_index3])
                    fingerprint = f

                else:
                    eviction_index = self._get_alternate3_index(
                        eviction_index, f)
                    if self.buckets[eviction_index].insert(f):
                        self.size += 1
                        return True
                    fingerprint = f

            # Filter is full
            return self.size, self.kicks
            # raise exceptions.CuckooFilterFullException('Insert operation failed. '
            #                                           'Filter is full.')

        # 否则采用2个候选桶存储
        else:
            i = self._get_index(item)
            j = self._get_alternate3_index(i, fingerprint)

            if self.buckets[i].insert(fingerprint) \
                    or self.buckets[j].insert(fingerprint):
                self.size += 1
                return True

            eviction_index = random.choice([i, j])
            for _ in range(self.max_displacements):
                self.kicks += 1
                f = self.buckets[eviction_index].swap(fingerprint)
                # 如果交换的指纹值位于阈值区间,则扩展到4个桶
                if f >= threshold1 and f <= threshold2:
                    eviction_index1 = self._get_alternate1_index(
                        eviction_index, f)
                    eviction_index2 = self._get_alternate2_index(
                        eviction_index, f)
                    eviction_index3 = self._get_alternate3_index(
                        eviction_index, f)

                    if self.buckets[eviction_index3].insert(f):
                        self.size += 1
                        return True
                    elif self.buckets[eviction_index1].insert(f):
                        self.size += 1
                        return True
                    elif self.buckets[eviction_index2].insert(f):
                        self.size += 1
                        return True
                    eviction_index = random.choice(
                        [eviction_index1, eviction_index2, eviction_index3])
                    fingerprint = f

                # 否则,还是两个桶
                else:
                    eviction_index = self._get_alternate3_index(
                        eviction_index, f)
                    if self.buckets[eviction_index].insert(f):
                        self.size += 1
                        return True
                    fingerprint = f

            # Filter is full
            return self.size, self.kicks
コード例 #6
0
    def I_insert7(self, item):
        """
        Insert an item into the filter.

        :param item: Item to be inserted.
        :return: True if insert is successful; CuckooFilterFullException if
        filter is full.
        """
        fingerprint = hashutils_murmurhash.fingerprint(item)
        i = self._get_index(item)
        j = self._get_alternate1_index(i, fingerprint)
        x = self._get_alternate2_index(i, fingerprint)
        y = self._get_alternate3_index(i, fingerprint)

        if i == j or x:  # 候选桶扩展失败
            if self.buckets[i].insert(fingerprint) \
                    or self.buckets[y].insert(fingerprint):
                self.size += 1
                return True

        if i != j or x:  # 候选桶扩展成功
            if self.buckets[i].insert(fingerprint):
                self.size += 1
                return True
            elif self.buckets[y].insert(fingerprint):
                self.size += 1
                return True
            elif self.buckets[j].insert(fingerprint):
                self.size += 1
                return True
            elif self.buckets[x].insert(fingerprint):
                self.size += 1
                return True

        eviction_index = random.choice([i, j, x, y])
        for _ in range(self.max_displacements):
            self.kicks += 1
            f = self.buckets[eviction_index].swap(fingerprint)
            eviction_index1 = self._get_alternate1_index(eviction_index, f)
            eviction_index2 = self._get_alternate2_index(eviction_index, f)
            eviction_index3 = self._get_alternate3_index(eviction_index, f)

            if eviction_index == eviction_index2 or eviction_index1:  # 扩展候选桶失败
                if self.buckets[eviction_index3].insert(f):
                    self.size += 1
                    return True
                eviction_index = eviction_index3

            if eviction_index != eviction_index2 or eviction_index1:  # 扩展候选桶成功
                if self.buckets[eviction_index3].insert(f):
                    self.size += 1
                    return True
                elif self.buckets[eviction_index1].insert(f):
                    self.size += 1
                    return True
                elif self.buckets[eviction_index2].insert(f):
                    self.size += 1
                    return True
                eviction_index = random.choice(
                    [eviction_index1, eviction_index2, eviction_index3])

            fingerprint = f  # 源码有问题,这一条代码还是得加上,不然导致重复插入初始的fingerprint,查询时会有问题
        # Filter is full
        return self.size, self.kicks