From 79b7787efff4362761ee131426de01fe823d6946 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 30 Jul 2016 14:35:43 +0100 Subject: let LocalGridServiceConnector also have a RegionInfoCache, use the remote one if this is active. --- .../Grid/LocalGridServiceConnector.cs | 95 +++++++++++----------- .../Grid/RemoteGridServiceConnector.cs | 80 ++++++++---------- .../Grid/Tests/GridConnectorsTests.cs | 2 +- 3 files changed, 83 insertions(+), 94 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index e585c25..3e03a5e 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid private IGridService m_GridService; private Dictionary m_LocalCache = new Dictionary(); + private RegionInfoCache m_RegionInfoCache = null; private bool m_Enabled; @@ -60,10 +61,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid m_log.DebugFormat("{0} LocalGridServicesConnector no parms.", LogHeader); } - public LocalGridServicesConnector(IConfigSource source) + public LocalGridServicesConnector(IConfigSource source, RegionInfoCache regionInfoCache) { m_log.DebugFormat("{0} LocalGridServicesConnector instantiated directly.", LogHeader); - InitialiseService(source); + InitialiseService(source, regionInfoCache); } #region ISharedRegionModule @@ -86,19 +87,25 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid string name = moduleConfig.GetString("GridServices", ""); if (name == Name) { - InitialiseService(source); - m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); + + if(InitialiseService(source,null)) + m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); } } } - private void InitialiseService(IConfigSource source) + private bool InitialiseService(IConfigSource source, RegionInfoCache ric) { + if(ric == null) + m_RegionInfoCache = new RegionInfoCache(); + else + m_RegionInfoCache = ric; + IConfig config = source.Configs["GridService"]; if (config == null) { m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini"); - return; + return false; } string serviceDll = config.GetString("LocalServiceModule", String.Empty); @@ -106,7 +113,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (serviceDll == String.Empty) { m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService"); - return; + return false; } Object[] args = new Object[] { source }; @@ -117,10 +124,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (m_GridService == null) { m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service"); - return; + return false; } m_Enabled = true; + return true; } public void PostInitialise() @@ -189,7 +197,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) { - return m_GridService.GetRegionByUUID(scopeID, regionID); + bool inCache = false; + GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache); + if (inCache) + return rinfo; + + rinfo = m_GridService.GetRegionByUUID(scopeID, regionID); + if(rinfo != null) + m_RegionInfoCache.Cache(scopeID, rinfo); + return rinfo; } // Get a region given its base coordinates. @@ -197,52 +213,37 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid // be the base coordinate of the region. public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) { - GridRegion region = null; - uint regionX = Util.WorldToRegionLoc((uint)x); - uint regionY = Util.WorldToRegionLoc((uint)y); + // try in cache by handler first + ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); - // First see if it's a neighbour, even if it isn't on this sim. - // Neighbour data is cached in memory, so this is fast + bool inCache = false; + GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); + if (inCache) + return rinfo; - lock (m_LocalCache) - { - foreach (RegionCache rcache in m_LocalCache.Values) - { - region = rcache.GetRegionByPosition(x, y); - if (region != null) - { - //m_log.DebugFormat("{0} GetRegionByPosition. Found region {1} in cache (of region {2}). Pos=<{3},{4}>", - // LogHeader, region.RegionName, rcache.RegionName, - // Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY)); - break; - } - } - } + // try in cache by slower position next + rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache); + if (inCache) + return rinfo; // Then try on this sim (may be a lookup in DB if this is using MySql). - if (region == null) - { - region = m_GridService.GetRegionByPosition(scopeID, x, y); - - if (region == null) - { - m_log.DebugFormat("{0} GetRegionByPosition. Region not found by grid service. Pos=<{1},{2}>", - LogHeader, regionX, regionY); - } - else - { - m_log.DebugFormat("{0} GetRegionByPosition. Got region {1} from grid service. Pos=<{2},{3}>", - LogHeader, region.RegionName, - Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY)); - } - } - - return region; + rinfo = m_GridService.GetRegionByPosition(scopeID, x, y); + if(rinfo != null) + m_RegionInfoCache.Cache(scopeID, rinfo); + return rinfo; } public GridRegion GetRegionByName(UUID scopeID, string regionName) { - return m_GridService.GetRegionByName(scopeID, regionName); + bool inCache = false; + GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionName, out inCache); + if (inCache) + return rinfo; + + rinfo = m_GridService.GetRegionByName(scopeID, regionName); + if(rinfo != null) + m_RegionInfoCache.Cache(scopeID, rinfo); + return rinfo; } public List GetRegionsByName(UUID scopeID, string name, int maxNumber) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index 6575cfd..363adde 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs @@ -87,39 +87,47 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid string name = moduleConfig.GetString("GridServices", ""); if (name == Name) { - InitialiseServices(source); - m_Enabled = true; - m_log.Info("[REMOTE GRID CONNECTOR]: Remote grid enabled"); + if(InitialiseServices(source)) + { + m_Enabled = true; + m_log.Info("[REMOTE GRID CONNECTOR]: Remote grid enabled"); + } } } } - private void InitialiseServices(IConfigSource source) + private bool InitialiseServices(IConfigSource source) { IConfig gridConfig = source.Configs["GridService"]; if (gridConfig == null) { m_log.Error("[REMOTE GRID CONNECTOR]: GridService missing from OpenSim.ini"); - return; + return false; } string networkConnector = gridConfig.GetString("NetworkConnector", string.Empty); if (networkConnector == string.Empty) { m_log.Error("[REMOTE GRID CONNECTOR]: Please specify a network connector under [GridService]"); - return; + return false; } Object[] args = new Object[] { source }; m_RemoteGridService = ServerUtils.LoadPlugin(networkConnector, args); - m_LocalGridService = new LocalGridServicesConnector(source); + m_LocalGridService = new LocalGridServicesConnector(source, m_RegionInfoCache); + if (m_LocalGridService == null) + { + m_log.Error("[REMOTE GRID CONNECTOR]: failed to loar local connector"); + return false; + } + + return true; } public void PostInitialise() { - if (m_LocalGridService != null) - ((ISharedRegionModule)m_LocalGridService).PostInitialise(); + ((ISharedRegionModule)m_LocalGridService).PostInitialise(); } public void Close() @@ -131,14 +139,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (m_Enabled) scene.RegisterModuleInterface(this); - if (m_LocalGridService != null) - ((ISharedRegionModule)m_LocalGridService).AddRegion(scene); + ((ISharedRegionModule)m_LocalGridService).AddRegion(scene); } public void RemoveRegion(Scene scene) { - if (m_LocalGridService != null) - ((ISharedRegionModule)m_LocalGridService).RemoveRegion(scene); + ((ISharedRegionModule)m_LocalGridService).RemoveRegion(scene); } public void RegionLoaded(Scene scene) @@ -174,15 +180,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) { - bool inCache = false; - GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache); - if (inCache) + GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); + if (rinfo != null) return rinfo; - - rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); - if (rinfo == null) - rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); + rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); m_RegionInfoCache.Cache(scopeID, rinfo); return rinfo; } @@ -193,24 +195,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid // The coordinates are world coords (meters), NOT region units. public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) { - // try in cache by handler first - ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); - - bool inCache = false; - GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); - if (inCache) - return rinfo; - - // try in cache by slower position next - rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache); - if (inCache) + GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); + if (rinfo != null) + { + m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache from local. Pos=<{1},{2}>, RegionHandle={3}", + rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); return rinfo; + } - rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); - if (rinfo == null) - rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y); - - + rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y); if (rinfo == null) { @@ -223,23 +216,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid m_RegionInfoCache.Cache(scopeID, rinfo); m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", - rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, (rinfo == null) ? regionHandle : rinfo.RegionHandle); + rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); } return rinfo; } public GridRegion GetRegionByName(UUID scopeID, string regionName) { - bool inCache = false; - GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionName, out inCache); - if (inCache) + GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); + if (rinfo != null) return rinfo; - - rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); - if (rinfo == null) - rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); - - // can't cache negative results for name lookups + + rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); m_RegionInfoCache.Cache(scopeID, rinfo); return rinfo; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs index c33f7f5..044e0e5 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion"); config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion"); - m_LocalConnector = new LocalGridServicesConnector(config); + m_LocalConnector = new LocalGridServicesConnector(config, null); } /// -- cgit v1.1 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/Region/CoreModules') 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 From e62f8fd09eb3798f2ee9eb34e30b8890e81d94c3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 30 Jul 2016 20:08:14 +0100 Subject: change RegionInfoCache expires control --- .../ServiceConnectorsOut/Grid/RegionInfoCache.cs | 84 ++++++++++------------ 1 file changed, 36 insertions(+), 48 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index 8736402..8f3dfc1 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs @@ -156,30 +156,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid // following code partialy adapted from lib OpenMetaverse public class RegionKey { - public UUID m_scopeID; - public UUID m_RegionID; - private DateTime m_expirationDate; + public UUID ScopeID; + public UUID RegionID; public RegionKey(UUID scopeID, UUID id) { - m_scopeID = scopeID; - m_RegionID = id; + ScopeID = scopeID; + RegionID = id; } - - public UUID ScopeID - { - get { return m_scopeID; } - } - public DateTime ExpirationDate - { - get { return m_expirationDate; } - set { m_expirationDate = value; } - } - + public override int GetHashCode() { - int hash = m_scopeID.GetHashCode(); - hash += hash * 23 + m_RegionID.GetHashCode(); + int hash = ScopeID.GetHashCode(); + hash += hash * 23 + RegionID.GetHashCode(); return hash; } @@ -188,7 +177,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(b == null) return false; RegionKey kb = b as RegionKey; - return (m_scopeID == kb.m_scopeID && m_RegionID == kb.m_RegionID); + return (ScopeID == kb.ScopeID && RegionID == kb.RegionID); } } @@ -196,14 +185,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { public override int GetHashCode(RegionKey rk) { - int hash = rk.m_scopeID.GetHashCode(); - hash += hash * 23 + rk.m_RegionID.GetHashCode(); - return hash; + return rk.GetHashCode(); } public override bool Equals(RegionKey a, RegionKey b) { - return (a.m_scopeID == b.m_scopeID && a.m_RegionID == b.m_RegionID); + return (a.ScopeID == b.ScopeID && a.RegionID == b.RegionID); } } @@ -291,6 +278,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid static RegionKeyEqual keyequal = new RegionKeyEqual(); Dictionary timedStorage = new Dictionary(keyequal); + Dictionary timedExpires = new Dictionary(); Dictionary InfobyScope = new Dictionary(); private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); @@ -312,8 +300,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (timedStorage.ContainsKey(key)) return false; - key.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); - timedStorage.Add(key, region); + DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); + timedStorage[key] = region; + timedExpires[key] = expire; RegionInfoByScope ris = null; if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) @@ -337,12 +326,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid try { RegionKey key = new RegionKey(scope, region.RegionID); - key.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); + DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); if (timedStorage.ContainsKey(key)) { - timedStorage.Remove(key); - timedStorage.Add(key, region); + timedStorage[key] = region; + if(expire > timedExpires[key]) + timedExpires[key] = expire; if(!InfobyScope.ContainsKey(scope)) { @@ -353,7 +343,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid } else { - timedStorage.Add(key, region); + timedStorage[key] = region; + timedExpires[key] = expire; RegionInfoByScope ris = null; if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) { @@ -375,6 +366,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid try { timedStorage.Clear(); + timedExpires.Clear(); InfobyScope.Clear(); } finally { Monitor.Exit(syncRoot); } @@ -428,6 +420,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid InfobyScope.Remove(scope); } timedStorage.Remove(key); + timedExpires.Remove(key); return true; } else @@ -581,9 +574,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (!timedStorage.ContainsKey(key)) return false; - timedStorage.Remove(key); - key.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); - timedStorage.Add(key, region); + DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); + timedStorage[key] = region; + if(expire > timedExpires[key]) + timedExpires[key] = expire; + return true; } finally { Monitor.Exit(syncRoot); } @@ -609,26 +604,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return; try { - OpenMetaverse.Lazy> expiredItems = new OpenMetaverse.Lazy>(); + List expiredkeys = new List(); - foreach (RegionKey timedKey in timedStorage.Keys) + foreach (KeyValuePair kvp in timedExpires) { - if (timedKey.ExpirationDate < signalTime) - { - // Mark the object for purge - expiredItems.Value.Add(timedKey); - } - else - { - break; - } + if (kvp.Value < signalTime) + expiredkeys.Add(kvp.Key); } - - - RegionInfoByScope ris; - if (expiredItems.IsValueCreated) + + if (expiredkeys.Count > 0) { - foreach (RegionKey key in expiredItems.Value) + RegionInfoByScope ris; + foreach (RegionKey key in expiredkeys) { ris = null; if(InfobyScope.TryGetValue(key.ScopeID, out ris) && ris != null) @@ -641,6 +628,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid InfobyScope.Remove(key.ScopeID); } timedStorage.Remove(key); + timedExpires.Remove(key); } } } -- cgit v1.1