func (bf *Filter) matches(data []byte) bool {
	if bf.msg == nil {
		return false
	}
	for i := uint32(0); i < bf.msg.HashFuncs; i++ {
		idx := bf.hash(i, data)
		if bf.msg.Filter[idx>>3]&(1<<(idx&7)) == 0 {
			return false
		}
	}
	return true
}
matches returns true if the bloom filter might contain the passed data and
false if it definitely does not.

This function MUST be called with the filter lock held.
package bloom
import (
	"math"
	"sync"
	"github.com/elastos/Elastos.ELA.SideChain/types"
	"github.com/elastos/Elastos.ELA/common"
	"github.com/elastos/Elastos.ELA/p2p/msg"
)
const (
	MaxFilterLoadHashFuncs = 50
	MaxFilterLoadFilterSize = 36000
)
const ln2Squared = math.Ln2 * math.Ln2
func minUint32(a, b uint32) uint32 {
	if a < b {
		return a
	}
	return b
}
type Filter struct {
	mtx sync.Mutex
	msg *msg.FilterLoad
}
func NewFilter(elements, tweak uint32, fprate float64) *Filter {
	if fprate > 1.0 {
		fprate = 1.0
	}
	if fprate < 1e-9 {
		fprate = 1e-9
	}
	dataLen := uint32(-1 * float64(elements) * math.Log(fprate) / ln2Squared)
	dataLen = minUint32(dataLen, MaxFilterLoadFilterSize*8) / 8
	hashFuncs := uint32(float64(dataLen*8) / float64(elements) * math.Ln2)
	hashFuncs = minUint32(hashFuncs, MaxFilterLoadHashFuncs)
	msg := &msg.FilterLoad{
		Filter:    make([]byte, dataLen),
		HashFuncs: hashFuncs,
		Tweak:     tweak,
	}
	return &Filter{msg: msg}
}
func LoadFilter(msg *msg.FilterLoad) *Filter {
	filter := new(Filter)
	filter.msg = msg
	return filter
}
func (bf *Filter) IsLoaded() bool {
	bf.mtx.Lock()
	loaded := bf.msg != nil
	bf.mtx.Unlock()
	return loaded
}
func (bf *Filter) Reload(msg *msg.FilterLoad) {
	bf.mtx.Lock()
	bf.msg = msg
	bf.mtx.Unlock()
}
func (bf *Filter) Unload() {
	bf.mtx.Lock()
	bf.msg = nil
	bf.mtx.Unlock()
}
func (bf *Filter) hash(hashNum uint32, data []byte) uint32 {
	mm := MurmurHash3(hashNum*0xfba4c795+bf.msg.Tweak, data)
	return mm % (uint32(len(bf.msg.Filter)) << 3)
}