diff options
author | onefang | 2019-05-19 21:24:15 +1000 |
---|---|---|
committer | onefang | 2019-05-19 21:24:15 +1000 |
commit | 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch) | |
tree | a9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid | |
parent | Add a build script. (diff) | |
download | opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2 opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz |
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid')
5 files changed, 1070 insertions, 321 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 1f782f5..d220568 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -51,7 +51,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
51 | private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]"; | 51 | private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]"; |
52 | 52 | ||
53 | private IGridService m_GridService; | 53 | private IGridService m_GridService; |
54 | private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>(); | 54 | private RegionInfoCache m_RegionInfoCache; |
55 | private HashSet<Scene> m_scenes = new HashSet<Scene>(); | ||
55 | 56 | ||
56 | private bool m_Enabled; | 57 | private bool m_Enabled; |
57 | 58 | ||
@@ -63,12 +64,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
63 | public LocalGridServicesConnector(IConfigSource source) | 64 | public LocalGridServicesConnector(IConfigSource source) |
64 | { | 65 | { |
65 | m_log.DebugFormat("{0} LocalGridServicesConnector instantiated directly.", LogHeader); | 66 | m_log.DebugFormat("{0} LocalGridServicesConnector instantiated directly.", LogHeader); |
66 | InitialiseService(source); | 67 | InitialiseService(source, null); |
68 | } | ||
69 | |||
70 | public LocalGridServicesConnector(IConfigSource source, RegionInfoCache regionInfoCache) | ||
71 | { | ||
72 | m_log.DebugFormat("{0} LocalGridServicesConnector instantiated directly with cache.", LogHeader); | ||
73 | InitialiseService(source, regionInfoCache); | ||
67 | } | 74 | } |
68 | 75 | ||
69 | #region ISharedRegionModule | 76 | #region ISharedRegionModule |
70 | 77 | ||
71 | public Type ReplaceableInterface | 78 | public Type ReplaceableInterface |
72 | { | 79 | { |
73 | get { return null; } | 80 | get { return null; } |
74 | } | 81 | } |
@@ -86,19 +93,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
86 | string name = moduleConfig.GetString("GridServices", ""); | 93 | string name = moduleConfig.GetString("GridServices", ""); |
87 | if (name == Name) | 94 | if (name == Name) |
88 | { | 95 | { |
89 | InitialiseService(source); | 96 | if(InitialiseService(source, null)) |
90 | m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); | 97 | m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); |
91 | } | 98 | } |
92 | } | 99 | } |
93 | } | 100 | } |
94 | 101 | ||
95 | private void InitialiseService(IConfigSource source) | 102 | private bool InitialiseService(IConfigSource source, RegionInfoCache ric) |
96 | { | 103 | { |
104 | if(ric == null && m_RegionInfoCache == null) | ||
105 | m_RegionInfoCache = new RegionInfoCache(); | ||
106 | else | ||
107 | m_RegionInfoCache = ric; | ||
108 | |||
97 | IConfig config = source.Configs["GridService"]; | 109 | IConfig config = source.Configs["GridService"]; |
98 | if (config == null) | 110 | if (config == null) |
99 | { | 111 | { |
100 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini"); | 112 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini"); |
101 | return; | 113 | return false; |
102 | } | 114 | } |
103 | 115 | ||
104 | string serviceDll = config.GetString("LocalServiceModule", String.Empty); | 116 | string serviceDll = config.GetString("LocalServiceModule", String.Empty); |
@@ -106,7 +118,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
106 | if (serviceDll == String.Empty) | 118 | if (serviceDll == String.Empty) |
107 | { | 119 | { |
108 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService"); | 120 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService"); |
109 | return; | 121 | return false; |
110 | } | 122 | } |
111 | 123 | ||
112 | Object[] args = new Object[] { source }; | 124 | Object[] args = new Object[] { source }; |
@@ -117,19 +129,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
117 | if (m_GridService == null) | 129 | if (m_GridService == null) |
118 | { | 130 | { |
119 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service"); | 131 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service"); |
120 | return; | 132 | return false; |
121 | } | 133 | } |
122 | 134 | ||
123 | m_Enabled = true; | 135 | m_Enabled = true; |
136 | return true; | ||
124 | } | 137 | } |
125 | 138 | ||
126 | public void PostInitialise() | 139 | public void PostInitialise() |
127 | { | 140 | { |
128 | // FIXME: We will still add this command even if we aren't enabled since RemoteGridServiceConnector | ||
129 | // will have instantiated us directly. | ||
130 | MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours", | ||
131 | "show neighbours", | ||
132 | "Shows the local regions' neighbours", HandleShowNeighboursCommand); | ||
133 | } | 141 | } |
134 | 142 | ||
135 | public void Close() | 143 | public void Close() |
@@ -141,15 +149,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
141 | if (!m_Enabled) | 149 | if (!m_Enabled) |
142 | return; | 150 | return; |
143 | 151 | ||
144 | scene.RegisterModuleInterface<IGridService>(this); | 152 | lock(m_scenes) |
145 | |||
146 | lock (m_LocalCache) | ||
147 | { | 153 | { |
148 | if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) | 154 | if(!m_scenes.Contains(scene)) |
149 | m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); | 155 | m_scenes.Add(scene); |
150 | else | ||
151 | m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); | ||
152 | } | 156 | } |
157 | scene.RegisterModuleInterface<IGridService>(this); | ||
158 | |||
159 | GridRegion r = new GridRegion(scene.RegionInfo); | ||
160 | m_RegionInfoCache.CacheLocal(r); | ||
161 | |||
162 | scene.EventManager.OnRegionUp += OnRegionUp; | ||
153 | } | 163 | } |
154 | 164 | ||
155 | public void RemoveRegion(Scene scene) | 165 | public void RemoveRegion(Scene scene) |
@@ -157,11 +167,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
157 | if (!m_Enabled) | 167 | if (!m_Enabled) |
158 | return; | 168 | return; |
159 | 169 | ||
160 | lock (m_LocalCache) | 170 | lock(m_scenes) |
161 | { | 171 | { |
162 | m_LocalCache[scene.RegionInfo.RegionID].Clear(); | 172 | if(m_scenes.Contains(scene)) |
163 | m_LocalCache.Remove(scene.RegionInfo.RegionID); | 173 | m_scenes.Remove(scene); |
164 | } | 174 | } |
175 | |||
176 | m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionHandle); | ||
177 | scene.EventManager.OnRegionUp -= OnRegionUp; | ||
165 | } | 178 | } |
166 | 179 | ||
167 | public void RegionLoaded(Scene scene) | 180 | public void RegionLoaded(Scene scene) |
@@ -172,6 +185,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
172 | 185 | ||
173 | #region IGridService | 186 | #region IGridService |
174 | 187 | ||
188 | private void OnRegionUp(GridRegion region) | ||
189 | { | ||
190 | // This shouldn't happen | ||
191 | if (region == null) | ||
192 | return; | ||
193 | |||
194 | m_RegionInfoCache.CacheNearNeighbour(region.ScopeID, region); | ||
195 | } | ||
196 | |||
175 | public string RegisterRegion(UUID scopeID, GridRegion regionInfo) | 197 | public string RegisterRegion(UUID scopeID, GridRegion regionInfo) |
176 | { | 198 | { |
177 | return m_GridService.RegisterRegion(scopeID, regionInfo); | 199 | return m_GridService.RegisterRegion(scopeID, regionInfo); |
@@ -184,12 +206,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
184 | 206 | ||
185 | public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID) | 207 | public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID) |
186 | { | 208 | { |
187 | return m_GridService.GetNeighbours(scopeID, regionID); | 209 | return m_GridService.GetNeighbours(scopeID, regionID); |
188 | } | 210 | } |
189 | 211 | ||
190 | public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) | 212 | public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) |
191 | { | 213 | { |
192 | return m_GridService.GetRegionByUUID(scopeID, regionID); | 214 | bool inCache = false; |
215 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache); | ||
216 | if (inCache) | ||
217 | return rinfo; | ||
218 | |||
219 | rinfo = m_GridService.GetRegionByUUID(scopeID, regionID); | ||
220 | if(rinfo != null) | ||
221 | m_RegionInfoCache.Cache(scopeID, rinfo); | ||
222 | return rinfo; | ||
193 | } | 223 | } |
194 | 224 | ||
195 | // Get a region given its base coordinates. | 225 | // Get a region given its base coordinates. |
@@ -197,59 +227,30 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
197 | // be the base coordinate of the region. | 227 | // be the base coordinate of the region. |
198 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 228 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
199 | { | 229 | { |
200 | GridRegion region = null; | ||
201 | uint regionX = Util.WorldToRegionLoc((uint)x); | ||
202 | uint regionY = Util.WorldToRegionLoc((uint)y); | ||
203 | 230 | ||
204 | // Sanity check | 231 | bool inCache = false; |
205 | if ((Util.RegionToWorldLoc(regionX) != (uint)x) || (Util.RegionToWorldLoc(regionY) != (uint)y)) | 232 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID, (uint)x, (uint)y, out inCache); |
206 | { | 233 | if (inCache) |
207 | m_log.WarnFormat("{0} GetRegionByPosition. Bad position requested: not the base of the region. Requested Pos=<{1},{2}>, Should Be=<{3},{4}>", | 234 | return rinfo; |
208 | LogHeader, x, y, Util.RegionToWorldLoc(regionX), Util.RegionToWorldLoc(regionY)); | ||
209 | } | ||
210 | |||
211 | // First see if it's a neighbour, even if it isn't on this sim. | ||
212 | // Neighbour data is cached in memory, so this is fast | ||
213 | |||
214 | lock (m_LocalCache) | ||
215 | { | ||
216 | foreach (RegionCache rcache in m_LocalCache.Values) | ||
217 | { | ||
218 | region = rcache.GetRegionByPosition(x, y); | ||
219 | if (region != null) | ||
220 | { | ||
221 | m_log.DebugFormat("{0} GetRegionByPosition. Found region {1} in cache (of region {2}). Pos=<{3},{4}>", | ||
222 | LogHeader, region.RegionName, rcache.RegionName, | ||
223 | Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY)); | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | 235 | ||
229 | // Then try on this sim (may be a lookup in DB if this is using MySql). | 236 | // Then try on this sim (may be a lookup in DB if this is using MySql). |
230 | if (region == null) | 237 | rinfo = m_GridService.GetRegionByPosition(scopeID, x, y); |
231 | { | 238 | if(rinfo != null) |
232 | region = m_GridService.GetRegionByPosition(scopeID, x, y); | 239 | m_RegionInfoCache.Cache(scopeID, rinfo); |
233 | 240 | return rinfo; | |
234 | if (region == null) | ||
235 | { | ||
236 | m_log.DebugFormat("{0} GetRegionByPosition. Region not found by grid service. Pos=<{1},{2}>", | ||
237 | LogHeader, regionX, regionY); | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | m_log.DebugFormat("{0} GetRegionByPosition. Got region {1} from grid service. Pos=<{2},{3}>", | ||
242 | LogHeader, region.RegionName, | ||
243 | Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY)); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | return region; | ||
248 | } | 241 | } |
249 | 242 | ||
250 | public GridRegion GetRegionByName(UUID scopeID, string regionName) | 243 | public GridRegion GetRegionByName(UUID scopeID, string regionName) |
251 | { | 244 | { |
252 | return m_GridService.GetRegionByName(scopeID, regionName); | 245 | bool inCache = false; |
246 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionName, out inCache); | ||
247 | if (inCache) | ||
248 | return rinfo; | ||
249 | |||
250 | rinfo = m_GridService.GetRegionByName(scopeID, regionName); | ||
251 | if(rinfo != null) | ||
252 | m_RegionInfoCache.Cache(scopeID, rinfo); | ||
253 | return rinfo; | ||
253 | } | 254 | } |
254 | 255 | ||
255 | public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) | 256 | public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) |
@@ -281,7 +282,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
281 | { | 282 | { |
282 | return m_GridService.GetHyperlinks(scopeID); | 283 | return m_GridService.GetHyperlinks(scopeID); |
283 | } | 284 | } |
284 | 285 | ||
285 | public int GetRegionFlags(UUID scopeID, UUID regionID) | 286 | public int GetRegionFlags(UUID scopeID, UUID regionID) |
286 | { | 287 | { |
287 | return m_GridService.GetRegionFlags(scopeID, regionID); | 288 | return m_GridService.GetRegionFlags(scopeID, regionID); |
@@ -294,22 +295,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
294 | 295 | ||
295 | #endregion | 296 | #endregion |
296 | 297 | ||
297 | public void HandleShowNeighboursCommand(string module, string[] cmdparams) | ||
298 | { | ||
299 | System.Text.StringBuilder caps = new System.Text.StringBuilder(); | ||
300 | |||
301 | lock (m_LocalCache) | ||
302 | { | ||
303 | foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache) | ||
304 | { | ||
305 | caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key); | ||
306 | List<GridRegion> regions = kvp.Value.GetNeighbours(); | ||
307 | foreach (GridRegion r in regions) | ||
308 | caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, Util.WorldToRegionLoc((uint)r.RegionLocX), Util.WorldToRegionLoc((uint)r.RegionLocY)); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | MainConsole.Instance.Output(caps.ToString()); | ||
313 | } | ||
314 | } | 298 | } |
315 | } | 299 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs deleted file mode 100644 index ae76288..0000000 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | |||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenSim.Services.Interfaces; | ||
35 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
36 | |||
37 | using OpenMetaverse; | ||
38 | using log4net; | ||
39 | |||
40 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | ||
41 | { | ||
42 | public class RegionCache | ||
43 | { | ||
44 | private static readonly ILog m_log = | ||
45 | LogManager.GetLogger( | ||
46 | MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | private Scene m_scene; | ||
49 | private Dictionary<ulong, GridRegion> m_neighbours = new Dictionary<ulong, GridRegion>(); | ||
50 | |||
51 | public string RegionName | ||
52 | { | ||
53 | get { return m_scene.RegionInfo.RegionName; } | ||
54 | } | ||
55 | |||
56 | public RegionCache(Scene s) | ||
57 | { | ||
58 | m_scene = s; | ||
59 | m_scene.EventManager.OnRegionUp += OnRegionUp; | ||
60 | } | ||
61 | |||
62 | private void OnRegionUp(GridRegion otherRegion) | ||
63 | { | ||
64 | // This shouldn't happen | ||
65 | if (otherRegion == null) | ||
66 | return; | ||
67 | |||
68 | m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}", | ||
69 | m_scene.RegionInfo.RegionName, otherRegion.RegionName, Util.WorldToRegionLoc((uint)otherRegion.RegionLocX), Util.WorldToRegionLoc((uint)otherRegion.RegionLocY)); | ||
70 | |||
71 | m_neighbours[otherRegion.RegionHandle] = otherRegion; | ||
72 | } | ||
73 | |||
74 | public void Clear() | ||
75 | { | ||
76 | m_scene.EventManager.OnRegionUp -= OnRegionUp; | ||
77 | m_neighbours.Clear(); | ||
78 | } | ||
79 | |||
80 | public List<GridRegion> GetNeighbours() | ||
81 | { | ||
82 | return new List<GridRegion>(m_neighbours.Values); | ||
83 | } | ||
84 | |||
85 | // Get a region given its base coordinates (in meters). | ||
86 | // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST | ||
87 | // be the base coordinate of the region. | ||
88 | // The snapping is technically unnecessary but is harmless because regions are always | ||
89 | // multiples of the legacy region size (256). | ||
90 | public GridRegion GetRegionByPosition(int x, int y) | ||
91 | { | ||
92 | uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize; | ||
93 | uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize; | ||
94 | ulong handle = Util.RegionWorldLocToHandle(xsnap, ysnap); | ||
95 | |||
96 | if (m_neighbours.ContainsKey(handle)) | ||
97 | return m_neighbours[handle]; | ||
98 | |||
99 | return null; | ||
100 | } | ||
101 | } | ||
102 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index be8a9a2..f6fff58 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs | |||
@@ -26,6 +26,8 @@ | |||
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Reflection; | 28 | using System.Reflection; |
29 | using System.Threading; | ||
30 | using System.Runtime.InteropServices; | ||
29 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
30 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
31 | using OpenSim.Services.Interfaces; | 33 | using OpenSim.Services.Interfaces; |
@@ -37,82 +39,68 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
37 | { | 39 | { |
38 | public class RegionInfoCache | 40 | public class RegionInfoCache |
39 | { | 41 | { |
40 | private const double CACHE_EXPIRATION_SECONDS = 300.0; // 5 minutes | 42 | private const float CACHE_EXPIRATION_SECONDS = 120; // 2 minutes opensim regions change a lot |
41 | 43 | ||
42 | // private static readonly ILog m_log = | 44 | // private static readonly ILog m_log = |
43 | // LogManager.GetLogger( | 45 | // LogManager.GetLogger( |
44 | // MethodBase.GetCurrentMethod().DeclaringType); | 46 | // MethodBase.GetCurrentMethod().DeclaringType); |
45 | 47 | ||
46 | internal struct ScopedRegionUUID | 48 | private static RegionsExpiringCache m_Cache; |
49 | private int numberInstances; | ||
50 | |||
51 | public RegionInfoCache() | ||
47 | { | 52 | { |
48 | public UUID m_scopeID; | 53 | if(m_Cache == null) |
49 | public UUID m_regionID; | 54 | m_Cache = new RegionsExpiringCache(); |
50 | public ScopedRegionUUID(UUID scopeID, UUID regionID) | 55 | numberInstances++; |
51 | { | ||
52 | m_scopeID = scopeID; | ||
53 | m_regionID = regionID; | ||
54 | } | ||
55 | } | 56 | } |
56 | 57 | ||
57 | internal struct ScopedRegionName | 58 | public void Cache(GridRegion rinfo) |
58 | { | 59 | { |
59 | public UUID m_scopeID; | 60 | if (rinfo != null) |
60 | public string m_name; | 61 | this.Cache(rinfo.ScopeID, rinfo); |
61 | public ScopedRegionName(UUID scopeID, string name) | ||
62 | { | ||
63 | m_scopeID = scopeID; | ||
64 | m_name = name; | ||
65 | } | ||
66 | } | 62 | } |
67 | 63 | ||
68 | internal struct ScopedRegionPosition | 64 | public void Cache(UUID scopeID, GridRegion rinfo) |
69 | { | 65 | { |
70 | public UUID m_scopeID; | 66 | if (rinfo == null) |
71 | public ulong m_regionHandle; | 67 | return; |
72 | public ScopedRegionPosition(UUID scopeID, ulong handle) | ||
73 | { | ||
74 | m_scopeID = scopeID; | ||
75 | m_regionHandle = handle; | ||
76 | } | ||
77 | } | ||
78 | 68 | ||
79 | private ExpiringCache<ScopedRegionUUID, GridRegion> m_UUIDCache; | 69 | m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); |
80 | private ExpiringCache<ScopedRegionName, ScopedRegionUUID> m_NameCache; | 70 | } |
81 | private ExpiringCache<ScopedRegionPosition, GridRegion> m_PositionCache; | ||
82 | 71 | ||
83 | public RegionInfoCache() | 72 | public void CacheLocal(GridRegion rinfo) |
84 | { | 73 | { |
85 | m_UUIDCache = new ExpiringCache<ScopedRegionUUID, GridRegion>(); | 74 | if (rinfo == null) |
86 | m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>(); | 75 | return; |
87 | m_PositionCache = new ExpiringCache<ScopedRegionPosition, GridRegion>(); | 76 | |
77 | m_Cache.AddOrUpdate(rinfo.ScopeID, rinfo, 1e7f); | ||
88 | } | 78 | } |
89 | 79 | ||
90 | public void Cache(GridRegion rinfo) | 80 | public void CacheNearNeighbour(UUID scopeID, GridRegion rinfo) |
91 | { | 81 | { |
92 | if (rinfo != null) | 82 | if (rinfo == null) |
93 | this.Cache(rinfo.ScopeID,rinfo.RegionID,rinfo); | 83 | return; |
84 | |||
85 | m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); | ||
94 | } | 86 | } |
95 | 87 | ||
96 | public void Cache(UUID scopeID, UUID regionID, GridRegion rinfo) | 88 | public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds) |
97 | { | 89 | { |
98 | // for now, do not cache negative results; this is because | ||
99 | // we need to figure out how to handle regions coming online | ||
100 | // in a timely way | ||
101 | if (rinfo == null) | 90 | if (rinfo == null) |
102 | return; | 91 | return; |
103 | |||
104 | ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID); | ||
105 | |||
106 | // Cache even null accounts | ||
107 | m_UUIDCache.AddOrUpdate(id, rinfo, CACHE_EXPIRATION_SECONDS); | ||
108 | if (rinfo != null) | ||
109 | { | ||
110 | ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName); | ||
111 | m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS); | ||
112 | 92 | ||
113 | ScopedRegionPosition pos = new ScopedRegionPosition(scopeID, rinfo.RegionHandle); | 93 | m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds); |
114 | m_PositionCache.AddOrUpdate(pos, rinfo, CACHE_EXPIRATION_SECONDS); | 94 | } |
115 | } | 95 | |
96 | public void Remove(UUID scopeID, GridRegion rinfo) | ||
97 | { | ||
98 | m_Cache.Remove(scopeID, rinfo); | ||
99 | } | ||
100 | |||
101 | public void Remove(UUID scopeID, ulong regionHandle) | ||
102 | { | ||
103 | m_Cache.Remove(scopeID, regionHandle); | ||
116 | } | 104 | } |
117 | 105 | ||
118 | public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) | 106 | public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) |
@@ -120,8 +108,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
120 | inCache = false; | 108 | inCache = false; |
121 | 109 | ||
122 | GridRegion rinfo = null; | 110 | GridRegion rinfo = null; |
123 | ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID); | 111 | if (m_Cache.TryGetValue(scopeID, regionID, out rinfo)) |
124 | if (m_UUIDCache.TryGetValue(id, out rinfo)) | ||
125 | { | 112 | { |
126 | inCache = true; | 113 | inCache = true; |
127 | return rinfo; | 114 | return rinfo; |
@@ -135,8 +122,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
135 | inCache = false; | 122 | inCache = false; |
136 | 123 | ||
137 | GridRegion rinfo = null; | 124 | GridRegion rinfo = null; |
138 | ScopedRegionPosition pos = new ScopedRegionPosition(scopeID, handle); | 125 | if (m_Cache.TryGetValue(scopeID, handle, out rinfo)) |
139 | if (m_PositionCache.TryGetValue(pos, out rinfo)) | ||
140 | { | 126 | { |
141 | inCache = true; | 127 | inCache = true; |
142 | return rinfo; | 128 | return rinfo; |
@@ -145,25 +131,868 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
145 | return null; | 131 | return null; |
146 | } | 132 | } |
147 | 133 | ||
148 | |||
149 | public GridRegion Get(UUID scopeID, string name, out bool inCache) | 134 | public GridRegion Get(UUID scopeID, string name, out bool inCache) |
150 | { | 135 | { |
151 | inCache = false; | 136 | inCache = false; |
152 | 137 | ||
153 | ScopedRegionName sname = new ScopedRegionName(scopeID,name); | 138 | GridRegion rinfo = null; |
139 | if (m_Cache.TryGetValue(scopeID, name, out rinfo)) | ||
140 | { | ||
141 | inCache = true; | ||
142 | return rinfo; | ||
143 | } | ||
144 | |||
145 | return null; | ||
146 | } | ||
147 | |||
148 | public GridRegion Get(UUID scopeID, uint x, uint y, out bool inCache) | ||
149 | { | ||
150 | inCache = false; | ||
151 | |||
152 | GridRegion rinfo = null; | ||
153 | if (m_Cache.TryGetValue(scopeID, x, y, out rinfo)) | ||
154 | { | ||
155 | inCache = true; | ||
156 | return rinfo; | ||
157 | } | ||
158 | |||
159 | return null; | ||
160 | } | ||
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 | |||
293 | public class RegionInfoForScope | ||
294 | { | ||
295 | public const ulong HANDLEMASK = 0xffffff00ffffff00ul; | ||
296 | public const ulong HANDLECOORDMASK = 0xffffff00ul; | ||
297 | |||
298 | private Dictionary<ulong, GridRegion> storage; | ||
299 | private Dictionary<ulong, DateTime> expires; | ||
300 | private Dictionary<string, ulong> byname; | ||
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>(); | ||
304 | |||
305 | public RegionInfoForScope() | ||
306 | { | ||
307 | storage = new Dictionary<ulong, GridRegion>(); | ||
308 | expires = new Dictionary<ulong, DateTime>(); | ||
309 | byname = new Dictionary<string, ulong>(); | ||
310 | byuuid = new Dictionary<UUID, ulong>(); | ||
311 | } | ||
312 | |||
313 | public RegionInfoForScope(GridRegion region, DateTime expire) | ||
314 | { | ||
315 | storage = new Dictionary<ulong, GridRegion>(); | ||
316 | expires = new Dictionary<ulong, DateTime>(); | ||
317 | byname = new Dictionary<string, ulong>(); | ||
318 | byuuid = new Dictionary<UUID, ulong>(); | ||
319 | |||
320 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
321 | storage[handle] = region; | ||
322 | expires[handle] = expire; | ||
323 | byname[region.RegionName] = handle; | ||
324 | byuuid[region.RegionID] = handle; | ||
325 | addToInner(region); | ||
326 | } | ||
327 | |||
328 | public void Add(GridRegion region, DateTime expire) | ||
329 | { | ||
330 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
331 | |||
332 | if(storage != null && storage.ContainsKey(handle)) | ||
333 | return; | ||
334 | |||
335 | if(storage == null) | ||
336 | storage = new Dictionary<ulong, GridRegion>(); | ||
337 | if(expires == null) | ||
338 | expires = new Dictionary<ulong, DateTime>(); | ||
339 | if(byname == null) | ||
340 | byname = new Dictionary<string, ulong>(); | ||
341 | if(byuuid == null) | ||
342 | byuuid = new Dictionary<UUID, ulong>(); | ||
343 | |||
344 | storage[handle] = region; | ||
345 | expires[handle] = expire; | ||
346 | byname[region.RegionName] = handle; | ||
347 | byuuid[region.RegionID] = handle; | ||
348 | |||
349 | addToInner(region); | ||
350 | } | ||
351 | |||
352 | public void AddUpdate(GridRegion region, DateTime expire) | ||
353 | { | ||
354 | if(storage == null) | ||
355 | storage = new Dictionary<ulong, GridRegion>(); | ||
356 | if(expires == null) | ||
357 | expires = new Dictionary<ulong, DateTime>(); | ||
358 | if(byname == null) | ||
359 | byname = new Dictionary<string, ulong>(); | ||
360 | if(byuuid == null) | ||
361 | byuuid = new Dictionary<UUID, ulong>(); | ||
362 | |||
363 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
154 | 364 | ||
155 | ScopedRegionUUID id; | 365 | if(expires.ContainsKey(handle)) |
156 | if (m_NameCache.TryGetValue(sname, out id)) | ||
157 | { | 366 | { |
158 | GridRegion rinfo = null; | 367 | if(expires[handle] < expire) |
159 | if (m_UUIDCache.TryGetValue(id, out rinfo)) | 368 | expires[handle] = expire; |
369 | if(storage.ContainsKey(handle)) | ||
160 | { | 370 | { |
161 | inCache = true; | 371 | GridRegion oldr = storage[handle]; |
162 | return rinfo; | 372 | if (oldr.RegionSizeX != region.RegionSizeX |
373 | || oldr.RegionSizeY != region.RegionSizeY) | ||
374 | { | ||
375 | removeFromInner(oldr); | ||
376 | addToInner(region); | ||
377 | } | ||
163 | } | 378 | } |
164 | } | 379 | } |
165 | 380 | else | |
381 | { | ||
382 | expires[handle] = expire; | ||
383 | addToInner(region); | ||
384 | } | ||
385 | storage[handle] = region; | ||
386 | byname[region.RegionName] = handle; | ||
387 | byuuid[region.RegionID] = handle; | ||
388 | } | ||
389 | |||
390 | public void Remove(GridRegion region) | ||
391 | { | ||
392 | if(region == null) | ||
393 | return; | ||
394 | |||
395 | if(byname != null) | ||
396 | byname.Remove(region.RegionName); | ||
397 | if(byuuid != null) | ||
398 | byuuid.Remove(region.RegionID); | ||
399 | |||
400 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
401 | if(storage != null) | ||
402 | { | ||
403 | if(storage.ContainsKey(handle)) | ||
404 | { | ||
405 | storage[handle] = null; | ||
406 | storage.Remove(handle); | ||
407 | } | ||
408 | } | ||
409 | removeFromInner(region); | ||
410 | if(expires != null) | ||
411 | { | ||
412 | expires.Remove(handle); | ||
413 | if(expires.Count == 0) | ||
414 | Clear(); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | public void Remove(ulong handle) | ||
419 | { | ||
420 | handle &= HANDLEMASK; | ||
421 | |||
422 | if(storage != null) | ||
423 | { | ||
424 | if(storage.ContainsKey(handle)) | ||
425 | { | ||
426 | GridRegion r = storage[handle]; | ||
427 | if(byname != null) | ||
428 | byname.Remove(r.RegionName); | ||
429 | if(byuuid != null) | ||
430 | byuuid.Remove(r.RegionID); | ||
431 | removeFromInner(r); | ||
432 | storage[handle] = null; | ||
433 | } | ||
434 | storage.Remove(handle); | ||
435 | } | ||
436 | if(expires != null) | ||
437 | { | ||
438 | expires.Remove(handle); | ||
439 | if(expires.Count == 0) | ||
440 | Clear(); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | public void Clear() | ||
445 | { | ||
446 | if(expires != null) | ||
447 | expires.Clear(); | ||
448 | if(storage != null) | ||
449 | storage.Clear(); | ||
450 | if(byname != null) | ||
451 | byname.Clear(); | ||
452 | if(byuuid != null) | ||
453 | byuuid.Clear(); | ||
454 | byname = null; | ||
455 | byuuid = null; | ||
456 | storage = null; | ||
457 | expires = null; | ||
458 | innerHandles.Clear(); | ||
459 | } | ||
460 | |||
461 | public bool Contains(GridRegion region) | ||
462 | { | ||
463 | if(storage == null) | ||
464 | return false; | ||
465 | if(region == null) | ||
466 | return false; | ||
467 | |||
468 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
469 | return storage.ContainsKey(handle); | ||
470 | } | ||
471 | |||
472 | public bool Contains(ulong handle) | ||
473 | { | ||
474 | if(storage == null) | ||
475 | return false; | ||
476 | |||
477 | handle &= HANDLEMASK; | ||
478 | return storage.ContainsKey(handle); | ||
479 | } | ||
480 | |||
481 | public GridRegion get(ulong handle) | ||
482 | { | ||
483 | if(storage == null) | ||
484 | return null; | ||
485 | |||
486 | handle &= HANDLEMASK; | ||
487 | if(storage.ContainsKey(handle)) | ||
488 | return storage[handle]; | ||
489 | |||
490 | if(!innerHandles.ContainsKey(handle)) | ||
491 | return null; | ||
492 | |||
493 | ulong rhandle = innerHandles[handle]; | ||
494 | if(storage.ContainsKey(rhandle)) | ||
495 | return storage[rhandle]; | ||
496 | |||
166 | return null; | 497 | return null; |
167 | } | 498 | } |
499 | |||
500 | public GridRegion get(string name) | ||
501 | { | ||
502 | if(byname == null || !byname.ContainsKey(name)) | ||
503 | return null; | ||
504 | |||
505 | ulong handle = byname[name]; | ||
506 | if(storage.ContainsKey(handle)) | ||
507 | return storage[handle]; | ||
508 | return null; | ||
509 | } | ||
510 | |||
511 | public GridRegion get(UUID id) | ||
512 | { | ||
513 | if(byuuid == null || !byuuid.ContainsKey(id)) | ||
514 | return null; | ||
515 | |||
516 | ulong handle = byuuid[id]; | ||
517 | if(storage.ContainsKey(handle)) | ||
518 | return storage[handle]; | ||
519 | return null; | ||
520 | } | ||
521 | |||
522 | public GridRegion get(uint x, uint y) | ||
523 | { | ||
524 | if(storage == null) | ||
525 | return null; | ||
526 | |||
527 | // look for a handle first this should find normal size regions | ||
528 | ulong handle = (ulong)x & HANDLECOORDMASK; | ||
529 | handle <<= 32; | ||
530 | handle |= ((ulong)y & HANDLECOORDMASK); | ||
531 | |||
532 | if(storage.ContainsKey(handle)) | ||
533 | return storage[handle]; | ||
534 | |||
535 | if(!innerHandles.ContainsKey(handle)) | ||
536 | return null; | ||
537 | |||
538 | ulong rhandle = innerHandles[handle]; | ||
539 | if(!storage.ContainsKey(rhandle)) | ||
540 | return null; | ||
541 | |||
542 | GridRegion r = storage[rhandle]; | ||
543 | if(r == null) | ||
544 | return null; | ||
545 | |||
546 | // extra check, possible redundant | ||
547 | |||
548 | int test = r.RegionLocX; | ||
549 | if(x < test) | ||
550 | return null; | ||
551 | test += r.RegionSizeX; | ||
552 | if(x >= test) | ||
553 | return null; | ||
554 | test = r.RegionLocY; | ||
555 | if (y < test) | ||
556 | return null; | ||
557 | test += r.RegionSizeY; | ||
558 | if (y < test) | ||
559 | return r; | ||
560 | |||
561 | /* | ||
562 | // next do the harder work | ||
563 | foreach(KeyValuePair<ulong, GridRegion> kvp in storage) | ||
564 | { | ||
565 | GridRegion r = kvp.Value; | ||
566 | if(r == null) // ?? | ||
567 | continue; | ||
568 | |||
569 | int test = r.RegionLocX; | ||
570 | if(x < test) | ||
571 | continue; | ||
572 | test += r.RegionSizeX; | ||
573 | if(x >= test) | ||
574 | continue; | ||
575 | test = r.RegionLocY; | ||
576 | if (y < test) | ||
577 | continue; | ||
578 | test += r.RegionSizeY; | ||
579 | if (y < test) | ||
580 | return r; | ||
581 | } | ||
582 | */ | ||
583 | return null; | ||
584 | } | ||
585 | |||
586 | public int expire(DateTime now ) | ||
587 | { | ||
588 | if(expires == null || expires.Count == 0) | ||
589 | return 0; | ||
590 | |||
591 | int expiresCount = expires.Count; | ||
592 | List<ulong> toexpire = new List<ulong>(); | ||
593 | |||
594 | foreach(KeyValuePair<ulong, DateTime> kvp in expires) | ||
595 | { | ||
596 | if(kvp.Value < now) | ||
597 | toexpire.Add(kvp.Key); | ||
598 | } | ||
599 | |||
600 | int toexpireCount = toexpire.Count; | ||
601 | if(toexpireCount == 0) | ||
602 | return expiresCount; | ||
603 | |||
604 | if(toexpireCount == expiresCount) | ||
605 | { | ||
606 | Clear(); | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | if(storage != null) | ||
611 | { | ||
612 | ulong h; | ||
613 | for(int i = 0; i < toexpireCount; i++) | ||
614 | { | ||
615 | h = toexpire[i]; | ||
616 | if(storage.ContainsKey(h)) | ||
617 | { | ||
618 | GridRegion r = storage[h]; | ||
619 | if(byname != null) | ||
620 | byname.Remove(r.RegionName); | ||
621 | if(byuuid != null) | ||
622 | byuuid.Remove(r.RegionID); | ||
623 | removeFromInner(r); | ||
624 | |||
625 | storage[h] = null; | ||
626 | storage.Remove(h); | ||
627 | } | ||
628 | if(expires != null) | ||
629 | expires.Remove(h); | ||
630 | } | ||
631 | } | ||
632 | else | ||
633 | { | ||
634 | Clear(); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | expiresCount = expires.Count; | ||
639 | if(expiresCount == 0) | ||
640 | { | ||
641 | byname = null; | ||
642 | byuuid = null; | ||
643 | storage = null; | ||
644 | expires = null; | ||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | return expiresCount; | ||
649 | } | ||
650 | |||
651 | public int Count() | ||
652 | { | ||
653 | if(byname == null) | ||
654 | return 0; | ||
655 | else | ||
656 | return byname.Count; | ||
657 | } | ||
658 | |||
659 | private void addToInner(GridRegion region) | ||
660 | { | ||
661 | int rsx = region.RegionSizeX; | ||
662 | int rsy = region.RegionSizeY; | ||
663 | |||
664 | if(rsx < 512 && rsy < 512) | ||
665 | return; | ||
666 | |||
667 | rsx >>= 8; | ||
668 | rsy >>= 8; | ||
669 | |||
670 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
671 | fastRegionHandle fh = new fastRegionHandle(handle); | ||
672 | uint startY = fh.y; | ||
673 | for(int i = 0; i < rsx; i++) | ||
674 | { | ||
675 | for(int j = 0; j < rsy ; j++) | ||
676 | { | ||
677 | innerHandles[fh.toHandle()] = handle; | ||
678 | fh.y += 256; | ||
679 | } | ||
680 | |||
681 | fh.y = startY; | ||
682 | fh.x += 256; | ||
683 | } | ||
684 | } | ||
685 | |||
686 | private void removeFromInner(GridRegion region) | ||
687 | { | ||
688 | int rsx = region.RegionSizeX; | ||
689 | int rsy = region.RegionSizeY; | ||
690 | |||
691 | if(rsx < 512 && rsy < 512) | ||
692 | return; | ||
693 | |||
694 | rsx >>= 8; | ||
695 | rsy >>= 8; | ||
696 | ulong handle = region.RegionHandle & HANDLEMASK; | ||
697 | fastRegionHandle fh = new fastRegionHandle(handle); | ||
698 | uint startY = fh.y; | ||
699 | for(int i = 0; i < rsx; i++) | ||
700 | { | ||
701 | for(int j = 0; j < rsy ; j++) | ||
702 | { | ||
703 | innerHandles.Remove(fh.toHandle()); | ||
704 | fh.y += 256; | ||
705 | } | ||
706 | |||
707 | fh.y = startY; | ||
708 | fh.x += 256; | ||
709 | } | ||
710 | } | ||
711 | } | ||
712 | |||
713 | public class RegionsExpiringCache | ||
714 | { | ||
715 | const double CACHE_PURGE_TIME = 60000; // milliseconds | ||
716 | const int MAX_LOCK_WAIT = 10000; // milliseconds | ||
717 | |||
718 | /// <summary>For thread safety</summary> | ||
719 | object syncRoot = new object(); | ||
720 | /// <summary>For thread safety</summary> | ||
721 | object isPurging = new object(); | ||
722 | |||
723 | Dictionary<UUID, RegionInfoForScope> InfobyScope = new Dictionary<UUID, RegionInfoForScope>(); | ||
724 | private System.Timers.Timer timer = new System.Timers.Timer(CACHE_PURGE_TIME); | ||
725 | |||
726 | public RegionsExpiringCache() | ||
727 | { | ||
728 | timer.Elapsed += PurgeCache; | ||
729 | timer.Start(); | ||
730 | } | ||
731 | |||
732 | public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds) | ||
733 | { | ||
734 | if(region == null) | ||
735 | return false; | ||
736 | |||
737 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
738 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
739 | |||
740 | try | ||
741 | { | ||
742 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); | ||
743 | |||
744 | RegionInfoForScope ris = null; | ||
745 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
746 | { | ||
747 | ris = new RegionInfoForScope(region, expire); | ||
748 | InfobyScope[scope] = ris; | ||
749 | } | ||
750 | else | ||
751 | ris.AddUpdate(region, expire); | ||
752 | |||
753 | return true; | ||
754 | } | ||
755 | finally { Monitor.Exit(syncRoot); } | ||
756 | } | ||
757 | |||
758 | public void Clear() | ||
759 | { | ||
760 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
761 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
762 | try | ||
763 | { | ||
764 | foreach(RegionInfoForScope ris in InfobyScope.Values) | ||
765 | ris.Clear(); | ||
766 | InfobyScope.Clear(); | ||
767 | } | ||
768 | finally { Monitor.Exit(syncRoot); } | ||
769 | } | ||
770 | |||
771 | public bool Contains(UUID scope, GridRegion region) | ||
772 | { | ||
773 | if(region == null) | ||
774 | return false; | ||
775 | |||
776 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
777 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
778 | |||
779 | try | ||
780 | { | ||
781 | RegionInfoForScope ris = null; | ||
782 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
783 | return false; | ||
784 | |||
785 | return ris.Contains(region); | ||
786 | } | ||
787 | finally { Monitor.Exit(syncRoot); } | ||
788 | } | ||
789 | |||
790 | public bool Contains(UUID scope, ulong handle) | ||
791 | { | ||
792 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
793 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
794 | |||
795 | try | ||
796 | { | ||
797 | RegionInfoForScope ris = null; | ||
798 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
799 | return false; | ||
800 | |||
801 | return ris.Contains(handle); | ||
802 | } | ||
803 | finally { Monitor.Exit(syncRoot); } | ||
804 | } | ||
805 | |||
806 | public int Count() | ||
807 | { | ||
808 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
809 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
810 | |||
811 | try | ||
812 | { | ||
813 | int count = 0; | ||
814 | foreach(RegionInfoForScope ris in InfobyScope.Values) | ||
815 | count += ris.Count(); | ||
816 | return count; | ||
817 | } | ||
818 | finally { Monitor.Exit(syncRoot); } | ||
819 | } | ||
820 | |||
821 | public bool Remove(UUID scope, ulong handle) | ||
822 | { | ||
823 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
824 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
825 | try | ||
826 | { | ||
827 | RegionInfoForScope ris = null; | ||
828 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
829 | return false; | ||
830 | |||
831 | ris.Remove(handle); | ||
832 | if(ris.Count() == 0) | ||
833 | InfobyScope.Remove(scope); | ||
834 | return true; | ||
835 | } | ||
836 | finally { Monitor.Exit(syncRoot); } | ||
837 | } | ||
838 | |||
839 | public bool Remove(UUID scope, GridRegion region) | ||
840 | { | ||
841 | if(region == null) | ||
842 | return false; | ||
843 | |||
844 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
845 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
846 | try | ||
847 | { | ||
848 | RegionInfoForScope ris = null; | ||
849 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
850 | return false; | ||
851 | |||
852 | ris.Remove(region); | ||
853 | if(ris.Count() == 0) | ||
854 | InfobyScope.Remove(scope); | ||
855 | return true; | ||
856 | } | ||
857 | finally { Monitor.Exit(syncRoot); } | ||
858 | } | ||
859 | |||
860 | public bool TryGetValue(UUID scope, ulong handle, out GridRegion value) | ||
861 | { | ||
862 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
863 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
864 | |||
865 | value = null; | ||
866 | try | ||
867 | { | ||
868 | RegionInfoForScope ris = null; | ||
869 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
870 | return false; | ||
871 | value = ris.get(handle); | ||
872 | } | ||
873 | finally { Monitor.Exit(syncRoot); } | ||
874 | |||
875 | return value != null; | ||
876 | } | ||
877 | |||
878 | public bool TryGetValue(UUID scope, string name, out GridRegion value) | ||
879 | { | ||
880 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
881 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
882 | |||
883 | value = null; | ||
884 | try | ||
885 | { | ||
886 | RegionInfoForScope ris = null; | ||
887 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
888 | return false; | ||
889 | value = ris.get(name); | ||
890 | } | ||
891 | finally { Monitor.Exit(syncRoot); } | ||
892 | |||
893 | return value != null; | ||
894 | } | ||
895 | |||
896 | public bool TryGetValue(UUID scope, UUID id, out GridRegion value) | ||
897 | { | ||
898 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
899 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
900 | |||
901 | value = null; | ||
902 | try | ||
903 | { | ||
904 | RegionInfoForScope ris = null; | ||
905 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
906 | return false; | ||
907 | value = ris.get(id); | ||
908 | } | ||
909 | finally { Monitor.Exit(syncRoot); } | ||
910 | |||
911 | return value != null; | ||
912 | } | ||
913 | |||
914 | // gets a region that contains world position (x,y) | ||
915 | // hopefull will not take ages | ||
916 | public bool TryGetValue(UUID scope, uint x, uint y, out GridRegion value) | ||
917 | { | ||
918 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
919 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
920 | |||
921 | value = null; | ||
922 | try | ||
923 | { | ||
924 | RegionInfoForScope ris = null; | ||
925 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
926 | return false; | ||
927 | |||
928 | value = ris.get(x, y); | ||
929 | } | ||
930 | finally { Monitor.Exit(syncRoot); } | ||
931 | |||
932 | return value != null; | ||
933 | } | ||
934 | |||
935 | public bool Update(UUID scope, GridRegion region, double expirationSeconds) | ||
936 | { | ||
937 | if(region == null) | ||
938 | return false; | ||
939 | |||
940 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
941 | throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); | ||
942 | |||
943 | try | ||
944 | { | ||
945 | RegionInfoForScope ris = null; | ||
946 | if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) | ||
947 | return false; | ||
948 | |||
949 | DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); | ||
950 | ris.AddUpdate(region,expire); | ||
951 | return true; | ||
952 | } | ||
953 | finally { Monitor.Exit(syncRoot); } | ||
954 | } | ||
955 | |||
956 | /// <summary> | ||
957 | /// Purges expired objects from the cache. Called automatically by the purge timer. | ||
958 | /// </summary> | ||
959 | private void PurgeCache(object sender, System.Timers.ElapsedEventArgs e) | ||
960 | { | ||
961 | // Only let one thread purge at once - a buildup could cause a crash | ||
962 | // This could cause the purge to be delayed while there are lots of read/write ops | ||
963 | // happening on the cache | ||
964 | if (!Monitor.TryEnter(isPurging)) | ||
965 | return; | ||
966 | |||
967 | DateTime now = DateTime.UtcNow; | ||
968 | |||
969 | try | ||
970 | { | ||
971 | // If we fail to acquire a lock on the synchronization root after MAX_LOCK_WAIT, skip this purge cycle | ||
972 | if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) | ||
973 | return; | ||
974 | try | ||
975 | { | ||
976 | List<UUID> expiredscopes = new List<UUID>(); | ||
977 | |||
978 | foreach (KeyValuePair<UUID, RegionInfoForScope> kvp in InfobyScope) | ||
979 | { | ||
980 | if (kvp.Value.expire(now) == 0) | ||
981 | expiredscopes.Add(kvp.Key); | ||
982 | } | ||
983 | |||
984 | if (expiredscopes.Count > 0) | ||
985 | { | ||
986 | foreach (UUID sid in expiredscopes) | ||
987 | { | ||
988 | InfobyScope[sid] = null; | ||
989 | InfobyScope.Remove(sid); | ||
990 | } | ||
991 | } | ||
992 | } | ||
993 | finally { Monitor.Exit(syncRoot); } | ||
994 | } | ||
995 | finally { Monitor.Exit(isPurging); } | ||
996 | } | ||
168 | } | 997 | } |
169 | } | 998 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index 85073fc..ee17093 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs | |||
@@ -52,12 +52,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
52 | MethodBase.GetCurrentMethod().DeclaringType); | 52 | MethodBase.GetCurrentMethod().DeclaringType); |
53 | 53 | ||
54 | private bool m_Enabled = false; | 54 | private bool m_Enabled = false; |
55 | private string m_ThisGatekeeper = string.Empty; | ||
55 | 56 | ||
56 | private IGridService m_LocalGridService; | 57 | private IGridService m_LocalGridService; |
57 | private IGridService m_RemoteGridService; | 58 | private IGridService m_RemoteGridService; |
58 | 59 | ||
59 | private RegionInfoCache m_RegionInfoCache = new RegionInfoCache(); | 60 | private RegionInfoCache m_RegionInfoCache; |
60 | 61 | ||
61 | public RemoteGridServicesConnector() | 62 | public RemoteGridServicesConnector() |
62 | { | 63 | { |
63 | } | 64 | } |
@@ -69,7 +70,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
69 | 70 | ||
70 | #region ISharedRegionmodule | 71 | #region ISharedRegionmodule |
71 | 72 | ||
72 | public Type ReplaceableInterface | 73 | public Type ReplaceableInterface |
73 | { | 74 | { |
74 | get { return null; } | 75 | get { return null; } |
75 | } | 76 | } |
@@ -87,38 +88,57 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
87 | string name = moduleConfig.GetString("GridServices", ""); | 88 | string name = moduleConfig.GetString("GridServices", ""); |
88 | if (name == Name) | 89 | if (name == Name) |
89 | { | 90 | { |
90 | InitialiseServices(source); | 91 | if(InitialiseServices(source)) |
91 | m_Enabled = true; | 92 | { |
92 | m_log.Info("[REMOTE GRID CONNECTOR]: Remote grid enabled"); | 93 | m_Enabled = true; |
94 | m_log.Info("[REMOTE GRID CONNECTOR]: Remote grid enabled"); | ||
95 | } | ||
93 | } | 96 | } |
94 | } | 97 | } |
95 | } | 98 | } |
96 | 99 | ||
97 | private void InitialiseServices(IConfigSource source) | 100 | private bool InitialiseServices(IConfigSource source) |
98 | { | 101 | { |
99 | IConfig gridConfig = source.Configs["GridService"]; | 102 | IConfig gridConfig = source.Configs["GridService"]; |
100 | if (gridConfig == null) | 103 | if (gridConfig == null) |
101 | { | 104 | { |
102 | m_log.Error("[REMOTE GRID CONNECTOR]: GridService missing from OpenSim.ini"); | 105 | m_log.Error("[REMOTE GRID CONNECTOR]: GridService missing from OpenSim.ini"); |
103 | return; | 106 | return false; |
104 | } | 107 | } |
105 | 108 | ||
106 | string networkConnector = gridConfig.GetString("NetworkConnector", string.Empty); | 109 | string networkConnector = gridConfig.GetString("NetworkConnector", string.Empty); |
107 | if (networkConnector == string.Empty) | 110 | if (networkConnector == string.Empty) |
108 | { | 111 | { |
109 | m_log.Error("[REMOTE GRID CONNECTOR]: Please specify a network connector under [GridService]"); | 112 | m_log.Error("[REMOTE GRID CONNECTOR]: Please specify a network connector under [GridService]"); |
110 | return; | 113 | return false; |
111 | } | 114 | } |
112 | 115 | ||
113 | Object[] args = new Object[] { source }; | 116 | Object[] args = new Object[] { source }; |
114 | m_RemoteGridService = ServerUtils.LoadPlugin<IGridService>(networkConnector, args); | 117 | m_RemoteGridService = ServerUtils.LoadPlugin<IGridService>(networkConnector, args); |
115 | 118 | ||
116 | m_LocalGridService = new LocalGridServicesConnector(source); | 119 | m_LocalGridService = new LocalGridServicesConnector(source, m_RegionInfoCache); |
117 | } | 120 | if (m_LocalGridService == null) |
121 | { | ||
122 | m_log.Error("[REMOTE GRID CONNECTOR]: failed to load local connector"); | ||
123 | return false; | ||
124 | } | ||
125 | |||
126 | if(m_RegionInfoCache == null) | ||
127 | m_RegionInfoCache = new RegionInfoCache(); | ||
128 | |||
129 | m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI", | ||
130 | new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty); | ||
131 | // Legacy. Remove soon! | ||
132 | m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", m_ThisGatekeeper); | ||
133 | |||
134 | Util.checkServiceURI(m_ThisGatekeeper, out m_ThisGatekeeper); | ||
135 | |||
136 | return true; | ||
137 | } | ||
118 | 138 | ||
119 | public void PostInitialise() | 139 | public void PostInitialise() |
120 | { | 140 | { |
121 | if (m_LocalGridService != null) | 141 | if (m_Enabled) |
122 | ((ISharedRegionModule)m_LocalGridService).PostInitialise(); | 142 | ((ISharedRegionModule)m_LocalGridService).PostInitialise(); |
123 | } | 143 | } |
124 | 144 | ||
@@ -129,15 +149,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
129 | public void AddRegion(Scene scene) | 149 | public void AddRegion(Scene scene) |
130 | { | 150 | { |
131 | if (m_Enabled) | 151 | if (m_Enabled) |
152 | { | ||
132 | scene.RegisterModuleInterface<IGridService>(this); | 153 | scene.RegisterModuleInterface<IGridService>(this); |
133 | |||
134 | if (m_LocalGridService != null) | ||
135 | ((ISharedRegionModule)m_LocalGridService).AddRegion(scene); | 154 | ((ISharedRegionModule)m_LocalGridService).AddRegion(scene); |
155 | } | ||
136 | } | 156 | } |
137 | 157 | ||
138 | public void RemoveRegion(Scene scene) | 158 | public void RemoveRegion(Scene scene) |
139 | { | 159 | { |
140 | if (m_LocalGridService != null) | 160 | if (m_Enabled) |
141 | ((ISharedRegionModule)m_LocalGridService).RemoveRegion(scene); | 161 | ((ISharedRegionModule)m_LocalGridService).RemoveRegion(scene); |
142 | } | 162 | } |
143 | 163 | ||
@@ -174,16 +194,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
174 | 194 | ||
175 | public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) | 195 | public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) |
176 | { | 196 | { |
177 | bool inCache = false; | 197 | GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); |
178 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache); | 198 | if (rinfo != null) |
179 | if (inCache) | ||
180 | return rinfo; | 199 | return rinfo; |
181 | |||
182 | rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); | ||
183 | if (rinfo == null) | ||
184 | rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); | ||
185 | 200 | ||
186 | m_RegionInfoCache.Cache(scopeID,regionID,rinfo); | 201 | rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); |
202 | m_RegionInfoCache.Cache(scopeID, rinfo); | ||
187 | return rinfo; | 203 | return rinfo; |
188 | } | 204 | } |
189 | 205 | ||
@@ -193,51 +209,56 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
193 | // The coordinates are world coords (meters), NOT region units. | 209 | // The coordinates are world coords (meters), NOT region units. |
194 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 210 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
195 | { | 211 | { |
196 | ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); | 212 | GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); |
197 | uint regionX = Util.WorldToRegionLoc((uint)x); | 213 | if (rinfo != null) |
198 | uint regionY = Util.WorldToRegionLoc((uint)y); | ||
199 | |||
200 | // Sanity check | ||
201 | if ((Util.RegionToWorldLoc(regionX) != (uint)x) || (Util.RegionToWorldLoc(regionY) != (uint)y)) | ||
202 | { | 214 | { |
203 | m_log.WarnFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Bad position requested: not the base of the region. Requested Pos=<{0},{1}>, Should Be=<{2},{3}>", | 215 | // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Found region {0} on local. Pos=<{1},{2}>, RegionHandle={3}", |
204 | x, y, Util.RegionToWorldLoc(regionX), Util.RegionToWorldLoc(regionY)); | 216 | // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); |
205 | } | ||
206 | |||
207 | bool inCache = false; | ||
208 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); | ||
209 | if (inCache) | ||
210 | { | ||
211 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Found region {0} in cache. Pos=<{1},{2}>, RegionHandle={3}", | ||
212 | // (rinfo == null) ? "<missing>" : rinfo.RegionName, regionX, regionY, (rinfo == null) ? regionHandle : rinfo.RegionHandle); | ||
213 | return rinfo; | 217 | return rinfo; |
214 | } | 218 | } |
215 | 219 | ||
216 | rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); | 220 | rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y); |
217 | if (rinfo == null) | ||
218 | rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y); | ||
219 | 221 | ||
220 | m_RegionInfoCache.Cache(rinfo); | 222 | if (rinfo == null) |
221 | 223 | { | |
222 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", | 224 | // uint regionX = Util.WorldToRegionLoc((uint)x); |
223 | // (rinfo == null) ? "<missing>" : rinfo.RegionName, regionX, regionY, (rinfo == null) ? regionHandle : rinfo.RegionHandle); | 225 | // uint regionY = Util.WorldToRegionLoc((uint)y); |
226 | // m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY); | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | m_RegionInfoCache.Cache(scopeID, rinfo); | ||
224 | 231 | ||
232 | // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", | ||
233 | // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); | ||
234 | } | ||
225 | return rinfo; | 235 | return rinfo; |
226 | } | 236 | } |
227 | 237 | ||
228 | public GridRegion GetRegionByName(UUID scopeID, string regionName) | 238 | public GridRegion GetRegionByName(UUID scopeID, string name) |
229 | { | 239 | { |
230 | bool inCache = false; | 240 | GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, name); |
231 | GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionName, out inCache); | 241 | if (rinfo != null) |
232 | if (inCache) | ||
233 | return rinfo; | 242 | return rinfo; |
234 | |||
235 | rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); | ||
236 | if (rinfo == null) | ||
237 | rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); | ||
238 | 243 | ||
239 | // can't cache negative results for name lookups | 244 | // HG urls should not get here, strip them |
240 | m_RegionInfoCache.Cache(rinfo); | 245 | // side effect is that local regions with same name as HG may also be found |
246 | // this mb good or bad | ||
247 | string regionName = name; | ||
248 | if(name.Contains(".")) | ||
249 | { | ||
250 | if(string.IsNullOrWhiteSpace(m_ThisGatekeeper)) | ||
251 | return rinfo; // no HG | ||
252 | |||
253 | string regionURI = ""; | ||
254 | if(!Util.buildHGRegionURI(name, out regionURI, out regionName) || string.IsNullOrWhiteSpace(regionName)) | ||
255 | return rinfo; // invalid | ||
256 | if(m_ThisGatekeeper != regionURI) | ||
257 | return rinfo; // not local grid | ||
258 | } | ||
259 | |||
260 | rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); | ||
261 | m_RegionInfoCache.Cache(scopeID, rinfo); | ||
241 | return rinfo; | 262 | return rinfo; |
242 | } | 263 | } |
243 | 264 | ||
@@ -245,7 +266,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
245 | { | 266 | { |
246 | List<GridRegion> rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber); | 267 | List<GridRegion> rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber); |
247 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionsByName {0} found {1} regions", name, rinfo.Count); | 268 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionsByName {0} found {1} regions", name, rinfo.Count); |
248 | List<GridRegion> grinfo = m_RemoteGridService.GetRegionsByName(scopeID, name, maxNumber); | 269 | |
270 | // HG urls should not get here, strip them | ||
271 | // side effect is that local regions with same name as HG may also be found | ||
272 | // this mb good or bad | ||
273 | string regionName = name; | ||
274 | if(name.Contains(".")) | ||
275 | { | ||
276 | if(string.IsNullOrWhiteSpace(m_ThisGatekeeper)) | ||
277 | return rinfo; // no HG | ||
278 | |||
279 | string regionURI = ""; | ||
280 | if(!Util.buildHGRegionURI(name, out regionURI, out regionName) || string.IsNullOrWhiteSpace(regionName)) | ||
281 | return rinfo; // invalid | ||
282 | if(m_ThisGatekeeper != regionURI) | ||
283 | return rinfo; // not local grid | ||
284 | } | ||
285 | |||
286 | List<GridRegion> grinfo = m_RemoteGridService.GetRegionsByName(scopeID, regionName, maxNumber); | ||
249 | 287 | ||
250 | if (grinfo != null) | 288 | if (grinfo != null) |
251 | { | 289 | { |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs index 25ae689..1378368 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 | |||
64 | config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion"); | 64 | config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion"); |
65 | config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion"); | 65 | config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion"); |
66 | 66 | ||
67 | m_LocalConnector = new LocalGridServicesConnector(config); | 67 | m_LocalConnector = new LocalGridServicesConnector(config, null); |
68 | } | 68 | } |
69 | 69 | ||
70 | /// <summary> | 70 | /// <summary> |
@@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests | |||
88 | Scene s = new Scene(new RegionInfo()); | 88 | Scene s = new Scene(new RegionInfo()); |
89 | s.RegionInfo.RegionID = r1.RegionID; | 89 | s.RegionInfo.RegionID = r1.RegionID; |
90 | m_LocalConnector.AddRegion(s); | 90 | m_LocalConnector.AddRegion(s); |
91 | 91 | ||
92 | GridRegion r2 = new GridRegion(); | 92 | GridRegion r2 = new GridRegion(); |
93 | r2.RegionName = "Test Region 2"; | 93 | r2.RegionName = "Test Region 2"; |
94 | r2.RegionID = new UUID(2); | 94 | r2.RegionID = new UUID(2); |
@@ -198,4 +198,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests | |||
198 | Assert.That(results.Count, Is.EqualTo(0), "Retrieved linked regions collection is not the number expected"); | 198 | Assert.That(results.Count, Is.EqualTo(0), "Retrieved linked regions collection is not the number expected"); |
199 | } | 199 | } |
200 | } | 200 | } |
201 | } \ No newline at end of file | 201 | } |