func InitIntervalMdd(size int) (b IntervalMddStore) { b.storage = rbtree.NewTree(Compare) b.Nodes = make([]*IntervalNode, 2) b.MaxNodes = *glob.MDD_max_flag b.Nodes[0] = &IntervalNode{Id: 0, Level: 0, Wmin: math.MinInt64 + 100000, Wmax: -1} // id 0 b.Nodes[1] = &IntervalNode{Id: 1, Level: 0, Wmin: 0, Wmax: math.MaxInt64 - 100000} // id 1 b.storage.Insert(*b.Nodes[0]) b.storage.Insert(*b.Nodes[1]) b.NextId = 2 return }
func newFrontier() *frontier { f := new(frontier) f.tree = rbtree.NewTree(func(p1, p2 rbtree.Item) int { f1 := p1.(frontierItem) f2 := p2.(frontierItem) if f1.x < f2.x { return -1 } else if f1.x == f2.x { return 0 } return 1 }) return f }
//构建Jedis Shard func NewJedisShard(nodes []RedisNodeOpt) RedisShard { checkDuplicateNode(nodes) s := &jedisShard{ clients: make([]*r.Client, 0), tree: rbtree.NewTree(func(a, b rbtree.Item) int { aNodeKey := a.(*jedisTreeNode).key bNodeKey := b.(*jedisTreeNode).key if aNodeKey == bNodeKey { return 0 } else if aNodeKey < bNodeKey { return -1 } else { return 1 } }), hashFunc: func(data []byte) int64 { return MurmurHash64A_Jedis(data, 0x1234ABCD) }} s.add(nodes) return s }
func (s *Segment) writePtr(off int, p Object, copies *rbtree.Tree, depth int) error { ps := p.Segment if p.typ == TypeNull { putLittle64(s.Data[off:], 0) return nil } else if s == p.Segment { // Same segment putLittle64(s.Data[off:], p.value(off)) return nil } else if s.Message != ps.Message || (p.flags&isListMember) != 0 || (p.flags&isBitListMember) != 0 { // We need to clone the target. if depth >= 32 { return ErrCopyDepth } // First see if the ptr has already been copied if copies == nil { copies = rbtree.NewTree(compare) } key := offset{ id: ps.Id, boff: int64(p.off) * 8, bend: int64(p.dataEnd()) * 8, newval: Object{ typ: p.typ, length: p.length, datasz: p.datasz, ptrs: p.ptrs, flags: (p.flags & isCompositeList), }, } if (p.flags & isBitListMember) != 0 { key.boff += int64(p.flags & bitOffsetMask) key.bend = key.boff + 1 key.newval.datasz = 8 } if (p.flags & isCompositeList) != 0 { key.boff -= 64 } iter := copies.FindLE(key) if key.bend > key.boff { if !iter.NegativeLimit() { other := iter.Item().(offset) if key.id == other.id { if key.boff == other.boff && key.bend == other.bend { return s.writePtr(off, other.newval, nil, depth+1) } else if other.bend >= key.bend { return ErrOverlap } } } iter = iter.Next() if !iter.Limit() { other := iter.Item().(offset) if key.id == other.id && other.boff < key.bend { return ErrOverlap } } } // No copy nor overlap found, so we need to clone the target n, err := s.create(int((key.bend-key.boff)/8), key.newval) if err != nil { return err } ns := n.Segment if (n.flags & isCompositeList) != 0 { copy(ns.Data[n.off:], ps.Data[p.off-8:p.off]) n.off += 8 } key.newval = n copies.Insert(key) switch p.typ { case TypeStruct: if (p.flags & isBitListMember) != 0 { if (ps.Data[p.off] & (1 << (p.flags & bitOffsetMask))) != 0 { ns.Data[n.off] = 1 } else { ns.Data[n.off] = 0 } for i := range ns.Data[n.off+1 : n.off+8] { ns.Data[i] = 0 } } else { copy(ns.Data[n.off:], ps.Data[p.off:p.off+p.datasz]) for i := 0; i < n.ptrs; i++ { c := ps.readPtr(p.off + p.datasz + i*8) if err := ns.writePtr(n.off+n.datasz+i*8, c, copies, depth+1); err != nil { return err } } } case TypeList: for i := 0; i < n.length; i++ { o := i * (n.datasz + n.ptrs*8) copy(ns.Data[n.off+o:], ps.Data[p.off+o:p.off+o+n.datasz]) o += n.datasz for j := 0; j < n.ptrs; j++ { c := ps.readPtr(p.off + o) if err := ns.writePtr(n.off+o, c, copies, depth+1); err != nil { return err } o += 8 } } case TypePointerList: for i := 0; i < n.ptrs; i++ { c := ps.readPtr(p.off + i*8) if err := ns.writePtr(n.off+i*8, c, copies, depth+1); err != nil { return err } } case TypeBitList: copy(ns.Data[n.off:], ps.Data[p.off:p.off+p.datasz]) } return s.writePtr(off, key.newval, nil, depth+1) } else if (p.flags & hasPointerTag) != 0 { // By lucky chance, the data has a tag in front of it. This // happens when create had to move the data to a new segment. putLittle64(s.Data[off:], ps.farPtrValue(farPointer, p.off-8)) return nil } else if len(ps.Data)+8 <= cap(ps.Data) { // Have room in the target for a tag putLittle64(ps.Data[len(ps.Data):], p.value(len(ps.Data))) putLittle64(s.Data[off:], ps.farPtrValue(farPointer, len(ps.Data))) ps.Data = ps.Data[:len(ps.Data)+8] return nil } else { // Need to create a double far pointer. Try and create it in // the originating segment if we can. t := s if len(t.Data)+16 > cap(t.Data) { var err error if t, err = t.Message.NewSegment(16); err != nil { return err } } putLittle64(t.Data[len(t.Data):], ps.farPtrValue(farPointer, p.off)) putLittle64(t.Data[len(t.Data)+8:], p.value(p.off-8)) putLittle64(s.Data[off:], t.farPtrValue(doubleFarPointer, len(t.Data))) t.Data = t.Data[:len(t.Data)+16] return nil } }