From 9d55871cce0ce979405bc31454ac312d2c09a20c Mon Sep 17 00:00:00 2001 From: Linlin Sun Date: Sun, 6 Aug 2023 17:57:03 -0700 Subject: [PATCH 1/2] Remove the repeated logic of the method that overwrites the lower nibble of container type descriptor. --- .../ion/impl/bin/IonRawBinaryWriter.java | 13 +++++-------- src/com/amazon/ion/impl/bin/WriteBuffer.java | 19 ++++++------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java b/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java index e5bda78333..1a1d88ed81 100644 --- a/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java +++ b/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java @@ -747,21 +747,18 @@ private ContainerInfo popContainer() // The number of bytes we need to shift by is determined by the writer's preallocation mode. final int numberOfBytesToShiftBy = preallocationMode.numberOfLengthBytes(); - // `length` is the encoded length of the container/wrapper we're stepping out of. It does not - // include any header bytes. In this `if` branch, we've confirmed that `length` is <= 0xD, - // so this downcast from `long` to `int` is safe. - final int lengthOfSliceToShift = (int) length; - // Shift the container/wrapper body backwards in the buffer. Because this only happens when // `lengthOfSliceToShift` is 13 or fewer bytes, this will usually be a very fast memcpy. // It's slightly more work if the slice we're shifting happens to straddle two memory blocks // inside the buffer. - buffer.shiftBytesLeft(lengthOfSliceToShift, numberOfBytesToShiftBy); + // `length` is the encoded length of the container/wrapper we're stepping out of. It does not + // include any header bytes. In this `if` branch, we've confirmed that `length` is <= 0xD, + // so this downcast from `long` to `int` is safe. + buffer.shiftBytesLeft((int)length, numberOfBytesToShiftBy); // Overwrite the lower nibble of the original type descriptor byte with the body's encoded length. final long typeDescriptorPosition = positionOfFirstLengthByte - 1; - final long type = (buffer.getUInt8At(typeDescriptorPosition) & 0xF0) | length; - buffer.writeUInt8At(typeDescriptorPosition, type); + buffer.writeUInt8At(typeDescriptorPosition, length); // We've reclaimed some number of bytes; adjust the container length as appropriate. length -= numberOfBytesToShiftBy; diff --git a/src/com/amazon/ion/impl/bin/WriteBuffer.java b/src/com/amazon/ion/impl/bin/WriteBuffer.java index fba4c60d48..257e16a8e8 100644 --- a/src/com/amazon/ion/impl/bin/WriteBuffer.java +++ b/src/com/amazon/ion/impl/bin/WriteBuffer.java @@ -104,17 +104,6 @@ public long position() return (((long) index) * allocator.getBlockSize()) + current.limit; } - private static final int OCTET_MASK = 0xFF; - - /** Returns the octet at the logical position given. */ - public int getUInt8At(final long position) - { - final int index = index(position); - final int offset = offset(position); - final Block block = blocks.get(index); - return block.data[offset] & OCTET_MASK; - } - /** Writes a single octet to the buffer, expanding if necessary. */ public void writeByte(final byte octet) { @@ -1266,10 +1255,14 @@ public void writeUInt8At(final long position, final long value) { final int index = index(position); final int offset = offset(position); - // XXX we'll never overrun a block unless we're given a position past our block array final Block block = blocks.get(index); - block.data[offset] = (byte) value; + long bitValue = block.data[offset]; + if (value <= 0xD) { + block.data[offset] = (byte) (bitValue & 0xF0 | value) ; + } else { + block.data[offset] = (byte) value; + } } /** Get the length of FlexInt for the provided value. */ From 0769dc0d1bb8c8f828af4e3b5d5bbf5b0eb62e0a Mon Sep 17 00:00:00 2001 From: Linlin Sun Date: Wed, 16 Aug 2023 16:15:54 -0700 Subject: [PATCH 2/2] Createa a new method 'writeLowerNibbleAt' to avoid creating new thread under 'writeUInt8At'. --- .../ion/impl/bin/IonRawBinaryWriter.java | 3 +-- src/com/amazon/ion/impl/bin/WriteBuffer.java | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java b/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java index 1a1d88ed81..2b4c26778f 100644 --- a/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java +++ b/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java @@ -758,8 +758,7 @@ private ContainerInfo popContainer() // Overwrite the lower nibble of the original type descriptor byte with the body's encoded length. final long typeDescriptorPosition = positionOfFirstLengthByte - 1; - buffer.writeUInt8At(typeDescriptorPosition, length); - + buffer.writeLowerNibbleAt(typeDescriptorPosition, length); // We've reclaimed some number of bytes; adjust the container length as appropriate. length -= numberOfBytesToShiftBy; } diff --git a/src/com/amazon/ion/impl/bin/WriteBuffer.java b/src/com/amazon/ion/impl/bin/WriteBuffer.java index 257e16a8e8..7e67af00bd 100644 --- a/src/com/amazon/ion/impl/bin/WriteBuffer.java +++ b/src/com/amazon/ion/impl/bin/WriteBuffer.java @@ -1257,12 +1257,20 @@ public void writeUInt8At(final long position, final long value) final int offset = offset(position); // XXX we'll never overrun a block unless we're given a position past our block array final Block block = blocks.get(index); + block.data[offset] = (byte) value; + } + + /** + * Overwrite the lower nibble of the specified type descriptor byte with the length information. + * @param position represents the position of the byte that will be overwritten. + * @param value represents the length value of the container. + */ + public void writeLowerNibbleAt(final long position, final long value) { + final int index = index(position); + final int offset = offset(position); + final Block block = blocks.get(index); long bitValue = block.data[offset]; - if (value <= 0xD) { - block.data[offset] = (byte) (bitValue & 0xF0 | value) ; - } else { - block.data[offset] = (byte) value; - } + block.data[offset] = (byte) (bitValue & 0xF0 | value) ; } /** Get the length of FlexInt for the provided value. */