Index: src/test/java/org/apache/hadoop/hbase/client/TestHCM.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/client/TestHCM.java (revision 0) +++ src/test/java/org/apache/hadoop/hbase/client/TestHCM.java (revision 0) @@ -0,0 +1,66 @@ +/* + * Copyright 2010 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.client; + +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HRegionLocation; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; + +/** + * This class is for testing HCM features + */ +public class TestHCM { + + private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static final byte[] TABLE_NAME = Bytes.toBytes("test"); + private static final byte[] FAM_NAM = Bytes.toBytes("f"); + private static final byte[] ROW = Bytes.toBytes("bbb"); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TEST_UTIL.startMiniCluster(1); + } + + /** + * Test that when we delete a location using the first row of a region + * that we really delete it. + * @throws Exception + */ + @Test + public void testRegionCaching() throws Exception{ + HTable table = TEST_UTIL.createTable(TABLE_NAME, FAM_NAM); + TEST_UTIL.createMultiRegions(table, FAM_NAM); + Put put = new Put(ROW); + put.add(FAM_NAM, ROW, ROW); + table.put(put); + HConnectionManager.TableServers conn = + (HConnectionManager.TableServers) table.getConnection(); + assertNotNull(conn.getCachedLocation(TABLE_NAME, ROW)); + conn.deleteCachedLocation(TABLE_NAME, ROW); + HRegionLocation rl = conn.getCachedLocation(TABLE_NAME, ROW); + assertNull("What is this location?? " + rl, rl); + } +} + Index: src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (revision 953830) +++ src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (working copy) @@ -243,7 +243,7 @@ } /* Encapsulates finding the servers for an HBase instance */ - private static class TableServers implements ServerConnection { + static class TableServers implements ServerConnection { static final Log LOG = LogFactory.getLog(TableServers.class); private final Class serverInterfaceClass; private final long pause; @@ -787,7 +787,7 @@ * @param row * @return Null or region location found in cache. */ - private HRegionLocation getCachedLocation(final byte [] tableName, + HRegionLocation getCachedLocation(final byte [] tableName, final byte [] row) { SoftValueSortedMap tableLocations = getTableLocations(tableName); @@ -849,7 +849,7 @@ * Delete a cached location, if it satisfies the table name and row * requirements. */ - private void deleteCachedLocation(final byte [] tableName, + void deleteCachedLocation(final byte [] tableName, final byte [] row) { synchronized (this.cachedRegionLocations) { SoftValueSortedMap tableLocations = @@ -858,32 +858,14 @@ // start to examine the cache. we can only do cache actions // if there's something in the cache for this table. if (!tableLocations.isEmpty()) { - // cut the cache so that we only get the part that could contain - // regions that match our key - SoftValueSortedMap 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 = - matchingRegions.get(matchingRegions.lastKey()); - byte [] endKey = possibleRegion.getRegionInfo().getEndKey(); - - // by nature of the map, we know that the start key has to be < - // otherwise it wouldn't be in the headMap. - if (Bytes.equals(endKey, HConstants.EMPTY_END_ROW) || - KeyValue.getRowComparator(tableName).compareRows(endKey, 0, endKey.length, - row, 0, row.length) > 0) { - // delete any matching entry - HRegionLocation rl = - tableLocations.remove(matchingRegions.lastKey()); - if (rl != null && LOG.isDebugEnabled()) { - LOG.debug("Removed " + rl.getRegionInfo().getRegionNameAsString() + - " for tableName=" + Bytes.toString(tableName) + " from cache " + - "because of " + Bytes.toStringBinary(row)); - } + HRegionLocation rl = getCachedLocation(tableName, row); + if (rl != null) { + tableLocations.remove(rl.getRegionInfo().getStartKey()); + if (LOG.isDebugEnabled()) { + LOG.debug("Removed " + + rl.getRegionInfo().getRegionNameAsString() + + " for tableName=" + Bytes.toString(tableName) + + " from cache " + "because of " + Bytes.toStringBinary(row)); } } }