// // This Add method attach an object "data" to a node "n" using // the BitVector key as path. // private void Add(Node n, BitVector key, object data) { if (n.Key == null) { AddAsChildren(n, key, data); return; } // // First, calculate the longest common prefix for the key // and the BitVector stored in this node. // int longest = key.LongestCommonPrefix(n.Key); if (longest == n.Key.Length) { // // If the current node is a perfect prefix of the // key, then remove the prefix from the key, and // we continue our walk on the children. // key = key.Range(longest, key.Length - longest); AddAsChildren(n, key, data); return; } else { // // Here, n.Key and key share a common prefix. So we: // // - Create a new node with this common prefix // held there, // // - make n.Key and a new node with key as // children of this new node. BitVector common = n.Key.Range(0, longest); Node c1 = new Node(); c1.Key = n.Key.Range(longest, n.Key.Length - longest); c1.Data = n.Data; c1.Children = n.Children; Node c2 = new Node(); c2.Key = key.Range(longest, key.Length - longest); c2.Data = data; n.Key = common; n.Data = null; n.Children = new ArrayList(); n.Children.Add(c1); n.Children.Add(c2); return; } }
// // The AddAsChildren() method create a new node with key // "key", attach a data "data" to it, and finally link it to // the node "n". // private void AddAsChildren(Node n, BitVector key, Object data) { // // If "n" has no children, just add a new one // if (n.Children == null) { n.Children = new ArrayList(); Node nu = new Node(); nu.Key = key; nu.Data = data; n.Children.Add(nu); return; } // // From here, the node n already has at least 1 // children. // Check the one that has a common prefix with our key //(if there is none, the bestindex variable stays at -1). int bestindex = -1; int bestlength = 0; for (int i = 0; i < n.Children.Count; i++) { int b = ((Node) (n.Children[i])).Key.LongestCommonPrefix(key); if (b > bestlength) { bestlength = b; bestindex = i; } } // // The node n has no children that have a common prefix // with our key, so we create a new children node and // attach our data there. if (bestindex == -1) { Node c2 = new Node(); c2.Key = key; c2.Data = data; n.Children.Add(c2); return; } else { // There is a children node that can hold our // data: continue our walk with this node. Add(((Node) n.Children[bestindex]), key, data); return; } }
// // Returns the object held in the node that best matches our // key. // public object GetBest(BitVector key) { Node curnode = Root; while (curnode != null) { if (curnode.Children == null) return curnode.Data; // Get the best fitting index int bestindex = -1; int bestlength = 0; for (int i = 0; i < curnode.Children.Count; i++) { int b = ((Node) (curnode.Children[i])).Key.LongestCommonPrefix(key); if (b > bestlength) { bestlength = b; bestindex = i; } } if (bestindex != -1) { key = key.Range(bestlength, key.Length - bestlength); curnode = ((Node) curnode.Children[bestindex]); if (key.Length == 0) return curnode.Data; } else { return curnode.Data; } } return null; }
public void Add(BitVector key, object data) { Add(Root, key, data); }
public BitVectorReader(BitVector v) { m_data = v; m_offset = 0; }
public BitVector Range(int start, int length) { BitVector result = new BitVector(); for (int i = start; i < (start + length); i++) { result.Set(i - start, Get(i)); } return result; }
public int LongestCommonPrefix(BitVector other) { int i = 0; while ((i <= other.m_maxoffset) && (i <= m_maxoffset)) { if (other.Get(i) != Get(i)) { return i; } i++; } return i; }