Author: manik.surtani(a)jboss.com
Date: 2008-10-03 11:12:19 -0400 (Fri, 03 Oct 2008)
New Revision: 6835
Modified:
core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
core/trunk/src/main/java/org/jboss/cache/util/FastCopyHashMap.java
Log:
JBCACHE-1082: Optimise nodes for single elements
Modified: core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-10-03 13:27:23 UTC
(rev 6834)
+++ core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-10-03 15:12:19 UTC
(rev 6835)
@@ -33,6 +33,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -49,13 +50,13 @@
/**
* Debug log.
*/
- static Log log = LogFactory.getLog(UnversionedNode.class);
+ protected static Log log = LogFactory.getLog(UnversionedNode.class);
protected static final boolean trace = log.isTraceEnabled();
/**
* Map of general data keys to values.
*/
- protected FastCopyHashMap<K, V> data;
+ protected Map<K, V> data;
protected NodeSPI<K, V> delegate;
protected CacheSPI<K, V> cache;
@@ -137,10 +138,10 @@
}
// does not need to be synchronized since this will only be accessed by a single
thread in MVCC thanks to the write lock.
- private void initDataMap()
- {
- if (data == null) data = new FastCopyHashMap<K, V>();
- }
+// private void initDataMap()
+// {
+// if (data == null) data = new FastCopyHashMap<K, V>();
+// }
public CacheSPI<K, V> getCache()
{
@@ -170,7 +171,19 @@
public V put(K key, V value)
{
- if (data == null) initDataMap();
+ if (data == null)
+ {
+ // new singleton map!
+ data = Collections.singletonMap(key, value);
+ return null;
+ }
+ if (data.size() == 1 && data.containsKey(key))
+ {
+ V oldVal = data.get(key);
+ data = Collections.singletonMap(key, value);
+ return oldVal;
+ }
+ upgradeDataMap();
return data.put(key, value);
}
@@ -280,7 +293,19 @@
public V remove(K key)
{
if (data == null) return null;
- return data.remove(key);
+ V value;
+ if (data instanceof FastCopyHashMap)
+ {
+ value = data.remove(key);
+ downgradeDataMapIfNeeded();
+ }
+ else
+ {
+ // singleton maps cannot remove!
+ value = data.get(key);
+ data = null;
+ }
+ return value;
}
public void printDetails(StringBuilder sb, int indent)
@@ -388,7 +413,8 @@
public void clear()
{
- if (data != null) data.clear();
+ data = null;
+// if (data != null) data.clear();
}
@SuppressWarnings("unchecked")
@@ -428,11 +454,38 @@
{
if (data != null)
{
- if (this.data == null) initDataMap();
- this.data.putAll(data);
+ if (this.data == null)
+ copyDataMap(data);
+ else
+ if (this.data.size() == 1 && data.size() == 1 &&
this.data.keySet().iterator().next().equals(data.keySet().iterator().next()))
+ {
+ // replace key!
+ Entry<? extends K, ? extends V> e = data.entrySet().iterator().next();
+ this.data = Collections.singletonMap(e.getKey(), e.getValue());
+ }
+ else
+ {
+ // size. Do we need to update the existing data map to a FCHM?
+ upgradeDataMap();
+ this.data.putAll(data);
+ }
}
}
+ protected final void upgradeDataMap()
+ {
+ if (data != null && !(data instanceof FastCopyHashMap)) data = new
FastCopyHashMap<K, V>(data);
+ }
+
+ protected final void downgradeDataMapIfNeeded()
+ {
+ if (data.size() == 1 && data instanceof FastCopyHashMap)
+ {
+ Entry<K, V> e = data.entrySet().iterator().next();
+ data = Collections.singletonMap(e.getKey(), e.getValue());
+ }
+ }
+
public void removeChildren()
{
children.clear();
@@ -556,7 +609,7 @@
public InternalNode<K, V> copy()
{
UnversionedNode<K, V> n = new UnversionedNode<K, V>(fqn, cache,
isFlagSet(LOCK_FOR_CHILD_INSERT_REMOVE));
- if (data != null) n.data = (FastCopyHashMap<K, V>) data.clone();
+ n.data = copyDataMap(data);
copyInternals(n);
return n;
}
@@ -573,7 +626,7 @@
{
if (data == null)
{
- data = state == null ? new FastCopyHashMap<K, V>() : new
FastCopyHashMap<K, V>(state);
+ data = copyDataMap(state);
}
else
{
@@ -582,6 +635,29 @@
}
}
+ protected final Map copyDataMap(Map<? extends K, ? extends V> toCopyFrom)
+ {
+ if (toCopyFrom != null && toCopyFrom.size() > 0)
+ {
+ Map map;
+ if (toCopyFrom instanceof FastCopyHashMap)
+ {
+ map = (FastCopyHashMap<K, V>) ((FastCopyHashMap<K, V>)
toCopyFrom).clone();
+ }
+ else if (toCopyFrom.size() == 1)
+ {
+ Entry<? extends K, ? extends V> e =
toCopyFrom.entrySet().iterator().next();
+ map = Collections.singletonMap(e.getKey(), e.getValue());
+ }
+ else
+ {
+ map = new FastCopyHashMap<K, V>(toCopyFrom);
+ }
+ return map;
+ }
+ return null;
+ }
+
public Map getInternalState(boolean onlyInternalState)
{
if (onlyInternalState)
Modified: core/trunk/src/main/java/org/jboss/cache/util/FastCopyHashMap.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/FastCopyHashMap.java 2008-10-03 13:27:23
UTC (rev 6834)
+++ core/trunk/src/main/java/org/jboss/cache/util/FastCopyHashMap.java 2008-10-03 15:12:19
UTC (rev 6835)
@@ -53,7 +53,7 @@
/**
* Same default as HashMap, must be a power of 2
*/
- private static final int DEFAULT_CAPACITY = 16;
+ private static final int DEFAULT_CAPACITY = 8;
/**
* MAX_INT - 1