func (ptree *ptree) runAdds(addOperations map[*node]Keys) { if len(addOperations) == 0 { return } q := queue.New(int64(len(addOperations))) for n := range addOperations { q.Put(n) } nextLayer := make(map[*node][]*recursiveBuild) dummyRoot := &node{ keys: newKeys(), nodes: newNodes(), } // constructed in case we need it var needRoot uint64 queue.ExecuteInParallel(q, func(ifc interface{}) { n := ifc.(*node) keys := addOperations[n] if len(keys) == 0 { return } parent := n.parent if parent == nil { parent = dummyRoot atomic.AddUint64(&needRoot, 1) } for _, key := range keys { oldKey := n.keys.insert(key) if oldKey == nil { atomic.AddUint64(&ptree.number, 1) } } if n.needsSplit(ptree.ary) { keys := make(Keys, 0, n.keys.len()) nodes := make([]*node, 0, n.nodes.len()) ptree.recursiveSplit(n, parent, nil, &nodes, &keys) ptree.write.Lock() nextLayer[parent] = append( nextLayer[parent], &recursiveBuild{keys: keys, nodes: nodes, parent: parent}, ) ptree.write.Unlock() } }) setRoot := needRoot > 0 ptree.recursiveAdd(nextLayer, setRoot) }
func (ptree *ptree) recursiveAdd(layer map[*node][]*recursiveBuild, setRoot bool) { if len(layer) == 0 { return } if setRoot && len(layer) > 1 { panic(`SHOULD ONLY HAVE ONE ROOT`) } q := queue.New(int64(len(layer))) for _, rbs := range layer { q.Put(rbs) } layer = make(map[*node][]*recursiveBuild, len(layer)) dummyRoot := &node{ keys: newKeys(), nodes: newNodes(), } queue.ExecuteInParallel(q, func(ifc interface{}) { rbs := ifc.([]*recursiveBuild) if len(rbs) == 0 { return } n := rbs[0].parent if setRoot { ptree.root = n } parent := n.parent if parent == nil { parent = dummyRoot setRoot = true } for _, rb := range rbs { for i, k := range rb.keys { if n.keys.len() == 0 { n.keys.insert(k) n.nodes.push(rb.nodes[i*2]) n.nodes.push(rb.nodes[i*2+1]) continue } n.keys.insert(k) index := n.search(k) n.nodes.replaceAt(index, rb.nodes[i*2]) n.nodes.insertAt(index+1, rb.nodes[i*2+1]) } } if n.needsSplit(ptree.ary) { keys := make(Keys, 0, n.keys.len()) nodes := make([]*node, 0, n.nodes.len()) ptree.recursiveSplit(n, parent, nil, &nodes, &keys) ptree.write.Lock() layer[parent] = append( layer[parent], &recursiveBuild{keys: keys, nodes: nodes, parent: parent}, ) ptree.write.Unlock() } }) ptree.recursiveAdd(layer, setRoot) }