mirror of
https://github.com/opensim/opensim.git
synced 2026-08-09 10:46:00 +08:00
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
This commit is contained in:
@@ -93,6 +93,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
// extract the internals of a has reference
|
||||
protected static Regex m_HashPattern = new Regex("{([^}]+)}");
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// This is a simple estimator for the size of the stored data, it
|
||||
/// is not precise, but should be close enough to implement reasonable
|
||||
/// limits on the storage space used
|
||||
/// </summary>
|
||||
// -----------------------------------------------------------------
|
||||
public int StringSpace { get; set; }
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
///
|
||||
@@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
// -----------------------------------------------------------------
|
||||
public JsonStore()
|
||||
{
|
||||
StringSpace = 0;
|
||||
m_TakeStore = new List<TakeValueCallbackClass>();
|
||||
m_ReadStore = new List<TakeValueCallbackClass>();
|
||||
}
|
||||
@@ -247,9 +257,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
if (path.Count == 0)
|
||||
{
|
||||
ValueStore = ovalue;
|
||||
StringSpace = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// pkey will be the final element in the path, we pull it out here to make sure
|
||||
// that the assignment works correctly
|
||||
string pkey = path.Pop();
|
||||
string pexpr = PathExpressionToKey(path);
|
||||
if (pexpr != "")
|
||||
@@ -259,7 +272,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
if (result == null)
|
||||
return false;
|
||||
|
||||
// Check for and extract array references
|
||||
// Check pkey, the last element in the path, for and extract array references
|
||||
MatchCollection amatches = m_ArrayPattern.Matches(pkey,0);
|
||||
if (amatches.Count > 0)
|
||||
{
|
||||
@@ -276,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
{
|
||||
string npkey = String.Format("[{0}]",amap.Count);
|
||||
|
||||
amap.Add(ovalue);
|
||||
InvokeNextCallback(pexpr + npkey);
|
||||
if (ovalue != null)
|
||||
{
|
||||
StringSpace += ComputeSizeOf(ovalue);
|
||||
|
||||
amap.Add(ovalue);
|
||||
InvokeNextCallback(pexpr + npkey);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -285,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
if (0 <= aval && aval < amap.Count)
|
||||
{
|
||||
if (ovalue == null)
|
||||
{
|
||||
StringSpace -= ComputeSizeOf(amap[aval]);
|
||||
amap.RemoveAt(aval);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringSpace -= ComputeSizeOf(amap[aval]);
|
||||
StringSpace += ComputeSizeOf(ovalue);
|
||||
amap[aval] = ovalue;
|
||||
InvokeNextCallback(pexpr + pkey);
|
||||
}
|
||||
@@ -307,16 +330,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
|
||||
if (result is OSDMap)
|
||||
{
|
||||
// this is the assignment case
|
||||
OSDMap hmap = result as OSDMap;
|
||||
if (ovalue != null)
|
||||
{
|
||||
StringSpace -= ComputeSizeOf(hmap[hkey]);
|
||||
StringSpace += ComputeSizeOf(ovalue);
|
||||
|
||||
hmap[hkey] = ovalue;
|
||||
InvokeNextCallback(pexpr + pkey);
|
||||
return true;
|
||||
}
|
||||
else if (hmap.ContainsKey(hkey))
|
||||
|
||||
// this is the remove case
|
||||
if (hmap.ContainsKey(hkey))
|
||||
{
|
||||
StringSpace -= ComputeSizeOf(hmap[hkey]);
|
||||
hmap.Remove(hkey);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -522,8 +556,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
// -----------------------------------------------------------------
|
||||
protected static int ComputeSizeOf(OSD value)
|
||||
{
|
||||
string sval;
|
||||
|
||||
if (ConvertOutputValue(value,out sval,true))
|
||||
return sval.Length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
// -----------------------------------------------------------------
|
||||
public class JsonObjectStore : JsonStore
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
@@ -557,6 +610,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
{
|
||||
m_scene = scene;
|
||||
m_objectID = oid;
|
||||
|
||||
// the size limit is imposed on whatever is already in the store
|
||||
StringSpace = ComputeSizeOf(ValueStore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
|
||||
private IConfig m_config = null;
|
||||
private bool m_enabled = false;
|
||||
private bool m_enableObjectStore = false;
|
||||
private int m_maxStringSpace = Int32.MaxValue;
|
||||
|
||||
private Scene m_scene = null;
|
||||
|
||||
private Dictionary<UUID,JsonStore> m_JsonValueStore;
|
||||
@@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
}
|
||||
|
||||
m_enabled = m_config.GetBoolean("Enabled", m_enabled);
|
||||
m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore);
|
||||
m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace);
|
||||
if (m_maxStringSpace == 0)
|
||||
m_maxStringSpace = Int32.MaxValue;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
public bool AttachObjectStore(UUID objectID)
|
||||
{
|
||||
if (! m_enabled) return false;
|
||||
if (! m_enableObjectStore) return false;
|
||||
|
||||
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
|
||||
if (sop == null)
|
||||
@@ -239,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
if (! m_enabled) return false;
|
||||
|
||||
lock (m_JsonValueStore)
|
||||
m_JsonValueStore.Remove(storeID);
|
||||
return m_JsonValueStore.Remove(storeID);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -311,8 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
try
|
||||
{
|
||||
lock (map)
|
||||
if (map.SetValue(path,value,useJson))
|
||||
return true;
|
||||
{
|
||||
if (map.StringSpace > m_maxStringSpace)
|
||||
{
|
||||
m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
|
||||
storeID,map.StringSpace,m_maxStringSpace);
|
||||
return false;
|
||||
}
|
||||
|
||||
return map.SetValue(path,value,useJson);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -344,8 +360,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
try
|
||||
{
|
||||
lock (map)
|
||||
if (map.RemoveValue(path))
|
||||
return true;
|
||||
return map.RemoveValue(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -504,7 +504,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
{
|
||||
string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
|
||||
int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
|
||||
m_comms.DispatchReply(scriptID,result, "", reqID.ToString());
|
||||
m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||
string notecardName = "nc1";
|
||||
|
||||
// Write notecard
|
||||
UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName);
|
||||
UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName);
|
||||
Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
|
||||
@@ -292,8 +292,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||
// TODO: Should independently check the contents.
|
||||
}
|
||||
|
||||
// TODO: Write partial test
|
||||
|
||||
{
|
||||
// Try to write notecard against bad path
|
||||
// Try to write notecard for a bad path
|
||||
// In this case we do get a request id but no notecard is written.
|
||||
string badPathNotecardName = "badPathNotecardName";
|
||||
|
||||
@@ -312,7 +314,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||
|
||||
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
|
||||
UUID fakeStoreWriteNotecardValue
|
||||
= (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "/", fakeStoreNotecardName);
|
||||
= (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName);
|
||||
Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
|
||||
@@ -321,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for reading and writing json to a notecard
|
||||
/// Test for reading json from a notecard
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
|
||||
@@ -338,20 +340,73 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
|
||||
m_scene.AddSceneObject(so);
|
||||
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
|
||||
UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
|
||||
|
||||
// Write notecard
|
||||
InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName);
|
||||
InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName);
|
||||
|
||||
// Read notecard
|
||||
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }");
|
||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName);
|
||||
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||
{
|
||||
// Read notecard
|
||||
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName);
|
||||
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
|
||||
Assert.That(value, Is.EqualTo("World"));
|
||||
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||
Assert.That(value, Is.EqualTo("World"));
|
||||
}
|
||||
|
||||
{
|
||||
// Read notecard to new single component path
|
||||
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName);
|
||||
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
// These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
|
||||
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||
Assert.That(value, Is.EqualTo(""));
|
||||
|
||||
value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello");
|
||||
Assert.That(value, Is.EqualTo("World"));
|
||||
}
|
||||
|
||||
{
|
||||
// Read notecard to new multi-component path
|
||||
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
|
||||
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
// These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
|
||||
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||
Assert.That(value, Is.EqualTo(""));
|
||||
|
||||
// TODO: Check that we are not expecting reading to a new path to work.
|
||||
value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
|
||||
Assert.That(value, Is.EqualTo(""));
|
||||
}
|
||||
|
||||
{
|
||||
// Read notecard to existing multi-component path
|
||||
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
|
||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
|
||||
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
// These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
|
||||
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||
Assert.That(value, Is.EqualTo(""));
|
||||
|
||||
value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
|
||||
Assert.That(value, Is.EqualTo("World"));
|
||||
}
|
||||
|
||||
{
|
||||
// Try read notecard to fake store.
|
||||
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
|
||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName);
|
||||
Assert.That(fakeStoreId, Is.Not.EqualTo(UUID.Zero));
|
||||
|
||||
string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
|
||||
Assert.That(value, Is.EqualTo(""));
|
||||
}
|
||||
}
|
||||
|
||||
public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
|
||||
|
||||
Reference in New Issue
Block a user