aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs174
1 files changed, 174 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 9689e04..34ef67f 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -40,6 +40,15 @@ using OpenSim.Services.Interfaces;
40 40
41namespace OpenSim.Region.CoreModules.World.Land 41namespace OpenSim.Region.CoreModules.World.Land
42{ 42{
43 public class ParcelCounts
44 {
45 public int Owner = 0;
46 public int Group = 0;
47 public int Others = 0;
48 public Dictionary <UUID, int> Users =
49 new Dictionary <UUID, int>();
50 }
51
43 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule 52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
44 { 53 {
45 private static readonly ILog m_log = 54 private static readonly ILog m_log =
@@ -48,6 +57,18 @@ namespace OpenSim.Region.CoreModules.World.Land
48 private Scene m_Scene; 57 private Scene m_Scene;
49 private Dictionary<UUID, PrimCounts> m_PrimCounts = 58 private Dictionary<UUID, PrimCounts> m_PrimCounts =
50 new Dictionary<UUID, PrimCounts>(); 59 new Dictionary<UUID, PrimCounts>();
60 private Dictionary<UUID, UUID> m_OwnerMap =
61 new Dictionary<UUID, UUID>();
62 private Dictionary<UUID, int> m_SimwideCounts =
63 new Dictionary<UUID, int>();
64 private Dictionary<UUID, ParcelCounts> m_ParcelCounts =
65 new Dictionary<UUID, ParcelCounts>();
66
67 // For now, a simple simwide taint to get this up. Later parcel based
68 // taint to allow recounting a parcel if only ownership has changed
69 // without recounting the whole sim.
70 private bool m_Tainted = true;
71 private Object m_TaintLock = new Object();
51 72
52 public Type ReplaceableInterface 73 public Type ReplaceableInterface
53 { 74 {
@@ -89,26 +110,97 @@ namespace OpenSim.Region.CoreModules.World.Land
89 110
90 private void OnParcelPrimCountAdd(SceneObjectGroup obj) 111 private void OnParcelPrimCountAdd(SceneObjectGroup obj)
91 { 112 {
113 // If we're tainted already, don't bother to add. The next
114 // access will cause a recount anyway
115 lock (m_TaintLock)
116 {
117 if (!m_Tainted)
118 AddObject(obj);
119 }
92 } 120 }
93 121
94 private void OnObjectBeingRemovedFromScene(SceneObjectGroup obj) 122 private void OnObjectBeingRemovedFromScene(SceneObjectGroup obj)
95 { 123 {
124 // Don't bother to update tainted counts
125 lock (m_TaintLock)
126 {
127 if (!m_Tainted)
128 RemoveObject(obj);
129 }
96 } 130 }
97 131
98 private void OnParcelPrimCountTainted() 132 private void OnParcelPrimCountTainted()
99 { 133 {
134 lock (m_TaintLock)
135 m_Tainted = true;
100 } 136 }
101 137
102 public void TaintPrimCount(ILandObject land) 138 public void TaintPrimCount(ILandObject land)
103 { 139 {
140 lock (m_TaintLock)
141 m_Tainted = true;
104 } 142 }
105 143
106 public void TaintPrimCount(int x, int y) 144 public void TaintPrimCount(int x, int y)
107 { 145 {
146 lock (m_TaintLock)
147 m_Tainted = true;
108 } 148 }
109 149
110 public void TaintPrimCount() 150 public void TaintPrimCount()
111 { 151 {
152 lock (m_TaintLock)
153 m_Tainted = true;
154 }
155
156 // NOTE: Call under Taint Lock
157 private void AddObject(SceneObjectGroup obj)
158 {
159 if (obj.IsAttachment)
160 return;
161 if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0))
162 return;
163
164 Vector3 pos = obj.AbsolutePosition;
165 ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
166 LandData landData = landObject.LandData;
167
168 ParcelCounts parcelCounts;
169 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
170 {
171 UUID landOwner = landData.OwnerID;
172 int partCount = obj.Parts.Length;
173
174 m_SimwideCounts[landOwner] += partCount;
175 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
176 parcelCounts.Users[obj.OwnerID] += partCount;
177 else
178 parcelCounts.Users[obj.OwnerID] = partCount;
179
180 if (landData.IsGroupOwned)
181 {
182 if (obj.OwnerID == landData.GroupID)
183 parcelCounts.Owner += partCount;
184 else if (obj.GroupID == landData.GroupID)
185 parcelCounts.Group += partCount;
186 else
187 parcelCounts.Others += partCount;
188 }
189 else
190 {
191 if (obj.OwnerID == landData.OwnerID)
192 parcelCounts.Owner += partCount;
193 else if (obj.GroupID == landData.GroupID)
194 parcelCounts.Group += partCount;
195 else
196 parcelCounts.Others += partCount;
197 }
198 }
199 }
200
201 // NOTE: Call under Taint Lock
202 private void RemoveObject(SceneObjectGroup obj)
203 {
112 } 204 }
113 205
114 public IPrimCounts GetPrimCounts(UUID parcelID) 206 public IPrimCounts GetPrimCounts(UUID parcelID)
@@ -128,28 +220,110 @@ namespace OpenSim.Region.CoreModules.World.Land
128 220
129 public int GetOwnerCount(UUID parcelID) 221 public int GetOwnerCount(UUID parcelID)
130 { 222 {
223 lock (m_TaintLock)
224 {
225 if (m_Tainted)
226 Recount();
227
228 ParcelCounts counts;
229 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
230 return counts.Owner;
231 }
131 return 0; 232 return 0;
132 } 233 }
133 234
134 public int GetGroupCount(UUID parcelID) 235 public int GetGroupCount(UUID parcelID)
135 { 236 {
237 lock (m_TaintLock)
238 {
239 if (m_Tainted)
240 Recount();
241
242 ParcelCounts counts;
243 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
244 return counts.Group;
245 }
136 return 0; 246 return 0;
137 } 247 }
138 248
139 public int GetOthersCount(UUID parcelID) 249 public int GetOthersCount(UUID parcelID)
140 { 250 {
251 lock (m_TaintLock)
252 {
253 if (m_Tainted)
254 Recount();
255
256 ParcelCounts counts;
257 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
258 return counts.Others;
259 }
141 return 0; 260 return 0;
142 } 261 }
143 262
144 public int GetSimulatorCount(UUID parcelID) 263 public int GetSimulatorCount(UUID parcelID)
145 { 264 {
265 lock (m_TaintLock)
266 {
267 if (m_Tainted)
268 Recount();
269
270 UUID owner;
271 if (m_OwnerMap.TryGetValue(parcelID, out owner))
272 {
273 int val;
274 if (m_SimwideCounts.TryGetValue(owner, out val))
275 return val;
276 }
277 }
146 return 0; 278 return 0;
147 } 279 }
148 280
149 public int GetUserCount(UUID parcelID, UUID userID) 281 public int GetUserCount(UUID parcelID, UUID userID)
150 { 282 {
283 lock (m_TaintLock)
284 {
285 if (m_Tainted)
286 Recount();
287
288 ParcelCounts counts;
289 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
290 {
291 int val;
292 if (counts.Users.TryGetValue(userID, out val))
293 return val;
294 }
295 }
151 return 0; 296 return 0;
152 } 297 }
298
299 // NOTE: This method MUST be called while holding the taint lock!
300 private void Recount()
301 {
302 m_OwnerMap.Clear();
303 m_SimwideCounts.Clear();
304 m_ParcelCounts.Clear();
305
306 List<ILandObject> land = m_Scene.LandChannel.AllParcels();
307
308 foreach (ILandObject l in land)
309 {
310 LandData landData = l.LandData;
311
312 m_OwnerMap[landData.GlobalID] = landData.OwnerID;
313 m_SimwideCounts[landData.OwnerID] = 0;
314 m_ParcelCounts[landData.GlobalID] = new ParcelCounts();
315 }
316
317 m_Scene.ForEachSOG(AddObject);
318
319 List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys);
320 foreach (UUID k in primcountKeys)
321 {
322 if (!m_OwnerMap.ContainsKey(k))
323 m_PrimCounts.Remove(k);
324 }
325 m_Tainted = false;
326 }
153 } 327 }
154 328
155 public class PrimCounts : IPrimCounts 329 public class PrimCounts : IPrimCounts