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.
dsg
Huaiyu (Kitty) Liu 2011-02-01 10:07:20 -08:00
parent a7d4c974dd
commit f36f1010b7
3 changed files with 215 additions and 1 deletions

View File

@ -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<string, int> m_primPropertyBucketMap = new Dictionary<string, int>();
public Dictionary<string, int> PrimPropertyBucketMap
{
get { return m_primPropertyBucketMap; }
}
public List<string> PropertyBucketDescription = new List<string>();
private RegionSyncListener m_localSyncListener = null;
private bool m_synced = false;
@ -186,6 +196,55 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
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

View File

@ -55,6 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces
string ActorID { get; }
DSGActorTypes DSGActorType { get; set; }
bool IsSyncRelay { get; }
Dictionary<string, int> PrimPropertyBucketMap { get; }
//Enqueue updates for scene-objects and scene-presences
void QueueSceneObjectPartForUpdate(SceneObjectPart part);

View File

@ -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
{
/// <value>
@ -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<string> PropertyList = new List<string>()
{
//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<BucketSyncInfo> m_bucketSyncInfo = null;
private Dictionary<string, int> m_primPropertyBucketMap = null;
private string m_localActorID = "";
public void InitializeBucketSyncInfo(Dictionary<string, int> 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
}