HBASE-5388 Tune HConnectionManager#getCachedLocation method (Ronghai Ma)
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1243994 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
37735435ec
commit
ac0fb8d5ae
|
@ -520,9 +520,9 @@ public class HConnectionManager {
|
||||||
* Map of table to table {@link HRegionLocation}s. The table key is made
|
* 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.
|
* 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 =
|
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
|
// 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
|
// entry in cachedRegionLocations that map to this server; but the absence
|
||||||
|
@ -1058,7 +1058,7 @@ public class HConnectionManager {
|
||||||
*/
|
*/
|
||||||
HRegionLocation getCachedLocation(final byte [] tableName,
|
HRegionLocation getCachedLocation(final byte [] tableName,
|
||||||
final byte [] row) {
|
final byte [] row) {
|
||||||
SortedMap<byte [], HRegionLocation> tableLocations =
|
SoftValueSortedMap<byte [], HRegionLocation> tableLocations =
|
||||||
getTableLocations(tableName);
|
getTableLocations(tableName);
|
||||||
|
|
||||||
// start to examine the cache. we can only do cache actions
|
// start to examine the cache. we can only do cache actions
|
||||||
|
@ -1067,43 +1067,26 @@ public class HConnectionManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRegionLocation rl = tableLocations.get(row);
|
HRegionLocation possibleRegion = tableLocations.get(row);
|
||||||
if (rl != null) {
|
if (possibleRegion != null) {
|
||||||
return rl;
|
return possibleRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cut the cache so that we only get the part that could contain
|
possibleRegion = tableLocations.lowerValueByKey(row);
|
||||||
// regions that match our key
|
if (possibleRegion == null) {
|
||||||
SortedMap<byte[], HRegionLocation> matchingRegions =
|
return null;
|
||||||
tableLocations.headMap(row);
|
}
|
||||||
|
|
||||||
// if that portion of the map is empty, then we're done. otherwise,
|
// make sure that the end key is greater than the row we're looking
|
||||||
// we need to examine the cached location to verify that it is
|
// for, otherwise the row actually belongs in the next region, not
|
||||||
// a match by end key as well.
|
// this one. the exception case is when the endkey is
|
||||||
if (!matchingRegions.isEmpty()) {
|
// HConstants.EMPTY_END_ROW, signifying that the region we're
|
||||||
HRegionLocation possibleRegion = null;
|
// checking is actually the last region in the table.
|
||||||
try {
|
byte[] endKey = possibleRegion.getRegionInfo().getEndKey();
|
||||||
possibleRegion = matchingRegions.get(matchingRegions.lastKey());
|
if (Bytes.equals(endKey, HConstants.EMPTY_END_ROW) ||
|
||||||
} catch (NoSuchElementException nsee) {
|
KeyValue.getRowComparator(tableName).compareRows(
|
||||||
LOG.warn("checkReferences() might have removed the key", nsee);
|
endKey, 0, endKey.length, row, 0, row.length) > 0) {
|
||||||
}
|
return possibleRegion;
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passed all the way through, so we got nothin - complete cache miss
|
// Passed all the way through, so we got nothin - complete cache miss
|
||||||
|
@ -1173,11 +1156,11 @@ public class HConnectionManager {
|
||||||
* @param tableName
|
* @param tableName
|
||||||
* @return Map of cached locations for passed <code>tableName</code>
|
* @return Map of cached locations for passed <code>tableName</code>
|
||||||
*/
|
*/
|
||||||
private SortedMap<byte [], HRegionLocation> getTableLocations(
|
private SoftValueSortedMap<byte [], HRegionLocation> getTableLocations(
|
||||||
final byte [] tableName) {
|
final byte [] tableName) {
|
||||||
// find the map of cached locations for this table
|
// find the map of cached locations for this table
|
||||||
Integer key = Bytes.mapKey(tableName);
|
Integer key = Bytes.mapKey(tableName);
|
||||||
SortedMap<byte [], HRegionLocation> result;
|
SoftValueSortedMap<byte [], HRegionLocation> result;
|
||||||
synchronized (this.cachedRegionLocations) {
|
synchronized (this.cachedRegionLocations) {
|
||||||
result = this.cachedRegionLocations.get(key);
|
result = this.cachedRegionLocations.get(key);
|
||||||
// if tableLocations for this table isn't built yet, make one
|
// if tableLocations for this table isn't built yet, make one
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NavigableMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
@ -175,6 +176,32 @@ public class SoftValueSortedMap<K,V> implements SortedMap<K,V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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() {
|
public boolean isEmpty() {
|
||||||
synchronized(sync) {
|
synchronized(sync) {
|
||||||
checkReferences();
|
checkReferences();
|
||||||
|
|
Loading…
Reference in New Issue