#include "ShBFM.h"


ShBF_M::ShBF_M(){}
ShBF_M::~ShBF_M()
{
	delete[] bf_base;
}

ShBF_M::ShBF_M(uint m, uint k) {
	bf_m = m;
	bf_k = k;
	bf_n = 0;
	query_NUM = 0;
	memacc_NUM = 0;

	bf_base = new uint64[bf_m/64+1];
	memset(bf_base, 0, sizeof(uint64) *(bf_m/64+1));

	for (uint i = 0; i <= bf_k; i++)bf_hfp[i].initialize(i);
}

uint ShBF_M::insert(const unsigned char * str, uint len){
	uint64 offset=bf_hfp[bf_k].run(str, len)%63+1;
	//if (0==offset)offset=63;

	uint64 val;
	for (uint i = 0; i < bf_k; i++){
		val=bf_hfp[i].run(str, len);
		bf_base[val % ((bf_m>>6)+1)] |=  
			( ( 1i64<<(val&63) ) | (1i64<<(((val&63)+offset)&63)));
	}
	bf_n++;
	return 1;
}

uint ShBF_M::query(const unsigned char * str, uint len){
	uint64 offset = bf_hfp[bf_k].run(str, len)%63+1;
	//if (0==offset)offset=63;
	query_NUM++;

	uint64 val, c, d;
	uint64 mlen = (bf_m >> 6) + 1;

	for (uint i = 0; i < bf_k; i++)
	{
		memacc_NUM++;
		val = bf_hfp[i].run(str, len);
		c = bf_base[val % mlen];
		d = val & 63;
		if (!((c & (1i64 << d)) && (c & (1i64 << ((d + offset) & 63)))))
			return 0;
	}
	return 1;
}