Bit-map (2) Bloom Filter 和 Counting Bloom Filter

来源:互联网 发布:java图片压缩开源框架 编辑:程序博客网 时间:2024/05/17 08:41

Bloom Filter 和 Counting Bloom Filter

Bloom-Filter是Bit-map的升级版本,至少从我了解这个算法的顺序上来说。Bloom-Filter原理大致是吧所需插入的元素用k个Hash函数散列到一个以bit为单位的Hash表上。只支持插入和查询,并且有false positive的可能。

Counting-Bloom-Filter又是BF的升级版,增加了几个bit用于计数,并且支持删除功能,同样有false positive的可能。

Variable-Increment Counting Bloom Filter

在2012年的Infocom上有一篇对Counting-Bloom-Filter算法的改进,
The Variable-Increment Counting Bloom Filter

其中的第二种改进算法大致是这样的。

用一个大小为数个bit的count数组替代CBF中的2个数组,count数组中所存的元素以及存放的位置由两组Hash函数确定。

H={h1,h2,...hn},G={g1,g2,...gn}

hi(x)size of Hash tablegi(x)DL,其中DL=[L,2L1], L=2i

插入

最初的内存状态是这样的:

0000 0000 0000 0000...0000 0000

假设插入一个元素x
h1(x)=0 h2(x)=3 g1(x)=3 g2(x)=2  DL={2,3}

插入元素后的内存状态:
0011 0000 0000 0010...0000 0000

再插入一个元素y
h1(y)=0 h2(y)=1 g1(y)=2 g2(y)=2  DL={2,3}

插入元素后的内存状态:
0101 0010 0000 0010...0000 0000

查询

假设我们要查询y是否在表内。首先,确定表内的位置即,h1(y)=0 h2(y)=1

  •  ValueOf( h2( y ) )[L,2L1]g2( y )=ValueOf( h2( y ) ),如若不然,则y就不再表内。

  •  ValueOf( h1( y ) )[2L,3L1]ValueOf( h2( y ) )g2( y )<L,如若不然,则y就不再表内。

  • 最后一种情况,对于一个元素z  ValueOf( h1( z ) )[3L,)则无法确定是不是在表内,就可能会出现false poitive

查询

删除的思路大概就是插入的反操作。代码还没有写出来。

代码

class memoryCountBloomFilter{public:    memoryCountBloomFilter ():table(nullptr)     {        initArr();    }    ~memoryCountBloomFilter ()     {        if (table != nullptr)            delete[] table;    }    void insertElem (int elem);    bool queryElem (int elem);    typedef unsigned short int ctype;    std::string ptrMemState ();private:    static const unsigned int tableSize = 8;    static const unsigned int L = 16;    ctype* table;    bool initArr();    ctype getCount (int elem);    /*        用于确定第一个位置    */    unsigned int h1 (int elem);    /*        用于确定第二个位置    */    unsigned int h2 (int elem);    /*        第一个位置的值    */    ctype g1 (int elem);    /*        第二个位置的值    */    ctype g2 (int elem);};inline memoryCountBloomFilter::ctype memoryCountBloomFilter::getCount (int elem){    return elem % 2 + 2;}bool memoryCountBloomFilter::initArr(){    table = new ctype[tableSize];    if (table != nullptr)    {        memset(table, 0, tableSize * sizeof(ctype));        return true;    }    else    {        return false;    }}unsigned int memoryCountBloomFilter::h1 (int elem){    return elem % tableSize;}unsigned int memoryCountBloomFilter::h2 (int elem){    elem >>= 5;    unsigned int mark = 7;  // 0000 0111    return mark & elem;}memoryCountBloomFilter::ctype memoryCountBloomFilter::g1 (int elem){    return elem % 15 + 16;}memoryCountBloomFilter::ctype memoryCountBloomFilter::g2 (int elem){    unsigned int mark = 15;    elem >>= 5;    mark &= elem;    return mark + 16;}void memoryCountBloomFilter::insertElem (int elem){    table[h1(elem)] += g1(elem);    int t1 = h1(elem), t2 = g1(elem);    table[h2(elem)] += g2(elem);    int t3 = h2(elem), t4 = g2(elem);}bool memoryCountBloomFilter::queryElem (int elem){    unsigned int p1 = table[h1(elem)], p2 = table[h2(elem)];    if (p1 == 0 || p2 == 0)        return false;    if (L <= p1 && p1 <= (2 * L - 1))        if (g1(elem) == p1)            goto next;        else            return false;    if ((2 * L) <= p1 && p1 <= (3 * L - 1))        if (L <= g1(elem) && g1(elem) <= (p1 - L))            goto next;        else            return false;    if (p1 >= 3 * L)        goto next;    return false;next:    if (L <= p2 && p2 <= (2 * L - 1))        if (g2(elem) == p2)            return true;        else            return false;    if ((2 * L) <= p2 && p2 <= (3 * L - 1))        if (L <= g2(elem) && g2(elem) <= (p2 - L))            return true;        else            return false;    if (p2 >= 3 * L)        return true;    return false;}std::string memoryCountBloomFilter::ptrMemState (){    std::string ret;    for (size_t i = 0; i < tableSize; ++i)    {        ret += bitsInMemory(table[i]);        ret += '\n';    }    return ret;}
0 0
原创粉丝点击