From 26d16567e1e2bf28a3eafce6d3acf8d9646aaf84 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 26 Mar 2011 00:53:19 +0000 Subject: [PATCH] Make SceneGraph.ForEachSOG() execute once for each SOG, not once for each prim (e.g. a SOG with 3 prims would have the action executed three times). To do this, a new SceneObjectGroupsByFullID index in SceneGraph which just index's prims by their root part UUID, in order to avoid the inefficiency of filtering existing lists. Existing callers to SceneGraph.ForEachSOG() did not fail due to the multiple per SOG action executions - they were probably just much less efficient. Code suggests that no callers expected ForEachSOG() to execute actions on sog multiple times --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 345ed7a5ef..1621398bcb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -88,9 +88,21 @@ namespace OpenSim.Region.Framework.Scenes protected internal object m_syncRoot = new object(); protected internal PhysicsScene _PhyScene; - - protected internal Dictionary SceneObjectGroupsByLocalPartID = new Dictionary(); + + /// + /// Index the SceneObjectGroup for each part by the root part's UUID. + /// + protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); + + /// + /// Index the SceneObjectGroup for each part by that part's UUID. + /// protected internal Dictionary SceneObjectGroupsByFullPartID = new Dictionary(); + + /// + /// Index the SceneObjectGroup for each part by that part's local ID. + /// + protected internal Dictionary SceneObjectGroupsByLocalPartID = new Dictionary(); private Object m_updateLock = new Object(); @@ -131,6 +143,8 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresenceArray = newlist; } + lock (SceneObjectGroupsByFullID) + SceneObjectGroupsByFullID.Clear(); lock (SceneObjectGroupsByFullPartID) SceneObjectGroupsByFullPartID.Clear(); lock (SceneObjectGroupsByLocalPartID) @@ -384,6 +398,9 @@ namespace OpenSim.Region.Framework.Scenes if (OnObjectCreate != null) OnObjectCreate(sceneObject); + lock (SceneObjectGroupsByFullID) + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + lock (SceneObjectGroupsByFullPartID) { SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject; @@ -426,6 +443,9 @@ namespace OpenSim.Region.Framework.Scenes if (OnObjectRemove != null) OnObjectRemove(Entities[uuid]); + + lock (SceneObjectGroupsByFullID) + SceneObjectGroupsByFullID.Remove(grp.UUID); lock (SceneObjectGroupsByFullPartID) { @@ -1064,12 +1084,13 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Performs action on all scene object groups. + /// Performs action once on all scene object groups. /// /// protected internal void ForEachSOG(Action action) { - List objlist = new List(SceneObjectGroupsByFullPartID.Values); + // FIXME: Need to lock here, really. + List objlist = new List(SceneObjectGroupsByFullID.Values); foreach (SceneObjectGroup obj in objlist) { try @@ -1084,7 +1105,6 @@ namespace OpenSim.Region.Framework.Scenes } } } - /// /// Performs action on all scene presences. This can ultimately run the actions in parallel but