From bd9124da1f6e581da0ea45103dab38caddd1911d Mon Sep 17 00:00:00 2001 From: Christopher Date: Wed, 8 Jul 2020 01:26:12 +0200 Subject: [PATCH] add first version of other data storage typs --- src/DataValue.cs | 111 +++++++++++++++++++++++++++++++----- src/Storage/FileSystem.cs | 45 ++++----------- src/Storage/MySQL.cs | 2 +- src/Storage/RegionExtras.cs | 2 +- src/Storage/iStorage.cs | 4 +- src/StorageElement.cs | 75 ++++++++++++++++++++++++ 6 files changed, 189 insertions(+), 50 deletions(-) create mode 100644 src/StorageElement.cs diff --git a/src/DataValue.cs b/src/DataValue.cs index dec5eb4..912649b 100644 --- a/src/DataValue.cs +++ b/src/DataValue.cs @@ -32,6 +32,11 @@ namespace OpenSim.Modules.DataValue private String m_storageTyp = null; private iStorage m_storage = null; + private List m_cache = new List(); + + private Timer m_timer = null; + private int m_rateLimit = 0; + public string Name { get { return "DataValueModule"; } @@ -58,13 +63,18 @@ namespace OpenSim.Modules.DataValue { m_config = source.Configs["XEngine"]; - m_storageTyp = m_config.GetString("DataStorageTyp", "RegionExtras").ToUpper().Trim(); + m_storageTyp = m_config.GetString("DataStorageTyp", "FileSystem").ToUpper().Trim(); } catch (Exception e) { m_log.ErrorFormat("[" + Name + "]: initialization error: {0}", e.Message); return; } + + m_timer = new Timer(); + m_timer.Interval = 1000; + m_timer.Elapsed += cleanUp; + m_timer.Start(); } public void RegionLoaded(Scene scene) @@ -83,26 +93,16 @@ namespace OpenSim.Modules.DataValue m_storage = new MySQL(m_scene, m_config); if(m_storage == null) - m_storage = new RegionExtras(m_scene, m_config); + m_storage = new FileSystem(m_scene, m_config); m_scriptModule = m_scene.RequestModuleInterface(); - if (m_scriptModule == null) - { - m_log.ErrorFormat("[" + Name + "]: Failed to load IScriptModuleComms!"); - return; - } - - try + if (m_scriptModule != null) { m_scriptModule.RegisterScriptInvocation(this, "osGetDataValue"); m_scriptModule.RegisterScriptInvocation(this, "osSetDataValue"); m_scriptModule.RegisterScriptInvocation(this, "osDeleteDataValue"); m_scriptModule.RegisterScriptInvocation(this, "osCheckDataValue"); } - catch (Exception e) - { - m_log.WarnFormat("[" + Name + "]: script method registration failed; {0}", e.Message); - } } public void RemoveRegion(Scene scene) @@ -117,24 +117,109 @@ namespace OpenSim.Modules.DataValue [ScriptInvocation] public string osGetDataValue(UUID hostID, UUID scriptID, string key) { + if(m_storage != null) + { + SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID); + StorageElement _element = m_cache.Find(X => X.Group == _host.GroupID.ToString() && X.Index == key); + if (_element != null) + return _element.get(); + + checkRateLimit(); + + String _data = m_storage.get(_host.GroupID.ToString(), key); + + if (_data == null) + return ""; + + m_cache.Add(new StorageElement(_host.GroupID.ToString(), key, _data, m_storage)); + + return _data; + } + + throw new Exception("No data Storage aviable."); } [ScriptInvocation] public void osSetDataValue(UUID hostID, UUID scriptID, string key, string value) { + if (m_storage != null) + { + SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID); + StorageElement _element = m_cache.Find(X => X.Group == _host.GroupID.ToString() && X.Index == key); + if(_element != null) + { + _element.save(value); + return; + } + checkRateLimit(); + + m_cache.Add(new StorageElement(_host.GroupID.ToString(), key, value, m_storage)); + m_storage.save(_host.GroupID.ToString(), key, value); + } + + throw new Exception("No data Storage aviable."); + } [ScriptInvocation] public void osDeleteDataValue(UUID hostID, UUID scriptID, string key, string value) { + if (m_storage != null) + { + SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID); + StorageElement _element = m_cache.Find(X => X.Group == _host.GroupID.ToString() && X.Index == key); + checkRateLimit(); + + if (_element != null) + m_cache.Remove(_element); + + m_storage.remove(_host.GroupID.ToString(), key); + } + + throw new Exception("No data Storage aviable."); } [ScriptInvocation] public int osCheckDataValue(UUID hostID, UUID scriptID, string key) { + if (m_storage != null) + { + SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID); + StorageElement _element = m_cache.Find(X => X.Group == _host.GroupID.ToString() && X.Index == key); + if (_element != null) + return 1; + + checkRateLimit(); + + if (m_storage.check(_host.GroupID.ToString(), key)) + return 1; + + return 0; + } + + throw new Exception("No data Storage aviable."); + } + + private void cleanUp(object sender, ElapsedEventArgs e) + { + if(m_rateLimit >= 0) + m_rateLimit = m_rateLimit - 100; + + List _allStorageElements = m_cache.FindAll(X => X.LastUse + 10 <= (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds); + + foreach(StorageElement _element in _allStorageElements) + m_cache.Remove(_element); + } + + private void checkRateLimit() + { + m_rateLimit++; + + if (m_rateLimit >= 1000) + throw new Exception("Data storage rate limit reached!"); } #endregion diff --git a/src/Storage/FileSystem.cs b/src/Storage/FileSystem.cs index 88395e6..9de1c60 100644 --- a/src/Storage/FileSystem.cs +++ b/src/Storage/FileSystem.cs @@ -26,45 +26,34 @@ namespace OpenSim.Modules.DataValue.Storage { m_scene = scene; - m_dataValueDirectory = config.Configs["XEngine"].GetString("DataValueStorageDirectory", m_dataValueDirectory); - m_enabledCompress = config.Configs["XEngine"].GetBoolean("EnabledDataStorageCompressing", m_enabledCompress); + m_dataValueDirectory = config.GetString("DataValueStorageDirectory", m_dataValueDirectory); } public bool check(String storageID, string key) { - string _filePath = getFilePath(hostID, key); + string _filePath = getFilePath(storageID, key); FileInfo file = new FileInfo(_filePath); if (file.Exists) - return 1; + return true; - return 0; + return false; } - public string get(String storageID, string key) + public String get(String storageID, string key) { - string _filePath = getFilePath(hostID, key); - - FileInfo file = new FileInfo(_filePath); + FileInfo file = new FileInfo(getFilePath(storageID, key)); if (file.Exists) - { - if (m_enabledCompress) - return Compress.Unzip(File.ReadAllBytes(file.FullName)); - return File.ReadAllText(file.FullName); - } - - return ""; + return null; } - public string remove(string storageID, string key) + public void remove(string storageID, string key) { - string _filePath = getFilePath(hostID, key); - - FileInfo file = new FileInfo(_filePath); + FileInfo file = new FileInfo(getFilePath(storageID, key)); if (file.Exists) file.Delete(); @@ -72,21 +61,11 @@ namespace OpenSim.Modules.DataValue.Storage public void save(String storageID, string key, string data) { - string _filePath = getFilePath(hostID, key); - - FileInfo file = new FileInfo(_filePath); - - if (m_enabledCompress) - { - File.WriteAllBytes(file.FullName, Compress.Zip(value)); - return; - } - - File.WriteAllText(file.FullName, value); + FileInfo file = new FileInfo(getFilePath(storageID, key)); + File.WriteAllText(file.FullName, data); } - } - private string getFilePath(UUID host, string index) + private string getFilePath(String host, String index) { SceneObjectGroup _host = m_scene.GetSceneObjectGroup(host); diff --git a/src/Storage/MySQL.cs b/src/Storage/MySQL.cs index 7c211ba..9878f77 100644 --- a/src/Storage/MySQL.cs +++ b/src/Storage/MySQL.cs @@ -31,7 +31,7 @@ namespace OpenSim.Modules.DataValue.Storage throw new NotImplementedException(); } - public string remove(string storageID, string key) + public void remove(string storageID, string key) { throw new NotImplementedException(); } diff --git a/src/Storage/RegionExtras.cs b/src/Storage/RegionExtras.cs index 2628034..33c2039 100644 --- a/src/Storage/RegionExtras.cs +++ b/src/Storage/RegionExtras.cs @@ -34,7 +34,7 @@ namespace OpenSim.Modules.DataValue.Storage return m_scene.GetExtraSetting("V:" + storageID + "." + key); } - public string remove(string storageID, string key) + public void remove(string storageID, string key) { throw new NotImplementedException(); } diff --git a/src/Storage/iStorage.cs b/src/Storage/iStorage.cs index ec4d383..a3cfad5 100644 --- a/src/Storage/iStorage.cs +++ b/src/Storage/iStorage.cs @@ -9,8 +9,8 @@ namespace OpenSim.Modules.DataValue.Storage interface iStorage { void save(String storageID, String key, String data); - string get(String storageID, String key); - string remove(String storageID, String key); + String get(String storageID, String key); + void remove(String storageID, String key); bool check(String storageID, String key); } } diff --git a/src/StorageElement.cs b/src/StorageElement.cs new file mode 100644 index 0000000..e0b669c --- /dev/null +++ b/src/StorageElement.cs @@ -0,0 +1,75 @@ +using OpenSim.Modules.DataValue.Storage; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenSim.Modules.DataValue +{ + class StorageElement + { + private String m_group = null; + private String m_index = null; + private String m_data = null; + + private int m_lastUseTime = 0; + + private iStorage m_storage = null; + + public StorageElement(String group, String index, String data, iStorage storage) + { + m_group = group; + m_index = index; + m_data = data; + + m_storage = storage; + + m_lastUseTime = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; + } + + public string get() + { + m_lastUseTime = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; + + return m_data; + } + + public void remove() + { + m_lastUseTime = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; + m_storage.remove(m_group, m_index); + } + + public void save(string data) + { + m_lastUseTime = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; + m_data = data; + m_storage.save(m_group, m_index, data); + } + + public int LastUse + { + get + { + return m_lastUseTime; + } + } + + public String Group + { + get + { + return m_group; + } + } + + public String Index + { + get + { + return m_index; + } + } + } +}