Return-Path: X-Original-To: apmail-hbase-commits-archive@www.apache.org Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D1AF8103BD for ; Sun, 28 Apr 2013 08:13:32 +0000 (UTC) Received: (qmail 69115 invoked by uid 500); 28 Apr 2013 08:13:32 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 68936 invoked by uid 500); 28 Apr 2013 08:13:32 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 68925 invoked by uid 99); 28 Apr 2013 08:13:32 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 28 Apr 2013 08:13:32 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 28 Apr 2013 08:13:30 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DB88A23889E7; Sun, 28 Apr 2013 08:13:10 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1476731 - in /hbase/branches/0.95: hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java Date: Sun, 28 Apr 2013 08:13:10 -0000 To: commits@hbase.apache.org From: zjushch@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130428081310.DB88A23889E7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: zjushch Date: Sun Apr 28 08:13:10 2013 New Revision: 1476731 URL: http://svn.apache.org/r1476731 Log: HBASE-8436 SeekBefore returns wrong result with PREFIX_TREE Encoding Modified: hbase/branches/0.95/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java Modified: hbase/branches/0.95/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java?rev=1476731&r1=1476730&r2=1476731&view=diff ============================================================================== --- hbase/branches/0.95/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java (original) +++ hbase/branches/0.95/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java Sun Apr 28 08:13:10 2013 @@ -91,6 +91,9 @@ public class PrefixTreeSeeker implements */ @Override public KeyValue getKeyValue() { + if (ptSearcher.current() == null) { + return null; + } return KeyValueUtil.copyToNewKeyValue(ptSearcher.current()); } @@ -163,14 +166,14 @@ public class PrefixTreeSeeker implements */ protected int seekToOrBeforeUsingPositionAtOrBefore(byte[] keyOnlyBytes, int offset, int length, - boolean forceBeforeOnExactMatch){ + boolean seekBefore){ // this does a deep copy of the key byte[] because the CellSearcher interface wants a Cell KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length); CellScannerPosition position = ptSearcher.seekForwardToOrBefore(kv); if(CellScannerPosition.AT == position){ - if (forceBeforeOnExactMatch) { + if (seekBefore) { ptSearcher.previous(); return 1; } @@ -182,7 +185,7 @@ public class PrefixTreeSeeker implements protected int seekToOrBeforeUsingPositionAtOrAfter(byte[] keyOnlyBytes, int offset, int length, - boolean forceBeforeOnExactMatch){ + boolean seekBefore){ // this does a deep copy of the key byte[] because the CellSearcher interface wants a Cell KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length); @@ -190,7 +193,7 @@ public class PrefixTreeSeeker implements CellScannerPosition position = ptSearcher.seekForwardToOrAfter(kv); if(CellScannerPosition.AT == position){ - if (forceBeforeOnExactMatch) { + if (seekBefore) { ptSearcher.previous(); return 1; } @@ -206,6 +209,9 @@ public class PrefixTreeSeeker implements } if(position == CellScannerPosition.AFTER_LAST){ + if (seekBefore) { + ptSearcher.previous(); + } return 1; } Modified: hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java?rev=1476731&r1=1476730&r2=1476731&view=diff ============================================================================== --- hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java (original) +++ hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java Sun Apr 28 08:13:10 2013 @@ -18,6 +18,9 @@ */ package org.apache.hadoop.hbase.io.encoding; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; @@ -57,9 +60,54 @@ public class TestPrefixTreeEncoding { private ConcurrentSkipListSet kvset = new ConcurrentSkipListSet( KeyValue.COMPARATOR); + private static boolean formatRowNum = false; + @Before public void setUp() throws Exception { kvset.clear(); + formatRowNum = false; + } + + @Test + public void testSeekBeforeWithFixedData() throws Exception { + formatRowNum = true; + PrefixTreeCodec encoder = new PrefixTreeCodec(); + int batchId = numBatchesWritten++; + ByteBuffer dataBuffer = generateFixedTestData(kvset, batchId, false); + HFileBlockEncodingContext blkEncodingCtx = new HFileBlockDefaultEncodingContext( + Algorithm.NONE, DataBlockEncoding.PREFIX_TREE, new byte[0]); + encoder.encodeKeyValues(dataBuffer, false, blkEncodingCtx); + EncodedSeeker seeker = encoder.createSeeker(KeyValue.KEY_COMPARATOR, false); + byte[] onDiskBytes = blkEncodingCtx.getOnDiskBytesWithHeader(); + ByteBuffer readBuffer = ByteBuffer.wrap(onDiskBytes, + DataBlockEncoding.ID_SIZE, onDiskBytes.length + - DataBlockEncoding.ID_SIZE); + seeker.setCurrentBuffer(readBuffer); + + // Seek before the first keyvalue; + KeyValue seekKey = KeyValue.createFirstDeleteFamilyOnRow( + getRowKey(batchId, 0), CF_BYTES); + seeker.seekToKeyInBlock(seekKey.getBuffer(), seekKey.getKeyOffset(), + seekKey.getKeyLength(), true); + assertEquals(null, seeker.getKeyValue()); + + // Seek before the middle keyvalue; + seekKey = KeyValue.createFirstDeleteFamilyOnRow( + getRowKey(batchId, NUM_ROWS_PER_BATCH / 3), CF_BYTES); + seeker.seekToKeyInBlock(seekKey.getBuffer(), seekKey.getKeyOffset(), + seekKey.getKeyLength(), true); + assertNotNull(seeker.getKeyValue()); + assertArrayEquals(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3 - 1), seeker + .getKeyValue().getRow()); + + // Seek before the last keyvalue; + seekKey = KeyValue.createFirstDeleteFamilyOnRow(Bytes.toBytes("zzzz"), + CF_BYTES); + seeker.seekToKeyInBlock(seekKey.getBuffer(), seekKey.getKeyOffset(), + seekKey.getKeyLength(), true); + assertNotNull(seeker.getKeyValue()); + assertArrayEquals(getRowKey(batchId, NUM_ROWS_PER_BATCH - 1), seeker + .getKeyValue().getRow()); } @Test @@ -157,10 +205,16 @@ public class TestPrefixTreeEncoding { private static ByteBuffer generateFixedTestData( ConcurrentSkipListSet kvset, int batchId) throws Exception { + return generateFixedTestData(kvset, batchId, true); + } + + private static ByteBuffer generateFixedTestData( + ConcurrentSkipListSet kvset, int batchId, boolean partial) + throws Exception { ByteArrayOutputStream baosInMemory = new ByteArrayOutputStream(); DataOutputStream userDataStream = new DataOutputStream(baosInMemory); for (int i = 0; i < NUM_ROWS_PER_BATCH; ++i) { - if (i / 10 % 2 == 1) continue; + if (partial && i / 10 % 2 == 1) continue; for (int j = 0; j < NUM_COLS_PER_ROW; ++j) { KeyValue kv = new KeyValue(getRowKey(batchId, i), CF_BYTES, getQualifier(j), getValue(batchId, i, j)); @@ -204,7 +258,8 @@ public class TestPrefixTreeEncoding { } private static byte[] getRowKey(int batchId, int i) { - return Bytes.toBytes("batch" + batchId + "_row" + i); + return Bytes.toBytes("batch" + batchId + "_row" + + (formatRowNum ? String.format("%04d", i) : i)); } private static byte[] getQualifier(int j) {