aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs185
1 files changed, 185 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
new file mode 100644
index 0000000..7d2da68
--- /dev/null
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
@@ -0,0 +1,185 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using OpenSim.Framework;
32using OpenMetaverse;
33
34using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim;
35
36namespace OpenSim.Region.ClientStack.LindenUDP
37{
38 public sealed class UDPClientCollection
39 {
40 Dictionary<UUID, LLUDPClient> Dictionary1;
41 Dictionary<IPEndPoint, LLUDPClient> Dictionary2;
42 LLUDPClient[] Array;
43 ReaderWriterLockImpl rwLock = new ReaderWriterLockImpl();
44
45 public UDPClientCollection()
46 {
47 Dictionary1 = new Dictionary<UUID, LLUDPClient>();
48 Dictionary2 = new Dictionary<IPEndPoint, LLUDPClient>();
49 Array = new LLUDPClient[0];
50 }
51
52 public UDPClientCollection(int capacity)
53 {
54 Dictionary1 = new Dictionary<UUID, LLUDPClient>(capacity);
55 Dictionary2 = new Dictionary<IPEndPoint, LLUDPClient>(capacity);
56 Array = new LLUDPClient[0];
57 }
58
59 public void Add(UUID key1, IPEndPoint key2, LLUDPClient value)
60 {
61 rwLock.EnterWriteLock();
62
63 try
64 {
65 if (Dictionary1.ContainsKey(key1))
66 {
67 if (!Dictionary2.ContainsKey(key2))
68 throw new ArgumentException("key1 exists in the dictionary but not key2");
69 }
70 else if (Dictionary2.ContainsKey(key2))
71 {
72 if (!Dictionary1.ContainsKey(key1))
73 throw new ArgumentException("key2 exists in the dictionary but not key1");
74 }
75
76 Dictionary1[key1] = value;
77 Dictionary2[key2] = value;
78
79 LLUDPClient[] oldArray = Array;
80 int oldLength = oldArray.Length;
81
82 LLUDPClient[] newArray = new LLUDPClient[oldLength + 1];
83 for (int i = 0; i < oldLength; i++)
84 newArray[i] = oldArray[i];
85 newArray[oldLength] = value;
86
87 Array = newArray;
88 }
89 finally { rwLock.ExitWriteLock(); }
90 }
91
92 public bool Remove(UUID key1, IPEndPoint key2)
93 {
94 rwLock.EnterWriteLock();
95
96 try
97 {
98 LLUDPClient value;
99 if (Dictionary1.TryGetValue(key1, out value))
100 {
101 Dictionary1.Remove(key1);
102 Dictionary2.Remove(key2);
103
104 LLUDPClient[] oldArray = Array;
105 int oldLength = oldArray.Length;
106
107 LLUDPClient[] newArray = new LLUDPClient[oldLength - 1];
108 int j = 0;
109 for (int i = 0; i < oldLength; i++)
110 {
111 if (oldArray[i] != value)
112 newArray[j++] = oldArray[i];
113 }
114
115 Array = newArray;
116 return true;
117 }
118 }
119 finally { rwLock.ExitWriteLock(); }
120
121 return false;
122 }
123
124 public void Clear()
125 {
126 rwLock.EnterWriteLock();
127
128 try
129 {
130 Dictionary1.Clear();
131 Dictionary2.Clear();
132 Array = new LLUDPClient[0];
133 }
134 finally { rwLock.ExitWriteLock(); }
135 }
136
137 public int Count
138 {
139 get { return Array.Length; }
140 }
141
142 public bool ContainsKey(UUID key)
143 {
144 return Dictionary1.ContainsKey(key);
145 }
146
147 public bool ContainsKey(IPEndPoint key)
148 {
149 return Dictionary2.ContainsKey(key);
150 }
151
152 public bool TryGetValue(UUID key, out LLUDPClient value)
153 {
154 bool success;
155 bool doLock = !rwLock.IsUpgradeableReadLockHeld;
156 if (doLock) rwLock.EnterReadLock();
157
158 try { success = Dictionary1.TryGetValue(key, out value); }
159 finally { if (doLock) rwLock.ExitReadLock(); }
160
161 return success;
162 }
163
164 public bool TryGetValue(IPEndPoint key, out LLUDPClient value)
165 {
166 bool success;
167 bool doLock = !rwLock.IsUpgradeableReadLockHeld;
168 if (doLock) rwLock.EnterReadLock();
169
170 try { success = Dictionary2.TryGetValue(key, out value); }
171 finally { if (doLock) rwLock.ExitReadLock(); }
172
173 return success;
174 }
175
176 public void ForEach(Action<LLUDPClient> action)
177 {
178 bool doLock = !rwLock.IsUpgradeableReadLockHeld;
179 if (doLock) rwLock.EnterUpgradeableReadLock();
180
181 try { Parallel.ForEach<LLUDPClient>(Array, action); }
182 finally { if (doLock) rwLock.ExitUpgradeableReadLock(); }
183 }
184 }
185}