/// <summary> /// Construct over an IDictionary instance. /// </summary> /// <param name="dictionary"></param> /// <param name="stringComparer">The string comparer to use.</param> internal CopyOnWriteHashtable(IDictionary dictionary, StringComparer stringComparer) { ErrorUtilities.VerifyThrowArgumentNull(dictionary, "dictionary"); ErrorUtilities.VerifyThrowArgumentNull(stringComparer, "stringComparer"); this.sharedLock = new object(); CopyOnWriteHashtable source = dictionary as CopyOnWriteHashtable; if (source != null) { if (source.stringComparer.GetHashCode() == stringComparer.GetHashCode()) { // If we're copying another CopyOnWriteHashtable then we can defer the clone until later. ConstructFrom(source); return; } else { // Technically, it would be legal to fall through here and let a new hashtable be constructed. // However, Engine is supposed to use consistent case comparisons everywhere and so, for us, // this means a bug in the engine code somewhere. throw new InternalErrorException("Bug: Changing the case-sensitiveness of a copied hash-table."); } } // Can't defer this because we don't control what gets written to the dictionary exogenously. writeableData = new Hashtable(dictionary, stringComparer); readonlyData = null; this.stringComparer = stringComparer; }
/// <summary> /// Implementation of construction logic. /// </summary> /// <param name="that"></param> private void ConstructFrom(CopyOnWriteHashtable that) { lock (that.sharedLock) { this.writeableData = null; // If the source it was writeable, need to transform it into // read-only because we don't want subsequent writes to bleed through. if (that.writeableData != null) { that.readonlyData = that.writeableData; that.writeableData = null; } this.readonlyData = that.readonlyData; this.stringComparer = that.stringComparer; } }
/// <summary> /// Construct a shallow copy over another instance of this class. /// </summary> /// <param name="that"></param> private CopyOnWriteHashtable(CopyOnWriteHashtable that) { this.sharedLock = new object(); ConstructFrom(that); }