From b48885ece4518c201bf0b8c27c1abb5c86b8167b Mon Sep 17 00:00:00 2001 From: Homer Horwitz Date: Sat, 11 Oct 2008 22:42:59 +0000 Subject: [PATCH] The "About Landmark" code with the fake parcelIDs had a serious bug. - Fix that bug. It will work with OSSearch now, too - Add some caching to reduce inter-region requests. --- .../World/Land/LandManagementModule.cs | 65 +++++++++++++++---- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs index 0245a9e8c4..0ecfdd3a6c 100644 --- a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs @@ -42,6 +42,13 @@ using Caps = OpenSim.Framework.Communications.Capabilities.Caps; namespace OpenSim.Region.Environment.Modules.World.Land { + // used for caching + internal class ExtendedLandData { + public LandData landData; + public ulong regionHandle; + public uint x, y; + } + public class LandManagementModule : IRegionModule { private static readonly ILog m_log = @@ -60,6 +67,9 @@ namespace OpenSim.Region.Environment.Modules.World.Land private bool m_allowedForcefulBans = true; + // caches ExtendedLandData + private Cache parcelInfoCache; + #region IRegionModule Members public void Initialise(Scene scene, IConfigSource source) @@ -68,6 +78,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land landIDList.Initialize(); landChannel = new LandChannel(scene, this); + parcelInfoCache = new Cache(); + parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache + parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0); + m_scene.EventManager.OnParcelPrimCountAdd += AddPrimToLandPrimCounts; m_scene.EventManager.OnParcelPrimCountUpdate += UpdateLandPrimCounts; m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(handleAvatarChangingParcel); @@ -1173,23 +1187,48 @@ namespace OpenSim.Region.Environment.Modules.World.Land if (parcelID == UUID.Zero) return; - // assume we've got the parcelID we just computed in RemoteParcelRequest - ulong regionHandle; - uint x, y; - Util.ParseFakeParcelID(parcelID, out regionHandle, out x, out y); - m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}", regionHandle, x, y); + ExtendedLandData data = (ExtendedLandData)parcelInfoCache.Get(parcelID, delegate(UUID parcel) { + // assume we've got the parcelID we just computed in RemoteParcelRequest + ExtendedLandData extLandData = new ExtendedLandData(); + Util.ParseFakeParcelID(parcel, out extLandData.regionHandle, out extLandData.x, out extLandData.y); + m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}", + extLandData.regionHandle, extLandData.x, extLandData.y); - LandData landData; - if (regionHandle == m_scene.RegionInfo.RegionHandle) - landData = this.GetLandObject(x, y).landData; - else - landData = m_scene.CommsManager.GridService.RequestLandData(regionHandle, x, y); + // for this region or for somewhere else? + if (extLandData.regionHandle == m_scene.RegionInfo.RegionHandle) + { + extLandData.landData = this.GetLandObject(extLandData.x, extLandData.y).landData; + } + else + { + extLandData.landData = m_scene.CommsManager.GridService.RequestLandData(extLandData.regionHandle, + extLandData.x, + extLandData.y); + if (extLandData.landData == null) + { + // we didn't find the region/land => don't cache + return null; + } + } + return extLandData; + }); - if (landData != null) + if (data != null) // if we found some data, send it { + RegionInfo info; + if (data.regionHandle == m_scene.RegionInfo.RegionHandle) + { + info = m_scene.RegionInfo; + } + else + { + // most likely still cached from building the extLandData entry + info = m_scene.CommsManager.GridService.RequestNeighbourInfo(data.regionHandle); + } // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. - m_log.Debug("[LAND] got parcelinfo; sending"); - remoteClient.SendParcelInfo(m_scene.RegionInfo, landData, parcelID, x, y); + m_log.DebugFormat("[LAND] got parcelinfo for parcel {0} in region {1}; sending...", + data.landData.Name, data.regionHandle); + remoteClient.SendParcelInfo(info, data.landData, parcelID, data.x, data.y); } else m_log.Debug("[LAND] got no parcelinfo; not sending");