Beispiel #1
0
        //
        // Returns the object held in the node that best matches our
        // key.
        //
        internal string GetBest(BitVector key)
        {
            var curnode = root;
            while (curnode != null)
            {
                if (curnode.Children == null)
                    return curnode.Data;

                // Get the best fitting index
                var bestindex = -1;
                var bestlength = 0;

                for (var i = 0; i < curnode.Children.Count; i++)
                {
                    var b = curnode.Children[i].Key.LongestCommonPrefix(key);
                    if (b <= bestlength) continue;
                    bestlength = b;
                    bestindex = i;
                }

                if (bestindex == -1)
                {
                    return curnode.Data;
                }

                key = key.Range(bestlength, key.Length - bestlength);
                curnode = curnode.Children[bestindex];
                if (key.Length == 0)
                {
                    return curnode.Data;
                }
            }

            return null;
        }
Beispiel #2
0
        //
        // 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, string data)
        {
            // If "n" has no children, just add a new one
            //
            if (n.Children == null)
            {
                // initialize the list with a capacity: we save ourself
                // a few ms
                n.Children = new List<Node>(2) { new Node { Key = key, Data = data } };
                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).
            var bestindex = -1;
            var bestlength = 0;

            for (var i = 0; i < n.Children.Count; i++)
            {
                var b = n.Children[i].Key.LongestCommonPrefix(key);

                if (b <= bestlength) continue;
                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)
            {
                n.Children.Add(new Node { Key = key, Data = data });
                return;
            }
            // There is a children node that can hold our
            // data: continue our walk with this node.
            Add(n.Children[bestindex], key, data);
        }
Beispiel #3
0
 internal void Add(BitVector key, string data)
 {
     Add(root, key, data);
 }
Beispiel #4
0
        //
        // This Add method attach an object "data" to a node "n" using
        // the BitVector key as path.
        //
        private void Add(Node n, BitVector key, string 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.
            //
            var longest = key.LongestCommonPrefix(n.Key);

            //System.Diagnostics.Debug.Assert(longest != 0);

            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;
            }
            //
            // 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.
            var common = n.Key.Range(0, longest);

            var c1 = new Node
            {
                Key = n.Key.Range(longest, n.Key.Length - longest),
                Data = n.Data,
                Children = n.Children
            };

            var c2 = new Node { Key = key.Range(longest, key.Length - longest), Data = data };

            n.Key = common;
            n.Data = null;

            // initialize the list with a capacity: we save ourself
            // a few ms
            n.Children = new List<Node>(2) { c1, c2 };
        }
Beispiel #5
0
 public int LongestCommonPrefix(BitVector other)
 {
     var i = 0;
     while ((i <= other.mMaxoffset) && (i <= mMaxoffset))
     {
         if (other.Get(i) != Get(i))
         {
             return i;
         }
         i++;
     }
     return i;
 }
Beispiel #6
0
 public BitVector Range(int start, int length)
 {
     var result = new BitVector();
     for (var i = start; i < (start + length); i++)
     {
         result.Set(i - start, Get(i));
     }
     return result;
 }
Beispiel #7
0
        private static BitVector Ip6ToBitVector(string ip)
        {
            var elements = ip.Split(':');
            var bv = new BitVector();

            // only the first three? parts are significant for geolocation
            for (var index = 0; index < Math.Min(elements.Length, 3); index++)
            {
                var h = elements[index];
                bv.AddData(
                    string.IsNullOrEmpty(h)
                        ? 0
                        : int.Parse(h, NumberStyles.HexNumber, CultureInfo.InvariantCulture), 16);

            }
            return bv;
        }
Beispiel #8
0
        private static BitVector Ip4ToBitVector(string ip)
        {
            var elements = ip.Split('.');
            var bv = new BitVector();

            // only the first three bits are important
            for (var index = 0; index < Math.Min(elements.Length, 3); index++)
            {
                var s = elements[index];
                if (string.IsNullOrEmpty(s)) break;
                bv.AddData(int.Parse(s, CultureInfo.InvariantCulture), 8);
            }
            return bv;
        }