Author: tedyu
Date: Tue Feb 14 15:28:59 2012
New Revision: 1243994
URL: http://svn.apache.org/viewvc?rev=1243994&view=rev
Log:
HBASE-5388 Tune HConnectionManager#getCachedLocation method (Ronghai Ma)
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1243994&r1=1243993&r2=1243994&view=diff
==============================================================================
---
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
(original)
+++
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
Tue Feb 14 15:28:59 2012
@@ -520,9 +520,9 @@ public class HConnectionManager {
* Map of table to table {@link HRegionLocation}s. The table key is made
* by doing a {@link Bytes#mapKey(byte[])} of the table's name.
*/
- private final Map<Integer, SortedMap<byte [], HRegionLocation>>
+ private final Map<Integer, SoftValueSortedMap<byte [], HRegionLocation>>
cachedRegionLocations =
- new HashMap<Integer, SortedMap<byte [], HRegionLocation>>();
+ new HashMap<Integer, SoftValueSortedMap<byte [], HRegionLocation>>();
// The presence of a server in the map implies it's likely that there is an
// entry in cachedRegionLocations that map to this server; but the absence
@@ -1058,7 +1058,7 @@ public class HConnectionManager {
*/
HRegionLocation getCachedLocation(final byte [] tableName,
final byte [] row) {
- SortedMap<byte [], HRegionLocation> tableLocations =
+ SoftValueSortedMap<byte [], HRegionLocation> tableLocations =
getTableLocations(tableName);
// start to examine the cache. we can only do cache actions
@@ -1067,43 +1067,26 @@ public class HConnectionManager {
return null;
}
- HRegionLocation rl = tableLocations.get(row);
- if (rl != null) {
- return rl;
+ HRegionLocation possibleRegion = tableLocations.get(row);
+ if (possibleRegion != null) {
+ return possibleRegion;
}
- // Cut the cache so that we only get the part that could contain
- // regions that match our key
- SortedMap<byte[], HRegionLocation> matchingRegions =
- tableLocations.headMap(row);
-
- // if that portion of the map is empty, then we're done. otherwise,
- // we need to examine the cached location to verify that it is
- // a match by end key as well.
- if (!matchingRegions.isEmpty()) {
- HRegionLocation possibleRegion = null;
- try {
- possibleRegion = matchingRegions.get(matchingRegions.lastKey());
- } catch (NoSuchElementException nsee) {
- LOG.warn("checkReferences() might have removed the key", nsee);
- }
-
- // there is a possibility that the reference was garbage collected
- // in the instant since we checked isEmpty().
- if (possibleRegion != null) {
- byte[] endKey = possibleRegion.getRegionInfo().getEndKey();
-
- // make sure that the end key is greater than the row we're looking
- // for, otherwise the row actually belongs in the next region, not
- // this one. the exception case is when the endkey is
- // HConstants.EMPTY_START_ROW, signifying that the region we're
- // checking is actually the last region in the table.
- if (Bytes.equals(endKey, HConstants.EMPTY_END_ROW) ||
- KeyValue.getRowComparator(tableName).compareRows(endKey, 0,
endKey.length,
- row, 0, row.length) > 0) {
- return possibleRegion;
- }
- }
+ possibleRegion = tableLocations.lowerValueByKey(row);
+ if (possibleRegion == null) {
+ return null;
+ }
+
+ // make sure that the end key is greater than the row we're looking
+ // for, otherwise the row actually belongs in the next region, not
+ // this one. the exception case is when the endkey is
+ // HConstants.EMPTY_END_ROW, signifying that the region we're
+ // checking is actually the last region in the table.
+ byte[] endKey = possibleRegion.getRegionInfo().getEndKey();
+ if (Bytes.equals(endKey, HConstants.EMPTY_END_ROW) ||
+ KeyValue.getRowComparator(tableName).compareRows(
+ endKey, 0, endKey.length, row, 0, row.length) > 0) {
+ return possibleRegion;
}
// Passed all the way through, so we got nothin - complete cache miss
@@ -1173,11 +1156,11 @@ public class HConnectionManager {
* @param tableName
* @return Map of cached locations for passed <code>tableName</code>
*/
- private SortedMap<byte [], HRegionLocation> getTableLocations(
+ private SoftValueSortedMap<byte [], HRegionLocation> getTableLocations(
final byte [] tableName) {
// find the map of cached locations for this table
Integer key = Bytes.mapKey(tableName);
- SortedMap<byte [], HRegionLocation> result;
+ SoftValueSortedMap<byte [], HRegionLocation> result;
synchronized (this.cachedRegionLocations) {
result = this.cachedRegionLocations.get(key);
// if tableLocations for this table isn't built yet, make one
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java?rev=1243994&r1=1243993&r2=1243994&view=diff
==============================================================================
---
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
(original)
+++
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
Tue Feb 14 15:28:59 2012
@@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.NavigableMap;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -175,6 +176,32 @@ public class SoftValueSortedMap<K,V> imp
}
}
+ /*
+ * retrieves the value associated with the greatest key strictly less than
+ * the given key, or null if there is no such key
+ * @param key the key we're interested in
+ */
+ public synchronized V lowerValueByKey(K key) {
+ synchronized(sync) {
+ checkReferences();
+
+ Map.Entry<K,SoftValue<K,V>> entry =
+ ((NavigableMap<K, SoftValue<K,V>>) this.internalMap).lowerEntry(key);
+ if (entry==null) {
+ return null;
+ }
+ SoftValue<K,V> value=entry.getValue();
+ if (value==null) {
+ return null;
+ }
+ if (value.get() == null) {
+ this.internalMap.remove(key);
+ return null;
+ }
+ return value.get();
+ }
+ }
+
public boolean isEmpty() {
synchronized(sync) {
checkReferences();