From 4580a66bbbb69f13738d7d97366c85a3b5b91d6d Mon Sep 17 00:00:00 2001 From: Michael Stack Date: Mon, 21 Jan 2013 20:11:42 +0000 Subject: [PATCH] HBASE-3170 RegionServer confused about empty row keys git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1436587 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/hadoop/hbase/client/Scan.java | 12 +++++-- .../hadoop/hbase/regionserver/HRegion.java | 2 +- .../hbase/client/TestFromClientSide3.java | 34 +++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/Scan.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/Scan.java index a6f45a210b0..961c1536d46 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/Scan.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/Scan.java @@ -92,6 +92,7 @@ public class Scan extends OperationWithAttributes { private int storeLimit = -1; private int storeOffset = 0; + private boolean getScan; // If application wants to collect scan metrics, it needs to // call scan.setAttribute(SCAN_ATTRIBUTES_ENABLE, Bytes.toBytes(Boolean.TRUE)) @@ -141,6 +142,8 @@ public class Scan extends OperationWithAttributes { public Scan(byte [] startRow, byte [] stopRow) { this.startRow = startRow; this.stopRow = stopRow; + //if the startRow and stopRow both are empty, it is not a Get + this.getScan = isStartRowAndEqualsStopRow(); } /** @@ -159,6 +162,7 @@ public class Scan extends OperationWithAttributes { caching = scan.getCaching(); maxResultSize = scan.getMaxResultSize(); cacheBlocks = scan.getCacheBlocks(); + getScan = scan.isGetScan(); filter = scan.getFilter(); // clone? loadColumnFamiliesOnDemand = scan.getLoadColumnFamiliesOnDemandValue(); TimeRange ctr = scan.getTimeRange(); @@ -194,13 +198,17 @@ public class Scan extends OperationWithAttributes { this.storeOffset = get.getRowOffsetPerColumnFamily(); this.tr = get.getTimeRange(); this.familyMap = get.getFamilyMap(); + this.getScan = true; } public boolean isGetScan() { - return this.startRow != null && this.startRow.length > 0 && - Bytes.equals(this.startRow, this.stopRow); + return this.getScan || isStartRowAndEqualsStopRow(); } + private boolean isStartRowAndEqualsStopRow() { + return this.startRow != null && this.startRow.length > 0 && + Bytes.equals(this.startRow, this.stopRow); + } /** * Get all columns from the specified family. *

diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 41f7c29f3fb..7aa71e88a6a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -3406,7 +3406,7 @@ public class HRegion implements HeapSize { // , Writable{ } this.batch = scan.getBatch(); - if (Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) { + if (Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW) && !scan.isGetScan()) { this.stopRow = null; } else { this.stopRow = scan.getStopRow(); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java index 5b2563120c0..e2ddedad17e 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java @@ -22,6 +22,7 @@ package org.apache.hadoop.hbase.client; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.util.Arrays; import java.util.List; import java.util.Random; @@ -51,6 +52,9 @@ public class TestFromClientSide3 { private static byte[] FAMILY = Bytes.toBytes("testFamily"); private static Random random = new Random(); private static int SLAVES = 3; + private final static byte[] COL_QUAL = Bytes.toBytes("f1"); + private final static byte[] VAL_BYTES = Bytes.toBytes("v1"); + private final static byte[] ROW_BYTES = Bytes.toBytes("r1"); /** * @throws java.lang.Exception @@ -256,4 +260,34 @@ public class TestFromClientSide3 { "hbase.hstore.compaction.min")); } + @Test + public void testGetEmptyRow() throws Exception { + //Create a table and put in 1 row + HBaseAdmin admin = TEST_UTIL.getHBaseAdmin(); + HTableDescriptor desc = new HTableDescriptor(Bytes.toBytes("test")); + desc.addFamily(new HColumnDescriptor(FAMILY)); + admin.createTable(desc); + HTable table = new HTable(TEST_UTIL.getConfiguration(), "test"); + + Put put = new Put(ROW_BYTES); + put.add(FAMILY, COL_QUAL, VAL_BYTES); + table.put(put); + table.flushCommits(); + + //Try getting the row with an empty row key and make sure the other base cases work as well + Result res = table.get(new Get(new byte[0])); + assertTrue(res.isEmpty() == true); + res = table.get(new Get(Bytes.toBytes("r1-not-exist"))); + assertTrue(res.isEmpty() == true); + res = table.get(new Get(ROW_BYTES)); + assertTrue(Arrays.equals(res.getValue(FAMILY, COL_QUAL), VAL_BYTES)); + + //Now actually put in a row with an empty row key + put = new Put(new byte[0]); + put.add(FAMILY, COL_QUAL, VAL_BYTES); + table.put(put); + table.flushCommits(); + res = table.get(new Get(new byte[0])); + assertTrue(Arrays.equals(res.getValue(FAMILY, COL_QUAL), VAL_BYTES)); + } }