You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2011/07/22 23:17:45 UTC
svn commit: r1149741 - in
/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src:
main/csharp/Util/LRUCache.cs test/csharp/Util/LRUCacheTest.cs
Author: tabish
Date: Fri Jul 22 21:17:43 2011
New Revision: 1149741
URL: http://svn.apache.org/viewvc?rev=1149741&view=rev
Log:
https://issues.apache.org/jira/browse/AMQNET-329
Adds a basic LRU Cache for use in Message Auditing to prevent dups.
Added:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs (with props)
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/Util/LRUCacheTest.cs (with props)
Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs?rev=1149741&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs Fri Jul 22 21:17:43 2011
@@ -0,0 +1,130 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Apache.NMS.ActiveMQ.Util
+{
+ /// <summary>
+ /// Implements the basic IDictionary interface and adds functionality for controlling
+ /// the maximum number of entries that can be contained in the Map. When the maximum
+ /// value is reached the oldest entry is removed so that the max size is never exceeded.
+ /// </summary>
+ public class LRUCache<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
+ {
+ public const int DEFAULT_MAX_CACHE_SIZE = 10000;
+
+ private readonly Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
+ private readonly LinkedList<KeyValuePair<TKey, TValue>> entries =
+ new LinkedList<KeyValuePair<TKey, TValue>>();
+ private int maxCacheSize = DEFAULT_MAX_CACHE_SIZE;
+
+ public LRUCache() : base()
+ {
+ }
+
+ public LRUCache(int maxCacheSize) : base()
+ {
+ this.maxCacheSize = maxCacheSize;
+ }
+
+ public void Clear()
+ {
+ dictionary.Clear();
+ }
+
+ public int Count
+ {
+ get { return this.dictionary.Count; }
+ }
+
+ public int MaxCacheSize
+ {
+ get { return maxCacheSize; }
+ set { this.maxCacheSize = value; }
+ }
+
+ public TValue this[TKey key]
+ {
+ get { return dictionary[key]; }
+ set { this.Add(key, value); }
+ }
+
+ public bool TryGetValue(TKey key, out TValue val)
+ {
+ return dictionary.TryGetValue(key, out val);
+ }
+
+ public ICollection<TKey> Keys
+ {
+ get { return dictionary.Keys; }
+ }
+
+ public ICollection<TValue> Values
+ {
+ get { return dictionary.Values; }
+ }
+
+ public void Add(TKey key, TValue val)
+ {
+ dictionary.Add(key, val);
+ entries.AddLast(new KeyValuePair<TKey, TValue>(key, val));
+
+ KeyValuePair<TKey, TValue> eldest = entries.First.Value;
+
+ if(this.RemoveEldestEntry(eldest))
+ {
+ this.dictionary.Remove(eldest.Key);
+ this.entries.RemoveFirst();
+ }
+ }
+
+ public bool Remove(TKey v)
+ {
+ return dictionary.Remove(v);
+ }
+
+ public bool ContainsKey(TKey key)
+ {
+ return this.dictionary.ContainsKey(key);
+ }
+
+ public bool ContainsValue(TValue theValue)
+ {
+ return this.dictionary.ContainsValue(theValue);
+ }
+
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ return dictionary.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return dictionary.GetEnumerator();
+ }
+
+ protected virtual bool RemoveEldestEntry(KeyValuePair<TKey, TValue> eldest)
+ {
+ return this.dictionary.Count > this.maxCacheSize;
+ }
+ }
+
+}
+
Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs
------------------------------------------------------------------------------
svn:eol-style = native
Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/Util/LRUCacheTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/Util/LRUCacheTest.cs?rev=1149741&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/Util/LRUCacheTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/Util/LRUCacheTest.cs Fri Jul 22 21:17:43 2011
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Apache.NMS;
+using Apache.NMS.ActiveMQ;
+using Apache.NMS.ActiveMQ.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+ [TestFixture]
+ public class LRUCacheTest
+ {
+ [Test]
+ public void TestConstructor1()
+ {
+ LRUCache<Int64, Int64> underTest = new LRUCache<Int64, Int64>();
+ Assert.AreEqual(LRUCache<Int64, Int64>.DEFAULT_MAX_CACHE_SIZE, underTest.MaxCacheSize);
+ }
+
+ [Test]
+ public void TestConstructor2()
+ {
+ LRUCache<Int64, Int64> underTest = new LRUCache<Int64, Int64>(666);
+ Assert.AreEqual(666, underTest.MaxCacheSize);
+ }
+
+ [Test]
+ public void TestMaxCacheSize()
+ {
+ LRUCache<Int64, Int64> underTest = new LRUCache<Int64, Int64>(666);
+ Assert.AreEqual(666, underTest.MaxCacheSize);
+ underTest.MaxCacheSize = 512;
+ Assert.AreEqual(512, underTest.MaxCacheSize);
+ }
+
+ [Test]
+ public void TestAdd()
+ {
+ LRUCache<String, String> underTest = new LRUCache<String, String>(666);
+
+ underTest.Add("key", "value");
+ Assert.That(underTest.Count == 1);
+ }
+
+ [Test]
+ public void TestRemove()
+ {
+ LRUCache<String, String> underTest = new LRUCache<String, String>(666);
+
+ underTest.Add("key", "value");
+ Assert.That(underTest.Count == 1);
+ underTest.Remove("key");
+ Assert.That(underTest.Count == 0);
+ }
+
+ [Test]
+ public void TestContainsKey()
+ {
+ LRUCache<String, String> underTest = new LRUCache<String, String>(666);
+
+ underTest.Add("key1", "value");
+ underTest.Add("key2", "value");
+ underTest.Add("key3", "value");
+ Assert.That(underTest.Count == 3);
+ Assert.That(underTest.ContainsKey("key2"));
+ Assert.That(underTest.ContainsKey("key1"));
+ Assert.That(underTest.ContainsKey("key3"));
+ Assert.IsFalse(underTest.ContainsKey("Key4"));
+ }
+
+ [Test]
+ public void TestContainsValue()
+ {
+ LRUCache<String, String> underTest = new LRUCache<String, String>(666);
+
+ underTest.Add("key1", "value1");
+ underTest.Add("key2", "value2");
+ underTest.Add("key3", "value3");
+ Assert.That(underTest.Count == 3);
+ Assert.That(underTest.ContainsValue("value1"));
+ Assert.That(underTest.ContainsValue("value2"));
+ Assert.That(underTest.ContainsValue("value3"));
+ Assert.IsFalse(underTest.ContainsValue("value4"));
+ }
+
+ [Test]
+ public void TestCount()
+ {
+ LRUCache<String, String> underTest = new LRUCache<String, String>(666);
+
+ Assert.That(underTest.Count == 0);
+ underTest.Add("key1", "value");
+ Assert.That(underTest.Count == 1);
+ underTest.Add("key2", "value");
+ Assert.That(underTest.Count == 2);
+ underTest.Add("key3", "value");
+ Assert.That(underTest.Count == 3);
+ underTest.Clear();
+ Assert.That(underTest.Count == 0);
+ }
+
+ [Test]
+ public void TestClear()
+ {
+ LRUCache<String, String> underTest = new LRUCache<String, String>(666);
+
+ underTest.Add("key1", "value");
+ underTest.Add("key2", "value");
+ underTest.Add("key3", "value");
+ Assert.That(underTest.Count == 3);
+ underTest.Clear();
+ Assert.That(underTest.Count == 0);
+ }
+
+ [Test]
+ public void TestResize()
+ {
+ LRUCache<Int64, Int64> underTest = new LRUCache<Int64, Int64>(1000);
+
+ Int64 count = new Int64();
+ long max = 0;
+ for (; count < 27276827; count++)
+ {
+ long start = DateTime.Now.Ticks;
+ if (!underTest.ContainsKey(count))
+ {
+ underTest.Add(count, count);
+ }
+ long duration = DateTime.Now.Ticks - start;
+ if (duration > max)
+ {
+ Tracer.Debug("count: " + count + ", new max=" + duration);
+ max = duration;
+ }
+ if (count % 100000000 == 0)
+ {
+ Tracer.Debug("count: " + count + ", max=" + max);
+ }
+ }
+
+ Assert.AreEqual(1000, underTest.Count, "size is still in order");
+ }
+ }
+}
+
Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/Util/LRUCacheTest.cs
------------------------------------------------------------------------------
svn:eol-style = native