From bf593dd6f4d1939b66335aa9ca5c006be2a751bb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 30 Jul 2016 17:14:17 +0100 Subject: fix RegionInfoCache keys compare, remove RegionCache now replaced by RegionInfoCache --- .../Grid/LocalGridServiceConnector.cs | 30 +++--- .../ServiceConnectorsOut/Grid/RegionCache.cs | 103 --------------------- .../ServiceConnectorsOut/Grid/RegionInfoCache.cs | 71 ++++++++++---- 3 files changed, 70 insertions(+), 134 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 3e03a5e..58bd4ea 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -51,7 +51,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]"; private IGridService m_GridService; - private Dictionary m_LocalCache = new Dictionary(); private RegionInfoCache m_RegionInfoCache = null; private bool m_Enabled; @@ -151,13 +150,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid scene.RegisterModuleInterface(this); - lock (m_LocalCache) - { - if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) - m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); - else - m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); - } + m_RegionInfoCache.CacheLocal(new GridRegion(scene.RegionInfo)); + scene.EventManager.OnRegionUp += OnRegionUp; } public void RemoveRegion(Scene scene) @@ -165,11 +159,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (!m_Enabled) return; - lock (m_LocalCache) - { - m_LocalCache[scene.RegionInfo.RegionID].Clear(); - m_LocalCache.Remove(scene.RegionInfo.RegionID); - } + m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionID); + scene.EventManager.OnRegionUp -= OnRegionUp; } public void RegionLoaded(Scene scene) @@ -180,6 +171,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid #region IGridService + private void OnRegionUp(GridRegion region) + { + // This shouldn't happen + if (region == null) + return; + + m_RegionInfoCache.CacheNearNeighbour(region.ScopeID, region); + } + public string RegisterRegion(UUID scopeID, GridRegion regionInfo) { return m_GridService.RegisterRegion(scopeID, regionInfo); @@ -291,7 +291,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public void HandleShowNeighboursCommand(string module, string[] cmdparams) { System.Text.StringBuilder caps = new System.Text.StringBuilder(); - +/* temporary broken lock (m_LocalCache) { foreach (KeyValuePair kvp in m_LocalCache) @@ -304,6 +304,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid } MainConsole.Instance.Output(caps.ToString()); +*/ + MainConsole.Instance.Output("Neighbours list not avaiable in this version\n"); } } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs deleted file mode 100644 index 2961c10..0000000 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -using OpenMetaverse; -using log4net; - -namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid -{ - public class RegionCache - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private Scene m_scene; - private Dictionary m_neighbours = new Dictionary(); - - public string RegionName - { - get { return m_scene.RegionInfo.RegionName; } - } - - public RegionCache(Scene s) - { - m_scene = s; - m_scene.EventManager.OnRegionUp += OnRegionUp; - } - - private void OnRegionUp(GridRegion otherRegion) - { - // This shouldn't happen - if (otherRegion == null) - return; - - m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}", - m_scene.RegionInfo.RegionName, otherRegion.RegionName, Util.WorldToRegionLoc((uint)otherRegion.RegionLocX), Util.WorldToRegionLoc((uint)otherRegion.RegionLocY)); - - m_neighbours[otherRegion.RegionHandle] = otherRegion; - } - - public void Clear() - { - m_scene.EventManager.OnRegionUp -= OnRegionUp; - m_neighbours.Clear(); - } - - public List GetNeighbours() - { - return new List(m_neighbours.Values); - } - - public GridRegion GetRegionByPosition(int x, int y) - { - // do actual search by position - // not the best, but this will not hold that many regions - GridRegion foundRegion = null; - foreach(GridRegion r in m_neighbours.Values) - { - if (x >= r.RegionLocX && x < r.RegionLocX + r.RegionSizeX - && y >= r.RegionLocY && y < r.RegionLocY + r.RegionSizeY) - { - foundRegion = r; - break; - } - } - - return foundRegion; - } - } -} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index ffe3fab..8736402 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs @@ -59,26 +59,42 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public void Cache(UUID scopeID, GridRegion rinfo) { - // for now, do not cache negative results; this is because - // we need to figure out how to handle regions coming online - // in a timely way if (rinfo == null) return; m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); } + public void CacheLocal(GridRegion rinfo) + { + if (rinfo == null) + return; + + m_Cache.AddOrUpdate(rinfo.ScopeID, rinfo, 1e7f); + } + + public void CacheNearNeighbour(UUID scopeID, GridRegion rinfo) + { + if (rinfo == null) + return; + +// m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); + m_Cache.Add(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); // don't override local regions + } + public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds) { - // for now, do not cache negative results; this is because - // we need to figure out how to handle regions coming online - // in a timely way if (rinfo == null) return; m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds); } + public void Remove(UUID scopeID, UUID regionID) + { + m_Cache.Remove(scopeID, regionID); + } + public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) { inCache = false; @@ -134,15 +150,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return null; } - } // following code partialy adapted from lib OpenMetaverse - public class RegionKey : IComparable + public class RegionKey { - private UUID m_scopeID; - private UUID m_RegionID; + public UUID m_scopeID; + public UUID m_RegionID; private DateTime m_expirationDate; public RegionKey(UUID scopeID, UUID id) @@ -161,16 +176,34 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid set { m_expirationDate = value; } } - public int GetHaskCode() + public override int GetHashCode() { int hash = m_scopeID.GetHashCode(); hash += hash * 23 + m_RegionID.GetHashCode(); return hash; } - public int CompareTo(RegionKey other) + public override bool Equals(Object b) + { + if(b == null) + return false; + RegionKey kb = b as RegionKey; + return (m_scopeID == kb.m_scopeID && m_RegionID == kb.m_RegionID); + } + } + + class RegionKeyEqual : EqualityComparer + { + public override int GetHashCode(RegionKey rk) + { + int hash = rk.m_scopeID.GetHashCode(); + hash += hash * 23 + rk.m_RegionID.GetHashCode(); + return hash; + } + + public override bool Equals(RegionKey a, RegionKey b) { - return GetHashCode().CompareTo(other.GetHashCode()); + return (a.m_scopeID == b.m_scopeID && a.m_RegionID == b.m_RegionID); } } @@ -246,7 +279,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid } } - public sealed class RegionsExpiringCache + public class RegionsExpiringCache { const double CACHE_PURGE_HZ = 60; // seconds const int MAX_LOCK_WAIT = 10000; // milliseconds @@ -256,7 +289,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid /// For thread safety object isPurging = new object(); - Dictionary timedStorage = new Dictionary(); + static RegionKeyEqual keyequal = new RegionKeyEqual(); + Dictionary timedStorage = new Dictionary(keyequal); Dictionary InfobyScope = new Dictionary(); private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); @@ -370,10 +404,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return timedStorage.Count; } } - public bool Remove(UUID scope, GridRegion region) { - RegionKey key = new RegionKey(scope, region.RegionID); + return Remove(scope, region.RegionID); + } + public bool Remove(UUID scope, UUID regionID) + { + RegionKey key = new RegionKey(scope, regionID); if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); -- cgit v1.1