Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
This commit is contained in:
Melanie
2013-02-08 23:29:47 +00:00
13 changed files with 354 additions and 97 deletions

View File

@@ -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);
}
}

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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; }