diff options
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs | 227 |
1 files changed, 224 insertions, 3 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index 6db9515..37fa441 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | using System; | 27 | using System; |
28 | using System.Reflection; | 28 | using System.Reflection; |
29 | using System.Threading; | 29 | using System.Threading; |
30 | using System.Runtime.InteropServices; | ||
30 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
31 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
32 | using OpenSim.Services.Interfaces; | 33 | using OpenSim.Services.Interfaces; |
@@ -159,6 +160,136 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
159 | } | 160 | } |
160 | } | 161 | } |
161 | 162 | ||
163 | // dont care about endianess | ||
164 | [StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)] | ||
165 | public class fastRegionHandle | ||
166 | { | ||
167 | [FieldOffset(0)] public ulong handle; | ||
168 | [FieldOffset(0)] public uint y; | ||
169 | [FieldOffset(4)] public uint x; | ||
170 | |||
171 | public fastRegionHandle(ulong h) | ||
172 | { | ||
173 | handle = h; | ||
174 | } | ||
175 | |||
176 | public fastRegionHandle(uint px, uint py) | ||
177 | { | ||
178 | y = py & 0xffffff00; | ||
179 | x = px & 0xffffff00; | ||
180 | } | ||
181 | // actually do care | ||
182 | public ulong toHandle() | ||
183 | { | ||
184 | if(BitConverter.IsLittleEndian) | ||
185 | return handle; | ||
186 | return (ulong) x << 32 | (ulong)y ; | ||
187 | } | ||
188 | |||
189 | public static bool operator ==(fastRegionHandle value1, fastRegionHandle value2) | ||
190 | { | ||
191 | return value1.handle == value2.handle; | ||
192 | } | ||
193 | public static bool operator !=(fastRegionHandle value1, fastRegionHandle value2) | ||
194 | { | ||
195 | return value1.handle != value2.handle; | ||
196 | } | ||
197 | public override int GetHashCode() | ||
198 | { | ||
199 | return handle.GetHashCode(); | ||
200 | } | ||
201 | public override bool Equals(Object obj) | ||
202 | { | ||
203 | if(obj == null) | ||
204 | return false; | ||
205 | fastRegionHandle p = obj as fastRegionHandle; | ||
206 | return p.handle == handle; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | [StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)] | ||
212 | public class regionHandle | ||
213 | { | ||
214 | [FieldOffset(0)] private ulong handle; | ||
215 | [FieldOffset(0)] public uint a; | ||
216 | [FieldOffset(4)] public uint b; | ||
217 | |||
218 | public regionHandle(ulong h) | ||
219 | { | ||
220 | handle = h; | ||
221 | } | ||
222 | |||
223 | public regionHandle(uint px, uint py) | ||
224 | { | ||
225 | if(BitConverter.IsLittleEndian) | ||
226 | { | ||
227 | a = py & 0xffffff00; | ||
228 | b = px & 0xffffff00; | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | a = px & 0xffffff00; | ||
233 | b = py & 0xffffff00; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | public uint x | ||
238 | { | ||
239 | get | ||
240 | { | ||
241 | if(BitConverter.IsLittleEndian) | ||
242 | return b; | ||
243 | return a; | ||
244 | } | ||
245 | set | ||
246 | { | ||
247 | if(BitConverter.IsLittleEndian) | ||
248 | b = value & 0xffffff00; | ||
249 | else | ||
250 | a = value & 0xffffff00; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | public uint y | ||
255 | { | ||
256 | get | ||
257 | { | ||
258 | if(BitConverter.IsLittleEndian) | ||
259 | return a; | ||
260 | return b; | ||
261 | } | ||
262 | set | ||
263 | { | ||
264 | if(BitConverter.IsLittleEndian) | ||
265 | a = value; | ||
266 | else | ||
267 | b = value; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | public static bool operator ==(regionHandle value1, regionHandle value2) | ||
272 | { | ||
273 | return value1.handle == value2.handle; | ||
274 | } | ||
275 | public static bool operator !=(regionHandle value1, regionHandle value2) | ||
276 | { | ||
277 | return value1.handle != value2.handle; | ||
278 | } | ||
279 | public override int GetHashCode() | ||
280 | { | ||
281 | return handle.GetHashCode(); | ||
282 | } | ||
283 | public override bool Equals(Object obj) | ||
284 | { | ||
285 | if(obj == null) | ||
286 | return false; | ||
287 | regionHandle p = obj as regionHandle; | ||
288 | return p.handle == handle; | ||
289 | } | ||
290 | } | ||
291 | */ | ||
292 | |||
162 | public class RegionInfoForScope | 293 | public class RegionInfoForScope |
163 | { | 294 | { |
164 | public const ulong HANDLEMASH = 0xffffff00ffffff00ul; | 295 | public const ulong HANDLEMASH = 0xffffff00ffffff00ul; |
@@ -168,6 +299,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
168 | private Dictionary<ulong, DateTime> expires; | 299 | private Dictionary<ulong, DateTime> expires; |
169 | private Dictionary<string, ulong> byname; | 300 | private Dictionary<string, ulong> byname; |
170 | private Dictionary<UUID, ulong> byuuid; | 301 | private Dictionary<UUID, ulong> byuuid; |
302 | // includes handles to the inside of large regions | ||
303 | private Dictionary<ulong, ulong> innerHandles = new Dictionary<ulong, ulong>(); | ||
171 | 304 | ||
172 | public RegionInfoForScope() | 305 | public RegionInfoForScope() |
173 | { | 306 | { |
@@ -189,6 +322,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
189 | expires[handle] = expire; | 322 | expires[handle] = expire; |
190 | byname[region.RegionName] = handle; | 323 | byname[region.RegionName] = handle; |
191 | byuuid[region.RegionID] = handle; | 324 | byuuid[region.RegionID] = handle; |
325 | addToInner(region); | ||
192 | } | 326 | } |
193 | 327 | ||
194 | public void Add(GridRegion region, DateTime expire) | 328 | public void Add(GridRegion region, DateTime expire) |
@@ -211,6 +345,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
211 | expires[handle] = expire; | 345 | expires[handle] = expire; |
212 | byname[region.RegionName] = handle; | 346 | byname[region.RegionName] = handle; |
213 | byuuid[region.RegionID] = handle; | 347 | byuuid[region.RegionID] = handle; |
348 | |||
349 | addToInner(region); | ||
214 | } | 350 | } |
215 | 351 | ||
216 | public void AddUpdate(GridRegion region, DateTime expire) | 352 | public void AddUpdate(GridRegion region, DateTime expire) |
@@ -226,16 +362,30 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
226 | 362 | ||
227 | ulong handle = region.RegionHandle & HANDLEMASH; | 363 | ulong handle = region.RegionHandle & HANDLEMASH; |
228 | 364 | ||
229 | storage[handle] = region; | ||
230 | if(expires.ContainsKey(handle)) | 365 | if(expires.ContainsKey(handle)) |
231 | { | 366 | { |
232 | if(expires[handle] < expire) | 367 | if(expires[handle] < expire) |
233 | expires[handle] = expire; | 368 | expires[handle] = expire; |
369 | if(storage.ContainsKey(handle)) | ||
370 | { | ||
371 | GridRegion oldr = storage[handle]; | ||
372 | if (oldr.RegionSizeX != region.RegionSizeX | ||
373 | || oldr.RegionSizeY != region.RegionSizeY) | ||
374 | { | ||
375 | removeFromInner(oldr); | ||
376 | addToInner(region); | ||
377 | } | ||
378 | } | ||
234 | } | 379 | } |
235 | else | 380 | else |
236 | expires[handle] = expire; | 381 | { |
382 | expires[handle] = expire; | ||
383 | addToInner(region); | ||
384 | } | ||
385 | storage[handle] = region; | ||
237 | byname[region.RegionName] = handle; | 386 | byname[region.RegionName] = handle; |
238 | byuuid[region.RegionID] = handle; | 387 | byuuid[region.RegionID] = handle; |
388 | |||
239 | } | 389 | } |
240 | 390 | ||
241 | public void Remove(GridRegion region) | 391 | public void Remove(GridRegion region) |
@@ -272,6 +422,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
272 | byname.Remove(r.RegionName); | 422 | byname.Remove(r.RegionName); |
273 | if(byuuid != null) | 423 | if(byuuid != null) |
274 | byuuid.Remove(r.RegionID); | 424 | byuuid.Remove(r.RegionID); |
425 | removeFromInner(r); | ||
275 | } | 426 | } |
276 | storage.Remove(handle); | 427 | storage.Remove(handle); |
277 | } | 428 | } |
@@ -297,6 +448,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
297 | byuuid = null; | 448 | byuuid = null; |
298 | storage = null; | 449 | storage = null; |
299 | expires = null; | 450 | expires = null; |
451 | innerHandles.Clear(); | ||
300 | } | 452 | } |
301 | 453 | ||
302 | public bool Contains(GridRegion region) | 454 | public bool Contains(GridRegion region) |
@@ -365,7 +517,34 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
365 | 517 | ||
366 | if(storage.ContainsKey(handle)) | 518 | if(storage.ContainsKey(handle)) |
367 | return storage[handle]; | 519 | return storage[handle]; |
368 | 520 | ||
521 | if(!innerHandles.ContainsKey(handle)) | ||
522 | return null; | ||
523 | |||
524 | ulong rhandle = innerHandles[handle]; | ||
525 | if(!storage.ContainsKey(rhandle)) | ||
526 | return null; | ||
527 | |||
528 | GridRegion r = storage[rhandle]; | ||
529 | if(r == null) | ||
530 | return null; | ||
531 | |||
532 | // extra check, possible redundant | ||
533 | |||
534 | int test = r.RegionLocX; | ||
535 | if(x < test) | ||
536 | return null; | ||
537 | test += r.RegionSizeX; | ||
538 | if(x >= test) | ||
539 | return null; | ||
540 | test = r.RegionLocY; | ||
541 | if (y < test) | ||
542 | return null; | ||
543 | test += r.RegionSizeY; | ||
544 | if (y < test) | ||
545 | return r; | ||
546 | |||
547 | /* | ||
369 | // next do the harder work | 548 | // next do the harder work |
370 | foreach(KeyValuePair<ulong, GridRegion> kvp in storage) | 549 | foreach(KeyValuePair<ulong, GridRegion> kvp in storage) |
371 | { | 550 | { |
@@ -386,6 +565,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
386 | if (y < test) | 565 | if (y < test) |
387 | return r; | 566 | return r; |
388 | } | 567 | } |
568 | */ | ||
389 | return null; | 569 | return null; |
390 | } | 570 | } |
391 | 571 | ||
@@ -421,6 +601,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
421 | byname.Remove(r.RegionName); | 601 | byname.Remove(r.RegionName); |
422 | if(byuuid != null) | 602 | if(byuuid != null) |
423 | byuuid.Remove(r.RegionID); | 603 | byuuid.Remove(r.RegionID); |
604 | removeFromInner(r); | ||
424 | } | 605 | } |
425 | storage.Remove(h); | 606 | storage.Remove(h); |
426 | } | 607 | } |
@@ -447,6 +628,46 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
447 | else | 628 | else |
448 | return byname.Count; | 629 | return byname.Count; |
449 | } | 630 | } |
631 | |||
632 | private void addToInner(GridRegion region) | ||
633 | { | ||
634 | int rsx = region.RegionSizeX >> 8; | ||
635 | int rsy = region.RegionSizeY >> 8; | ||
636 | ulong handle = region.RegionHandle & HANDLEMASH; | ||
637 | fastRegionHandle fh = new fastRegionHandle(handle); | ||
638 | uint startY = fh.y; | ||
639 | for(int i = 0; i < rsx; i++) | ||
640 | { | ||
641 | for(int j = 0; j < rsy ; j++) | ||
642 | { | ||
643 | innerHandles[fh.toHandle()] = handle; | ||
644 | fh.y += 256; | ||
645 | } | ||
646 | |||
647 | fh.y = startY; | ||
648 | fh.x += 256; | ||
649 | } | ||
650 | } | ||
651 | |||
652 | private void removeFromInner(GridRegion region) | ||
653 | { | ||
654 | int rsx = region.RegionSizeX >> 8; | ||
655 | int rsy = region.RegionSizeY >> 8; | ||
656 | ulong handle = region.RegionHandle & HANDLEMASH; | ||
657 | fastRegionHandle fh = new fastRegionHandle(handle); | ||
658 | uint startY = fh.y; | ||
659 | for(int i = 0; i < rsx; i++) | ||
660 | { | ||
661 | for(int j = 0; j < rsy ; j++) | ||
662 | { | ||
663 | innerHandles.Remove(fh.toHandle()); | ||
664 | fh.y += 256; | ||
665 | } | ||
666 | |||
667 | fh.y = startY; | ||
668 | fh.x += 256; | ||
669 | } | ||
670 | } | ||
450 | } | 671 | } |
451 | 672 | ||
452 | public class RegionsExpiringCache | 673 | public class RegionsExpiringCache |