Browse Source

Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

Diva Canto 13 years ago
parent
commit
7819b4a794

+ 137 - 0
OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs

@@ -0,0 +1,137 @@
+/*
+ * 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.Reflection;
+using System.Collections.Generic;
+using OpenSim.Framework;
+using OpenSim.Services.Interfaces;
+using OpenMetaverse;
+using log4net;
+using GridRegion = OpenSim.Services.Interfaces.GridRegion;
+
+namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
+{
+    public class RegionInfoCache
+    {
+        private const double CACHE_EXPIRATION_SECONDS = 300.0; // 5 minutes
+
+//        private static readonly ILog m_log =
+//                LogManager.GetLogger(
+//                MethodBase.GetCurrentMethod().DeclaringType);
+        
+        internal struct ScopedRegionUUID
+        {
+            public UUID m_scopeID;
+            public UUID m_regionID;
+            public ScopedRegionUUID(UUID scopeID, UUID regionID)
+            {
+                m_scopeID = scopeID;
+                m_regionID = regionID;
+            }
+        }
+            
+        internal struct ScopedRegionName
+        {
+            public UUID m_scopeID;
+            public string m_name;
+            public ScopedRegionName(UUID scopeID, string name)
+            {
+                m_scopeID = scopeID;
+                m_name = name;
+            }
+        }
+
+        private ExpiringCache<ScopedRegionUUID, GridRegion> m_UUIDCache;
+        private ExpiringCache<ScopedRegionName, ScopedRegionUUID> m_NameCache;
+
+        public RegionInfoCache()
+        {
+            m_UUIDCache = new ExpiringCache<ScopedRegionUUID, GridRegion>();
+            m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>(); 
+        }
+
+        public void Cache(GridRegion rinfo)
+        {
+            if (rinfo != null)
+                this.Cache(rinfo.ScopeID,rinfo.RegionID,rinfo);
+        }
+        
+        public void Cache(UUID scopeID, UUID regionID, 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;
+            
+            ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID);
+            
+            // Cache even null accounts
+            m_UUIDCache.AddOrUpdate(id, rinfo, CACHE_EXPIRATION_SECONDS);
+            if (rinfo != null)
+            {
+                ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName);
+                m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS);
+            }
+        }
+
+        public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
+        {
+            inCache = false;
+
+            GridRegion rinfo = null;
+            ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID);
+            if (m_UUIDCache.TryGetValue(id, out rinfo))
+            {
+                inCache = true;
+                return rinfo;
+            }
+
+            return null;
+        }
+
+        public GridRegion Get(UUID scopeID, string name, out bool inCache)
+        {
+            inCache = false;
+
+            ScopedRegionName sname = new ScopedRegionName(scopeID,name);
+
+            ScopedRegionUUID id;
+            if (m_NameCache.TryGetValue(sname, out id))
+            {
+                GridRegion rinfo = null;
+                if (m_UUIDCache.TryGetValue(id, out rinfo))
+                {
+                    inCache = true;
+                    return rinfo;
+                }
+            }
+            
+            return null;
+        }
+    }
+}

+ 32 - 2
OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs

@@ -53,6 +53,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
         private IGridService m_LocalGridService;
         private IGridService m_RemoteGridService;
 
+        private RegionInfoCache m_RegionInfoCache = new RegionInfoCache();
+        
         public RemoteGridServicesConnector()
         {
         }
@@ -169,10 +171,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
 
         public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
         {
-            GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
+            bool inCache = false;
+            GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache);
+            if (inCache)
+                return rinfo;
+            
+            rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
             if (rinfo == null)
                 rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID);
 
+            m_RegionInfoCache.Cache(scopeID,regionID,rinfo);
             return rinfo;
         }
 
@@ -187,10 +195,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
 
         public GridRegion GetRegionByName(UUID scopeID, string regionName)
         {
-            GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName);
+            bool inCache = false;
+            GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionName, out inCache);
+            if (inCache)
+                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
+            m_RegionInfoCache.Cache(rinfo);
             return rinfo;
         }
 
@@ -204,8 +219,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             {
                 //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count);
                 foreach (GridRegion r in grinfo)
+                {
+                    m_RegionInfoCache.Cache(r);
                     if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
                         rinfo.Add(r);
+                }
             }
 
             return rinfo;
@@ -221,8 +239,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             {
                 //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count);
                 foreach (GridRegion r in grinfo)
+                {
+                    m_RegionInfoCache.Cache(r);
                     if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
                         rinfo.Add(r);
+                }
             }
 
             return rinfo;
@@ -238,8 +259,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             {
                 //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count);
                 foreach (GridRegion r in grinfo)
+                {
+                    m_RegionInfoCache.Cache(r);
                     if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
                         rinfo.Add(r);
+                }
             }
 
             return rinfo;
@@ -255,8 +279,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             {
                 //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count);
                 foreach (GridRegion r in grinfo)
+                {
+                    m_RegionInfoCache.Cache(r);
                     if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
                         rinfo.Add(r);
+                }
             }
 
             return rinfo;
@@ -272,8 +299,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
             {
                 //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count);
                 foreach (GridRegion r in grinfo)
+                {
+                    m_RegionInfoCache.Cache(r);
                     if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
                         rinfo.Add(r);
+                }
             }
 
             return rinfo;

+ 9 - 4
OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs

@@ -1449,19 +1449,25 @@ namespace OpenSim.Region.Framework.Scenes
 
             foreach (SceneObjectPart part in partList)
             {
+                SceneObjectPart newPart;
                 if (part.UUID != m_rootPart.UUID)
                 {
-                    SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
+                    newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
                     newPart.LinkNum = part.LinkNum;
                 }
+                else
+                {
+                    newPart = dupe.m_rootPart;
+                }
 
                 // Need to duplicate the physics actor as well
                 if (part.PhysActor != null && userExposed)
                 {
                     PrimitiveBaseShape pbs = part.Shape;
     
-                    part.PhysActor 
+                    newPart.PhysActor
                         = m_scene.PhysicsScene.AddPrimShape(
+                            part.LocalId,
                             string.Format("{0}/{1}", part.Name, part.UUID),
                             pbs,
                             part.AbsolutePosition,
@@ -1469,8 +1475,7 @@ namespace OpenSim.Region.Framework.Scenes
                             part.RotationOffset,
                             part.PhysActor.IsPhysical);
     
-                    part.PhysActor.LocalID = part.LocalId;
-                    part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
+                    newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
                 }
             }
             

+ 2 - 2
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs

@@ -1582,6 +1582,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
                 {
                     PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
+                        LocalId,
                         string.Format("{0}/{1}", Name, UUID),
                         Shape,
                         AbsolutePosition,
@@ -1594,7 +1595,6 @@ namespace OpenSim.Region.Framework.Scenes
                     {
                         PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
                         PhysActor.SOPDescription = this.Description;
-                        PhysActor.LocalID = LocalId;
                         DoPhysicsPropertyUpdate(RigidBody, true);
                         PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
                     }
@@ -4410,6 +4410,7 @@ namespace OpenSim.Region.Framework.Scenes
                 {
                     // It's not phantom anymore. So make sure the physics engine get's knowledge of it
                     PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
+                        LocalId,
                         string.Format("{0}/{1}", Name, UUID),
                         Shape,
                         AbsolutePosition,
@@ -4420,7 +4421,6 @@ namespace OpenSim.Region.Framework.Scenes
                     pa = PhysActor;
                     if (pa != null)
                     {
-                        pa.LocalID = LocalId;
                         DoPhysicsPropertyUpdate(UsePhysics, true);
                         if (m_parentGroup != null)
                         {

+ 1 - 1
OpenSim/Region/Framework/Scenes/ScenePresence.cs

@@ -3295,7 +3295,7 @@ namespace OpenSim.Region.Framework.Scenes
             Vector3 pVec = AbsolutePosition;
 
             // Old bug where the height was in centimeters instead of meters
-            m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
+            m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec,
                                                  new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
 
             scene.AddPhysicsActorTaint(m_physicsActor);

+ 6 - 1
OpenSim/Region/Physics/Manager/PhysicsActor.cs

@@ -142,7 +142,12 @@ namespace OpenSim.Region.Physics.Manager
 
         public abstract PrimitiveBaseShape Shape { set; }
 
-        public abstract uint LocalID { set; }
+        uint m_baseLocalID;
+        public virtual uint LocalID
+        {
+            set { m_baseLocalID = value; }
+            get { return m_baseLocalID; }
+        }
 
         public abstract bool Grabbed { set; }
 

+ 15 - 0
OpenSim/Region/Physics/Manager/PhysicsScene.cs

@@ -66,6 +66,13 @@ namespace OpenSim.Region.Physics.Manager
 
         public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying);
 
+        public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying)
+        {
+            PhysicsActor ret = AddAvatar(avName, position, size, isFlying);
+            if (ret != null) ret.LocalID = localID;
+            return ret;
+        }
+
         public abstract void RemoveAvatar(PhysicsActor actor);
 
         public abstract void RemovePrim(PhysicsActor prim);
@@ -75,6 +82,14 @@ namespace OpenSim.Region.Physics.Manager
         public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
                                                   Vector3 size, Quaternion rotation, bool isPhysical);
 
+        public virtual PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position,
+                                                  Vector3 size, Quaternion rotation, bool isPhysical)
+        {
+            PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical);
+            if (ret != null) ret.LocalID = localID;
+            return ret;
+        }
+
         public virtual float TimeDilation
         {
             get { return 1.0f; }