aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-23 01:02:36 -0700
committerJohn Hurliman2009-10-23 01:02:36 -0700
commit588361e2a2398b963871762c2b5485c6a086cf47 (patch)
tree5be2c6705096817c599075da4e12a0e9b0a4c841 /OpenSim/Region/Framework/Scenes/SceneGraph.cs
parentAdded VS2010 support to Prebuild and created runprebuild2010.bat (diff)
downloadopensim-SC-588361e2a2398b963871762c2b5485c6a086cf47.zip
opensim-SC-588361e2a2398b963871762c2b5485c6a086cf47.tar.gz
opensim-SC-588361e2a2398b963871762c2b5485c6a086cf47.tar.bz2
opensim-SC-588361e2a2398b963871762c2b5485c6a086cf47.tar.xz
Experimental change to use an immutable array for iterating ScenePresences, avoiding locking and copying the list each time it is accessed
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs160
1 files changed, 84 insertions, 76 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index deee6c3..db055f9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -66,7 +66,9 @@ namespace OpenSim.Region.Framework.Scenes
66 66
67 #region Fields 67 #region Fields
68 68
69 protected internal Dictionary<UUID, ScenePresence> ScenePresences = new Dictionary<UUID, ScenePresence>(); 69 protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>();
70 protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0];
71
70 // SceneObjects is not currently populated or used. 72 // SceneObjects is not currently populated or used.
71 //public Dictionary<UUID, SceneObjectGroup> SceneObjects; 73 //public Dictionary<UUID, SceneObjectGroup> SceneObjects;
72 protected internal EntityManager Entities = new EntityManager(); 74 protected internal EntityManager Entities = new EntityManager();
@@ -126,10 +128,12 @@ namespace OpenSim.Region.Framework.Scenes
126 128
127 protected internal void Close() 129 protected internal void Close()
128 { 130 {
129 lock (ScenePresences) 131 lock (m_scenePresences)
130 { 132 {
131 ScenePresences.Clear(); 133 m_scenePresences.Clear();
134 m_scenePresenceArray = new ScenePresence[0];
132 } 135 }
136
133 lock (m_dictionary_lock) 137 lock (m_dictionary_lock)
134 { 138 {
135 SceneObjectGroupsByFullID.Clear(); 139 SceneObjectGroupsByFullID.Clear();
@@ -157,11 +161,9 @@ namespace OpenSim.Region.Framework.Scenes
157 161
158 protected internal void UpdatePresences() 162 protected internal void UpdatePresences()
159 { 163 {
160 List<ScenePresence> updateScenePresences = GetScenePresences(); 164 ScenePresence[] updateScenePresences = GetScenePresences();
161 foreach (ScenePresence pres in updateScenePresences) 165 for (int i = 0; i < updateScenePresences.Length; i++)
162 { 166 updateScenePresences[i].Update();
163 pres.Update();
164 }
165 } 167 }
166 168
167 protected internal float UpdatePhysics(double elapsed) 169 protected internal float UpdatePhysics(double elapsed)
@@ -190,15 +192,9 @@ namespace OpenSim.Region.Framework.Scenes
190 192
191 protected internal void UpdateScenePresenceMovement() 193 protected internal void UpdateScenePresenceMovement()
192 { 194 {
193 List<ScenePresence> moveEntities = GetScenePresences(); 195 ScenePresence[] moveEntities = GetScenePresences();
194 196 for (int i = 0; i < moveEntities.Length; i++)
195 foreach (EntityBase entity in moveEntities) 197 moveEntities[i].UpdateMovement();
196 {
197 //cfk. This throws occaisional exceptions on a heavily used region
198 //and I added this null check to try to preclude the exception.
199 if (entity != null)
200 entity.UpdateMovement();
201 }
202 } 198 }
203 199
204 #endregion 200 #endregion
@@ -645,9 +641,34 @@ namespace OpenSim.Region.Framework.Scenes
645 641
646 Entities[presence.UUID] = presence; 642 Entities[presence.UUID] = presence;
647 643
648 lock (ScenePresences) 644 lock (m_scenePresences)
649 { 645 {
650 ScenePresences[presence.UUID] = presence; 646 if (!m_scenePresences.ContainsKey(presence.UUID))
647 {
648 m_scenePresences.Add(presence.UUID, presence);
649
650 // Create a new array of ScenePresence references
651 int oldLength = m_scenePresenceArray.Length;
652 ScenePresence[] newArray = new ScenePresence[oldLength + 1];
653 Array.Copy(m_scenePresenceArray, newArray, oldLength);
654 newArray[oldLength] = presence;
655 m_scenePresenceArray = newArray;
656 }
657 else
658 {
659 m_scenePresences[presence.UUID] = presence;
660
661 // Do a linear search through the array of ScenePresence references
662 // and update the modified entry
663 for (int i = 0; i < m_scenePresenceArray.Length; i++)
664 {
665 if (m_scenePresenceArray[i].UUID == presence.UUID)
666 {
667 m_scenePresenceArray[i] = presence;
668 break;
669 }
670 }
671 }
651 } 672 }
652 } 673 }
653 674
@@ -663,16 +684,30 @@ namespace OpenSim.Region.Framework.Scenes
663 agentID); 684 agentID);
664 } 685 }
665 686
666 lock (ScenePresences) 687 lock (m_scenePresences)
667 { 688 {
668 if (!ScenePresences.Remove(agentID)) 689 if (m_scenePresences.Remove(agentID))
690 {
691 // Copy all of the elements from the previous array
692 // into the new array except the removed element
693 int oldLength = m_scenePresenceArray.Length;
694 ScenePresence[] newArray = new ScenePresence[oldLength - 1];
695 int j = 0;
696 for (int i = 0; i < m_scenePresenceArray.Length; i++)
697 {
698 ScenePresence presence = m_scenePresenceArray[i];
699 if (presence.UUID != agentID)
700 {
701 newArray[j] = presence;
702 ++j;
703 }
704 }
705 m_scenePresenceArray = newArray;
706 }
707 else
669 { 708 {
670 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 709 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
671 } 710 }
672// else
673// {
674// m_log.InfoFormat("[SCENE] Removed scene presence {0} from scene presences list", agentID);
675// }
676 } 711 }
677 } 712 }
678 713
@@ -704,20 +739,21 @@ namespace OpenSim.Region.Framework.Scenes
704 739
705 public void RecalculateStats() 740 public void RecalculateStats()
706 { 741 {
707 List<ScenePresence> SPList = GetScenePresences(); 742 ScenePresence[] presences = GetScenePresences();
708 int rootcount = 0; 743 int rootcount = 0;
709 int childcount = 0; 744 int childcount = 0;
710 745
711 foreach (ScenePresence user in SPList) 746 for (int i = 0; i < presences.Length; i++)
712 { 747 {
748 ScenePresence user = presences[i];
713 if (user.IsChildAgent) 749 if (user.IsChildAgent)
714 childcount++; 750 ++childcount;
715 else 751 else
716 rootcount++; 752 ++rootcount;
717 } 753 }
754
718 m_numRootAgents = rootcount; 755 m_numRootAgents = rootcount;
719 m_numChildAgents = childcount; 756 m_numChildAgents = childcount;
720
721 } 757 }
722 758
723 public int GetChildAgentCount() 759 public int GetChildAgentCount()
@@ -767,12 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
767 /// locking is required to iterate over it. 803 /// locking is required to iterate over it.
768 /// </summary> 804 /// </summary>
769 /// <returns></returns> 805 /// <returns></returns>
770 protected internal List<ScenePresence> GetScenePresences() 806 protected internal ScenePresence[] GetScenePresences()
771 { 807 {
772 lock (ScenePresences) 808 return m_scenePresenceArray;
773 {
774 return new List<ScenePresence>(ScenePresences.Values);
775 }
776 } 809 }
777 810
778 protected internal List<ScenePresence> GetAvatars() 811 protected internal List<ScenePresence> GetAvatars()
@@ -817,14 +850,13 @@ namespace OpenSim.Region.Framework.Scenes
817 // No locking of scene presences here since we're passing back a list... 850 // No locking of scene presences here since we're passing back a list...
818 851
819 List<ScenePresence> result = new List<ScenePresence>(); 852 List<ScenePresence> result = new List<ScenePresence>();
820 List<ScenePresence> ScenePresencesList = GetScenePresences(); 853 ScenePresence[] scenePresences = GetScenePresences();
821 854
822 foreach (ScenePresence avatar in ScenePresencesList) 855 for (int i = 0; i < scenePresences.Length; i++)
823 { 856 {
857 ScenePresence avatar = scenePresences[i];
824 if (filter(avatar)) 858 if (filter(avatar))
825 {
826 result.Add(avatar); 859 result.Add(avatar);
827 }
828 } 860 }
829 861
830 return result; 862 return result;
@@ -839,9 +871,9 @@ namespace OpenSim.Region.Framework.Scenes
839 { 871 {
840 ScenePresence sp; 872 ScenePresence sp;
841 873
842 lock (ScenePresences) 874 lock (m_scenePresences)
843 { 875 {
844 ScenePresences.TryGetValue(agentID, out sp); 876 m_scenePresences.TryGetValue(agentID, out sp);
845 } 877 }
846 878
847 return sp; 879 return sp;
@@ -1000,48 +1032,24 @@ namespace OpenSim.Region.Framework.Scenes
1000 1032
1001 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) 1033 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
1002 { 1034 {
1003 ScenePresence presence; 1035 lock (m_scenePresences)
1004 1036 return m_scenePresences.TryGetValue(avatarId, out avatar);
1005 lock (ScenePresences)
1006 {
1007 if (ScenePresences.TryGetValue(avatarId, out presence))
1008 {
1009 avatar = presence;
1010 return true;
1011
1012 //if (!presence.IsChildAgent)
1013 //{
1014 // avatar = presence;
1015 // return true;
1016 //}
1017 //else
1018 //{
1019 // m_log.WarnFormat(
1020 // "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!",
1021 // avatarId, m_parentScene.RegionInfo.RegionName);
1022 //}
1023 }
1024 }
1025
1026 avatar = null;
1027 return false;
1028 } 1037 }
1029 1038
1030 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) 1039 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
1031 { 1040 {
1032 lock (ScenePresences) 1041 ScenePresence[] presences = GetScenePresences();
1042
1043 for (int i = 0; i < presences.Length; i++)
1033 { 1044 {
1034 foreach (ScenePresence presence in ScenePresences.Values) 1045 ScenePresence presence = presences[i];
1046
1047 if (!presence.IsChildAgent)
1035 { 1048 {
1036 if (!presence.IsChildAgent) 1049 if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0)
1037 { 1050 {
1038 string name = presence.ControllingClient.Name; 1051 avatar = presence;
1039 1052 return true;
1040 if (String.Compare(avatarName, name, true) == 0)
1041 {
1042 avatar = presence;
1043 return true;
1044 }
1045 } 1053 }
1046 } 1054 }
1047 } 1055 }