From efef11e2dc4dec550e37678b4a4117f213139407 Mon Sep 17 00:00:00 2001 From: Michael Stack Date: Fri, 13 Nov 2009 06:39:58 +0000 Subject: [PATCH] HBASE-1841 If multiple of same key in an hfile and they span blocks, may miss the earlier keys on a lookup git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@835757 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 3 +++ .../apache/hadoop/hbase/io/hfile/HFile.java | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 0a0d788be37..86f6fc5886a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -107,6 +107,9 @@ Release 0.21.0 - Unreleased Java 5 HBASE-1967 [Transactional] client.TestTransactions.testPutPutScan fails sometimes -- Temporary fix + HBASE-1841 If multiple of same key in an hfile and they span blocks, may + miss the earlier keys on a lookup + (Schubert Zhang via Stack) IMPROVEMENTS HBASE-1760 Cleanup TODOs in HTable diff --git a/src/java/org/apache/hadoop/hbase/io/hfile/HFile.java b/src/java/org/apache/hadoop/hbase/io/hfile/HFile.java index e212cf745f4..ee7b03ae460 100644 --- a/src/java/org/apache/hadoop/hbase/io/hfile/HFile.java +++ b/src/java/org/apache/hadoop/hbase/io/hfile/HFile.java @@ -475,9 +475,11 @@ public class HFile { public void append(final byte [] key, final int koffset, final int klength, final byte [] value, final int voffset, final int vlength) throws IOException { - checkKey(key, koffset, klength); + boolean dupKey = checkKey(key, koffset, klength); checkValue(value, voffset, vlength); - checkBlockBoundary(); + if (!dupKey) { + checkBlockBoundary(); + } // Write length of key and value and then actual key and value bytes. this.out.writeInt(klength); this.keylength += klength; @@ -499,10 +501,13 @@ public class HFile { /* * @param key Key to check. + * @return the flag of duplicate Key or not * @throws IOException */ - private void checkKey(final byte [] key, final int offset, final int length) + private boolean checkKey(final byte [] key, final int offset, final int length) throws IOException { + boolean dupKey = false; + if (key == null || length <= 0) { throw new IOException("Key cannot be null or empty"); } @@ -511,14 +516,18 @@ public class HFile { MAXIMUM_KEY_LENGTH); } if (this.lastKeyBuffer != null) { - if (this.comparator.compare(this.lastKeyBuffer, this.lastKeyOffset, - this.lastKeyLength, key, offset, length) > 0) { + int keyComp = this.comparator.compare(this.lastKeyBuffer, this.lastKeyOffset, + this.lastKeyLength, key, offset, length); + if (keyComp > 0) { throw new IOException("Added a key not lexically larger than" + " previous key=" + Bytes.toString(key, offset, length) + ", lastkey=" + Bytes.toString(this.lastKeyBuffer, this.lastKeyOffset, this.lastKeyLength)); + } else if (keyComp == 0) { + dupKey = true; } } + return dupKey; } private void checkValue(final byte [] value, final int offset,