Only force prim persistence before delete if the prim is the result of an unpersisted delink

This considerably improves delete performance for objects with large linksets
This commit is contained in:
Justin Clark-Casey (justincc)
2010-12-03 00:08:58 +00:00
parent 5246d98b8d
commit 7e72afcb3e
4 changed files with 28 additions and 8 deletions

View File

@@ -1997,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="group">Object Id</param>
/// <param name="silent">Suppress broadcasting changes to other clients.</param>
public void DeleteSceneObject(SceneObjectGroup group, bool silent)
{
{
// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
//SceneObjectPart rootPart = group.GetChildPart(group.UUID);
@@ -2038,7 +2038,7 @@ namespace OpenSim.Region.Framework.Scenes
group.DeleteGroupFromScene(silent);
// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
}
/// <summary>
@@ -2057,9 +2057,12 @@ namespace OpenSim.Region.Framework.Scenes
// Force a database update so that the scene object group ID is accurate. It's possible that the
// group has recently been delinked from another group but that this change has not been persisted
// to the DB.
ForceSceneObjectBackup(so);
// This is an expensive thing to do so only do it if absolutely necessary.
if (so.HasGroupChangedDueToDelink)
ForceSceneObjectBackup(so);
so.DetachFromBackup();
SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID);
SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID);
}
// We need to keep track of this state in case this group is still queued for further backup.

View File

@@ -119,10 +119,19 @@ namespace OpenSim.Region.Framework.Scenes
timeFirstChanged = DateTime.Now.Ticks;
}
m_hasGroupChanged = value;
// m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: HasGroupChanged set to {0} for {1} {2}", m_hasGroupChanged, Name, LocalId);
}
get { return m_hasGroupChanged; }
}
/// <summary>
/// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since
/// an unlinked group currently has to be persisted to the database before we can perform an unlink operation.
/// </summary>
public bool HasGroupChangedDueToDelink { get; private set; }
private bool isTimeToPersist()
{
@@ -1330,6 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes
backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
HasGroupChanged = false;
HasGroupChangedDueToDelink = false;
m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
@@ -2208,8 +2218,9 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.Rezzed = RootPart.Rezzed;
//HasGroupChanged = true;
//ScheduleGroupForFullUpdate();
// When we delete a group, we currently have to force persist to the database if the object id has changed
// (since delete works by deleting all rows which have a given object id)
objectGroup.HasGroupChangedDueToDelink = true;
return objectGroup;
}

View File

@@ -121,13 +121,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
"Not exactly sure what this is asserting...");
// Delink part 2
grp1.DelinkFromGroup(part2.LocalId);
SceneObjectGroup grp3 = grp1.DelinkFromGroup(part2.LocalId);
if (debugtest)
m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset);
Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink.");
Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero");
Assert.That(grp3.HasGroupChangedDueToDelink, Is.True);
}
[Test]
@@ -325,7 +326,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
SceneObjectGroup sog = new SceneObjectGroup(rootPart);
sog.AddPart(linkPart);
scene.AddNewSceneObject(sog, true);
scene.AddNewSceneObject(sog, true);
// In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked
// scene backup thread.
@@ -333,7 +334,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// These changes should occur immediately without waiting for a backup pass
SceneObjectGroup groupToDelete = sog.DelinkFromGroup(linkPart, false);
Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.True);
scene.DeleteSceneObject(groupToDelete, false);
Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.False);
List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID);