func (bf *Filter) AddHash(hash *common.Uint256) {
	bf.mtx.Lock()
	bf.add(hash[:])
	bf.mtx.Unlock()
}
AddHash adds the passed chainhash.Hash to the Filter.

This function is safe for concurrent access.
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)
}
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
}
func (bf *Filter) Matches(data []byte) bool {
	bf.mtx.Lock()
	match := bf.matches(data)
	bf.mtx.Unlock()
	return match
}
func (bf *Filter) matchesOutPoint(outpoint *types.OutPoint) bool {
	return bf.matches(outpoint.Bytes())
}
func (bf *Filter) MatchesOutPoint(outpoint *types.OutPoint) bool {
	bf.mtx.Lock()
	match := bf.matchesOutPoint(outpoint)
	bf.mtx.Unlock()
	return match
}
func (bf *Filter) add(data []byte) {
	if bf.msg == nil {
		return
	}
	for i := uint32(0); i < bf.msg.HashFuncs; i++ {
		idx := bf.hash(i, data)
		bf.msg.Filter[idx>>3] |= (1 << (7 & idx))
	}
}
func (bf *Filter) Add(data []byte) {
	bf.mtx.Lock()
	bf.add(data)
	bf.mtx.Unlock()
}