diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs index dbb9861acc..06fa3e2e49 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Net; using OpenSim.Framework; using OpenMetaverse; +using BclExtras.Collections; using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim; @@ -37,246 +38,113 @@ namespace OpenSim.Region.ClientStack.LindenUDP { public sealed class UDPClientCollection { - Dictionary Dictionary1; - Dictionary Dictionary2; - LLUDPClient[] Array; - ReaderWriterLockImpl rwLock = new ReaderWriterLockImpl(); - object m_sync = new object(); + #region IComparers + + private sealed class UUIDComparer : IComparer + { + public int Compare(UUID x, UUID y) + { + return x.Guid.CompareTo(y.Guid); + } + } + + private sealed class IPEndPointComparer : IComparer + { + public int Compare(IPEndPoint x, IPEndPoint y) + { + int result = x.Address.Address.CompareTo(y.Address.Address); + if (result == 0) result = x.Port.CompareTo(y.Port); + return result; + } + } + + #endregion IComparers + + private ImmutableMap m_dict1; + private ImmutableMap m_dict2; + private LLUDPClient[] m_array; public UDPClientCollection() { - Dictionary1 = new Dictionary(); - Dictionary2 = new Dictionary(); - Array = new LLUDPClient[0]; - } - - public UDPClientCollection(int capacity) - { - Dictionary1 = new Dictionary(capacity); - Dictionary2 = new Dictionary(capacity); - Array = new LLUDPClient[0]; + m_dict1 = new ImmutableMap(new UUIDComparer()); + m_dict2 = new ImmutableMap(new IPEndPointComparer()); + m_array = new LLUDPClient[0]; } public void Add(UUID key1, IPEndPoint key2, LLUDPClient value) { - //rwLock.EnterWriteLock(); + m_dict1 = m_dict1.Add(key1, value); + m_dict2 = m_dict2.Add(key2, value); - //try - //{ - // if (Dictionary1.ContainsKey(key1)) - // { - // if (!Dictionary2.ContainsKey(key2)) - // throw new ArgumentException("key1 exists in the dictionary but not key2"); - // } - // else if (Dictionary2.ContainsKey(key2)) - // { - // if (!Dictionary1.ContainsKey(key1)) - // throw new ArgumentException("key2 exists in the dictionary but not key1"); - // } - - // Dictionary1[key1] = value; - // Dictionary2[key2] = value; - - // LLUDPClient[] oldArray = Array; - // int oldLength = oldArray.Length; - - // LLUDPClient[] newArray = new LLUDPClient[oldLength + 1]; - // for (int i = 0; i < oldLength; i++) - // newArray[i] = oldArray[i]; - // newArray[oldLength] = value; - - // Array = newArray; - //} - //finally { rwLock.ExitWriteLock(); } - - lock (m_sync) - { - if (Dictionary1.ContainsKey(key1)) - { - if (!Dictionary2.ContainsKey(key2)) - throw new ArgumentException("key1 exists in the dictionary but not key2"); - } - else if (Dictionary2.ContainsKey(key2)) - { - if (!Dictionary1.ContainsKey(key1)) - throw new ArgumentException("key2 exists in the dictionary but not key1"); - } - - Dictionary1[key1] = value; - Dictionary2[key2] = value; - - LLUDPClient[] oldArray = Array; - int oldLength = oldArray.Length; - - LLUDPClient[] newArray = new LLUDPClient[oldLength + 1]; - for (int i = 0; i < oldLength; i++) - newArray[i] = oldArray[i]; - newArray[oldLength] = value; - - Array = newArray; - } + // Copy the array by hand + LLUDPClient[] oldArray = m_array; + int oldLength = oldArray.Length; + LLUDPClient[] newArray = new LLUDPClient[oldLength + 1]; + for (int i = 0; i < oldLength; i++) + newArray[i] = oldArray[i]; + newArray[oldLength] = value; + + m_array = newArray; } - public bool Remove(UUID key1, IPEndPoint key2) + public void Remove(UUID key1, IPEndPoint key2) { - //rwLock.EnterWriteLock(); + m_dict1 = m_dict1.Delete(key1); + m_dict2 = m_dict2.Delete(key2); - //try - //{ - // LLUDPClient value; - // if (Dictionary1.TryGetValue(key1, out value)) - // { - // Dictionary1.Remove(key1); - // Dictionary2.Remove(key2); + LLUDPClient[] oldArray = m_array; + int oldLength = oldArray.Length; - // LLUDPClient[] oldArray = Array; - // int oldLength = oldArray.Length; + // Copy the array by hand - // LLUDPClient[] newArray = new LLUDPClient[oldLength - 1]; - // int j = 0; - // for (int i = 0; i < oldLength; i++) - // { - // if (oldArray[i] != value) - // newArray[j++] = oldArray[i]; - // } + LLUDPClient[] newArray = new LLUDPClient[oldLength - 1]; + int j = 0; - // Array = newArray; - // return true; - // } - //} - //finally { rwLock.ExitWriteLock(); } - - //return false; - - lock (m_sync) + for (int i = 0; i < oldLength; i++) { - LLUDPClient value; - if (Dictionary1.TryGetValue(key1, out value)) - { - Dictionary1.Remove(key1); - Dictionary2.Remove(key2); - - LLUDPClient[] oldArray = Array; - int oldLength = oldArray.Length; - - LLUDPClient[] newArray = new LLUDPClient[oldLength - 1]; - int j = 0; - for (int i = 0; i < oldLength; i++) - { - if (oldArray[i] != value) - newArray[j++] = oldArray[i]; - } - - Array = newArray; - return true; - } + if (oldArray[i].AgentID != key1) + newArray[j++] = oldArray[i]; } - return false; - + m_array = newArray; } public void Clear() { - //rwLock.EnterWriteLock(); - - //try - //{ - // Dictionary1.Clear(); - // Dictionary2.Clear(); - // Array = new LLUDPClient[0]; - //} - //finally { rwLock.ExitWriteLock(); } - - lock (m_sync) - { - Dictionary1.Clear(); - Dictionary2.Clear(); - Array = new LLUDPClient[0]; - } - + m_dict1 = new ImmutableMap(new UUIDComparer()); + m_dict2 = new ImmutableMap(new IPEndPointComparer()); + m_array = new LLUDPClient[0]; } public int Count { - get { return Array.Length; } + get { return m_array.Length; } } public bool ContainsKey(UUID key) { - return Dictionary1.ContainsKey(key); + return m_dict1.ContainsKey(key); } public bool ContainsKey(IPEndPoint key) { - return Dictionary2.ContainsKey(key); + return m_dict2.ContainsKey(key); } public bool TryGetValue(UUID key, out LLUDPClient value) { - ////bool success; - ////bool doLock = !rwLock.IsUpgradeableReadLockHeld; - ////if (doLock) rwLock.EnterReadLock(); - - ////try { success = Dictionary1.TryGetValue(key, out value); } - ////finally { if (doLock) rwLock.ExitReadLock(); } - - ////return success; - - lock (m_sync) - return Dictionary1.TryGetValue(key, out value); - - //try - //{ - // return Dictionary1.TryGetValue(key, out value); - //} - //catch { } - //value = null; - //return false; + return m_dict1.TryGetValue(key, out value); } public bool TryGetValue(IPEndPoint key, out LLUDPClient value) { - ////bool success; - ////bool doLock = !rwLock.IsUpgradeableReadLockHeld; - ////if (doLock) rwLock.EnterReadLock(); - - ////try { success = Dictionary2.TryGetValue(key, out value); } - ////finally { if (doLock) rwLock.ExitReadLock(); } - - ////return success; - - lock (m_sync) - return Dictionary2.TryGetValue(key, out value); - - //try - //{ - // return Dictionary2.TryGetValue(key, out value); - //} - //catch { } - //value = null; - //return false; - + return m_dict2.TryGetValue(key, out value); } public void ForEach(Action action) { - //bool doLock = !rwLock.IsUpgradeableReadLockHeld; - //if (doLock) rwLock.EnterUpgradeableReadLock(); - - //try { Parallel.ForEach(Array, action); } - //finally { if (doLock) rwLock.ExitUpgradeableReadLock(); } - - LLUDPClient[] localArray = null; - lock (m_sync) - { - localArray = new LLUDPClient[Array.Length]; - Array.CopyTo(localArray, 0); - } - - Parallel.ForEach(localArray, action); - + Parallel.ForEach(m_array, action); } } } diff --git a/ThirdPartyLicenses/BclExtras.txt b/ThirdPartyLicenses/BclExtras.txt new file mode 100644 index 0000000000..a8a02925b1 --- /dev/null +++ b/ThirdPartyLicenses/BclExtras.txt @@ -0,0 +1,60 @@ +MICROSOFT PUBLIC LICENSE (Ms-PL) + +This license governs use of the accompanying software. If you use the software, +you accept this license. If you do not accept the license, do not use the +software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" +have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the +software. + +A "contributor" is any person that distributes its contribution under this +license. + +"Licensed patents" are a contributor's patent claims that read directly on its +contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license +conditions and limitations in section 3, each contributor grants you a +non-exclusive, worldwide, royalty-free copyright license to reproduce its +contribution, prepare derivative works of its contribution, and distribute its +contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license +conditions and limitations in section 3, each contributor grants you a +non-exclusive, worldwide, royalty-free license under its licensed patents to +make, have made, use, sell, offer for sale, import, and/or otherwise dispose of +its contribution in the software or derivative works of the contribution in the +software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any +contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you +claim are infringed by the software, your patent license from such contributor +to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all +copyright, patent, trademark, and attribution notices that are present in the +software. + +(D) If you distribute any portion of the software in source code form, you may +do so only under this license by including a complete copy of this license with +your distribution. If you distribute any portion of the software in compiled or +object code form, you may only do so under a license that complies with this +license. + +(E) The software is licensed "as-is." You bear the risk of using it. The +contributors give no express warranties, guarantees or conditions. You may have +additional consumer rights under your local laws which this license cannot +change. To the extent permitted under your local laws, the contributors exclude +the implied warranties of merchantability, fitness for a particular purpose and +non-infringement. diff --git a/ThirdPartyLicenses/CSJ2K.txt b/ThirdPartyLicenses/CSJ2K.txt new file mode 100644 index 0000000000..303254816b --- /dev/null +++ b/ThirdPartyLicenses/CSJ2K.txt @@ -0,0 +1,28 @@ +Copyright (c) 1999/2000 JJ2000 Partners. + +This software module was originally developed by Raphaël Grosbois and +Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel +Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David +Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research +Centre France S.A) in the course of development of the JPEG2000 +standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This +software module is an implementation of a part of the JPEG 2000 +Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio +Systems AB and Canon Research Centre France S.A (collectively JJ2000 +Partners) agree not to assert against ISO/IEC and users of the JPEG +2000 Standard (Users) any of their rights under the copyright, not +including other intellectual property rights, for this software module +with respect to the usage by ISO/IEC and Users of this software module +or modifications thereof for use in hardware or software products +claiming conformance to the JPEG 2000 Standard. Those intending to use +this software module in hardware or software products are advised that +their use may infringe existing patents. The original developers of +this software module, JJ2000 Partners and ISO/IEC assume no liability +for use of this software module or modifications thereof. No license +or right to this software module is granted for non JPEG 2000 Standard +conforming products. JJ2000 Partners have full right to use this +software module for his/her own purpose, assign or donate this +software module to any third party and to inhibit third parties from +using this software module for non JPEG 2000 Standard conforming +products. This copyright notice must be included in all copies or +derivative works of this software module. diff --git a/bin/BclExtras.dll b/bin/BclExtras.dll new file mode 100644 index 0000000000..505cf01f06 Binary files /dev/null and b/bin/BclExtras.dll differ diff --git a/prebuild.xml b/prebuild.xml index bba54f3fa3..028e5e734c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1767,6 +1767,7 @@ +