Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMemcache.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMemcache.java (revision 575373) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMemcache.java (working copy) @@ -26,7 +26,6 @@ import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; -import java.util.Vector; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; @@ -40,10 +39,9 @@ */ public class HMemcache { static final Log LOG = LogFactory.getLog(HMemcache.class); - TreeMap memcache = - new TreeMap(); - final Vector> history - = new Vector>(); + TreeMap memcache = new TreeMap(); + final ArrayList> history = + new ArrayList>(); TreeMap snapshot = null; final HLocking lock = new HLocking(); @@ -100,7 +98,9 @@ Snapshot retval = new Snapshot(memcache, Long.valueOf(log.startCacheFlush())); this.snapshot = memcache; - history.add(memcache); + synchronized (history) { + history.add(memcache); + } memcache = new TreeMap(); // Reset size of this memcache. this.size.set(0); @@ -123,12 +123,14 @@ if(snapshot == null) { throw new IOException("Snapshot not present!"); } - for (Iterator> it = history.iterator(); - it.hasNext();) { - TreeMap cur = it.next(); - if (snapshot == cur) { - it.remove(); - break; + synchronized (history) { + for (Iterator> it = history.iterator(); + it.hasNext();) { + TreeMap cur = it.next(); + if (snapshot == cur) { + it.remove(); + break; + } } } this.snapshot = null; @@ -178,15 +180,18 @@ this.lock.obtainReadLock(); try { ArrayList results = get(memcache, key, numVersions); - for (int i = history.size() - 1; i >= 0; i--) { - if (numVersions > 0 && results.size() >= numVersions) { - break; + synchronized (history) { + for (int i = history.size() - 1; i >= 0; i--) { + if (numVersions > 0 && results.size() >= numVersions) { + break; + } + results.addAll(results.size(), + get(history.get(i), key, numVersions - results.size())); } - results.addAll(results.size(), - get(history.elementAt(i), key, numVersions - results.size())); } - return (results.size() == 0)? - null: ImmutableBytesWritable.toArray(results); + return (results.size() == 0) ? null : + ImmutableBytesWritable.toArray(results); + } finally { this.lock.releaseReadLock(); } @@ -205,9 +210,11 @@ this.lock.obtainReadLock(); try { internalGetFull(memcache, key, results); - for (int i = history.size()-1; i >= 0; i--) { - TreeMap cur = history.elementAt(i); - internalGetFull(cur, key, results); + synchronized (history) { + for (int i = history.size()-1; i >= 0; i--) { + TreeMap cur = history.get(i); + internalGetFull(cur, key, results); + } } return results; @@ -284,10 +291,12 @@ this.lock.obtainReadLock(); try { List results = getKeys(this.memcache, origin, versions); - for (int i = history.size() - 1; i >= 0; i--) { - results.addAll(results.size(), getKeys(history.elementAt(i), origin, - versions == HConstants.ALL_VERSIONS? versions: - (results != null? versions - results.size(): versions))); + synchronized (history) { + for (int i = history.size() - 1; i >= 0; i--) { + results.addAll(results.size(), getKeys(history.get(i), origin, + versions == HConstants.ALL_VERSIONS ? versions : + (versions - results.size()))); + } } return results; } finally { @@ -366,32 +375,35 @@ super(timestamp, targetCols); lock.obtainReadLock(); try { - this.backingMaps = new TreeMap[history.size() + 1]; - - //NOTE: Since we iterate through the backing maps from 0 to n, we need - // to put the memcache first, the newest history second, ..., etc. - backingMaps[0] = memcache; - for(int i = history.size() - 1; i > 0; i--) { - backingMaps[i] = history.elementAt(i); - } - - this.keyIterators = new Iterator[backingMaps.length]; - this.keys = new HStoreKey[backingMaps.length]; - this.vals = new byte[backingMaps.length][]; + synchronized (history) { + this.backingMaps = new TreeMap[history.size() + 1]; + + //NOTE: Since we iterate through the backing maps from 0 to n, we need + // to put the memcache first, the newest history second, ..., etc. + backingMaps[0] = memcache; + for(int i = history.size() - 1; i > 0; i--) { + backingMaps[i] = history.get(i); + } + + this.keyIterators = new Iterator[backingMaps.length]; + this.keys = new HStoreKey[backingMaps.length]; + this.vals = new byte[backingMaps.length][]; + + // Generate list of iterators + HStoreKey firstKey = new HStoreKey(firstRow); + for(int i = 0; i < backingMaps.length; i++) { + keyIterators[i] = (firstRow != null && firstRow.getLength() != 0) ? + backingMaps[i].tailMap(firstKey).keySet().iterator() : + backingMaps[i].keySet().iterator(); - // Generate list of iterators - HStoreKey firstKey = new HStoreKey(firstRow); - for(int i = 0; i < backingMaps.length; i++) { - keyIterators[i] = (/*firstRow != null &&*/ firstRow.getLength() != 0)? - backingMaps[i].tailMap(firstKey).keySet().iterator(): - backingMaps[i].keySet().iterator(); - while(getNext(i)) { - if(! findFirstRow(i, firstRow)) { - continue; - } - if(columnMatch(i)) { - break; - } + while(getNext(i)) { + if(! findFirstRow(i, firstRow)) { + continue; + } + if(columnMatch(i)) { + break; + } + } } } } catch (RuntimeException ex) {