GlobalContextProperties.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #region Apache License
  2. //
  3. // Licensed to the Apache Software Foundation (ASF) under one or more
  4. // contributor license agreements. See the NOTICE file distributed with
  5. // this work for additional information regarding copyright ownership.
  6. // The ASF licenses this file to you under the Apache License, Version 2.0
  7. // (the "License"); you may not use this file except in compliance with
  8. // the License. You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. //
  18. #endregion
  19. using System;
  20. using System.Collections;
  21. namespace log4net.Util
  22. {
  23. /// <summary>
  24. /// Implementation of Properties collection for the <see cref="log4net.GlobalContext"/>
  25. /// </summary>
  26. /// <remarks>
  27. /// <para>
  28. /// This class implements a properties collection that is thread safe and supports both
  29. /// storing properties and capturing a read only copy of the current propertied.
  30. /// </para>
  31. /// <para>
  32. /// This class is optimized to the scenario where the properties are read frequently
  33. /// and are modified infrequently.
  34. /// </para>
  35. /// </remarks>
  36. /// <author>Nicko Cadell</author>
  37. public sealed class GlobalContextProperties : ContextPropertiesBase
  38. {
  39. #region Private Instance Fields
  40. /// <summary>
  41. /// The read only copy of the properties.
  42. /// </summary>
  43. /// <remarks>
  44. /// <para>
  45. /// This variable is declared <c>volatile</c> to prevent the compiler and JIT from
  46. /// reordering reads and writes of this thread performed on different threads.
  47. /// </para>
  48. /// </remarks>
  49. #if NETCF
  50. private ReadOnlyPropertiesDictionary m_readOnlyProperties = new ReadOnlyPropertiesDictionary();
  51. #else
  52. private volatile ReadOnlyPropertiesDictionary m_readOnlyProperties = new ReadOnlyPropertiesDictionary();
  53. #endif
  54. /// <summary>
  55. /// Lock object used to synchronize updates within this instance
  56. /// </summary>
  57. private readonly object m_syncRoot = new object();
  58. #endregion Private Instance Fields
  59. #region Public Instance Constructors
  60. /// <summary>
  61. /// Constructor
  62. /// </summary>
  63. /// <remarks>
  64. /// <para>
  65. /// Initializes a new instance of the <see cref="GlobalContextProperties" /> class.
  66. /// </para>
  67. /// </remarks>
  68. internal GlobalContextProperties()
  69. {
  70. }
  71. #endregion Public Instance Constructors
  72. #region Public Instance Properties
  73. /// <summary>
  74. /// Gets or sets the value of a property
  75. /// </summary>
  76. /// <value>
  77. /// The value for the property with the specified key
  78. /// </value>
  79. /// <remarks>
  80. /// <para>
  81. /// Reading the value for a key is faster than setting the value.
  82. /// When the value is written a new read only copy of
  83. /// the properties is created.
  84. /// </para>
  85. /// </remarks>
  86. override public object this[string key]
  87. {
  88. get
  89. {
  90. return m_readOnlyProperties[key];
  91. }
  92. set
  93. {
  94. lock(m_syncRoot)
  95. {
  96. PropertiesDictionary mutableProps = new PropertiesDictionary(m_readOnlyProperties);
  97. mutableProps[key] = value;
  98. m_readOnlyProperties = new ReadOnlyPropertiesDictionary(mutableProps);
  99. }
  100. }
  101. }
  102. #endregion Public Instance Properties
  103. #region Public Instance Methods
  104. /// <summary>
  105. /// Remove a property from the global context
  106. /// </summary>
  107. /// <param name="key">the key for the entry to remove</param>
  108. /// <remarks>
  109. /// <para>
  110. /// Removing an entry from the global context properties is relatively expensive compared
  111. /// with reading a value.
  112. /// </para>
  113. /// </remarks>
  114. public void Remove(string key)
  115. {
  116. lock(m_syncRoot)
  117. {
  118. if (m_readOnlyProperties.Contains(key))
  119. {
  120. PropertiesDictionary mutableProps = new PropertiesDictionary(m_readOnlyProperties);
  121. mutableProps.Remove(key);
  122. m_readOnlyProperties = new ReadOnlyPropertiesDictionary(mutableProps);
  123. }
  124. }
  125. }
  126. /// <summary>
  127. /// Clear the global context properties
  128. /// </summary>
  129. public void Clear()
  130. {
  131. lock(m_syncRoot)
  132. {
  133. m_readOnlyProperties = new ReadOnlyPropertiesDictionary();
  134. }
  135. }
  136. #endregion Public Instance Methods
  137. #region Internal Instance Methods
  138. /// <summary>
  139. /// Get a readonly immutable copy of the properties
  140. /// </summary>
  141. /// <returns>the current global context properties</returns>
  142. /// <remarks>
  143. /// <para>
  144. /// This implementation is fast because the GlobalContextProperties class
  145. /// stores a readonly copy of the properties.
  146. /// </para>
  147. /// </remarks>
  148. internal ReadOnlyPropertiesDictionary GetReadOnlyProperties()
  149. {
  150. return m_readOnlyProperties;
  151. }
  152. #endregion Internal Instance Methods
  153. }
  154. }