fix RegionInfoCache keys compare, remove RegionCache now replaced by RegionInfoCache
parent
79b7787eff
commit
bf593dd6f4
|
@ -51,7 +51,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]";
|
private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]";
|
||||||
|
|
||||||
private IGridService m_GridService;
|
private IGridService m_GridService;
|
||||||
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
|
|
||||||
private RegionInfoCache m_RegionInfoCache = null;
|
private RegionInfoCache m_RegionInfoCache = null;
|
||||||
|
|
||||||
private bool m_Enabled;
|
private bool m_Enabled;
|
||||||
|
@ -151,13 +150,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IGridService>(this);
|
scene.RegisterModuleInterface<IGridService>(this);
|
||||||
|
|
||||||
lock (m_LocalCache)
|
m_RegionInfoCache.CacheLocal(new GridRegion(scene.RegionInfo));
|
||||||
{
|
scene.EventManager.OnRegionUp += OnRegionUp;
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -165,11 +159,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
if (!m_Enabled)
|
if (!m_Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (m_LocalCache)
|
m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionID);
|
||||||
{
|
scene.EventManager.OnRegionUp -= OnRegionUp;
|
||||||
m_LocalCache[scene.RegionInfo.RegionID].Clear();
|
|
||||||
m_LocalCache.Remove(scene.RegionInfo.RegionID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
|
@ -180,6 +171,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
|
||||||
#region IGridService
|
#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)
|
public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
|
||||||
{
|
{
|
||||||
return m_GridService.RegisterRegion(scopeID, regionInfo);
|
return m_GridService.RegisterRegion(scopeID, regionInfo);
|
||||||
|
@ -291,7 +291,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
public void HandleShowNeighboursCommand(string module, string[] cmdparams)
|
public void HandleShowNeighboursCommand(string module, string[] cmdparams)
|
||||||
{
|
{
|
||||||
System.Text.StringBuilder caps = new System.Text.StringBuilder();
|
System.Text.StringBuilder caps = new System.Text.StringBuilder();
|
||||||
|
/* temporary broken
|
||||||
lock (m_LocalCache)
|
lock (m_LocalCache)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
|
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
|
||||||
|
@ -304,6 +304,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output(caps.ToString());
|
MainConsole.Instance.Output(caps.ToString());
|
||||||
|
*/
|
||||||
|
MainConsole.Instance.Output("Neighbours list not avaiable in this version\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<ulong, GridRegion> m_neighbours = new Dictionary<ulong, GridRegion>();
|
|
||||||
|
|
||||||
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<GridRegion> GetNeighbours()
|
|
||||||
{
|
|
||||||
return new List<GridRegion>(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -59,26 +59,42 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
|
||||||
public void Cache(UUID scopeID, GridRegion rinfo)
|
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)
|
if (rinfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS);
|
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)
|
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)
|
if (rinfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds);
|
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)
|
public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
|
||||||
{
|
{
|
||||||
inCache = false;
|
inCache = false;
|
||||||
|
@ -134,15 +150,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// following code partialy adapted from lib OpenMetaverse
|
// following code partialy adapted from lib OpenMetaverse
|
||||||
public class RegionKey : IComparable<RegionKey>
|
public class RegionKey
|
||||||
{
|
{
|
||||||
private UUID m_scopeID;
|
public UUID m_scopeID;
|
||||||
private UUID m_RegionID;
|
public UUID m_RegionID;
|
||||||
private DateTime m_expirationDate;
|
private DateTime m_expirationDate;
|
||||||
|
|
||||||
public RegionKey(UUID scopeID, UUID id)
|
public RegionKey(UUID scopeID, UUID id)
|
||||||
|
@ -161,16 +176,34 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
set { m_expirationDate = value; }
|
set { m_expirationDate = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetHaskCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
int hash = m_scopeID.GetHashCode();
|
int hash = m_scopeID.GetHashCode();
|
||||||
hash += hash * 23 + m_RegionID.GetHashCode();
|
hash += hash * 23 + m_RegionID.GetHashCode();
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(RegionKey other)
|
public override bool Equals(Object b)
|
||||||
{
|
{
|
||||||
return GetHashCode().CompareTo(other.GetHashCode());
|
if(b == null)
|
||||||
|
return false;
|
||||||
|
RegionKey kb = b as RegionKey;
|
||||||
|
return (m_scopeID == kb.m_scopeID && m_RegionID == kb.m_RegionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegionKeyEqual : EqualityComparer<RegionKey>
|
||||||
|
{
|
||||||
|
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 (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 double CACHE_PURGE_HZ = 60; // seconds
|
||||||
const int MAX_LOCK_WAIT = 10000; // milliseconds
|
const int MAX_LOCK_WAIT = 10000; // milliseconds
|
||||||
|
@ -256,7 +289,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
/// <summary>For thread safety</summary>
|
/// <summary>For thread safety</summary>
|
||||||
object isPurging = new object();
|
object isPurging = new object();
|
||||||
|
|
||||||
Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>();
|
static RegionKeyEqual keyequal = new RegionKeyEqual();
|
||||||
|
Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>(keyequal);
|
||||||
Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>();
|
Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>();
|
||||||
private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds);
|
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;
|
return timedStorage.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove(UUID scope, GridRegion region)
|
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))
|
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
|
||||||
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
|
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
|
||||||
|
|
Loading…
Reference in New Issue