From 7e72afcb3e9d5467ad4dd2e6ba5d1e0632d77877 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 3 Dec 2010 00:08:58 +0000
Subject: 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
---
OpenSim/Region/Framework/Scenes/Scene.cs | 11 +++++++----
OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 15 +++++++++++++--
.../Framework/Scenes/Tests/SceneObjectLinkingTests.cs | 8 ++++++--
3 files changed, 26 insertions(+), 8 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 90223b1..66c6924 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1997,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Object Id
/// Suppress broadcasting changes to other clients.
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);
}
///
@@ -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.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4ec530e..f17fb28 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -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; }
}
+
+ ///
+ /// 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.
+ ///
+ 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;
}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index f57cf98..b84298f 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -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 storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID);
--
cgit v1.1