Author: manik.surtani(a)jboss.com
Date: 2008-08-05 06:23:56 -0400 (Tue, 05 Aug 2008)
New Revision: 6504
Modified:
core/trunk/src/main/java/org/jboss/cache/util/Caches.java
core/trunk/src/test/java/org/jboss/cache/util/CachesTest.java
Log:
Update to Caches code
Modified: core/trunk/src/main/java/org/jboss/cache/util/Caches.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/Caches.java 2008-08-04 20:26:13 UTC (rev
6503)
+++ core/trunk/src/main/java/org/jboss/cache/util/Caches.java 2008-08-05 10:23:56 UTC (rev
6504)
@@ -3,6 +3,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.loader.CacheLoader;
import java.util.AbstractMap;
@@ -10,7 +11,6 @@
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
/**
@@ -36,12 +36,13 @@
/**
* Returns a {@link Map} from the root node.
*
+ * @param cache cache to wrap as a map
+ * @return a map representation of the cache
* @see #asMap(Node)
*/
- public static Map asMap(Cache cache)
+ public static <K, V> Map<K, V> asMap(Cache<K, V> cache)
{
- if (cache == null)
- throw new NullPointerException("cache");
+ if (cache == null) throw new NullPointerException("cache");
return asMap(cache.getRoot());
}
@@ -62,10 +63,13 @@
* Also, when using a {@link CacheLoader} for storage, keys used must be valid as
* part of the {@link Fqn} used in calls. Generally speaking, simple string values
are
* preferred.
+ *
+ * @param node node in a cache to wrap
+ * @return a Map representation of the cache
*/
- public static Map asMap(Node node)
+ public static <K, V> Map<K, V> asMap(Node<K, V> node)
{
- return new MapNode(node);
+ return new MapNode<K, V>(node);
}
/**
@@ -83,10 +87,13 @@
* of the data at time of calling. This may be very inefficient.
* <p/>
* The map is not serializable.
+ *
+ * @param node node to wrap
+ * @return Map representation of the cache
*/
- public static Map asSimpleMap(Node node)
+ public static <K, V> Map<K, V> asSimpleMap(Node<K, V> node)
{
- return new SimpleMapNode(node);
+ return new SimpleMapNode<K, V>(node);
}
/**
@@ -100,23 +107,28 @@
* and all methods are thread safe.
* <p/>
* The set is not serializable.
+ *
+ * @param node node to wrap
+ * @return a Set representation of the values in a node
*/
- public static Set asSimpleSet(Node node)
+ public static <K, V> Set<V> asSimpleSet(Node<K, V> node)
{
- return new SimpleSetNode(node);
+ return new SimpleSetNode<V>(node);
}
/**
* Returns a {@link Map}, where map entries are partitioned into
* children nodes, within a cache node.
- * The default child selector divides the data into 16 child nodes based on hash
code.
+ * The default child selector divides the data into 128 child nodes based on hash
code.
* Note that for large data sets, the number of child nodes should be increased.
*
* @param node node to cache under
+ * @return a Map representation of the cache
*/
- public static Map asPartitionedMap(Node node)
+ @SuppressWarnings("unchecked")
+ public static <K, V> Map<K, V> asPartitionedMap(Node<K, V> node)
{
- return new PartitionedMapNode(node, HashKeySelector.DEFAULT);
+ return new PartitionedMapNode<K, V>(node, HashKeySelector.DEFAULT);
}
/**
@@ -132,10 +144,11 @@
*
* @param node node to cache under
* @param ss selector strategy that chooses a segment based on key
+ * @return a Map representation of the cache
*/
- public static Map asPartitionedMap(Node node, ChildSelector ss)
+ public static <K, V> Map<K, V> asPartitionedMap(Node<K, V> node,
ChildSelector<K> ss)
{
- return new PartitionedMapNode(node, ss);
+ return new PartitionedMapNode<K, V>(node, ss);
}
/**
@@ -143,31 +156,36 @@
* within the cache root, by key hash code.
*
* @param cache cache to use
- * @return
+ * @return a Map representation of the cache
*/
- public static Map asPartitionedMap(Cache cache)
+ public static <K, V> Map<K, V> asPartitionedMap(Cache<K, V> cache)
{
return asPartitionedMap(cache.getRoot());
}
/**
+ * Computes an improved hash code from an object's hash code.
+ */
+ static protected final int hashCode(int i)
+ {
+ i ^= i >>> 20 ^ i >>> 12;
+ return i ^ i >>> 7 ^ i >>> 4;
+ }
+
+ /**
* Returns a segment ({@link Node#getChild(Object) child node name})
* to use based on the characteristics of a key.
* <p/>
* Here is an example class which selects a child based on a person's department:
* <pre>
- * public static class DepartmentSelector implements ChildSelector<Person>
+ * public static class DepartmentSelector implements
ChildSelector<Person>
* {
- * <p/>
- * public Object childName(Person key)
- * {
- * return key.getDepartment();
+ * public Object childName(Person key)
+ * {
+ * return key.getDepartment();
+ * }
* }
- * <p/>
- * }
* </pre>
- *
- * @
*/
public interface ChildSelector<T>
{
@@ -177,21 +195,23 @@
* @param key for calls to {@link Map#put}, {@link Map#get} etc.
* @return node name
*/
- Object childName(T key);
+ Fqn childName(T key);
}
/**
* Class that returns a child name to use based on the hash code of a key.
*/
- public static class HashKeySelector implements ChildSelector
+ public static class HashKeySelector<T> implements ChildSelector<T>
{
- static ChildSelector DEFAULT = new HashKeySelector(16);
+ static ChildSelector DEFAULT = new HashKeySelector(128);
protected int segments;
/**
* Constructs with N segments, where N must be a power of 2.
+ *
+ * @param segments Number of hash segments
*/
public HashKeySelector(int segments)
{
@@ -203,42 +223,34 @@
}
/**
- * Computes an improved hash code from an object's hash code.
- */
- protected int hashCode(int i)
- {
- i ^= i >>> 20 ^ i >>> 12;
- return i ^ i >>> 7 ^ i >>> 4;
- }
-
- /**
* Returns the segment for this key, in the inclusive range 0 to {@link #segments}
- 1.
*/
- protected int segmentFor(Object key)
+ protected final int segmentFor(T key)
{
if (key == null)
return 0;
int hc = key.hashCode();
- return hashCode(hc) & (segments - 1);
+ return Caches.hashCode(hc) & (segments - 1);
}
/**
* Returns the node name for this segment.
*/
- protected Object childName(int segment)
+ protected final Fqn childName(int segment)
{
- return "" + segment;//IntegerCache.toString(segment);
+ return Fqn.fromElements(Integer.toString(segment));
}
/**
* Returns the node name for this key.
* By default, returns a String containing the segment.
*/
- public Object childName(Object key)
+ public final Fqn childName(T key)
{
return childName(segmentFor(key));
}
+ @Override
public String toString()
{
return super.toString() + " segments=" + segments;
@@ -246,14 +258,14 @@
}
- static class MapNode extends AbstractMap
+ static class MapNode<K, V> extends AbstractMap<K, V>
{
public static final String KEY = "K";
- private Node node;
+ private Node node; // purposefully un-genericized
- public MapNode(Node node)
+ public MapNode(Node<K, V> node)
{
if (node == null)
throw new NullPointerException("node");
@@ -261,16 +273,16 @@
}
@Override
- public Set entrySet()
+ public Set<Map.Entry<K, V>> entrySet()
{
- return new AbstractSet()
+ return new AbstractSet<Map.Entry<K, V>>()
{
@Override
- public Iterator iterator()
+ public Iterator<Map.Entry<K, V>> iterator()
{
- final Iterator<Node> i = set().iterator();
- return new Iterator()
+ final Iterator<Node<K, V>> i = set().iterator();
+ return new Iterator<Map.Entry<K, V>>()
{
Object name;
@@ -282,13 +294,14 @@
return i.hasNext();
}
- public Object next()
+ @SuppressWarnings("unchecked")
+ public Entry<K, V> next()
{
Node n = i.next();
this.name = n.getFqn().getLastElement();
this.next = true;
Object key = n.get(KEY);
- return new SimpleEntry(name, key);
+ return new SimpleImmutableEntry(name, key);
}
public void remove()
@@ -298,6 +311,7 @@
node.removeChild(name);
}
+ @Override
public String toString()
{
return "Itr name=" + name;
@@ -306,7 +320,8 @@
};
}
- private Set<Node> set()
+ @SuppressWarnings("unchecked")
+ private Set<Node<K, V>> set()
{
return node.getChildren();
}
@@ -334,12 +349,13 @@
}
@Override
- public Object get(Object arg0)
+ @SuppressWarnings("unchecked")
+ public V get(Object arg0)
{
Node child = node.getChild(arg0);
if (child == null)
return null;
- return child.get(KEY);
+ return (V) child.get(KEY);
}
@Override
@@ -349,10 +365,10 @@
}
@Override
- public Set keySet()
+ public Set<K> keySet()
{
- return new AbstractSet()
+ return new AbstractSet<K>()
{
private Set set()
@@ -361,22 +377,23 @@
}
@Override
- public Iterator iterator()
+ public Iterator<K> iterator()
{
final Iterator i = set().iterator();
- return new Iterator()
+ return new Iterator<K>()
{
- Object child;
+ K child;
public boolean hasNext()
{
return i.hasNext();
}
- public Object next()
+ @SuppressWarnings("unchecked")
+ public K next()
{
- child = i.next();
+ child = (K) i.next();
return child;
}
@@ -408,18 +425,20 @@
}
@Override
- public Object put(Object arg0, Object arg1)
+ @SuppressWarnings("unchecked")
+ public V put(K arg0, V arg1)
{
- return node.addChild(Fqn.fromElements(arg0)).put(KEY, arg1);
+ return (V) node.addChild(Fqn.fromElements(arg0)).put(KEY, arg1);
}
@Override
- public Object remove(Object arg0)
+ @SuppressWarnings("unchecked")
+ public V remove(Object arg0)
{
Node child = node.getChild(arg0);
if (child == null)
return null;
- Object o = child.remove(KEY);
+ V o = (V) child.remove(KEY);
node.removeChild(arg0);
return o;
}
@@ -432,12 +451,12 @@
}
- static class SimpleMapNode extends AbstractMap implements java.util.Map
+ static class SimpleMapNode<K, V> extends AbstractMap<K, V>
{
- private Node node;
+ private Node<K, V> node;
- public SimpleMapNode(Node node)
+ public SimpleMapNode(Node<K, V> node)
{
if (node == null)
throw new NullPointerException("node");
@@ -465,39 +484,43 @@
/**
* getData returns a snapshot of the data.
*/
- public Set entrySet()
+ @Override
+ public Set<Map.Entry<K, V>> entrySet()
{
return node.getData().entrySet();
}
@Override
- public Object get(Object key)
+ @SuppressWarnings("unchecked")
+ public V get(Object key)
{
- return node.get(key);
+ return node.get((K) key);
}
@Override
- public Set keySet()
+ public Set<K> keySet()
{
return node.getKeys();
}
@Override
- public Object put(Object key, Object value)
+ public V put(K key, V value)
{
return node.put(key, value);
}
@Override
- public void putAll(Map map)
+ @SuppressWarnings("unchecked")
+ public void putAll(Map<? extends K, ? extends V> map)
{
- node.putAll(map);
+ node.putAll((Map) map);
}
@Override
- public Object remove(Object key)
+ @SuppressWarnings("unchecked")
+ public V remove(Object key)
{
- return node.remove(key);
+ return node.remove((K) key);
}
@Override
@@ -508,14 +531,14 @@
}
- static class SimpleSetNode extends AbstractSet implements java.util.Set
+ static class SimpleSetNode<K> extends AbstractSet<K> implements
java.util.Set<K>
{
private Node node;
private static final String VALUE = "V";
- public SimpleSetNode(Node node)
+ public <K, V> SimpleSetNode(Node<K, V> node)
{
if (node == null)
throw new NullPointerException("node");
@@ -535,6 +558,7 @@
}
@Override
+ @SuppressWarnings("unchecked")
public boolean remove(Object key)
{
return node.remove(key) != null;
@@ -547,18 +571,19 @@
}
@Override
- public boolean add(Object arg0)
+ @SuppressWarnings("unchecked")
+ public boolean add(K arg0)
{
return node.put(arg0, VALUE) == null;
}
@Override
- public Iterator iterator()
+ public Iterator<K> iterator()
{
final Iterator i = node.getKeys().iterator();
- return new Iterator()
+ return new Iterator<K>()
{
- Object key;
+ K key;
boolean next = false;
@@ -567,13 +592,15 @@
return i.hasNext();
}
- public Object next()
+ @SuppressWarnings("unchecked")
+ public K next()
{
- key = i.next();
+ key = (K) i.next();
next = true;
return key;
}
+ @SuppressWarnings("unchecked")
public void remove()
{
if (!next)
@@ -586,31 +613,31 @@
}
- static class PartitionedMapNode extends AbstractMap
+ static class PartitionedMapNode<K, V> extends AbstractMap<K, V>
{
- private Node node;
+ private NodeSPI node;
- private ChildSelector selector;
+ private ChildSelector<K> selector;
- public PartitionedMapNode(Node node, ChildSelector selector)
+ public PartitionedMapNode(Node<K, V> node, ChildSelector<K> selector)
{
- this.node = node;
+ this.node = (NodeSPI) node;
this.selector = selector;
}
@Override
- public Set entrySet()
+ public Set<Map.Entry<K, V>> entrySet()
{
- return new AbstractSet<Map.Entry>()
+ return new AbstractSet<Map.Entry<K, V>>()
{
Iterator<Node> ci = node.getChildren().iterator();
@Override
- public Iterator<Entry> iterator()
+ public Iterator<Entry<K, V>> iterator()
{
- return new Iterator<Entry>()
+ return new Iterator<Entry<K, V>>()
{
Iterator ni;
@@ -620,6 +647,7 @@
findNext();
}
+ @SuppressWarnings("unchecked")
private void nextChild()
{
ni = new SimpleMapNode(ci.next()).entrySet().iterator();
@@ -640,9 +668,10 @@
return ni.hasNext();
}
- public Entry next()
+ @SuppressWarnings("unchecked")
+ public Entry<K, V> next()
{
- Entry n = (Entry) ni.next();
+ Entry<K, V> n = (Entry<K, V>) ni.next();
findNext();
return n;
}
@@ -665,15 +694,17 @@
}
@Override
+ @SuppressWarnings("unchecked")
public Set keySet()
{
- return new AbstractSet<Map.Entry>()
+ return new AbstractSet<Map.Entry<K, V>>()
{
@Override
- public Iterator<Entry> iterator()
+ @SuppressWarnings("unchecked")
+ public Iterator<Entry<K, V>> iterator()
{
- return PartitionedMapNode.super.keySet().iterator();
+ return (Iterator<Entry<K, V>>)
PartitionedMapNode.super.keySet().iterator();
}
@Override
@@ -706,40 +737,38 @@
node.getChild(o).clearData();
}
- private Node nodeFor(Object o)
+ @SuppressWarnings("unchecked")
+ private Fqn fqnFor(Object o)
{
- return node.getChild(selector.childName(o));
+ return Fqn.fromRelativeFqn(node.getFqn(), selector.childName((K) o));
}
@Override
+ @SuppressWarnings("unchecked")
public boolean containsKey(Object o)
{
- Node n = nodeFor(o);
- if (n == null) return false;
- return n.getKeys().contains(o);
+ Fqn fqn = fqnFor(o);
+ Set keys = node.getCache().getKeys(fqn);
+ return keys != null && keys.contains(o);
}
@Override
- public Object get(Object o)
+ @SuppressWarnings("unchecked")
+ public V get(Object key)
{
- Node n = nodeFor(o);
- if (n == null) return null;
- return n.get(o);
+ return (V) node.getCache().get(fqnFor(key), key);
}
+ @SuppressWarnings("unchecked")
public Object put(Object key, Object value)
{
- Object name = selector.childName(key);
- Node n = node.getChild(name);
- if (n == null)
- n = node.addChild(Fqn.fromElements(name));
- return n.put(key, value);
+ return node.getCache().put(fqnFor(key), key, value);
}
- public Object remove(Object o)
+ @SuppressWarnings("unchecked")
+ public V remove(Object key)
{
- Node n = nodeFor(o);
- return n.remove(o);
+ return (V) node.getCache().remove(fqnFor(key), key);
}
public int size()
@@ -752,65 +781,5 @@
}
return size;
}
-
}
-
- public static class SimpleEntry<K, V> implements Entry<K, V>
- {
- K key;
- V value;
-
- public SimpleEntry(K key, V value)
- {
- this.key = key;
- this.value = value;
- }
-
- public SimpleEntry(Entry<K, V> e)
- {
- this.key = e.getKey();
- this.value = e.getValue();
- }
-
- public K getKey()
- {
- return key;
- }
-
- public V getValue()
- {
- return value;
- }
-
- public V setValue(V value)
- {
- V oldValue = this.value;
- this.value = value;
- return oldValue;
- }
-
- public boolean equals(Object o)
- {
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry e = (Map.Entry) o;
- return eq(key, e.getKey()) && eq(value, e.getValue());
- }
-
- public int hashCode()
- {
- return ((key == null) ? 0 : key.hashCode()) ^
- ((value == null) ? 0 : value.hashCode());
- }
-
- public String toString()
- {
- return key + "=" + value;
- }
-
- private static boolean eq(Object o1, Object o2)
- {
- return (o1 == null ? o2 == null : o1.equals(o2));
- }
- }
}
Modified: core/trunk/src/test/java/org/jboss/cache/util/CachesTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/util/CachesTest.java 2008-08-04 20:26:13 UTC
(rev 6503)
+++ core/trunk/src/test/java/org/jboss/cache/util/CachesTest.java 2008-08-05 10:23:56 UTC
(rev 6504)
@@ -1,12 +1,14 @@
package org.jboss.cache.util;
+import junit.framework.TestCase;
import org.jboss.cache.Cache;
+import org.jboss.cache.DataContainer;
+import org.jboss.cache.DataContainerImpl;
import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.invocation.CacheInvocationDelegate;
import org.jboss.cache.util.Caches.ChildSelector;
-import org.jboss.cache.util.Caches.SimpleEntry;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.Test;
import java.util.Collection;
import java.util.Iterator;
@@ -16,8 +18,7 @@
/**
* Tests {@link Caches}.
*/
-@Test(groups = "functional")
-public class CachesTest
+public class CachesTest extends TestCase
{
String a = "a";
@@ -25,11 +26,11 @@
String c = "c";
- Cache<Object, Object> cache = new DefaultCacheFactory<Object,
Object>().createCache();
+ Cache cache = new DefaultCacheFactory().createCache();
public void testSegment()
{
- Map<Object, Object> m = Caches.asPartitionedMap(cache);
+ Map m = Caches.asPartitionedMap(cache);
// m.put(a, b);
testMap(m);
m.clear();
@@ -42,14 +43,13 @@
{
assertEquals("foo " + i, m.get(Integer.toHexString(i)));
}
- System.out.println(CachePrinter.printCacheDetails(cache));
}
public void testAsMap()
{
- Map<Object, Object> m = Caches.asMap(cache);
+ Map m = Caches.asMap(cache);
testMap(m);
- for (Node n : cache.getRoot().getChildren())
+ for (Node n : (Set<Node>) cache.getRoot().getChildren())
{
assertEquals("/a", n.getFqn().toString());
assertEquals(c, n.get("K"));
@@ -141,10 +141,10 @@
assertEquals(false, i.hasNext());
assertEquals(true, m.keySet().contains(c));
- assertEquals(true, m.entrySet().contains(new SimpleEntry(c, a)));
+ assertEquals(true, m.entrySet().contains(new SimpleImmutableEntry(c, a)));
assertEquals(true, m.values().contains(a));
assertEquals(false, m.keySet().contains(a));
- assertEquals(false, m.entrySet().contains(new SimpleEntry(a, c)));
+ assertEquals(false, m.entrySet().contains(new SimpleImmutableEntry(a, c)));
assertEquals(false, m.values().contains(c));
assertEquals(false, m.isEmpty());
m.clear();
@@ -173,9 +173,15 @@
m.put(h, 21);
assertEquals(42, m.get(f));
assertEquals(69, m.get(g));
- System.out.println(CachePrinter.printCacheDetails(cache));
+ System.out.println(printDetails(cache));
}
+ private String printDetails(Cache c)
+ {
+ DataContainer dc = ((CacheInvocationDelegate) c).getDataContainer();
+ return ((DataContainerImpl) dc).printDetails();
+ }
+
public static class Person
{
String name;
@@ -203,9 +209,9 @@
public static class DepartmentSelector implements ChildSelector<Person>
{
- public Object childName(Person key)
+ public Fqn childName(Person key)
{
- return key.getDepartment();
+ return Fqn.fromElements(key.getDepartment());
}
}