### Eclipse Workspace Patch 1.0 #P apache-trunk Index: hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java =================================================================== --- hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java (revision 1475627) +++ hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java (working copy) @@ -91,6 +91,9 @@ */ @Override public KeyValue getKeyValue() { + if (ptSearcher.current() == null) { + return null; + } return KeyValueUtil.copyToNewKeyValue(ptSearcher.current()); } @@ -206,6 +209,9 @@ } if(position == CellScannerPosition.AFTER_LAST){ + if (forceBeforeOnExactMatch) { + ptSearcher.previous(); + } return 1; } Index: hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java (revision 1475627) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java (working copy) @@ -18,6 +18,8 @@ */ package org.apache.hadoop.hbase.io.encoding; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; @@ -63,6 +65,56 @@ } @Test + public void testSeekBeforeWithFixedData() throws Exception { + 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()); + } + + /** + * @param rowKey + * @param row + */ + private void assertArrayEquals(byte[] rowKey, byte[] row) { + // TODO Auto-generated method stub + + } + + @Test public void testScanWithRandomData() throws Exception { PrefixTreeCodec encoder = new PrefixTreeCodec(); ByteBuffer dataBuffer = generateRandomTestData(kvset, numBatchesWritten++); @@ -157,10 +209,16 @@ 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));