private static long HashTrieGet <V>(HashTrie <V> trie, int key, int times) { V ignored = default(V); var watch = Stopwatch.StartNew(); for (int i = 0; i < times; i++) { ignored = trie.GetValueOrDefault(key); } watch.Stop(); GC.KeepAlive(ignored); GC.Collect(); return(watch.ElapsedMilliseconds); }
private static long TrieGet <T>(HashTrie <Type, T> tree, Type key, int times) { T ignored = default(T); var treeWatch = Stopwatch.StartNew(); for (int i = 0; i < times; i++) { ignored = tree.GetValueOrDefault(key); } treeWatch.Stop(); GC.KeepAlive(ignored); GC.Collect(); return(treeWatch.ElapsedMilliseconds); }
private static long HashTrieAdd <V>(ref HashTrie <V> trie, int[] keys, int key, V value) { var ignored = default(V); var treeTime = Stopwatch.StartNew(); for (var i = 0; i < keys.Length; i++) { Interlocked.Exchange(ref trie, trie.AddOrUpdate(keys[i], ignored)); } Interlocked.Exchange(ref trie, trie.AddOrUpdate(key, value)); treeTime.Stop(); GC.Collect(); return(treeTime.ElapsedMilliseconds); }
private static long TrieAdd <V>(ref HashTrie <Type, V> tree, Type[] keys, Type key, V value) { var ignored = default(V); var treeTime = Stopwatch.StartNew(); for (var i = 0; i < keys.Length; i++) { var k = keys[i]; Interlocked.Exchange(ref tree, tree.AddOrUpdate(k, ignored)); } Interlocked.Exchange(ref tree, tree.AddOrUpdate(key, value)); treeTime.Stop(); GC.KeepAlive(ignored); GC.Collect(); return(treeTime.ElapsedMilliseconds); }
public HashTrie <V> AddOrUpdate(int hash, V value, UpdateMethod <V> updateValue = null) { var index = hash & LEVEL_MASK; // index from 0 to 31 var restOfHash = hash >> LEVEL_BITS; if (_indexBitmap == 0) { return(new HashTrie <V>(1u << index, restOfHash == 0 ? (object)value : Empty.AddOrUpdate(restOfHash, value))); } var nodeCount = _nodes.Length; var pastIndexBitmap = _indexBitmap >> index; if ((pastIndexBitmap & 1) == 0) // no nodes at the index, could be inserted. { var subnode = restOfHash == 0 ? (object)value : Empty.AddOrUpdate(restOfHash, value); var pastIndexCount = pastIndexBitmap == 0 ? 0 : GetSetBitsCount(pastIndexBitmap); var insertIndex = nodeCount - pastIndexCount; var nodesToInsert = new object[nodeCount + 1]; if (insertIndex != 0) { Array.Copy(_nodes, 0, nodesToInsert, 0, insertIndex); } nodesToInsert[insertIndex] = subnode; if (pastIndexCount != 0) { Array.Copy(_nodes, insertIndex, nodesToInsert, insertIndex + 1, pastIndexCount); } return(new HashTrie <V>(_indexBitmap | (1u << index), nodesToInsert)); } var updateIndex = nodeCount == 1 ? 0 : nodeCount - (pastIndexBitmap == 1 ? 1 : GetSetBitsCount(pastIndexBitmap)); var updatedNode = _nodes[updateIndex]; if (updatedNode is HashTrie <V> ) { updatedNode = ((HashTrie <V>)updatedNode).AddOrUpdate(restOfHash, value, updateValue); } else if (restOfHash != 0) // if we need to update value with node we will move value down to new node sub-nodes at index 0. { updatedNode = new HashTrie <V>(1u, updatedNode).AddOrUpdate(restOfHash, value, updateValue); } else // here the actual update should go, cause old and new nodes contain values. { updatedNode = updateValue == null ? value : updateValue((V)updatedNode, value); } var nodesToUpdate = new object[nodeCount]; if (nodesToUpdate.Length > 1) { Array.Copy(_nodes, 0, nodesToUpdate, 0, nodesToUpdate.Length); } nodesToUpdate[updateIndex] = updatedNode; return(new HashTrie <V>(_indexBitmap, nodesToUpdate)); }