diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/VectorMapJoinFastKeyStore.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/VectorMapJoinFastKeyStore.java index 58af4eb..efdcd43 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/VectorMapJoinFastKeyStore.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/VectorMapJoinFastKeyStore.java @@ -30,7 +30,6 @@ private WriteBuffers writeBuffers; - private WriteBuffers.ByteSegmentRef byteSegmentRef; private WriteBuffers.Position readPos; /** @@ -141,17 +140,11 @@ public boolean equalKey(long keyRefWord, byte[] keyBytes, int keyStart, int keyL } // Our reading is positioned to the key. - writeBuffers.getByteSegmentRefToCurrent(byteSegmentRef, keyLength, readPos); - - byte[] currentBytes = byteSegmentRef.getBytes(); - int currentStart = (int) byteSegmentRef.getOffset(); - - for (int i = 0; i < keyLength; i++) { - if (currentBytes[currentStart + i] != keyBytes[keyStart + i]) { - // LOG.debug("VectorMapJoinFastKeyStore equalKey no match on bytes"); - return false; - } + if (!writeBuffers.isEqual(keyBytes, keyStart, readPos, keyLength)) { + // LOG.debug("VectorMapJoinFastKeyStore equalKey no match on bytes"); + return false; } + // LOG.debug("VectorMapJoinFastKeyStore equalKey match on bytes"); return true; } @@ -159,7 +152,6 @@ public boolean equalKey(long keyRefWord, byte[] keyBytes, int keyStart, int keyL public VectorMapJoinFastKeyStore(int writeBuffersSize) { writeBuffers = new WriteBuffers(writeBuffersSize, AbsoluteKeyOffset.maxSize); - byteSegmentRef = new WriteBuffers.ByteSegmentRef(); readPos = new WriteBuffers.Position(); } @@ -167,7 +159,6 @@ public VectorMapJoinFastKeyStore(WriteBuffers writeBuffers) { // TODO: Check if maximum size compatible with AbsoluteKeyOffset.maxSize. this.writeBuffers = writeBuffers; - byteSegmentRef = new WriteBuffers.ByteSegmentRef(); readPos = new WriteBuffers.Position(); } } diff --git serde/src/java/org/apache/hadoop/hive/serde2/WriteBuffers.java serde/src/java/org/apache/hadoop/hive/serde2/WriteBuffers.java index b47456e..c8f7be8 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/WriteBuffers.java +++ serde/src/java/org/apache/hadoop/hive/serde2/WriteBuffers.java @@ -282,32 +282,30 @@ public boolean isEqual(long leftOffset, int leftLength, long rightOffset, int ri return true; } - /** - * Compares part of the buffer with a part of an external byte array. - * Does not modify readPoint. - */ - public boolean isEqual(byte[] left, int leftLength, long rightOffset, int rightLength) { - if (rightLength != leftLength) { - return false; - } - int rightIndex = getBufferIndex(rightOffset), rightFrom = getOffset(rightOffset); + private final boolean isEqual(byte[] left, int leftOffset, int rightIndex, int rightFrom, int length) { + // invariant: rightLength = leftLength + // rightOffset is within the buffers byte[] rightBuffer = writeBuffers.get(rightIndex); - if (rightFrom + rightLength <= wbSize) { + if (rightFrom + length <= wbSize) { // TODO: allow using unsafe optionally. - for (int i = 0; i < leftLength; ++i) { - if (left[i] != rightBuffer[rightFrom + i]) { + // bounds check first, to trigger bugs whether the first byte matches or not + if (left[leftOffset + length - 1] != rightBuffer[rightFrom + length - 1]) { + return false; + } + for (int i = 0; i < length; ++i) { + if (left[leftOffset + i] != rightBuffer[rightFrom + i]) { return false; } } return true; } - for (int i = 0; i < rightLength; ++i) { + for (int i = 0; i < length; ++i) { if (rightFrom == wbSize) { ++rightIndex; rightBuffer = writeBuffers.get(rightIndex); rightFrom = 0; } - if (left[i] != rightBuffer[rightFrom++]) { + if (left[leftOffset + i] != rightBuffer[rightFrom++]) { return false; } } @@ -318,32 +316,30 @@ public boolean isEqual(byte[] left, int leftLength, long rightOffset, int rightL * Compares part of the buffer with a part of an external byte array. * Does not modify readPoint. */ - public boolean isEqual(byte[] left, int leftOffset, int leftLength, long rightOffset, int rightLength) { + public boolean isEqual(byte[] left, int leftLength, long rightOffset, int rightLength) { if (rightLength != leftLength) { return false; } - int rightIndex = getBufferIndex(rightOffset), rightFrom = getOffset(rightOffset); - byte[] rightBuffer = writeBuffers.get(rightIndex); - if (rightFrom + rightLength <= wbSize) { - // TODO: allow using unsafe optionally. - for (int i = 0; i < leftLength; ++i) { - if (left[leftOffset + i] != rightBuffer[rightFrom + i]) { - return false; - } - } - return true; - } - for (int i = 0; i < rightLength; ++i) { - if (rightFrom == wbSize) { - ++rightIndex; - rightBuffer = writeBuffers.get(rightIndex); - rightFrom = 0; - } - if (left[leftOffset + i] != rightBuffer[rightFrom++]) { - return false; - } + return isEqual(left, 0, getBufferIndex(rightOffset), getOffset(rightOffset), leftLength); + } + + /** + * Compares part of the buffer with a part of an external byte array. + * Does not modify readPoint. + */ + public boolean isEqual(byte[] left, int leftOffset, int leftLength, long rightOffset, int rightLength) { + if (rightLength != leftLength) { + return false; } - return true; + return isEqual(left, leftOffset, getBufferIndex(rightOffset), getOffset(rightOffset), leftLength); + } + + /** + * Compares the current readPosition of the buffer with the external byte array. + * Does not modify readPoint. + */ + public boolean isEqual(byte[] left, int leftOffset, Position readPos, int length) { + return isEqual(left, leftOffset, readPos.bufferIndex, readPos.offset, length); } public void clear() {