* Make object persistence more granular by separating prim and prim inventory persistence
parent
da8923450a
commit
504ae63669
|
@ -156,9 +156,9 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
// MainLog.Instance.Verbose("DATASTORE", "Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveObject(LLUUID obj, LLUUID regionUUID)
|
||||
|
@ -198,9 +198,9 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
// Remove prim row
|
||||
row.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -215,84 +215,77 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
DataTable prims = m_primTable;
|
||||
DataTable shapes = m_shapeTable;
|
||||
|
||||
try
|
||||
string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'";
|
||||
string orderByParent = "ParentID ASC";
|
||||
|
||||
lock (m_dataSet)
|
||||
{
|
||||
string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'";
|
||||
string orderByParent = "ParentID ASC";
|
||||
DataRow[] primsForRegion = prims.Select(byRegion, orderByParent);
|
||||
MainLog.Instance.Verbose("DATASTORE",
|
||||
"Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
|
||||
|
||||
lock (m_dataSet)
|
||||
foreach (DataRow primRow in primsForRegion)
|
||||
{
|
||||
DataRow[] primsForRegion = prims.Select(byRegion, orderByParent);
|
||||
MainLog.Instance.Verbose("DATASTORE",
|
||||
"Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
|
||||
|
||||
foreach (DataRow primRow in primsForRegion)
|
||||
try
|
||||
{
|
||||
try
|
||||
string uuid = (string) primRow["UUID"];
|
||||
string objID = (string) primRow["SceneGroupID"];
|
||||
|
||||
SceneObjectPart prim = buildPrim(primRow);
|
||||
|
||||
if (uuid == objID) //is new SceneObjectGroup ?
|
||||
{
|
||||
string uuid = (string)primRow["UUID"];
|
||||
string objID = (string)primRow["SceneGroupID"];
|
||||
|
||||
SceneObjectPart prim = buildPrim(primRow);
|
||||
|
||||
if (uuid == objID) //is new SceneObjectGroup ?
|
||||
SceneObjectGroup group = new SceneObjectGroup();
|
||||
|
||||
DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID));
|
||||
if (shapeRow != null)
|
||||
{
|
||||
SceneObjectGroup group = new SceneObjectGroup();
|
||||
|
||||
DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID));
|
||||
if (shapeRow != null)
|
||||
{
|
||||
prim.Shape = buildShape(shapeRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Notice(
|
||||
"No shape found for prim in storage, so setting default box shape");
|
||||
prim.Shape = PrimitiveBaseShape.Default;
|
||||
}
|
||||
group.AddPart(prim);
|
||||
group.RootPart = prim;
|
||||
|
||||
createdObjects.Add(group.UUID, group);
|
||||
retvals.Add(group);
|
||||
prim.Shape = buildShape(shapeRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID));
|
||||
if (shapeRow != null)
|
||||
{
|
||||
prim.Shape = buildShape(shapeRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Notice(
|
||||
"No shape found for prim in storage, so setting default box shape");
|
||||
prim.Shape = PrimitiveBaseShape.Default;
|
||||
}
|
||||
createdObjects[new LLUUID(objID)].AddPart(prim);
|
||||
MainLog.Instance.Notice(
|
||||
"No shape found for prim in storage, so setting default box shape");
|
||||
prim.Shape = PrimitiveBaseShape.Default;
|
||||
}
|
||||
group.AddPart(prim);
|
||||
group.RootPart = prim;
|
||||
|
||||
if (persistPrimInventories)
|
||||
{
|
||||
LoadItems(prim);
|
||||
}
|
||||
createdObjects.Add(group.UUID, group);
|
||||
retvals.Add(group);
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error("DATASTORE", "Failed create prim object, exception and data follows");
|
||||
MainLog.Instance.Verbose("DATASTORE", e.ToString());
|
||||
foreach (DataColumn col in prims.Columns)
|
||||
DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID));
|
||||
if (shapeRow != null)
|
||||
{
|
||||
MainLog.Instance.Verbose("DATASTORE", "Col: " + col.ColumnName + " => " + primRow[col]);
|
||||
prim.Shape = buildShape(shapeRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Notice(
|
||||
"No shape found for prim in storage, so setting default box shape");
|
||||
prim.Shape = PrimitiveBaseShape.Default;
|
||||
}
|
||||
createdObjects[new LLUUID(objID)].AddPart(prim);
|
||||
}
|
||||
|
||||
if (persistPrimInventories)
|
||||
{
|
||||
LoadItems(prim);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MainLog.Instance.Error("DATASTORE", "Failed create prim object, exception and data follows");
|
||||
MainLog.Instance.Verbose("DATASTORE", e.ToString());
|
||||
foreach (DataColumn col in prims.Columns)
|
||||
{
|
||||
MainLog.Instance.Verbose("DATASTORE", "Col: " + col.ColumnName + " => " + primRow[col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MainLog.Instance.Error("DATASTORE", "Exception trying to load prim objects for region " + regionUUID + ": " + ex.ToString());
|
||||
}
|
||||
return retvals;
|
||||
}
|
||||
|
||||
|
@ -416,8 +409,6 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
|
||||
public void StoreLandObject(Land parcel, LLUUID regionUUID)
|
||||
{
|
||||
MainLog.Instance.Verbose("DATASTORE", "Tedds temp fix: Waiting 3 seconds for stuff to catch up. (Someone please fix! :))");
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
lock (m_dataSet)
|
||||
{
|
||||
DataTable land = m_landTable;
|
||||
|
@ -449,9 +440,9 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID);
|
||||
landaccesslist.Rows.Add(newAccessRow);
|
||||
}
|
||||
}
|
||||
|
||||
Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public List<LandData> LoadLandObjects(LLUUID regionUUID)
|
||||
|
@ -519,6 +510,8 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
m_connection.Open();
|
||||
}
|
||||
|
||||
lock (m_dataSet)
|
||||
{
|
||||
// DisplayDataSet(m_dataSet, "Region DataSet");
|
||||
|
||||
m_primDataAdapter.Update(m_primTable);
|
||||
|
@ -528,20 +521,18 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
{
|
||||
m_itemsDataAdapter.Update(m_itemsTable);
|
||||
}
|
||||
|
||||
|
||||
m_terrainDataAdapter.Update(m_terrainTable);
|
||||
m_landDataAdapter.Update(m_landTable);
|
||||
m_landAccessListDataAdapter.Update(m_landAccessListTable);
|
||||
|
||||
m_dataSet.AcceptChanges();
|
||||
}
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (m_dataSet)
|
||||
{
|
||||
Commit();
|
||||
}
|
||||
Commit();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1201,23 +1192,16 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
else
|
||||
{
|
||||
fillShapeRow(shapeRow, prim);
|
||||
}
|
||||
|
||||
if (persistPrimInventories)
|
||||
{
|
||||
addPrimInventory(prim.UUID, prim.TaskInventory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persist prim inventory. Deletes, updates and inserts rows.
|
||||
/// </summary>
|
||||
/// <param name="primID"></param>
|
||||
/// <param name="items"></param>
|
||||
/// <returns></returns>
|
||||
private void addPrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
|
||||
// see IRegionDatastore
|
||||
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
|
||||
{
|
||||
MainLog.Instance.Verbose("DATASTORE", "Entered addPrimInventory with prim ID {0}", primID);
|
||||
if (!persistPrimInventories)
|
||||
return;
|
||||
|
||||
MainLog.Instance.Verbose("DATASTORE", "Entered StorePrimInventory with prim ID {0}", primID);
|
||||
|
||||
// Find all existing inventory rows for this prim
|
||||
DataTable dbItems = m_itemsTable;
|
||||
|
@ -1585,12 +1569,10 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
{
|
||||
pDa.Fill(tmpDS, "prims");
|
||||
sDa.Fill(tmpDS, "primshapes");
|
||||
|
||||
|
||||
if (persistPrimInventories)
|
||||
{
|
||||
iDa.Fill(tmpDS, "primitems");
|
||||
}
|
||||
|
||||
|
||||
tDa.Fill(tmpDS, "terrain");
|
||||
lDa.Fill(tmpDS, "land");
|
||||
lalDa.Fill(tmpDS, "landaccesslist");
|
||||
|
@ -1603,12 +1585,10 @@ namespace OpenSim.Framework.Data.MySQL
|
|||
|
||||
pDa.Fill(tmpDS, "prims");
|
||||
sDa.Fill(tmpDS, "primshapes");
|
||||
|
||||
|
||||
if (persistPrimInventories)
|
||||
{
|
||||
iDa.Fill(tmpDS, "primitems");
|
||||
}
|
||||
|
||||
|
||||
tDa.Fill(tmpDS, "terrain");
|
||||
lDa.Fill(tmpDS, "land");
|
||||
lalDa.Fill(tmpDS, "landaccesslist");
|
||||
|
|
|
@ -1248,22 +1248,15 @@ namespace OpenSim.Framework.Data.SQLite
|
|||
{
|
||||
fillShapeRow(shapeRow, prim);
|
||||
}
|
||||
|
||||
if (persistPrimInventories)
|
||||
{
|
||||
addPrimInventory(prim.UUID, prim.TaskInventory);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persist prim inventory. Deletes, updates and inserts rows.
|
||||
/// </summary>
|
||||
/// <param name="primID"></param>
|
||||
/// <param name="items"></param>
|
||||
/// <returns></returns>
|
||||
private void addPrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
|
||||
// see IRegionDatastore
|
||||
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
|
||||
{
|
||||
MainLog.Instance.Verbose("DATASTORE", "Entered addPrimInventory with prim ID {0}", primID);
|
||||
if (!persistPrimInventories)
|
||||
return;
|
||||
|
||||
MainLog.Instance.Verbose("DATASTORE", "Entered StorePrimInventory with prim ID {0}", primID);
|
||||
|
||||
// Find all existing inventory rows for this prim
|
||||
DataTable dbItems = ds.Tables["primitems"];
|
||||
|
|
|
@ -44,8 +44,26 @@ namespace OpenSim.Region.Environment.Interfaces
|
|||
/// <param name="persistPrimInventories">Temporary switch while this option is immature</param>
|
||||
void Initialise(string filename, bool persistPrimInventories);
|
||||
|
||||
/// <summary>
|
||||
/// Stores all object's details apart from inventory
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="regionUUID"></param>
|
||||
void StoreObject(SceneObjectGroup obj, LLUUID regionUUID);
|
||||
|
||||
/// <summary>
|
||||
/// Entirely removes the object, including inventory
|
||||
/// </summary>
|
||||
/// <param name="uuid"></param>
|
||||
/// <param name="regionUUID"></param>
|
||||
/// <returns></returns>
|
||||
void RemoveObject(LLUUID uuid, LLUUID regionUUID);
|
||||
|
||||
/// <summary>
|
||||
/// Store a prim's inventory
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items);
|
||||
|
||||
List<SceneObjectGroup> LoadObjects(LLUUID regionUUID);
|
||||
|
||||
|
@ -58,4 +76,4 @@ namespace OpenSim.Region.Environment.Interfaces
|
|||
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,13 +179,6 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
taskItem.InvType = item.invType;
|
||||
part.AddInventoryItem(taskItem);
|
||||
|
||||
// It might seem somewhat crude to update the whole group for a single prim inventory change,
|
||||
// but it's possible that other prim inventory changes will take place before the region
|
||||
// persistence thread visits this object. In the future, changes can be signalled at a more
|
||||
// granular level, or we could let the datastore worry about whether prims have really
|
||||
// changed since they were last persisted.
|
||||
HasGroupChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -234,14 +227,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
SceneObjectPart part = GetChildPart(item.ParentPartID);
|
||||
if (part != null)
|
||||
{
|
||||
part.UpdateInventoryItem(item);
|
||||
|
||||
// It might seem somewhat crude to update the whole group for a single prim inventory change,
|
||||
// but it's possible that other prim inventory changes will take place before the region
|
||||
// persistence thread visits this object. In the future, changes can be signalled at a more
|
||||
// granular level, or we could let the datastore worry about whether prims have really
|
||||
// changed since they were last persisted.
|
||||
HasGroupChanged = true;
|
||||
part.UpdateInventoryItem(item);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -263,13 +249,6 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
int type = part.RemoveInventoryItem(itemID);
|
||||
|
||||
// It might seem somewhat crude to update the whole group for a single prim inventory change,
|
||||
// but it's possible that other prim inventory changes will take place before the region
|
||||
// persistence thread visits this object. In the future, changes can be signalled at a more
|
||||
// granular level, or we could let the datastore worry about whether prims have really
|
||||
// changed since they were last persisted.
|
||||
HasGroupChanged = true;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -1492,6 +1492,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
datastore.StoreObject(this, m_scene.RegionInfo.RegionID);
|
||||
HasGroupChanged = false;
|
||||
}
|
||||
|
||||
ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -1704,9 +1706,12 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
public void ForEachPart(Action<SceneObjectPart> whatToDo)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
lock (m_parts)
|
||||
{
|
||||
whatToDo(part);
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
whatToDo(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,11 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
set { m_taskInventory = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks whether inventory has changed since the last persistent backup
|
||||
/// </summary>
|
||||
private bool HasInventoryChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Reset LLUUIDs for all the items in the prim's inventory. This involves either generating
|
||||
/// new ones or setting existing UUIDs to the correct parent UUIDs
|
||||
|
@ -207,6 +212,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
|
||||
m_inventorySerial++;
|
||||
HasInventoryChanged = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -224,7 +230,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_inventorySerial++;
|
||||
}
|
||||
|
||||
|
@ -268,6 +274,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_taskInventory[item.ItemID] = item;
|
||||
m_inventorySerial++;
|
||||
TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
|
||||
HasInventoryChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -300,6 +308,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_inventorySerial++;
|
||||
TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
|
||||
HasInventoryChanged = true;
|
||||
|
||||
return type;
|
||||
}
|
||||
else
|
||||
|
@ -380,6 +390,20 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
xferManager.AddNewFile(m_inventoryFileName, fileData);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process inventory backup
|
||||
/// </summary>
|
||||
/// <param name="datastore"></param>
|
||||
public void ProcessInventoryBackup(IRegionDataStore datastore)
|
||||
{
|
||||
if (HasInventoryChanged)
|
||||
{
|
||||
datastore.StorePrimInventory(UUID, TaskInventory);
|
||||
|
||||
HasInventoryChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class InventoryStringBuilder
|
||||
{
|
||||
|
|
|
@ -752,6 +752,12 @@ namespace OpenSim.DataStore.MSSQL
|
|||
fillShapeRow(shapeRow, prim);
|
||||
}
|
||||
}
|
||||
|
||||
// see IRegionDatastore
|
||||
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
|
||||
{
|
||||
// No implementation yet
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
|
|
|
@ -49,6 +49,11 @@ namespace OpenSim.DataStore.NullStorage
|
|||
public void RemoveObject(LLUUID obj, LLUUID regionUUID)
|
||||
{
|
||||
}
|
||||
|
||||
// see IRegionDatastore
|
||||
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
|
||||
{
|
||||
}
|
||||
|
||||
public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID)
|
||||
{
|
||||
|
@ -81,4 +86,4 @@ namespace OpenSim.DataStore.NullStorage
|
|||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue