From f36f1010b7cf48c4447b5bc409597645b53f8523 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 1 Feb 2011 10:07:20 -0800 Subject: [PATCH] Started to add code for concurrency control of updating objec properties on per bucket base. Added code to process to PrimPropertyBucketMap in RegionSyncModule and BucketSyncInfo in SceneObjectPart. --- .../SymmetricSync/RegionSyncModule.cs | 59 +++++++ .../Framework/Interfaces/IRegionSyncModule.cs | 1 + .../Framework/Scenes/SceneObjectPart.cs | 156 +++++++++++++++++- 3 files changed, 215 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index ecbae7927c..b26d2942d4 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_isSyncRelay = m_sysConfig.GetBoolean("IsSyncRelay", false); m_isSyncListenerLocal = m_sysConfig.GetBoolean("IsSyncListenerLocal", false); + //Setup the PropertyBucketMap + PupolatePropertyBucketMap(m_sysConfig); + m_active = true; LogHeader += "-Actor " + m_actorID; @@ -176,6 +179,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule get { return m_isSyncRelay; } } + private Dictionary m_primPropertyBucketMap = new Dictionary(); + public Dictionary PrimPropertyBucketMap + { + get { return m_primPropertyBucketMap; } + } + public List PropertyBucketDescription = new List(); + private RegionSyncListener m_localSyncListener = null; private bool m_synced = false; @@ -186,6 +196,55 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private Dictionary m_presenceUpdates = new Dictionary(); private int m_sendingUpdates; + private int m_maxNumOfPropertyBuckets; + + //Read in configuration for which property-bucket each property belongs to, and the description of each bucket + private void PupolatePropertyBucketMap(IConfig config) + { + PupolatePropertyBuketMapByDefault(); + + } + + //If nothing configured in the config file, this is the default settings for grouping properties into different bucket + private void PupolatePropertyBuketMapByDefault() + { + //by default, there are two property buckets: the "General" bucket and the "Physics" bucket. + PropertyBucketDescription.Add("General"); + PropertyBucketDescription.Add("Physics"); + m_maxNumOfPropertyBuckets = 2; + + int generalBucketID = 0; + int physicsBucketID = 1; + + foreach (string pName in SceneObjectPart.PropertyList) + { + switch (pName){ + case "GroupPosition": + case "OffsetPosition": + case "Scale": + case "Velocity": + case "AngularVelocity": + case "RotationOffset": + case "Position": + case "Size": + case "Force": + case "RotationalVelocity": + case "PA_Acceleration": + case "Torque": + case "Orientation": + case "IsPhysical": + case "Flying": + case "Buoyancy": + m_primPropertyBucketMap.Add(pName, physicsBucketID); + break; + default: + //all other properties belong to the "General" bucket. + m_primPropertyBucketMap.Add(pName, generalBucketID); + break; + } + } + } + public void QueueSceneObjectPartForUpdate(SceneObjectPart part) { //if the last update of the prim is caused by this actor itself, or if the actor is a relay node, then enqueue the update diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs index 5bd5957706..0b2fccb24b 100755 --- a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs @@ -55,6 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces string ActorID { get; } DSGActorTypes DSGActorType { get; set; } bool IsSyncRelay { get; } + Dictionary PrimPropertyBucketMap { get; } //Enqueue updates for scene-objects and scene-presences void QueueSceneObjectPartForUpdate(SceneObjectPart part); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 153fee1154..05140def97 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -107,6 +107,44 @@ namespace OpenSim.Region.Framework.Scenes #endregion Enumerations + //SYMMETRIC SYNC + + //Information for concurrency control of one bucket of prim proproperties. + public class BucketSyncInfo + { + private long m_lastUpdateTimeStamp; + private string m_lastUpdateActorID; + //lock for concurrent updates of the timestamp and actorID. + private Object m_updateLock = new Object(); + + public long LastUpdateTimeStamp + { + get { return m_lastUpdateTimeStamp; } + } + + public string LastUpdateActorID + { + get { return m_lastUpdateActorID; } + } + + public BucketSyncInfo(long timeStamp, string actorID) + { + m_lastUpdateTimeStamp = timeStamp; + m_lastUpdateActorID = actorID; + } + + public void UpdateSyncInfo(long timeStamp, string actorID) + { + lock (m_updateLock) + { + m_lastUpdateTimeStamp = timeStamp; + m_lastUpdateActorID = actorID; + } + } + + } + //end of SYMMETRIC SYNC + public class SceneObjectPart : IScriptHost, ISceneEntity { /// @@ -127,7 +165,18 @@ namespace OpenSim.Region.Framework.Scenes #region Fields - public bool AllowedDrop; + //SYMMETRIC SYNC + //public bool AllowedDrop; + private bool m_allowedDrop; + public bool AllowedDrop + { + get { return m_allowedDrop; } + set + { + m_allowedDrop = value; + UpdateBucketSyncInfo("AllowedDrop"); + } + } public bool DIE_AT_EDGE; @@ -4971,6 +5020,83 @@ namespace OpenSim.Region.Framework.Scenes } } + //The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors. + //This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the + //properties Physics Engine needs to synchronize to other actors. + public static List PropertyList = new List() + { + //Following properties copied from SceneObjectSerializer() + "AllowedDrop", + "CreatorID", + "CreatorData", + "FolderID", + "InventorySerial", + "TaskInventory", + "UUID", + "LocalId", + "Name", + "Material", + "PassTouches", + "RegionHandle", + "ScriptAccessPin", + "GroupPosition", + "OffsetPosition", + "RotationOffset", + "Velocity", + "AngularVelocity", + //"Acceleration", + "SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies + "Description", + "Color", + "Text", + "SitName", + "TouchName", + "LinkNum", + "ClickAction", + "Shape", + "Scale", + "UpdateFlag", + "SitTargetOrientation", + "SitTargetPosition", + "SitTargetPositionLL", + "SitTargetOrientationLL", + "ParentID", + "CreationDate", + "Category", + "SalePrice", + "ObjectSaleType", + "OwnershipCost", + "GroupID", + "OwnerID", + "LastOwnerID", + "BaseMask", + "OwnerMask", + "GroupMask", + "EveryoneMask", + "NextOwnerMask", + "Flags", + "CollisionSound", + "CollisionSoundVolume", + "MediaUrl", + "TextureAnimation", + "ParticleSystem", + //Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties + //Physics properties "Velocity" is covered above + "Position", + "Size", + "Force", + "RotationalVelocity", + "PA_Acceleration", + "Torque", + "Orientation", + "IsPhysical", + "Flying", + "Buoyancy", + }; + + + + private Object propertyUpdateLock = new Object(); //!!!!!! -- TODO: @@ -5150,6 +5276,34 @@ namespace OpenSim.Region.Framework.Scenes } + //The following three variables should be initialized when this SceneObjectPart is added into the local Scene. + private List m_bucketSyncInfo = null; + private Dictionary m_primPropertyBucketMap = null; + private string m_localActorID = ""; + + public void InitializeBucketSyncInfo(Dictionary propertyBucketMap, string actorID) + { + m_primPropertyBucketMap = propertyBucketMap; + m_localActorID = actorID; + int bucketNum = propertyBucketMap.Count; + long timeStamp = DateTime.Now.Ticks; + for (int i = 0; i < bucketNum; i++) + { + BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID); + m_bucketSyncInfo.Add(syncInfo); + } + } + + private void UpdateBucketSyncInfo(string propertyName) + { + if (m_bucketSyncInfo != null) + { + int bucketIndex = m_primPropertyBucketMap[propertyName]; + long timeStamp = DateTime.Now.Ticks; + m_bucketSyncInfo[bucketIndex].UpdateSyncInfo(timeStamp, m_localActorID); + } + } + #endregion }