func (s *PtreeSuite) TestInsertNodeSplit(c *gc.C) { root, err := s.ptree.Root() for _, sv := range root.SValues() { c.Log("SV:", sv) c.Assert(sv.Cmp(cf.Zi(cf.P_SKS, 1)), gc.Equals, 0) } // Add a bunch of nodes, enough to cause splits for i := 0; i < s.config.SplitThreshold()*4; i++ { z := cf.Zi(cf.P_SKS, i+65536) c.Log("Insert:", z) s.ptree.Insert(z) } // Remove a bunch of nodes, enough to cause joins for i := 0; i < s.config.SplitThreshold()*4; i++ { z := cf.Zi(cf.P_SKS, i+65536) c.Log("Remove:", z) s.ptree.Remove(z) } root, err = s.ptree.Root() c.Assert(err, gc.IsNil) // Insert/Remove reversible after splitting & joining? for _, sv := range root.SValues() { c.Log("SV:", sv) c.Assert(sv.Cmp(cf.Zi(cf.P_SKS, 1)), gc.Equals, 0) } c.Assert(recon.MustChildren(root), gc.HasLen, 0) c.Assert(recon.MustElements(root), gc.HasLen, 0) }
func visit(node recon.PrefixNode) { render := struct { SValues []*conflux.Zp NumElements int Key string Leaf bool Fingerprints []string Children []string }{ node.SValues(), node.Size(), node.Key().String(), node.IsLeaf(), []string{}, []string{}, } if node.IsLeaf() { for _, element := range recon.MustElements(node) { render.Fingerprints = append(render.Fingerprints, fmt.Sprintf("%x", element.Bytes())) } } for _, child := range recon.MustChildren(node) { render.Children = append(render.Children, child.Key().String()) } out, err := json.MarshalIndent(render, "", "\t") if err != nil { die(err) } os.Stdout.Write(out) os.Stdout.Write([]byte("\n")) }
func (s *ReconSuite) TestSplits85(c *gc.C) { ptree, cleanup, err := s.Factory() c.Assert(err, gc.IsNil) defer cleanup() for _, z := range PtreeSplits85 { err = ptree.Insert(z) c.Assert(err, gc.IsNil) } root, err := ptree.Root() c.Assert(err, gc.IsNil) c.Assert(85, gc.Equals, root.Size()) for i, child := range recon.MustChildren(root) { c.Log("child#", i, ":", child.Key()) } for _, svalue := range root.SValues() { c.Log("root svalue:", svalue) } for _, node := range recon.MustChildren(root) { c.Log("child:", node.Key(), "has", node.Size()) } node, err := lookupNode("00", root) c.Assert(err, gc.IsNil) c.Assert(17, gc.Equals, node.Size()) node, err = lookupNode("01", root) c.Assert(err, gc.IsNil) c.Assert(19, gc.Equals, node.Size()) node, err = lookupNode("10", root) c.Assert(err, gc.IsNil) c.Assert(21, gc.Equals, node.Size()) node, err = lookupNode("11", root) c.Assert(err, gc.IsNil) c.Assert(28, gc.Equals, node.Size()) }
func lookupNode(key string, start recon.PrefixNode) (recon.PrefixNode, error) { node := start for len(key) > 0 { if node.IsLeaf() { return nil, fmt.Errorf("unexpected leaf node") } if len(key) < node.Config().BitQuantum { return nil, fmt.Errorf("bitstring alignment error, must be multiple of bitquantum") } childIndex := 0 if key[0] == '1' { childIndex |= 0x1 } if key[1] == '1' { childIndex |= 0x2 } node = recon.MustChildren(node)[childIndex] key = key[2:] } return node, nil }
func walk(tree recon.PrefixTree) { fmt.Println("[") var nodes []recon.PrefixNode root, err := tree.Root() if err != nil { die(err) } nodes = append(nodes, root) first := true for len(nodes) > 0 { if first { first = false } else { fmt.Println(",") } node := nodes[len(nodes)-1] nodes = nodes[:len(nodes)-1] visit(node) if !node.IsLeaf() { nodes = append(recon.MustChildren(node), nodes...) } } fmt.Println("]") }