You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2013/03/13 15:47:05 UTC
svn commit: r1455971 - in /hbase/trunk/hbase-server/src:
main/java/org/apache/hadoop/hbase/regionserver/
test/java/org/apache/hadoop/hbase/io/hfile/
Author: tedyu
Date: Wed Mar 13 14:47:05 2013
New Revision: 1455971
URL: http://svn.apache.org/r1455971
Log:
HBASE-8063 Filter HFiles based on first/last key (Liang Xie)
Added:
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestScannerSelectionUsingKeyRange.java
Modified:
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java?rev=1455971&r1=1455970&r2=1455971&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java Wed Mar 13 14:47:05 2013
@@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.HConstant
import org.apache.hadoop.hbase.HDFSBlocksDistribution;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValue.KVComparator;
+import org.apache.hadoop.hbase.KeyValue.MetaKeyComparator;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.Reference;
import org.apache.hadoop.hbase.io.compress.Compression;
@@ -1401,6 +1402,28 @@ public class StoreFile {
return true;
}
+ /**
+ * Checks whether the given scan rowkey range overlaps with the current storefile's
+ * @param scan the scan specification. Used to determine the rowkey range.
+ * @return true if there is overlap, false otherwise
+ */
+ boolean passesKeyRangeFilter(Scan scan) {
+ if (this.getFirstKey() == null || this.getLastKey() == null) {
+ // the file is empty
+ return false;
+ }
+ if (Bytes.equals(scan.getStartRow(), HConstants.EMPTY_START_ROW)
+ && Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) {
+ return true;
+ }
+ KeyValue startKeyValue = KeyValue.createFirstOnRow(scan.getStartRow());
+ KeyValue stopKeyValue = KeyValue.createLastOnRow(scan.getStopRow());
+ boolean nonOverLapping = (getComparator().compare(this.getFirstKey(),
+ stopKeyValue.getKey()) > 0 && !Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW))
+ || getComparator().compare(this.getLastKey(), startKeyValue.getKey()) < 0;
+ return !nonOverLapping;
+ }
+
public Map<byte[], byte[]> loadFileInfo() throws IOException {
Map<byte [], byte []> fi = reader.loadFileInfo();
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java?rev=1455971&r1=1455970&r2=1455971&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java Wed Mar 13 14:47:05 2013
@@ -369,9 +369,8 @@ public class StoreFileScanner implements
}
@Override
- public boolean shouldUseScanner(Scan scan, SortedSet<byte[]> columns,
- long oldestUnexpiredTS) {
- return reader.passesTimerangeFilter(scan, oldestUnexpiredTS) &&
- reader.passesBloomFilter(scan, columns);
+ public boolean shouldUseScanner(Scan scan, SortedSet<byte[]> columns, long oldestUnexpiredTS) {
+ return reader.passesTimerangeFilter(scan, oldestUnexpiredTS)
+ && reader.passesKeyRangeFilter(scan) && reader.passesBloomFilter(scan, columns);
}
}
Added: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestScannerSelectionUsingKeyRange.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestScannerSelectionUsingKeyRange.java?rev=1455971&view=auto
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestScannerSelectionUsingKeyRange.java (added)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestScannerSelectionUsingKeyRange.java Wed Mar 13 14:47:05 2013
@@ -0,0 +1,128 @@
+/*
+ * 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.io.hfile;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.SmallTests;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.regionserver.BloomType;
+import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.InternalScanner;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Test the optimization that does not scan files where all key ranges are excluded.
+ */
+@RunWith(Parameterized.class)
+@Category(SmallTests.class)
+public class TestScannerSelectionUsingKeyRange {
+ private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+ private static String TABLE = "myTable";
+ private static String FAMILY = "myCF";
+ private static byte[] FAMILY_BYTES = Bytes.toBytes(FAMILY);
+ private static final int NUM_ROWS = 8;
+ private static final int NUM_COLS_PER_ROW = 5;
+ private static final int NUM_FILES = 2;
+ private static final Map<Object, Integer> TYPE_COUNT = new HashMap<Object, Integer>(3);
+ static {
+ TYPE_COUNT.put(BloomType.ROWCOL, 0);
+ TYPE_COUNT.put(BloomType.ROW, 0);
+ TYPE_COUNT.put(BloomType.NONE, 0);
+ }
+
+ private BloomType bloomType;
+ private int expectedCount;
+
+ @Parameters
+ public static Collection<Object[]> parameters() {
+ List<Object[]> params = new ArrayList<Object[]>();
+ for (Object type : TYPE_COUNT.keySet()) {
+ params.add(new Object[] { type, TYPE_COUNT.get(type) });
+ }
+ return params;
+ }
+
+ public TestScannerSelectionUsingKeyRange(Object type, Object count) {
+ bloomType = (BloomType)type;
+ expectedCount = (Integer) count;
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TEST_UTIL.cleanupTestDir();
+ }
+
+ @Test
+ public void testScannerSelection() throws IOException {
+ Configuration conf = TEST_UTIL.getConfiguration();
+ conf.setInt("hbase.hstore.compactionThreshold", 10000);
+ HColumnDescriptor hcd = new HColumnDescriptor(FAMILY_BYTES).setBlockCacheEnabled(true)
+ .setBloomFilterType(bloomType);
+ HTableDescriptor htd = new HTableDescriptor(TABLE);
+ htd.addFamily(hcd);
+ HRegionInfo info = new HRegionInfo(Bytes.toBytes(TABLE));
+ HRegion region = HRegion.createHRegion(info, TEST_UTIL.getDataTestDir(), conf, htd);
+
+ for (int iFile = 0; iFile < NUM_FILES; ++iFile) {
+ for (int iRow = 0; iRow < NUM_ROWS; ++iRow) {
+ Put put = new Put(Bytes.toBytes("row" + iRow));
+ for (int iCol = 0; iCol < NUM_COLS_PER_ROW; ++iCol) {
+ put.add(FAMILY_BYTES, Bytes.toBytes("col" + iCol),
+ Bytes.toBytes("value" + iFile + "_" + iRow + "_" + iCol));
+ }
+ region.put(put);
+ }
+ region.flushcache();
+ }
+
+ Scan scan = new Scan(Bytes.toBytes("aaa"), Bytes.toBytes("aaz"));
+ CacheConfig cacheConf = new CacheConfig(conf);
+ LruBlockCache cache = (LruBlockCache) cacheConf.getBlockCache();
+ cache.clearCache();
+ InternalScanner scanner = region.getScanner(scan);
+ List<KeyValue> results = new ArrayList<KeyValue>();
+ while (scanner.next(results)) {
+ }
+ scanner.close();
+ assertEquals(0, results.size());
+ Set<String> accessedFiles = cache.getCachedFileNamesForTest();
+ assertEquals(expectedCount, accessedFiles.size());
+ region.close();
+ }
+}