From c8cdf32eb277cd31bac770a8af10512d2fb85a94 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sat, 7 May 2011 07:36:39 +0000 Subject: [PATCH] Added explicit caching support classes ahead of potential block collection refactoring. --- .../SubstrateCS/Source/NBT/NBTVerifier.cs | 8 - .../Source/Utility/IndexedLinkedList.cs | 137 ++++++++++++++ .../SubstrateCS/Source/Utility/LRUCache.cs | 174 ++++++++++++++++++ Substrate/SubstrateCS/Substrate.csproj | 15 +- Substrate/SubstrateCS/Substrate.sln | 4 +- 5 files changed, 324 insertions(+), 14 deletions(-) create mode 100644 Substrate/SubstrateCS/Source/Utility/IndexedLinkedList.cs create mode 100644 Substrate/SubstrateCS/Source/Utility/LRUCache.cs diff --git a/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs b/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs index 88387b7..31973de 100644 --- a/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs +++ b/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs @@ -73,14 +73,6 @@ namespace Substrate.NBT return Verify(_root, _schema); } - static NBTCompoundNode inventorySchema = new NBTCompoundNode("") - { - new NBTScalerNode("id", TagType.TAG_SHORT), - new NBTScalerNode("Damage", TagType.TAG_SHORT), - new NBTScalerNode("Count", TagType.TAG_BYTE), - new NBTScalerNode("Slot", TagType.TAG_BYTE), - }; - private bool Verify (TagValue tag, NBTSchemaNode schema) { if (tag == null) { diff --git a/Substrate/SubstrateCS/Source/Utility/IndexedLinkedList.cs b/Substrate/SubstrateCS/Source/Utility/IndexedLinkedList.cs new file mode 100644 index 0000000..2aee393 --- /dev/null +++ b/Substrate/SubstrateCS/Source/Utility/IndexedLinkedList.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Substrate.Utility +{ + class IndexedLinkedList : ICollection, ICollection + { + private LinkedList _list; + private Dictionary> _index; + + public T First + { + get { return _list.First.Value; } + } + + public T Last + { + get { return _list.Last.Value; } + } + + public IndexedLinkedList () + { + _list = new LinkedList(); + _index = new Dictionary>(); + } + + public void AddFirst (T value) + { + LinkedListNode node = _list.AddFirst(value); + _index.Add(value, node); + } + + public void AddLast (T value) + { + LinkedListNode node = _list.AddLast(value); + _index.Add(value, node); + } + + public void RemoveFirst () + { + _index.Remove(_list.First.Value); + _list.RemoveFirst(); + } + + public void RemoveLast () + { + _index.Remove(_list.First.Value); + _list.RemoveLast(); + } + + #region ICollection Members + + public void Add (T item) + { + AddLast(item); + } + + public void Clear () + { + _index.Clear(); + _list.Clear(); + } + + public bool Contains (T item) + { + return _index.ContainsKey(item); + } + + public void CopyTo (T[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove (T value) + { + LinkedListNode node; + if (_index.TryGetValue(value, out node)) + { + _index.Remove(value); + _list.Remove(node); + return true; + } + + return false; + } + + #endregion + + #region ICollection Members + + void ICollection.CopyTo (Array array, int index) + { + (_list as ICollection).CopyTo(array, index); + } + + public int Count + { + get { return _list.Count; } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return this; } + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator () + { + return _list.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator () + { + return _list.GetEnumerator(); + } + + #endregion + } +} diff --git a/Substrate/SubstrateCS/Source/Utility/LRUCache.cs b/Substrate/SubstrateCS/Source/Utility/LRUCache.cs new file mode 100644 index 0000000..bb0e220 --- /dev/null +++ b/Substrate/SubstrateCS/Source/Utility/LRUCache.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Substrate.Utility +{ + class LRUCache : IDictionary + { + private Dictionary _data; + private IndexedLinkedList _index; + + private int _capacity; + + public LRUCache (int capacity) + { + if (_capacity <= 0) + { + throw new ArgumentException("Cache capacity must be positive"); + } + + _capacity = capacity; + + _data = new Dictionary(); + _index = new IndexedLinkedList(); + } + + #region IDictionary Members + + public void Add (TKey key, TValue value) + { + if (_data.ContainsKey(key)) + { + throw new ArgumentException("Attempted to insert a duplicate key"); + } + + _data[key] = value; + _index.Add(key); + + if (_data.Count > _capacity) + { + _data.Remove(_index.First); + _index.RemoveFirst(); + } + } + + public bool ContainsKey (TKey key) + { + return _data.ContainsKey(key); + } + + public ICollection Keys + { + get { return _data.Keys; } + } + + public bool Remove (TKey key) + { + if (_data.Remove(key)) + { + _index.Remove(key); + return true; + } + + return false; + } + + public bool TryGetValue (TKey key, out TValue value) + { + if (!_data.TryGetValue(key, out value)) + { + return false; + } + + _index.Remove(key); + _index.Add(key); + + return true; + } + + public ICollection Values + { + get { return _data.Values; } + } + + public TValue this[TKey key] + { + get + { + TValue value = _data[key]; + _index.Remove(key); + _index.Add(key); + return value; + } + set + { + _data[key] = value; + _index.Remove(key); + _index.Add(key); + + if (_data.Count > _capacity) + { + _data.Remove(_index.First); + _index.RemoveFirst(); + } + } + } + + #endregion + + #region ICollection> Members + + public void Add (KeyValuePair item) + { + Add(item.Key, item.Value); + } + + public void Clear () + { + _data.Clear(); + _index.Clear(); + } + + public bool Contains (KeyValuePair item) + { + return ((ICollection>)_data).Contains(item); + } + + public void CopyTo (KeyValuePair[] array, int arrayIndex) + { + ((ICollection>)_data).CopyTo(array, arrayIndex); + } + + public int Count + { + get { return _data.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove (KeyValuePair item) + { + if (((ICollection>)_data).Remove(item)) + { + _index.Remove(item.Key); + return true; + } + + return false; + } + + #endregion + + #region IEnumerable> Members + + public IEnumerator> GetEnumerator () + { + return _data.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator () + { + return _data.GetEnumerator(); + } + + #endregion + } +} diff --git a/Substrate/SubstrateCS/Substrate.csproj b/Substrate/SubstrateCS/Substrate.csproj index d8c4f71..34e4ed5 100644 --- a/Substrate/SubstrateCS/Substrate.csproj +++ b/Substrate/SubstrateCS/Substrate.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -13,10 +13,13 @@ v2.0 512 false - - + + + 3.5 + + publish\ true Disk @@ -67,6 +70,8 @@ + + @@ -134,14 +139,16 @@ + + False - .NET Framework Client Profile + .NET Framework 3.5 SP1 Client Profile false diff --git a/Substrate/SubstrateCS/Substrate.sln b/Substrate/SubstrateCS/Substrate.sln index eb0b547..bc88c2e 100644 --- a/Substrate/SubstrateCS/Substrate.sln +++ b/Substrate/SubstrateCS/Substrate.sln @@ -1,6 +1,6 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C# Express 2008 +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate", "Substrate.csproj", "{AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBToolkit", "..\..\NBToolkit\NBToolkit.csproj", "{68207314-C080-4823-97F1-A6623145AA00}"