func (db *DB) ZUnionStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) { var destMap = map[string]int64{} aggregateFunc := getAggregateFunc(aggregate) if aggregateFunc == nil { return 0, errInvalidAggregate } if len(srcKeys) < 1 { return 0, errInvalidSrcKeyNum } if weights != nil { if len(srcKeys) != len(weights) { return 0, errInvalidWeightNum } } else { weights = make([]int64, len(srcKeys)) for i := 0; i < len(weights); i++ { weights[i] = 1 } } for i, key := range srcKeys { scorePairs, err := db.ZRange(key, 0, -1) if err != nil { return 0, err } for _, pair := range scorePairs { if score, ok := destMap[hack.String(pair.Member)]; !ok { destMap[hack.String(pair.Member)] = pair.Score * weights[i] } else { destMap[hack.String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i]) } } } t := db.zsetBatch t.Lock() defer t.Unlock() db.zDelete(t, destKey) for member, score := range destMap { if err := checkZSetKMSize(destKey, []byte(member)); err != nil { return 0, err } if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil { return 0, err } } var n = int64(len(destMap)) sk := db.zEncodeSizeKey(destKey) t.Put(sk, PutInt64(n)) if err := t.Commit(); err != nil { return 0, err } return n, nil }
func (db *DB) sInterGeneric(keys ...[]byte) ([][]byte, error) { destMap := make(map[string]bool) members, err := db.SMembers(keys[0]) if err != nil { return nil, err } for _, m := range members { destMap[hack.String(m)] = true } for _, key := range keys[1:] { if err := checkKeySize(key); err != nil { return nil, err } members, err := db.SMembers(key) if err != nil { return nil, err } else if len(members) == 0 { return nil, err } tempMap := make(map[string]bool) for _, member := range members { if err := checkKeySize(member); err != nil { return nil, err } if _, ok := destMap[hack.String(member)]; ok { tempMap[hack.String(member)] = true //mark this item as selected } } destMap = tempMap //reduce the size of the result set if len(destMap) == 0 { return nil, nil } } slice := make([][]byte, len(destMap)) idx := 0 for k, v := range destMap { if !v { continue } slice[idx] = []byte(k) idx++ } return slice, nil }
func (db *DB) sUnionGeneric(keys ...[]byte) ([][]byte, error) { dstMap := make(map[string]bool) for _, key := range keys { if err := checkKeySize(key); err != nil { return nil, err } members, err := db.SMembers(key) if err != nil { return nil, err } for _, member := range members { dstMap[hack.String(member)] = true } } slice := make([][]byte, len(dstMap)) idx := 0 for k, v := range dstMap { if !v { continue } slice[idx] = []byte(k) idx++ } return slice, nil }
func (l *lBlockKeys) signal(key []byte, num int) { l.Lock() defer l.Unlock() s := hack.String(key) chs, ok := l.keys[s] if !ok { return } var n *list.Element i := 0 for e := chs.Front(); e != nil && i < num; e = n { ch := e.Value.(lbKeyCh) n = e.Next() select { case ch <- key: chs.Remove(e) i++ default: //waiter unwait chs.Remove(e) } } if chs.Len() == 0 { delete(l.keys, s) } }
func StrUint64(v []byte, err error) (uint64, error) { if err != nil { return 0, err } else if v == nil { return 0, nil } else { return strconv.ParseUint(hack.String(v), 10, 64) } }
func (db *DB) sDiffGeneric(keys ...[]byte) ([][]byte, error) { destMap := make(map[string]bool) members, err := db.SMembers(keys[0]) if err != nil { return nil, err } for _, m := range members { destMap[hack.String(m)] = true } for _, k := range keys[1:] { members, err := db.SMembers(k) if err != nil { return nil, err } for _, m := range members { if _, ok := destMap[hack.String(m)]; !ok { continue } else if ok { delete(destMap, hack.String(m)) } } // O - A = O, O is zero set. if len(destMap) == 0 { return nil, nil } } slice := make([][]byte, len(destMap)) idx := 0 for k, v := range destMap { if !v { continue } slice[idx] = []byte(k) idx++ } return slice, nil }
func StrInt8(v []byte, err error) (int8, error) { if err != nil { return 0, err } else if v == nil { return 0, nil } else { res, err := strconv.ParseInt(hack.String(v), 10, 8) return int8(res), err } }
func (l *lBlockKeys) wait(key []byte, ch lbKeyCh) { l.Lock() defer l.Unlock() s := hack.String(key) chs, ok := l.keys[s] if !ok { chs = list.New() l.keys[s] = chs } chs.PushBack(ch) }
func (l *lBlockKeys) unwait(key []byte, ch lbKeyCh) { l.Lock() defer l.Unlock() s := hack.String(key) chs, ok := l.keys[s] if !ok { return } else { var n *list.Element for e := chs.Front(); e != nil; e = n { c := e.Value.(lbKeyCh) n = e.Next() if c == ch { chs.Remove(e) } } if chs.Len() == 0 { delete(l.keys, s) } } }
func formatEventKey(buf []byte, k []byte) ([]byte, error) { if len(k) < 2 { return nil, errInvalidEvent } buf = append(buf, fmt.Sprintf("DB:%2d ", k[0])...) buf = append(buf, fmt.Sprintf("%s ", TypeName[k[1]])...) db := new(DB) index, _, err := decodeDBIndex(k) if err != nil { return nil, err } db.setIndex(index) //to do format at respective place switch k[1] { case KVType: if key, err := db.decodeKVKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) } case HashType: if key, field, err := db.hDecodeHashKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) buf = append(buf, ' ') buf = strconv.AppendQuote(buf, hack.String(field)) } case HSizeType: if key, err := db.hDecodeSizeKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) } case ListType: if key, seq, err := db.lDecodeListKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) buf = append(buf, ' ') buf = strconv.AppendInt(buf, int64(seq), 10) } case LMetaType: if key, err := db.lDecodeMetaKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) } case ZSetType: if key, m, err := db.zDecodeSetKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) buf = append(buf, ' ') buf = strconv.AppendQuote(buf, hack.String(m)) } case ZSizeType: if key, err := db.zDecodeSizeKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) } case ZScoreType: if key, m, score, err := db.zDecodeScoreKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) buf = append(buf, ' ') buf = strconv.AppendQuote(buf, hack.String(m)) buf = append(buf, ' ') buf = strconv.AppendInt(buf, score, 10) } // case BitType: // if key, seq, err := db.bDecodeBinKey(k); err != nil { // return nil, err // } else { // buf = strconv.AppendQuote(buf, hack.String(key)) // buf = append(buf, ' ') // buf = strconv.AppendUint(buf, uint64(seq), 10) // } // case BitMetaType: // if key, err := db.bDecodeMetaKey(k); err != nil { // return nil, err // } else { // buf = strconv.AppendQuote(buf, hack.String(key)) // } case SetType: if key, member, err := db.sDecodeSetKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) buf = append(buf, ' ') buf = strconv.AppendQuote(buf, hack.String(member)) } case SSizeType: if key, err := db.sDecodeSizeKey(k); err != nil { return nil, err } else { buf = strconv.AppendQuote(buf, hack.String(key)) } case ExpTimeType: if tp, key, t, err := db.expDecodeTimeKey(k); err != nil { return nil, err } else { buf = append(buf, TypeName[tp]...) buf = append(buf, ' ') buf = strconv.AppendQuote(buf, hack.String(key)) buf = append(buf, ' ') buf = strconv.AppendInt(buf, t, 10) } case ExpMetaType: if tp, key, err := db.expDecodeMetaKey(k); err != nil { return nil, err } else { buf = append(buf, TypeName[tp]...) buf = append(buf, ' ') buf = strconv.AppendQuote(buf, hack.String(key)) } default: return nil, errInvalidEvent } return buf, nil }