Ejemplo n.º 1
0
 public void SetResults(StructureType type, Tuple <long, long>[] res)
 {
     if ((Types & type) > 0)
     {
         results[BitHacks.Power2MSB((uint)type)] = res;
     }
 }
Ejemplo n.º 2
0
 public Tuple <long, long>[] GetResults(StructureType type)
 {
     if ((Types & type) == 0)
     {
         return(null);
     }
     return(results[BitHacks.Power2MSB((uint)type)]);
 }
Ejemplo n.º 3
0
            internal InnerHashTable(uint length)
            {
                count = length;
                limit = 2 * length;
                uint hashSize = BitHacks.RoundToPower(2 * limit * (limit - 1));

                width = BitHacks.Power2MSB(hashSize);
                table = new KeyValuePair <uint, T>?[hashSize];
            }
Ejemplo n.º 4
0
            internal static RBTree FromSortedList(RBTree.Node[] list, int start, int stop)
            {
                RBTree tree   = new RBTree(new RBUIntNodeHelper());
                int    length = stop - start + 1;

                if (start == stop)
                {
                    return(tree);
                }
                int maxDepth = BitHacks.Power2MSB(BitHacks.RoundToPower((uint)(length + 1))) - 1;

                tree.root         = list[start + (length >> 1)];
                tree.root.IsBlack = true;
                tree.root.Size    = (uint)length;
                RBInsertChildren(tree.root, true, 1, maxDepth, list, start, start + (length >> 1) - 1);
                RBInsertChildren(tree.root, false, 1, maxDepth, list, start + (length >> 1) + 1, stop);
                return(tree);
            }
Ejemplo n.º 5
0
        // add overwrites
        public void Add(uint key, T value)
        {
            uint           firstHash   = GetHash(key);
            InnerHashTable innerHashed = inner[firstHash];
            uint           secondHash  = innerHashed.GetHash(key);

            // overwrite
            if (innerHashed.table[secondHash] != null && innerHashed.table[secondHash].Value.Key == key)
            {
                throw new ArgumentException();
            }
            count++;
            if (++pseudoCount > limit)
            {
                RehashAll(new KeyValuePair <uint, T>(key, value));
                return;
            }
            // empty spot - just plop the value there and call it a day
            if (innerHashed.IsDeleted((int)secondHash))
            {
                innerHashed.count++;
                innerHashed.table[secondHash] = new KeyValuePair <uint, T>(key, value);
            }
            // We've got collision now, do something about it
            else
            {
                // Note that original algorithm does this in a roundabout way due to their weird data structures
                if (++innerHashed.count <= innerHashed.limit)
                {
                    // Rehash second level
                    innerHashed.RehashWith(key, value, this, innerHashed.table, innerHashed.table.Length);
                }
                else
                {
                    // Grow the second level
                    uint newLimit = limit = 2 * Math.Max(1, innerHashed.limit);
                    uint newSize  = BitHacks.RoundToPower(2 * newLimit * (newLimit - 1));
                    innerHashed.limit = newLimit;
                    innerHashed.width = BitHacks.Power2MSB(newSize);
                    innerHashed.RehashWith(key, value, this, innerHashed.table, (int)newSize);
                }
            }
        }
Ejemplo n.º 6
0
        public VEBTree(int width)
        {
            if (width > 32 || width < 1)
            {
                throw new ArgumentOutOfRangeException();
            }

            this.width = width;
            if (width > 1)
            {
                int highHalf = width / 2 + (width & 1);
                int lowhHalf = width / 2;
                int halfSize = (int)BitHacks.MaxValue(highHalf) + 1;
                summary = new VEBTree <uint>(highHalf);
                cluster = new VEBTree <T> [halfSize];
                for (int i = 0; i < halfSize; i++)
                {
                    cluster[i] = new VEBTree <T>(lowhHalf);
                }
            }
        }
Ejemplo n.º 7
0
        private void AddChecked(uint key, T value, bool overwrite)
        {
            var separator = Separator(key);

            if (separator == null)
            {
                // add first element
                RBTree newTree = new RBTree(Node.Helper);
                newTree.root = new RBUIntNode(key, value)
                {
                    IsBlack = true
                };
                cluster.Add(BitHacks.MaxValue(cluster.width), newTree);
                return;
            }
            RBUIntNode newNode  = new RBUIntNode(key, value);
            RBUIntNode interned = (RBUIntNode)separator.value.Intern(key, newNode);

            if (interned != newNode)
            {
                if (overwrite)
                {
                    interned.value = value;
                }
                else
                {
                    throw new ArgumentException();
                }
            }
            else
            {
                count++;
                version++;
            }
            SplitIfTooLarge(separator);
        }
Ejemplo n.º 8
0
        /*
         * internal Func<uint, uint> GetRandomHashMethod(uint size)
         * {
         *  System.Diagnostics.Debug.Assert(size == BitHacks.RoundToPower(size));
         *  uint a = (uint)random.Next();
         *  uint b = (uint)(random.Next(65536) << 16);
         *  int shift = 31 - (int)BitHacks.Log2Ceiling(size);
         *  // weird shifting because c# can't shift uint by more than 31 bits
         *  return (x) =>  ((a * x + b) >> shift) >> 1;
         * }
         * */

        private void RehashAll(KeyValuePair <uint, T>?newValue)
        {
            List <KeyValuePair <uint, T> > elements = new List <KeyValuePair <uint, T> >((int)(newValue == null ? pseudoCount : pseudoCount + 1));

            if (inner != null)
            {
                int j = 0;
                foreach (InnerHashTable table in inner)
                {
                    for (int i = 0; i < table.AllocatedSize; i++)
                    {
                        if (table.IsContained(i))
                        {
                            elements.Add(table.table[i].Value);
                            j++;
                        }
                    }
                }
                if (newValue.HasValue)
                {
                    elements.Add(newValue.Value);
                }
            }
            pseudoCount = (uint)elements.Count;
            float newLimit = (1.0f + Fill) * Math.Max(pseudoCount, 4.0f);

            limit = (uint)newLimit;
            // hashSize = s(M)
            uint hashSize = BitHacks.RoundToPower(limit << 1);

            width = BitHacks.Power2MSB(hashSize);
            List <KeyValuePair <uint, T> >[] hashList = null;
            // find suitable higher level function
            for (bool injective = false; !injective;)
            {
                InitializeRandomHash(out a, out b);
                hashList = new List <KeyValuePair <uint, T> > [hashSize];
                // initialize provisional list of elemnts going into second level table
                for (int i = 0; i < hashList.Length; i++)
                {
                    hashList[i] = new List <KeyValuePair <uint, T> >();
                }
                // run first level hashes
                foreach (var elm in elements)
                {
                    hashList[GetHash(elm.Key)].Add(elm);
                }
                var testTable = new InnerHashTable[hashSize];
                injective = SatisfiesMagicalCondition(hashList, limit);
            }
            // find suitable lower level function
            inner = new InnerHashTable[hashSize];
            for (int i = 0; i < hashSize; i++)
            {
                // We deviate from original algorithm here,
                // if we've got empty second level we initialize it to size one to avoid out-of-bounds access in other functions.
                inner[i] = new InnerHashTable(Math.Max((uint)hashList[i].Count, 1));
                if (hashList[i].Count == 0)
                {
                    inner[i].count = 0;
                }
                while (true)
                {
                    inner[i].Clear();
                    inner[i].InitializeRandomHash(this);
                    for (int j = 0; j < hashList[i].Count; j++)
                    {
                        uint hash = inner[i].GetHash(hashList[i][j].Key);
                        if (inner[i].IsContained((int)hash))
                        {
                            // don't judge me
                            goto Failed;
                        }
                        inner[i].table[hash] = hashList[i][j];
                    }
                    break;
Failed:
                    continue;
                }
            }
        }
Ejemplo n.º 9
0
        public static MeasureResults MeasureSeriesDelete(StructureType types, int start, int count, int step)
        {
            // validate types
            types &= DictionaryMask;

            // initialize result sets
            Tuple <long, long>[] rbTreeResults        = new Tuple <long, long> [count];
            Tuple <long, long>[] vebResults           = new Tuple <long, long> [count];
            Tuple <long, long>[] dphResults           = new Tuple <long, long> [count];
            Tuple <long, long>[] xfastDPHResults      = new Tuple <long, long> [count];
            Tuple <long, long>[] yfastDPHResults      = new Tuple <long, long> [count];
            Tuple <long, long>[] xfastStandardResults = new Tuple <long, long> [count];
            Tuple <long, long>[] yfastStandardResults = new Tuple <long, long> [count];

            // calc the ranges
            int maxval = 2 * (int)BitHacks.RoundToPower((uint)(start + (count - 1) * step));
            int width  = BitHacks.Power2MSB((uint)maxval);

            // run benchmarks
            int i = 0;

            foreach (var size in Enumerable.Range(0, count).Select(x => start + (x * step)))
            {
                var itemSet = GenerateRandomSet(size, maxval).ToArray();
                var delSet  = itemSet.ToArray();
                Shuffle(delSet);

                if (types.HasFlag(StructureType.RBTree))
                {
                    var dict = new FromMono.SortedDictionary <uint, uint>();
                    Fill(delSet, delSet, dict);
                    rbTreeResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                if (types.HasFlag(StructureType.VEB))
                {
                    var dict = new VEBTree <uint>(width);
                    Fill(delSet, delSet, dict);
                    vebResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                if (types.HasFlag(StructureType.DPH))
                {
                    var dict = new HashTable <uint>();
                    Fill(delSet, delSet, dict);
                    dphResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                if (types.HasFlag(StructureType.XTrieDPH))
                {
                    var dict = new XFastTrie <uint>(width);
                    Fill(delSet, delSet, dict);
                    xfastDPHResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                if (types.HasFlag(StructureType.YTrieDPH))
                {
                    var dict = new YFastTrie <uint>(width);
                    Fill(delSet, delSet, dict);
                    yfastDPHResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                if (types.HasFlag(StructureType.XTrieStandard))
                {
                    var dict = XFastTrie <uint> .FromDictionary <Dictionary <uint, XFastNode> >(width);

                    Fill(delSet, delSet, dict);
                    xfastStandardResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                if (types.HasFlag(StructureType.YTrieStandard))
                {
                    var dict = YFastTrie <uint> .FromDictionary <Dictionary <uint, XFastNode> >(width);

                    Fill(delSet, delSet, dict);
                    yfastStandardResults[i] = Tuple.Create((long)size, MeasureDelete(delSet, dict));
                }
                i++;
            }

            // dump the results
            MeasureResults results = new MeasureResults(types, maxval);

            results.SetResults(StructureType.RBTree, rbTreeResults);
            results.SetResults(StructureType.VEB, vebResults);
            results.SetResults(StructureType.DPH, dphResults);
            results.SetResults(StructureType.XTrieDPH, xfastDPHResults);
            results.SetResults(StructureType.YTrieDPH, yfastDPHResults);
            results.SetResults(StructureType.XTrieStandard, xfastStandardResults);
            results.SetResults(StructureType.YTrieStandard, yfastStandardResults);
            return(results);
        }
Ejemplo n.º 10
0
        public static MeasureResults MeasureSeriesSearch(StructureType types, int start, int count, int step, int control)
        {
            // validate types
            types &= SortedDictionaryMask;

            // initialize result sets
            Tuple <long, long>[] rbTreeResults        = new Tuple <long, long> [count];
            Tuple <long, long>[] vebResults           = new Tuple <long, long> [count];
            Tuple <long, long>[] dphResults           = new Tuple <long, long> [count];
            Tuple <long, long>[] xfastDPHResults      = new Tuple <long, long> [count];
            Tuple <long, long>[] yfastDPHResults      = new Tuple <long, long> [count];
            Tuple <long, long>[] xfastStandardResults = new Tuple <long, long> [count];
            Tuple <long, long>[] yfastStandardResults = new Tuple <long, long> [count];

            // calc the ranges
            int maxval   = 2 * Math.Max((int)BitHacks.RoundToPower((uint)(start + (count - 1) * step)), control);
            int width    = BitHacks.Power2MSB((uint)maxval);
            int positive = (int)(0.9 * control);
            int negative = control - positive;

            // run benchmarks
            int i = 0;

            foreach (var size in Enumerable.Range(0, count).Select(x => start + (x * step)))
            {
                uint[]         searchSet = new uint[control];
                HashSet <uint> itemSet   = GenerateRandomSet(size, maxval);
                uint[]         itemArray = itemSet.ToArray();
                int            j         = 0;
                for (; j < positive; j++)
                {
                    searchSet[j] = itemArray[random.Next(itemArray.Length)];
                }
                while (j < searchSet.Length)
                {
                    uint next = (uint)random.Next(maxval);
                    if (!itemSet.Contains(next))
                    {
                        searchSet[j] = next;
                        j++;
                    }
                }

                if (types.HasFlag(StructureType.RBTree))
                {
                    var dict = new FromMono.SortedDictionary <uint, uint>();
                    Fill(itemArray, itemArray, dict);
                    rbTreeResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                if (types.HasFlag(StructureType.VEB))
                {
                    var dict = new VEBTree <uint>(width);
                    Fill(itemArray, itemArray, dict);
                    vebResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                if (types.HasFlag(StructureType.DPH))
                {
                    var dict = new HashTable <uint>();
                    Fill(itemArray, itemArray, dict);
                    dphResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                if (types.HasFlag(StructureType.XTrieDPH))
                {
                    var dict = new XFastTrie <uint>(width);
                    Fill(itemArray, itemArray, dict);
                    xfastDPHResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                if (types.HasFlag(StructureType.YTrieDPH))
                {
                    var dict = new YFastTrie <uint>(width);
                    Fill(itemArray, itemArray, dict);
                    yfastDPHResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                if (types.HasFlag(StructureType.XTrieStandard))
                {
                    var dict = XFastTrie <uint> .FromDictionary <Dictionary <uint, XFastNode> >(width);

                    Fill(itemArray, itemArray, dict);
                    xfastStandardResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                if (types.HasFlag(StructureType.YTrieStandard))
                {
                    var dict = YFastTrie <uint> .FromDictionary <Dictionary <uint, XFastNode> >(width);

                    Fill(itemArray, itemArray, dict);
                    yfastStandardResults[i] = Tuple.Create((long)size, MeasureSearch(searchSet, dict));
                }
                i++;
            }

            // dump the results
            MeasureResults results = new MeasureResults(types, maxval);

            results.SetResults(StructureType.RBTree, rbTreeResults);
            results.SetResults(StructureType.VEB, vebResults);
            results.SetResults(StructureType.DPH, dphResults);
            results.SetResults(StructureType.XTrieDPH, xfastDPHResults);
            results.SetResults(StructureType.YTrieDPH, yfastDPHResults);
            results.SetResults(StructureType.XTrieStandard, xfastStandardResults);
            results.SetResults(StructureType.YTrieStandard, yfastStandardResults);
            return(results);
        }