diff options
author | John Hurliman | 2009-10-23 01:02:36 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-23 01:02:36 -0700 |
commit | 588361e2a2398b963871762c2b5485c6a086cf47 (patch) | |
tree | 5be2c6705096817c599075da4e12a0e9b0a4c841 /OpenSim/Region/Framework/Scenes/SceneGraph.cs | |
parent | Added VS2010 support to Prebuild and created runprebuild2010.bat (diff) | |
download | opensim-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.cs | 160 |
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 | } |