public void SetResults(StructureType type, Tuple <long, long>[] res) { if ((Types & type) > 0) { results[BitHacks.Power2MSB((uint)type)] = res; } }
public Tuple <long, long>[] GetResults(StructureType type) { if ((Types & type) == 0) { return(null); } return(results[BitHacks.Power2MSB((uint)type)]); }
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]; }
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); }
// 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); } } }
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); } } }
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); }
/* * 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; } } }
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); }
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); }