diff --git a/OpenSim/Framework/MapAndArray.cs b/OpenSim/Framework/MapAndArray.cs index 32d6978fb6..a3ce55e185 100644 --- a/OpenSim/Framework/MapAndArray.cs +++ b/OpenSim/Framework/MapAndArray.cs @@ -41,14 +41,16 @@ namespace OpenSim.Framework { private Dictionary m_dict; private TValue[] m_array; - private object m_syncRoot = new object(); + private int m_lastArrayVersion; + private int m_arrayVersion; /// Number of values currently stored in the collection - public int Count { get { return m_array.Length; } } + public int Count { get { return m_dict.Count; } } /// NOTE: This collection is thread safe. You do not need to /// acquire a lock to add, remove, or enumerate entries. This /// synchronization object should only be locked for larger /// transactions + private object m_syncRoot = new object(); public object SyncRoot { get { return m_syncRoot; } } /// @@ -58,6 +60,8 @@ namespace OpenSim.Framework { m_dict = new Dictionary(); m_array = new TValue[0]; + m_lastArrayVersion = 0; + m_arrayVersion = 0; } /// @@ -68,6 +72,8 @@ namespace OpenSim.Framework { m_dict = new Dictionary(capacity); m_array = new TValue[0]; + m_lastArrayVersion = 0; + m_arrayVersion = 0; } /// @@ -85,7 +91,7 @@ namespace OpenSim.Framework bool containedKey = m_dict.ContainsKey(key); m_dict[key] = value; - CreateArray(); + ++m_arrayVersion; return !containedKey; } @@ -103,8 +109,8 @@ namespace OpenSim.Framework lock (m_syncRoot) { m_dict.Add(key, value); - CreateArray(); - return m_array.Length; + ++m_arrayVersion; + return m_dict.Count; } } @@ -118,8 +124,7 @@ namespace OpenSim.Framework lock (m_syncRoot) { bool removed = m_dict.Remove(key); - CreateArray(); - + ++m_arrayVersion; return removed; } } @@ -159,6 +164,8 @@ namespace OpenSim.Framework { m_dict = new Dictionary(); m_array = new TValue[0]; + m_lastArrayVersion = 0; + m_arrayVersion = 0; } } @@ -170,20 +177,17 @@ namespace OpenSim.Framework /// values public TValue[] GetArray() { - return m_array; - } - - private void CreateArray() - { - // Rebuild the array from the dictionary. This method must be - // called from inside a lock - TValue[] array = new TValue[m_dict.Count]; - int i = 0; - - foreach (TValue value in m_dict.Values) - array[i++] = value; - - m_array = array; + lock (m_syncRoot) + { + if(m_lastArrayVersion != m_arrayVersion) + { + TValue[] array = new TValue[m_dict.Count]; + m_dict.Values.CopyTo(array, 0); + m_array = array; + m_lastArrayVersion = m_arrayVersion; + } + return m_array; + } } } }