| | |
| | | |
| | | import ( |
| | | "sync" |
| | | "encoding/json" |
| | | "fmt" |
| | | |
| | | "basic.com/pubsub/protomsg.git" |
| | | ) |
| | | |
| | | var commonmux sync.Mutex |
| | | const ( |
| | | DEF_SHARD_CNT = 32 |
| | | |
| | | BKDR_SEED = 131 // 31 131 1313 13131 131313 etc... |
| | | ) |
| | | |
| | | type shardItem struct { |
| | | sync.RWMutex |
| | | |
| | | data map[string]interface{} |
| | | } |
| | | |
| | |
| | | * @param uint8, shardCnt must be pow of two |
| | | */ |
| | | func New(shardCnt uint8) *ShardMap { |
| | | if !isPowOfTwo(shardCnt) { |
| | | shardCnt = DEF_SHARD_CNT |
| | | } |
| | | |
| | | s := &ShardMap{ |
| | | shardCnt: shardCnt, |
| | |
| | | } |
| | | |
| | | // modify by long. |
| | | func (s *ShardMap) Walk(wf wfOp, cfrom string) []*protomsg.Baseinfo{ |
| | | func (s *ShardMap) Walk(wf wfOp, cfrom string) ([]byte){ |
| | | var wg sync.WaitGroup |
| | | var second float32 |
| | | var buf []byte |
| | | var err error |
| | | |
| | | var baseinfos []*protomsg.Baseinfo |
| | | |
| | | ids := make(map[string]float32) |
| | | for _, si := range s.shards { |
| | | var tempsi shardItem |
| | | tempsi = *si |
| | | |
| | | |
| | | wg.Add(1) |
| | | go func(s *shardItem, fw wfOp, cf string) { |
| | | |
| | | go func(st *shardItem, fw wfOp, cf string) { |
| | | defer wg.Done() |
| | | s.RLock() |
| | | for key, value := range s.data { |
| | | second = fw(cf,key) |
| | | commonmux.Lock() |
| | | for id, feature := range st.data { |
| | | if str, ok := feature.(string); ok { |
| | | second = fw(cf,str) |
| | | if second == -1 { |
| | | continue |
| | | } |
| | | if info, ok := value.(*protomsg.Baseinfo) ;ok { |
| | | fmt.Println("比对分数: ", second) |
| | | info.CompareScore = second |
| | | baseinfos = append(baseinfos,info) |
| | | ids[id]=second |
| | | } |
| | | } |
| | | commonmux.Unlock() |
| | | }(&tempsi, wf, cfrom) |
| | | } |
| | | |
| | | wg.Wait() |
| | | |
| | | buf, err = json.Marshal(ids) |
| | | if err != nil { |
| | | fmt.Println("compare json err") |
| | | buf = nil |
| | | |
| | | } |
| | | return buf |
| | | } |
| | | |
| | | // print all |
| | | func (s *ShardMap) Printall() (infos []interface{}){ |
| | | var wg sync.WaitGroup |
| | | |
| | | for _, si := range s.shards { |
| | | wg.Add(1) |
| | | go func(s *shardItem) { |
| | | defer wg.Done() |
| | | s.RLock() |
| | | for _, value := range s.data { |
| | | infos = append(infos, value) |
| | | } |
| | | |
| | | s.RUnlock() |
| | | }(si,wf, cfrom) |
| | | }(si) |
| | | } |
| | | wg.Wait() |
| | | return baseinfos |
| | | return |
| | | } |
| | | |
| | | func (s * ShardMap)GetLen() int { |
| | |
| | | i := bkdrHash(key) & uint32(s.shardCnt-1) |
| | | |
| | | return s.shards[i] |
| | | } |
| | | |
| | | func isPowOfTwo(x uint8) bool { |
| | | return x != 0 && (x&(x-1) == 0) |
| | | } |
| | | |
| | | //https://www.byvoid.com/blog/string-hash-compare/ |