protected virtual void Rehash(int newCapacity, OpenHashMapBase <K, V> source) { var fillFactor = FillFactorForSize(m_size); m_threshold = (int)(newCapacity * fillFactor); m_mask = newCapacity - 1; m_mask2 = newCapacity * 2 - 1; object[] sourceData = source.m_data; m_data = new object[newCapacity * 2]; m_size = m_hasNull ? 1 : 0; //Arrays.Fill(m_data, FreeKey); // not needed any more, since FreeKey is null int oldLength = sourceData.Length; for (int i = 0; i < oldLength; i += 2) { object oldKey = sourceData[i]; if (oldKey != FreeKey && oldKey != RemovedKey) { Put((K)oldKey, (V)sourceData[i + 1], false); } } }
public bool Remove(TKey key) { lock (_sync) { var map = _writeMap; if (map != null) { if (!_writeMap.Remove(key)) { return(false); } _readMap = _writeMap; _writeMap = null; _writeMapAccessCounter = 0; return(true); } map = _readMap; if (!_readMap.Contains(key)) { return(false); } map = CloneMap(map, map.Size - 1); map.Remove(key); _readMap = map; return(true); } }
protected override void Rehash(int newCapacity, OpenHashMapBase <K, V> source) { var other = source as OpenEqualityComparerHashMap <K, V>; if (_comparer == null && other != null) { _comparer = other._comparer; } base.Rehash(newCapacity, source); }
internal FastConcurrentHashMap(bool useIdentityComparison) { if (useIdentityComparison) { _readMap = new OpenIdentityHashMap <TKey, TVal>(DefaultSize, DefaultFillFactor, DefaultFillFactor2Threshold, DefaultFillFactor2); } else { _readMap = new OpenHashMap <TKey, TVal>(DefaultSize, DefaultFillFactor, DefaultFillFactor2Threshold, DefaultFillFactor2); } }
public void Clear() { var empty = CloneMap(_readMap, -1); lock (_sync) { _readMap = empty; _writeMap = null; _writeMapAccessCounter = 0; } }
/// <summary> /// Clones the hash map. /// </summary> protected OpenHashMapBase(OpenHashMapBase <K, V> other, int newSize) { m_fillFactor = other.m_fillFactor; m_fillFactor2 = other.m_fillFactor2; m_fillFactor2Threshold = other.m_fillFactor2Threshold; #if HASH_MAP_PERFORMANCE m_totalAccesses = other.m_totalAccesses; m_totalGets = other.m_totalGets; #endif if (newSize < 0) { InitializeEmpty(DefaultSize); return; } if (newSize < other.m_size) { newSize = other.m_size; } if (newSize < DefaultSize) { newSize = DefaultSize; } m_mask = other.m_mask; m_mask2 = other.m_mask2; m_threshold = other.m_threshold; m_hasNull = other.m_hasNull; m_nullValue = other.m_nullValue; int newCapacity = Tools.ArraySize(newSize, FillFactorForSize(newSize)); if (2 * newCapacity == other.m_data.Length) { m_data = Arrays.CopyOf(other.m_data, other.m_data.Length); m_size = other.m_size; } else { Rehash(newCapacity, other); } }
public TVal PutIfAbsent(TKey key, TVal value) { if (value == null) { throw new ArgumentNullException(); } lock (_sync) { _writeMapAccessCounter = Math.Max(_writeMapAccessCounter - 1, 0); var map = _writeMap; if (map == null) { var baseMap = _readMap; map = CloneMap(baseMap, baseMap.Size + 1); _writeMap = map; } return(map.PutIfAbsent(key, value)); } }
public TVal Get(TKey key) { // Try the fast path. var ret = _readMap.Get(key); if (ret != null) { return(ret); } // This second volatile field access is not strictly required for a caching map, // that will 'PutIfAbsent' or 'Put' if we return null anyway. For those types it // would suffice if we always return null, or make the write map non-volatile. // As a caching map will on the other hand hopefully most of the time have // cache-hits, this volatile access should not hurt too much. if (_writeMap == null) { return(default(TVal)); } // walk the slow path. lock (_sync) { ++_writeMapAccessCounter; var map = _writeMap; if (++_writeMapAccessCounter > CopyWriteMapAfterThreshold) { // Set the read map after a number of servings from the write map. _readMap = map; _writeMap = null; _writeMapAccessCounter = 0; } return(map.Get(key)); } }
public FastConcurrentHashMap(IEqualityComparer <TKey> comparer) { _readMap = new OpenEqualityComparerHashMap <TKey, TVal>(comparer, DefaultSize, DefaultFillFactor, DefaultFillFactor2Threshold, DefaultFillFactor2); }
internal FastConcurrentHashMap(OpenHashMapBase <TKey, TVal> readMap) { _readMap = readMap; }
private static OpenHashMapBase <TKey, TVal> CloneMap(OpenHashMapBase <TKey, TVal> map, int newSize) { return((OpenHashMapBase <TKey, TVal>)map.Clone(newSize)); }
public Enumerator(OpenHashMapBase <K, V> map) : base(map) { }
public ValueCollection(OpenHashMapBase <K, V> map) { m_map = map; }
public KeyCollection(OpenHashMapBase <K, V> map) { m_map = map; }
protected EnumeratorBase(OpenHashMapBase <K, V> map) { m_map = map; m_position = InitialPosition; }