You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2022/07/19 07:42:42 UTC
[lucene] branch branch_9x updated: LUCENE-10657: CopyBytes now saves one memory copy on ByteBuffersDataOutput (#1034)
This is an automated email from the ASF dual-hosted git repository.
jpountz pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 7328ad2dafc LUCENE-10657: CopyBytes now saves one memory copy on ByteBuffersDataOutput (#1034)
7328ad2dafc is described below
commit 7328ad2dafc2e78bf2950cb4bdd2c8785f31f7b9
Author: luyuncheng <lu...@bytedance.com>
AuthorDate: Tue Jul 19 15:37:07 2022 +0800
LUCENE-10657: CopyBytes now saves one memory copy on ByteBuffersDataOutput (#1034)
Abstract method copyBytes need to copy from input to a buffer and then write into ByteBuffersDataOutput, i think there is unnecessary, we can override it, copy directly from input into output
---
lucene/CHANGES.txt | 2 ++
.../apache/lucene/store/ByteBuffersDataOutput.java | 23 ++++++++++++++
.../lucene/store/TestByteBuffersDataOutput.java | 36 ++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 508a4ae092d..f422c5da0d8 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -60,6 +60,8 @@ Optimizations
* GITHUB#1010: Specialize ordinal encoding for common case in SortedSetDocValues. (Greg Miller)
+* LUCENE-10657: CopyBytes now saves one memory copy on ByteBuffersDataOutput. (luyuncheng)
+
Changes in runtime behavior
---------------------
diff --git a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java
index 8639ac5522e..84a7b317d88 100644
--- a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java
+++ b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java
@@ -309,6 +309,29 @@ public final class ByteBuffersDataOutput extends DataOutput implements Accountab
return arr;
}
+ @Override
+ public void copyBytes(DataInput input, long numBytes) throws IOException {
+ assert numBytes >= 0 : "numBytes=" + numBytes;
+ int length = (int) numBytes;
+ while (length > 0) {
+ if (!currentBlock.hasRemaining()) {
+ appendBlock();
+ }
+ if (!currentBlock.hasArray()) {
+ break;
+ }
+ int chunk = Math.min(currentBlock.remaining(), length);
+ final int pos = currentBlock.position();
+ input.readBytes(currentBlock.array(), Math.addExact(currentBlock.arrayOffset(), pos), chunk);
+ length -= chunk;
+ currentBlock.position(pos + chunk);
+ }
+ // if current block is Direct, we fall back to super.copyBytes for remaining bytes
+ if (length > 0) {
+ super.copyBytes(input, length);
+ }
+ }
+
/** Copy the current content of this object into another {@link DataOutput}. */
public void copyTo(DataOutput output) throws IOException {
for (ByteBuffer bb : blocks) {
diff --git a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java
index 065606c3ba3..50eefc3f3bf 100644
--- a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java
+++ b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java
@@ -204,6 +204,42 @@ public final class TestByteBuffersDataOutput extends BaseDataOutputTestCase<Byte
ArrayUtil.copyOfSubArray(bytes, offset, offset + len), o.toArrayCopy());
}
+ @Test
+ public void testCopyBytesOnHeap() throws IOException {
+ byte[] bytes = new byte[1024 * 8 + 10];
+ random().nextBytes(bytes);
+ int offset = TestUtil.nextInt(random(), 0, 100);
+ int len = bytes.length - offset;
+ ByteArrayDataInput in = new ByteArrayDataInput(bytes, offset, len);
+ ByteBuffersDataOutput o =
+ new ByteBuffersDataOutput(
+ ByteBuffersDataOutput.DEFAULT_MIN_BITS_PER_BLOCK,
+ ByteBuffersDataOutput.DEFAULT_MAX_BITS_PER_BLOCK,
+ ByteBuffersDataOutput.ALLOCATE_BB_ON_HEAP,
+ ByteBuffersDataOutput.NO_REUSE);
+ o.copyBytes(in, len);
+ Assert.assertArrayEquals(
+ o.toArrayCopy(), ArrayUtil.copyOfSubArray(bytes, offset, offset + len));
+ }
+
+ @Test
+ public void testCopyBytesOnDirectByteBuffer() throws IOException {
+ byte[] bytes = new byte[1024 * 8 + 10];
+ random().nextBytes(bytes);
+ int offset = TestUtil.nextInt(random(), 0, 100);
+ int len = bytes.length - offset;
+ ByteArrayDataInput in = new ByteArrayDataInput(bytes, offset, len);
+ ByteBuffersDataOutput o =
+ new ByteBuffersDataOutput(
+ ByteBuffersDataOutput.DEFAULT_MIN_BITS_PER_BLOCK,
+ ByteBuffersDataOutput.DEFAULT_MAX_BITS_PER_BLOCK,
+ ByteBuffer::allocateDirect,
+ ByteBuffersDataOutput.NO_REUSE);
+ o.copyBytes(in, len);
+ Assert.assertArrayEquals(
+ o.toArrayCopy(), ArrayUtil.copyOfSubArray(bytes, offset, offset + len));
+ }
+
@Test
public void testToBufferListReturnsReadOnlyBuffers() throws Exception {
ByteBuffersDataOutput dst = new ByteBuffersDataOutput();