diff options
author | UbitUmarov | 2016-07-31 19:08:35 +0100 |
---|---|---|
committer | UbitUmarov | 2016-07-31 19:08:35 +0100 |
commit | 703e96b4cbaec3b499284accaeb1f6242e71d7e5 (patch) | |
tree | 6c1c4b83a53e8e898d90c40aa661d4238026e10c /OpenSim/Region/CoreModules/ServiceConnectorsOut | |
parent | rearrange handlers convertion math, harcoding the grid unit size of 256m, als... (diff) | |
download | opensim-SC_OLD-703e96b4cbaec3b499284accaeb1f6242e71d7e5.zip opensim-SC_OLD-703e96b4cbaec3b499284accaeb1f6242e71d7e5.tar.gz opensim-SC_OLD-703e96b4cbaec3b499284accaeb1f6242e71d7e5.tar.bz2 opensim-SC_OLD-703e96b4cbaec3b499284accaeb1f6242e71d7e5.tar.xz |
Change RegionInfoCache again...
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut')
3 files changed, 368 insertions, 278 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index d38ac9b..7d8ae57 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
166 | if (!m_Enabled) | 166 | if (!m_Enabled) |
167 | return; | 167 | return; |
168 | 168 | ||
169 | m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionID); | 169 | m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionHandle); |
170 | scene.EventManager.OnRegionUp -= OnRegionUp; | 170 | scene.EventManager.OnRegionUp -= OnRegionUp; |
171 | } | 171 | } |
172 | 172 | ||
@@ -220,16 +220,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
220 | // be the base coordinate of the region. | 220 | // be the base coordinate of the region. |
221 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 221 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
222 | { | 222 | { |
223 | |||
223 | // try in cache by handler first | 224 | // try in cache by handler first |
224 | ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); | 225 | // ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); |
225 | 226 | ||
226 | bool inCache = false; | 227 | bool inCache = false; |
227 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); | 228 | // GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); |
228 | if (inCache) | 229 | // if (inCache) |
229 | return rinfo; | 230 | // return rinfo; |
230 | 231 | ||
231 | // try in cache by slower position next | 232 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID, (uint)x, (uint)y, out inCache); |
232 | rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache); | ||
233 | if (inCache) | 233 | if (inCache) |
234 | return rinfo; | 234 | return rinfo; |
235 | 235 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index 8f3dfc1..03fc9ea 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs | |||
@@ -44,11 +44,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
44 | // LogManager.GetLogger( | 44 | // LogManager.GetLogger( |
45 | // MethodBase.GetCurrentMethod().DeclaringType); | 45 | // MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private RegionsExpiringCache m_Cache; | 47 | private static RegionsExpiringCache m_Cache; |
48 | private int numberInstances; | ||
48 | 49 | ||
49 | public RegionInfoCache() | 50 | public RegionInfoCache() |
50 | { | 51 | { |
51 | m_Cache = new RegionsExpiringCache(); | 52 | if(m_Cache == null) |
53 | m_Cache = new RegionsExpiringCache(); | ||
54 | numberInstances++; | ||
52 | } | 55 | } |
53 | 56 | ||
54 | public void Cache(GridRegion rinfo) | 57 | public void Cache(GridRegion rinfo) |
@@ -78,8 +81,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
78 | if (rinfo == null) | 81 | if (rinfo == null) |
79 | return; | 82 | return; |
80 | 83 | ||
81 | // m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); | 84 | m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); |
82 | m_Cache.Add(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); // don't override local regions | ||
83 | } | 85 | } |
84 | 86 | ||
85 | public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds) | 87 | public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds) |
@@ -90,9 +92,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
90 | m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds); | 92 | m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds); |
91 | } | 93 | } |
92 | 94 | ||
93 | public void Remove(UUID scopeID, UUID regionID) | 95 | public void Remove(UUID scopeID, GridRegion rinfo) |
96 | { | ||
97 | m_Cache.Remove(scopeID, rinfo); | ||
98 | } | ||
99 | |||
100 | public void Remove(UUID scopeID, ulong regionHandle) | ||
94 | { | 101 | { |
95 | m_Cache.Remove(scopeID, regionID); | 102 | m_Cache.Remove(scopeID, regionHandle); |
96 | } | 103 | } |
97 | 104 | ||
98 | public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) | 105 | public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) |
@@ -137,7 +144,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
137 | return null; | 144 | return null; |
138 | } | 145 | } |
139 | 146 | ||
140 | public GridRegion Get(UUID scopeID, int x, int y, out bool inCache) | 147 | public GridRegion Get(UUID scopeID, uint x, uint y, out bool inCache) |
141 | { | 148 | { |
142 | inCache = false; | 149 | inCache = false; |
143 | 150 | ||
@@ -152,109 +159,281 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
152 | } | 159 | } |
153 | } | 160 | } |
154 | 161 | ||
155 | 162 | public class RegionInfoForScope | |
156 | // following code partialy adapted from lib OpenMetaverse | ||
157 | public class RegionKey | ||
158 | { | 163 | { |
159 | public UUID ScopeID; | 164 | public const ulong HANDLEMASH = 0xffffff00ffffff00ul; |
160 | public UUID RegionID; | 165 | public const ulong HANDLECOORDMASH = 0xffffff00ul; |
166 | |||
167 | private Dictionary<ulong, GridRegion> storage; | ||
168 | private Dictionary<ulong, DateTime> expires; | ||
169 | private Dictionary<string, ulong> byname; | ||
170 | private Dictionary<UUID, ulong> byuuid; | ||
161 | 171 | ||
162 | public RegionKey(UUID scopeID, UUID id) | 172 | public RegionInfoForScope() |
163 | { | 173 | { |
164 | ScopeID = scopeID; | 174 | storage = new Dictionary<ulong, GridRegion>(); |
165 | RegionID = id; | 175 | expires = new Dictionary<ulong, DateTime>(); |
176 | byname = new Dictionary<string, ulong>(); | ||
177 | byuuid = new Dictionary<UUID, ulong>(); | ||
166 | } | 178 | } |
167 | 179 | ||
168 | public override int GetHashCode() | 180 | public RegionInfoForScope(GridRegion region, DateTime expire) |
169 | { | 181 | { |
170 | int hash = ScopeID.GetHashCode(); | 182 | storage = new Dictionary<ulong, GridRegion>(); |
171 | hash += hash * 23 + RegionID.GetHashCode(); | 183 | expires = new Dictionary<ulong, DateTime>(); |
172 | return hash; | 184 | byname = new Dictionary<string, ulong>(); |
185 | byuuid = new Dictionary<UUID, ulong>(); | ||
186 | |||
187 | ulong handle = region.RegionHandle & HANDLEMASH; | ||
188 | storage[handle] = region; | ||
189 | expires[handle] = expire; | ||
190 | byname[region.RegionName] = handle; | ||
191 | byuuid[region.RegionID] = handle; | ||
173 | } | 192 | } |
174 | 193 | ||
175 | public override bool Equals(Object b) | 194 | public void Add(GridRegion region, DateTime expire) |
176 | { | 195 | { |
177 | if(b == null) | 196 | ulong handle = region.RegionHandle & HANDLEMASH; |
178 | return false; | 197 | |
179 | RegionKey kb = b as RegionKey; | 198 | if(storage != null && storage.ContainsKey(handle)) |
180 | return (ScopeID == kb.ScopeID && RegionID == kb.RegionID); | 199 | return; |
200 | |||
201 | if(storage == null) | ||
202 | storage = new Dictionary<ulong, GridRegion>(); | ||
203 | if(expires == null) | ||
204 | expires = new Dictionary<ulong, DateTime>(); | ||
205 | if(byname == null) | ||
206 | byname = new Dictionary<string, ulong>(); | ||
207 | if(byuuid == null) | ||
208 | byuuid = new Dictionary<UUID, ulong>(); | ||
209 | |||
210 | storage[handle] = region; | ||
211 | expires[handle] = expire; | ||
212 | byname[region.RegionName] = handle; | ||
213 | byuuid[region.RegionID] = handle; | ||
181 | } | 214 | } |
182 | } | ||
183 | 215 | ||
184 | class RegionKeyEqual : EqualityComparer<RegionKey> | 216 | public void AddUpdate(GridRegion region, DateTime expire) |
185 | { | ||
186 | public override int GetHashCode(RegionKey rk) | ||
187 | { | 217 | { |
188 | return rk.GetHashCode(); | 218 | if(storage == null) |
219 | storage = new Dictionary<ulong, GridRegion>(); | ||
220 | if(expires == null) | ||
221 | expires = new Dictionary<ulong, DateTime>(); | ||
222 | if(byname == null) | ||
223 | byname = new Dictionary<string, ulong>(); | ||
224 | if(byuuid == null) | ||
225 | byuuid = new Dictionary<UUID, ulong>(); | ||
226 | |||
227 | ulong handle = region.RegionHandle & HANDLEMASH; | ||
228 | |||
229 | storage[handle] = region; | ||
230 | if(expires.ContainsKey(handle)) | ||
231 | { | ||
232 | if(expires[handle] < expire) | ||
233 | expires[handle] = expire; | ||
234 | } | ||
235 | else | ||
236 | expires[handle] = expire; | ||
237 | byname[region.RegionName] = handle; | ||
238 | byuuid[region.RegionID] = handle; | ||
189 | } | 239 | } |
190 | 240 | ||
191 | public override bool Equals(RegionKey a, RegionKey b) | 241 | public void Remove(GridRegion region) |
192 | { | 242 | { |
193 | return (a.ScopeID == b.ScopeID && a.RegionID == b.RegionID); | 243 | if(region == null) |
244 | return; | ||
245 | |||
246 | if(byname != null) | ||
247 | byname.Remove(region.RegionName); | ||
248 | if(byuuid != null) | ||
249 | byuuid.Remove(region.RegionID); | ||
250 | |||
251 | ulong handle = region.RegionHandle & HANDLEMASH; | ||
252 | if(storage != null) | ||
253 | storage.Remove(handle); | ||
254 | if(expires != null) | ||
255 | { | ||
256 | expires.Remove(handle); | ||
257 | if(expires.Count == 0) | ||
258 | Clear(); | ||
259 | } | ||
194 | } | 260 | } |
195 | } | ||
196 | 261 | ||
197 | public class RegionInfoByScope | 262 | public void Remove(ulong handle) |
198 | { | 263 | { |
199 | private Dictionary<string, RegionKey> byname; | 264 | handle &= HANDLEMASH; |
200 | private Dictionary<ulong, RegionKey> byhandle; | 265 | |
266 | if(storage != null) | ||
267 | { | ||
268 | if(storage.ContainsKey(handle)) | ||
269 | { | ||
270 | GridRegion r = storage[handle]; | ||
271 | if(byname != null) | ||
272 | byname.Remove(r.RegionName); | ||
273 | if(byuuid != null) | ||
274 | byuuid.Remove(r.RegionID); | ||
275 | } | ||
276 | storage.Remove(handle); | ||
277 | } | ||
278 | if(expires != null) | ||
279 | { | ||
280 | expires.Remove(handle); | ||
281 | if(expires.Count == 0) | ||
282 | Clear(); | ||
283 | } | ||
284 | } | ||
201 | 285 | ||
202 | public RegionInfoByScope() | 286 | public void Clear() |
203 | { | 287 | { |
204 | byname = new Dictionary<string, RegionKey>(); | 288 | if(expires != null) |
205 | byhandle = new Dictionary<ulong, RegionKey>(); | 289 | expires.Clear(); |
290 | if(storage != null) | ||
291 | storage.Clear(); | ||
292 | if(byname != null) | ||
293 | byname.Clear(); | ||
294 | if(byuuid != null) | ||
295 | byuuid.Clear(); | ||
296 | byname = null; | ||
297 | byuuid = null; | ||
298 | storage = null; | ||
299 | expires = null; | ||
206 | } | 300 | } |
207 | 301 | ||
208 | public RegionInfoByScope(GridRegion region, RegionKey key) | 302 | public bool Contains(GridRegion region) |
209 | { | 303 | { |
210 | byname = new Dictionary<string, RegionKey>(); | 304 | if(storage == null) |
211 | byhandle = new Dictionary<ulong, RegionKey>(); | 305 | return false; |
306 | if(region == null) | ||
307 | return false; | ||
212 | 308 | ||
213 | byname[region.RegionName] = key; | 309 | ulong handle = region.RegionHandle & HANDLEMASH; |
214 | byhandle[region.RegionHandle] = key; | 310 | return storage.ContainsKey(handle); |
215 | } | 311 | } |
216 | 312 | ||
217 | public void AddRegion(GridRegion region, RegionKey key) | 313 | public bool Contains(ulong handle) |
218 | { | 314 | { |
219 | if(byname == null) | 315 | if(storage == null) |
220 | byname = new Dictionary<string, RegionKey>(); | 316 | return false; |
221 | if(byhandle == null) | ||
222 | byhandle = new Dictionary<ulong, RegionKey>(); | ||
223 | 317 | ||
224 | byname[region.RegionName] = key; | 318 | handle &= HANDLEMASH; |
225 | byhandle[region.RegionHandle] = key; | 319 | return storage.ContainsKey(handle); |
226 | } | 320 | } |
227 | 321 | ||
228 | public void RemoveRegion(GridRegion region) | 322 | public GridRegion get(ulong handle) |
229 | { | 323 | { |
230 | if(byname != null) | 324 | if(storage == null) |
231 | byname.Remove(region.RegionName); | 325 | return null; |
232 | if(byhandle != null) | 326 | |
233 | byhandle.Remove(region.RegionHandle); | 327 | handle &= HANDLEMASH; |
328 | if(storage.ContainsKey(handle)) | ||
329 | return storage[handle]; | ||
330 | |||
331 | return null; | ||
234 | } | 332 | } |
235 | 333 | ||
236 | public void Clear() | 334 | public GridRegion get(string name) |
237 | { | 335 | { |
238 | if(byname != null) | 336 | if(byname == null || !byname.ContainsKey(name)) |
239 | byname.Clear(); | 337 | return null; |
240 | if(byhandle != null) | 338 | |
241 | byhandle.Clear(); | 339 | ulong handle = byname[name]; |
242 | byname = null; | 340 | if(storage.ContainsKey(handle)) |
243 | byhandle = null; | 341 | return storage[handle]; |
342 | return null; | ||
244 | } | 343 | } |
245 | 344 | ||
246 | public RegionKey get(string name) | 345 | public GridRegion get(UUID id) |
247 | { | 346 | { |
248 | if(byname == null || !byname.ContainsKey(name)) | 347 | if(byuuid == null || !byuuid.ContainsKey(id)) |
249 | return null; | 348 | return null; |
250 | return byname[name]; | 349 | |
350 | ulong handle = byuuid[id]; | ||
351 | if(storage.ContainsKey(handle)) | ||
352 | return storage[handle]; | ||
353 | return null; | ||
251 | } | 354 | } |
252 | 355 | ||
253 | public RegionKey get(ulong handle) | 356 | public GridRegion get(uint x, uint y) |
254 | { | 357 | { |
255 | if(byhandle == null || !byhandle.ContainsKey(handle)) | 358 | if(storage == null) |
256 | return null; | 359 | return null; |
257 | return byhandle[handle]; | 360 | |
361 | // look for a handle first this should find normal size regions | ||
362 | ulong handle = (ulong)x & HANDLECOORDMASH; | ||
363 | handle <<= 32; | ||
364 | handle |= ((ulong)y & HANDLECOORDMASH); | ||
365 | |||
366 | if(storage.ContainsKey(handle)) | ||
367 | return storage[handle]; | ||
368 | |||
369 | // next do the harder work | ||
370 | foreach(KeyValuePair<ulong, GridRegion> kvp in storage) | ||
371 | { | ||
372 | GridRegion r = kvp.Value; | ||
373 | if(r == null) // ?? | ||
374 | continue; | ||
375 | |||
376 | if(handle < r.RegionHandle) | ||
377 | continue; | ||
378 | int test = r.RegionLocX + r.RegionSizeX; | ||
379 | if(x >= test) | ||
380 | continue; | ||
381 | test = r.RegionLocY + r.RegionSizeY; | ||
382 | if (y < test) | ||
383 | return r; | ||
384 | } | ||
385 | return null; | ||
386 | } | ||
387 | |||
388 | public int expire(DateTime now ) | ||
389 | { | ||
390 | if(expires == null || expires.Count == 0) | ||
391 | return 0; | ||
392 | |||
393 | List<ulong> toexpire = new List<ulong>(); | ||
394 | foreach(KeyValuePair<ulong, DateTime> kvp in expires) | ||
395 | { | ||
396 | if(kvp.Value < now) | ||
397 | toexpire.Add(kvp.Key); | ||
398 | } | ||
399 | |||
400 | if(toexpire.Count == 0) | ||
401 | return expires.Count; | ||
402 | |||
403 | if(toexpire.Count == expires.Count) | ||
404 | { | ||
405 | Clear(); | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | foreach(ulong h in toexpire) | ||
410 | { | ||
411 | if(storage != null) | ||
412 | { | ||
413 | if(storage.ContainsKey(h)) | ||
414 | { | ||
415 | GridRegion r = storage[h]; | ||
416 | if(byname != null) | ||
417 | byname.Remove(r.RegionName); | ||
418 | if(byuuid != null) | ||
419 | byuuid.Remove(r.RegionID); | ||
420 | } | ||
421 | storage.Remove(h); | ||
422 | } | ||
423 | if(expires != null) | ||
424 | expires.Remove(h); | ||
425 | } | ||
426 | |||
427 | if(expires.Count == 0) | ||
428 | { | ||
429 | byname = null; | ||
430 | byuuid = null; | ||
431 | storage = null; | ||
432 | expires = null; | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | return expires.Count; | ||
258 | } | 437 | } |
259 | 438 | ||
260 | public int Count() | 439 | public int Count() |
@@ -276,10 +455,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
276 | /// <summary>For thread safety</summary> | 455 | /// <summary>For thread safety</summary> |
277 | object isPurging = new object(); | 456 | object isPurging = new object(); |
278 | 457 | ||
279 | static RegionKeyEqual keyequal = new RegionKeyEqual(); | 458 | Dictionary<UUID, RegionInfoForScope> InfobyScope = new Dictionary<UUID, RegionInfoForScope>(); |
280 | Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>(keyequal); | ||
281 | Dictionary<RegionKey, DateTime> timedExpires = new Dictionary<RegionKey, DateTime>(); | ||
282 | Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>(); | ||
283 | private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); | 459 | private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); |
284 | 460 | ||
285 | public RegionsExpiringCache() | 461 | public RegionsExpiringCache() |
@@ -288,297 +464,225 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
288 | timer.Start(); | 464 | timer.Start(); |
289 | } | 465 | } |
290 | 466 | ||
291 | public bool Add(UUID scope, GridRegion region, float expirationSeconds) | 467 | public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds) |
292 | { | 468 | { |
469 | if(region == null) | ||
470 | return false; | ||
471 | |||
293 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 472 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
294 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 473 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
295 | 474 | ||
296 | RegionKey key = new RegionKey(scope , region.RegionID); | ||
297 | |||
298 | try | 475 | try |
299 | { | 476 | { |
300 | if (timedStorage.ContainsKey(key)) | ||
301 | return false; | ||
302 | |||
303 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); | 477 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); |
304 | timedStorage[key] = region; | ||
305 | timedExpires[key] = expire; | ||
306 | 478 | ||
307 | RegionInfoByScope ris = null; | 479 | RegionInfoForScope ris = null; |
308 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | 480 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
309 | { | 481 | { |
310 | ris = new RegionInfoByScope(region, key); | 482 | ris = new RegionInfoForScope(region, expire); |
311 | InfobyScope[scope] = ris; | 483 | InfobyScope[scope] = ris; |
312 | } | 484 | } |
313 | else | 485 | else |
314 | ris.AddRegion(region, key); | 486 | ris.AddUpdate(region, expire); |
315 | 487 | ||
316 | return true; | 488 | return true; |
317 | } | 489 | } |
318 | finally { Monitor.Exit(syncRoot);} | 490 | finally { Monitor.Exit(syncRoot); } |
319 | } | 491 | } |
320 | 492 | ||
321 | public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds) | 493 | public void Clear() |
322 | { | 494 | { |
323 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 495 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
324 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 496 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
325 | |||
326 | try | 497 | try |
327 | { | 498 | { |
328 | RegionKey key = new RegionKey(scope, region.RegionID); | 499 | foreach(RegionInfoForScope ris in InfobyScope.Values) |
329 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); | 500 | ris.Clear(); |
501 | InfobyScope.Clear(); | ||
502 | } | ||
503 | finally { Monitor.Exit(syncRoot); } | ||
504 | } | ||
505 | |||
506 | public bool Contains(UUID scope, GridRegion region) | ||
507 | { | ||
508 | if(region == null) | ||
509 | return false; | ||
330 | 510 | ||
331 | if (timedStorage.ContainsKey(key)) | 511 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
332 | { | 512 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
333 | timedStorage[key] = region; | ||
334 | if(expire > timedExpires[key]) | ||
335 | timedExpires[key] = expire; | ||
336 | 513 | ||
337 | if(!InfobyScope.ContainsKey(scope)) | 514 | try |
338 | { | 515 | { |
339 | RegionInfoByScope ris = new RegionInfoByScope(region, key); | 516 | RegionInfoForScope ris = null; |
340 | InfobyScope[scope] = ris; | 517 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
341 | } | ||
342 | return false; | 518 | return false; |
343 | } | 519 | |
344 | else | 520 | return ris.Contains(region); |
345 | { | ||
346 | timedStorage[key] = region; | ||
347 | timedExpires[key] = expire; | ||
348 | RegionInfoByScope ris = null; | ||
349 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
350 | { | ||
351 | ris = new RegionInfoByScope(region,key); | ||
352 | InfobyScope[scope] = ris; | ||
353 | } | ||
354 | else | ||
355 | ris.AddRegion(region,key); | ||
356 | return true; | ||
357 | } | ||
358 | } | 521 | } |
359 | finally { Monitor.Exit(syncRoot); } | 522 | finally { Monitor.Exit(syncRoot); } |
360 | } | 523 | } |
361 | 524 | ||
362 | public void Clear() | 525 | public bool Contains(UUID scope, ulong handle) |
363 | { | 526 | { |
364 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 527 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
365 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 528 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
529 | |||
366 | try | 530 | try |
367 | { | 531 | { |
368 | timedStorage.Clear(); | 532 | RegionInfoForScope ris = null; |
369 | timedExpires.Clear(); | 533 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
370 | InfobyScope.Clear(); | 534 | return false; |
535 | |||
536 | return ris.Contains(handle); | ||
371 | } | 537 | } |
372 | finally { Monitor.Exit(syncRoot); } | 538 | finally { Monitor.Exit(syncRoot); } |
373 | } | 539 | } |
374 | |||
375 | public bool Contains(UUID scope, GridRegion region) | ||
376 | { | ||
377 | RegionKey key = new RegionKey(scope, region.RegionID); | ||
378 | return Contains(key); | ||
379 | } | ||
380 | 540 | ||
381 | public bool Contains(RegionKey key) | 541 | public int Count() |
382 | { | 542 | { |
383 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 543 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
384 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 544 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
545 | |||
385 | try | 546 | try |
386 | { | 547 | { |
387 | return timedStorage.ContainsKey(key); | 548 | int count = 0; |
549 | foreach(RegionInfoForScope ris in InfobyScope.Values) | ||
550 | count += ris.Count(); | ||
551 | return count; | ||
388 | } | 552 | } |
389 | finally { Monitor.Exit(syncRoot); } | 553 | finally { Monitor.Exit(syncRoot); } |
390 | } | 554 | } |
391 | 555 | ||
392 | public int Count | 556 | public bool Remove(UUID scope, ulong handle) |
393 | { | ||
394 | get | ||
395 | { | ||
396 | return timedStorage.Count; | ||
397 | } | ||
398 | } | ||
399 | public bool Remove(UUID scope, GridRegion region) | ||
400 | { | 557 | { |
401 | return Remove(scope, region.RegionID); | ||
402 | } | ||
403 | public bool Remove(UUID scope, UUID regionID) | ||
404 | { | ||
405 | RegionKey key = new RegionKey(scope, regionID); | ||
406 | |||
407 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 558 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
408 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 559 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
409 | try | 560 | try |
410 | { | 561 | { |
411 | if (timedStorage.ContainsKey(key)) | 562 | RegionInfoForScope ris = null; |
412 | { | 563 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
413 | RegionInfoByScope ris = null; | ||
414 | if(InfobyScope.TryGetValue(scope, out ris) && ris != null) | ||
415 | { | ||
416 | GridRegion r = timedStorage[key]; | ||
417 | if(r != null) | ||
418 | ris.RemoveRegion(r); | ||
419 | if(ris.Count() == 0) | ||
420 | InfobyScope.Remove(scope); | ||
421 | } | ||
422 | timedStorage.Remove(key); | ||
423 | timedExpires.Remove(key); | ||
424 | return true; | ||
425 | } | ||
426 | else | ||
427 | return false; | 564 | return false; |
565 | |||
566 | ris.Remove(handle); | ||
567 | if(ris.Count() == 0) | ||
568 | InfobyScope.Remove(scope); | ||
569 | return true; | ||
428 | } | 570 | } |
429 | finally { Monitor.Exit(syncRoot); } | 571 | finally { Monitor.Exit(syncRoot); } |
430 | } | 572 | } |
431 | 573 | ||
432 | public bool TryGetValue(RegionKey key, out GridRegion value) | 574 | public bool Remove(UUID scope, GridRegion region) |
433 | { | 575 | { |
576 | if(region == null) | ||
577 | return false; | ||
578 | |||
434 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 579 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
435 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 580 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
436 | try | 581 | try |
437 | { | 582 | { |
438 | if (timedStorage.ContainsKey(key)) | 583 | RegionInfoForScope ris = null; |
439 | { | 584 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
440 | value = timedStorage[key]; | 585 | return false; |
441 | return true; | 586 | |
442 | } | 587 | ris.Remove(region); |
588 | if(ris.Count() == 0) | ||
589 | InfobyScope.Remove(scope); | ||
590 | return true; | ||
443 | } | 591 | } |
444 | finally { Monitor.Exit(syncRoot); } | 592 | finally { Monitor.Exit(syncRoot); } |
445 | |||
446 | value = null; | ||
447 | return false; | ||
448 | } | 593 | } |
449 | 594 | ||
450 | public bool TryGetValue(UUID scope, UUID id, out GridRegion value) | 595 | public bool TryGetValue(UUID scope, ulong handle, out GridRegion value) |
451 | { | 596 | { |
452 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 597 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
453 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 598 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
599 | |||
600 | value = null; | ||
454 | try | 601 | try |
455 | { | 602 | { |
456 | RegionKey rk = new RegionKey(scope, id); | 603 | RegionInfoForScope ris = null; |
457 | if(timedStorage.ContainsKey(rk)) | 604 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
458 | { | 605 | return false; |
459 | value = timedStorage[rk]; | 606 | value = ris.get(handle); |
460 | return true; | ||
461 | } | ||
462 | } | 607 | } |
463 | finally { Monitor.Exit(syncRoot); } | 608 | finally { Monitor.Exit(syncRoot); } |
464 | 609 | ||
465 | value = null; | 610 | return value != null; |
466 | return false; | ||
467 | } | 611 | } |
468 | 612 | ||
469 | public bool TryGetValue(UUID scope, string name, out GridRegion value) | 613 | public bool TryGetValue(UUID scope, string name, out GridRegion value) |
470 | { | 614 | { |
471 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 615 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
472 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 616 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
617 | |||
618 | value = null; | ||
473 | try | 619 | try |
474 | { | 620 | { |
475 | value = null; | 621 | RegionInfoForScope ris = null; |
476 | RegionInfoByScope ris = null; | ||
477 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | 622 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
478 | return false; | 623 | return false; |
479 | 624 | value = ris.get(name); | |
480 | RegionKey key = ris.get(name); | ||
481 | if(key == null) | ||
482 | return false; | ||
483 | |||
484 | if(timedStorage.ContainsKey(key)) | ||
485 | { | ||
486 | value = timedStorage[key]; | ||
487 | return true; | ||
488 | } | ||
489 | } | 625 | } |
490 | finally { Monitor.Exit(syncRoot); } | 626 | finally { Monitor.Exit(syncRoot); } |
491 | 627 | ||
492 | return false; | 628 | return value != null; |
493 | } | 629 | } |
494 | 630 | ||
495 | public bool TryGetValue(UUID scope, ulong handle, out GridRegion value) | 631 | public bool TryGetValue(UUID scope, UUID id, out GridRegion value) |
496 | { | 632 | { |
497 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 633 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
498 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 634 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
635 | |||
636 | value = null; | ||
499 | try | 637 | try |
500 | { | 638 | { |
501 | value = null; | 639 | RegionInfoForScope ris = null; |
502 | RegionInfoByScope ris = null; | ||
503 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | 640 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) |
504 | return false; | 641 | return false; |
505 | 642 | value = ris.get(id); | |
506 | RegionKey key = ris.get(handle); | ||
507 | if(key == null) | ||
508 | return false; | ||
509 | |||
510 | if(timedStorage.ContainsKey(key)) | ||
511 | { | ||
512 | value = timedStorage[key]; | ||
513 | return true; | ||
514 | } | ||
515 | } | 643 | } |
516 | finally { Monitor.Exit(syncRoot); } | 644 | finally { Monitor.Exit(syncRoot); } |
517 | 645 | ||
518 | value = null; | 646 | return value != null; |
519 | return false; | ||
520 | } | 647 | } |
521 | 648 | ||
522 | // gets a region that contains world position (x,y) | 649 | // gets a region that contains world position (x,y) |
523 | // hopefull will not take ages | 650 | // hopefull will not take ages |
524 | public bool TryGetValue(UUID scope, int x, int y, out GridRegion value) | 651 | public bool TryGetValue(UUID scope, uint x, uint y, out GridRegion value) |
525 | { | 652 | { |
526 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 653 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
527 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 654 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
655 | |||
656 | value = null; | ||
528 | try | 657 | try |
529 | { | 658 | { |
530 | value = null; | 659 | RegionInfoForScope ris = null; |
531 | 660 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | |
532 | if(timedStorage.Count == 0) | ||
533 | return false; | 661 | return false; |
534 | 662 | ||
535 | foreach(KeyValuePair<RegionKey, GridRegion> kvp in timedStorage) | 663 | value = ris.get(x, y); |
536 | { | ||
537 | if(kvp.Key.ScopeID != scope) | ||
538 | continue; | ||
539 | |||
540 | GridRegion r = kvp.Value; | ||
541 | if(r == null) // ?? | ||
542 | continue; | ||
543 | int test = r.RegionLocX; | ||
544 | if(x < test) | ||
545 | continue; | ||
546 | test += r.RegionSizeX; | ||
547 | if(x >= test) | ||
548 | continue; | ||
549 | test = r.RegionLocY; | ||
550 | if(y < test) | ||
551 | continue; | ||
552 | test += r.RegionSizeY; | ||
553 | if (y < test) | ||
554 | { | ||
555 | value = r; | ||
556 | return true; | ||
557 | } | ||
558 | } | ||
559 | } | 664 | } |
560 | finally { Monitor.Exit(syncRoot); } | 665 | finally { Monitor.Exit(syncRoot); } |
561 | 666 | ||
562 | value = null; | 667 | return value != null; |
563 | return false; | ||
564 | } | 668 | } |
565 | 669 | ||
566 | public bool Update(UUID scope, GridRegion region, double expirationSeconds) | 670 | public bool Update(UUID scope, GridRegion region, double expirationSeconds) |
567 | { | 671 | { |
672 | if(region == null) | ||
673 | return false; | ||
674 | |||
568 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | 675 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) |
569 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | 676 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); |
570 | 677 | ||
571 | RegionKey key = new RegionKey(scope, region.RegionID); | ||
572 | try | 678 | try |
573 | { | 679 | { |
574 | if (!timedStorage.ContainsKey(key)) | 680 | RegionInfoForScope ris = null; |
681 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
575 | return false; | 682 | return false; |
576 | 683 | ||
577 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); | 684 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); |
578 | timedStorage[key] = region; | 685 | ris.AddUpdate(region,expire); |
579 | if(expire > timedExpires[key]) | ||
580 | timedExpires[key] = expire; | ||
581 | |||
582 | return true; | 686 | return true; |
583 | } | 687 | } |
584 | finally { Monitor.Exit(syncRoot); } | 688 | finally { Monitor.Exit(syncRoot); } |
@@ -595,7 +699,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
595 | if (!Monitor.TryEnter(isPurging)) | 699 | if (!Monitor.TryEnter(isPurging)) |
596 | return; | 700 | return; |
597 | 701 | ||
598 | DateTime signalTime = DateTime.UtcNow; | 702 | DateTime now = DateTime.UtcNow; |
599 | 703 | ||
600 | try | 704 | try |
601 | { | 705 | { |
@@ -604,32 +708,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
604 | return; | 708 | return; |
605 | try | 709 | try |
606 | { | 710 | { |
607 | List<RegionKey> expiredkeys = new List<RegionKey>(); | 711 | List<UUID> expiredscopes = new List<UUID>(); |
608 | 712 | ||
609 | foreach (KeyValuePair<RegionKey, DateTime> kvp in timedExpires) | 713 | foreach (KeyValuePair<UUID, RegionInfoForScope> kvp in InfobyScope) |
610 | { | 714 | { |
611 | if (kvp.Value < signalTime) | 715 | if (kvp.Value.expire(now) == 0) |
612 | expiredkeys.Add(kvp.Key); | 716 | expiredscopes.Add(kvp.Key); |
613 | } | 717 | } |
614 | 718 | ||
615 | if (expiredkeys.Count > 0) | 719 | if (expiredscopes.Count > 0) |
616 | { | 720 | { |
617 | RegionInfoByScope ris; | 721 | foreach (UUID sid in expiredscopes) |
618 | foreach (RegionKey key in expiredkeys) | 722 | InfobyScope.Remove(sid); |
619 | { | ||
620 | ris = null; | ||
621 | if(InfobyScope.TryGetValue(key.ScopeID, out ris) && ris != null) | ||
622 | { | ||
623 | GridRegion r = timedStorage[key]; | ||
624 | if(r != null) | ||
625 | ris.RemoveRegion(r); | ||
626 | |||
627 | if(ris.Count() == 0) | ||
628 | InfobyScope.Remove(key.ScopeID); | ||
629 | } | ||
630 | timedStorage.Remove(key); | ||
631 | timedExpires.Remove(key); | ||
632 | } | ||
633 | } | 723 | } |
634 | } | 724 | } |
635 | finally { Monitor.Exit(syncRoot); } | 725 | finally { Monitor.Exit(syncRoot); } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index 96ff4b3..e6e3abb 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs | |||
@@ -204,8 +204,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
204 | GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); | 204 | GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); |
205 | if (rinfo != null) | 205 | if (rinfo != null) |
206 | { | 206 | { |
207 | m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache from local. Pos=<{1},{2}>, RegionHandle={3}", | 207 | // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Found region {0} on local. Pos=<{1},{2}>, RegionHandle={3}", |
208 | rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); | 208 | // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); |
209 | return rinfo; | 209 | return rinfo; |
210 | } | 210 | } |
211 | 211 | ||
@@ -213,16 +213,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
213 | 213 | ||
214 | if (rinfo == null) | 214 | if (rinfo == null) |
215 | { | 215 | { |
216 | uint regionX = Util.WorldToRegionLoc((uint)x); | 216 | // uint regionX = Util.WorldToRegionLoc((uint)x); |
217 | uint regionY = Util.WorldToRegionLoc((uint)y); | 217 | // uint regionY = Util.WorldToRegionLoc((uint)y); |
218 | m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY); | 218 | // m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY); |
219 | } | 219 | } |
220 | else | 220 | else |
221 | { | 221 | { |
222 | m_RegionInfoCache.Cache(scopeID, rinfo); | 222 | m_RegionInfoCache.Cache(scopeID, rinfo); |
223 | 223 | ||
224 | m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", | 224 | // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", |
225 | rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); | 225 | // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); |
226 | } | 226 | } |
227 | return rinfo; | 227 | return rinfo; |
228 | } | 228 | } |