IGNITE-1960: Reworked and simplified binary object header write logic.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/462f8332 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/462f8332 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/462f8332 Branch: refs/heads/ignite-1.5-tx-futs-opts Commit: 462f8332b5b745c6f748d157657365cf576355db Parents: b876f76 Author: vozerov-gridgain <[email protected]> Authored: Fri Nov 20 13:01:21 2015 +0300 Committer: vozerov-gridgain <[email protected]> Committed: Fri Nov 20 13:01:21 2015 +0300 ---------------------------------------------------------------------- .../internal/portable/BinaryWriterExImpl.java | 101 ++++++++++++------- .../portable/PortableClassDescriptor.java | 45 ++++----- .../ignite/internal/portable/PortableUtils.java | 32 +----- .../builder/BinaryObjectBuilderImpl.java | 8 +- .../streams/PortableAbstractOutputStream.java | 7 +- .../portable/streams/PortableOutputStream.java | 7 ++ .../memory/PlatformOutputStreamImpl.java | 7 +- 7 files changed, 107 insertions(+), 100 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java index 6f8534a..ec47f57 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java @@ -51,11 +51,11 @@ import static org.apache.ignite.internal.portable.GridPortableMarshaller.DATE; import static org.apache.ignite.internal.portable.GridPortableMarshaller.DATE_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.DECIMAL; import static org.apache.ignite.internal.portable.GridPortableMarshaller.DECIMAL_ARR; +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DFLT_HDR_LEN; import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE; import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.ENUM; import static org.apache.ignite.internal.portable.GridPortableMarshaller.ENUM_ARR; -import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLAGS_POS; import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT; import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT; @@ -65,18 +65,17 @@ import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG_AR import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP; import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP_ENTRY; import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL; +import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ; import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.OPTM_MARSH; import static org.apache.ignite.internal.portable.GridPortableMarshaller.PORTABLE_OBJ; -import static org.apache.ignite.internal.portable.GridPortableMarshaller.SCHEMA_ID_POS; -import static org.apache.ignite.internal.portable.GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS; +import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROTO_VER; import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT; import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING; import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.TIMESTAMP; import static org.apache.ignite.internal.portable.GridPortableMarshaller.TIMESTAMP_ARR; -import static org.apache.ignite.internal.portable.GridPortableMarshaller.TOTAL_LEN_POS; import static org.apache.ignite.internal.portable.GridPortableMarshaller.UNREGISTERED_TYPE_ID; import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID; import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID_ARR; @@ -265,44 +264,53 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje } /** - * @param bytes Number of bytes to reserve. - * @return Offset. + * Perform pre-write. Reserves space for header and writes class name if needed. + * + * @param clsName Class name (optional). */ - public int reserve(int bytes) { - int pos = out.position(); + public void preWrite(@Nullable String clsName) { + out.position(out.position() + DFLT_HDR_LEN); - out.position(pos + bytes); - - return pos; + if (clsName != null) + doWriteString(clsName); } /** - * Perform post-write activity. This includes: - * - writing flags; - * - writing object length; - * - writing schema offset; - * - writing schema to the tail. + * Perform post-write. Fills object header. * * @param userType User type flag. + * @param registered Whether type is registered. + * @param hashCode Hash code. */ - public void postWrite(boolean userType) { - short flags = userType ? PortableUtils.FLAG_USR_TYP : 0; + public void postWrite(boolean userType, boolean registered, int hashCode) { + short flags; + boolean useCompactFooter; - boolean useCompactFooter = ctx.isCompactFooter() && userType; + if (userType) { + if (ctx.isCompactFooter()) { + flags = PortableUtils.FLAG_USR_TYP | PortableUtils.FLAG_COMPACT_FOOTER; + useCompactFooter = true; + } + else { + flags = PortableUtils.FLAG_USR_TYP; + useCompactFooter = false; + } + } + else { + flags = 0; + useCompactFooter = false; + } - if (useCompactFooter) - flags |= PortableUtils.FLAG_COMPACT_FOOTER; + int finalSchemaId; + int offset; if (fieldCnt != 0) { - flags |= PortableUtils.FLAG_HAS_SCHEMA; - - // Write schema ID. - out.unsafeWriteInt(start + SCHEMA_ID_POS, schemaId); - - // Write schema offset. - out.unsafeWriteInt(start + SCHEMA_OR_RAW_OFF_POS, out.position() - start); + finalSchemaId = schemaId; + offset = out.position() - start; // Write the schema. + flags |= PortableUtils.FLAG_HAS_SCHEMA; + int offsetByteCnt = schema.write(out, fieldCnt, useCompactFooter); if (offsetByteCnt == PortableUtils.OFFSET_1) @@ -319,20 +327,33 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje } else { if (rawOffPos != 0) { - // If there are no schema, we are free to write raw offset to schema offset. - flags |= PortableUtils.FLAG_HAS_RAW; + finalSchemaId = 0; + offset = rawOffPos - start; - out.unsafeWriteInt(start + SCHEMA_OR_RAW_OFF_POS, rawOffPos - start); + // If there is no schema, we are free to write raw offset to schema offset. + flags |= PortableUtils.FLAG_HAS_RAW; + } + else { + finalSchemaId = 0; + offset = 0; } - else - out.unsafeWriteInt(start + SCHEMA_OR_RAW_OFF_POS, 0); } - // Write flags. - out.unsafeWriteShort(start + FLAGS_POS, flags); + // Actual write. + int retPos = out.position(); - // Write length. - out.unsafeWriteInt(start + TOTAL_LEN_POS, out.position() - start); + out.unsafePosition(start); + + out.unsafeWriteByte(OBJ); + out.unsafeWriteByte(PROTO_VER); + out.unsafeWriteShort(flags); + out.unsafeWriteInt(registered ? typeId : UNREGISTERED_TYPE_ID); + out.unsafeWriteInt(hashCode); + out.unsafeWriteInt(retPos - start); + out.unsafeWriteInt(finalSchemaId); + out.unsafeWriteInt(offset); + + out.unsafePosition(retPos); } /** @@ -1645,7 +1666,11 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje /** {@inheritDoc} */ @Override public int reserveInt() { - return reserve(LEN_INT); + int pos = out.position(); + + out.position(pos + LEN_INT); + + return pos; } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java index c233267..7c857be 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java @@ -548,14 +548,14 @@ public class PortableClassDescriptor { break; case PORTABLE: - if (writeHeader(obj, writer)) { + if (preWrite(writer, obj)) { try { if (serializer != null) serializer.writeBinary(obj, writer); else ((Binarylizable)obj).writeBinary(writer); - writer.postWrite(userType); + postWrite(writer, obj); // Check whether we need to update metadata. if (obj.getClass() != BinaryMetadata.class) { @@ -590,13 +590,13 @@ public class PortableClassDescriptor { break; case EXTERNALIZABLE: - if (writeHeader(obj, writer)) { + if (preWrite(writer, obj)) { writer.rawWriter(); try { ((Externalizable)obj).writeExternal(writer); - writer.postWrite(userType); + postWrite(writer, obj); } catch (IOException e) { throw new BinaryObjectException("Failed to write Externalizable object: " + obj, e); @@ -609,14 +609,14 @@ public class PortableClassDescriptor { break; case OBJECT: - if (writeHeader(obj, writer)) { + if (preWrite(writer, obj)) { try { for (BinaryFieldAccessor info : fields) info.write(obj, writer); writer.schemaId(stableSchema.schemaId()); - writer.postWrite(userType); + postWrite(writer, obj); } finally { writer.popSchema(); @@ -705,35 +705,32 @@ public class PortableClassDescriptor { } /** - * @param obj Object. + * Pre-write phase. + * * @param writer Writer. + * @param obj Object. * @return Whether further write is needed. */ - private boolean writeHeader(Object obj, BinaryWriterExImpl writer) { + private boolean preWrite(BinaryWriterExImpl writer, Object obj) { if (writer.tryWriteAsHandle(obj)) return false; - if (registered) { - PortableUtils.writeHeader( - writer, - typeId, - obj instanceof CacheObjectImpl ? 0 : obj.hashCode(), - null - ); - } - else { - PortableUtils.writeHeader( - writer, - GridPortableMarshaller.UNREGISTERED_TYPE_ID, - obj instanceof CacheObjectImpl ? 0 : obj.hashCode(), - cls.getName() - ); - } + writer.preWrite(registered ? null : cls.getName()); return true; } /** + * Post-write phase. + * + * @param writer Writer. + * @param obj Object. + */ + private void postWrite(BinaryWriterExImpl writer, Object obj) { + writer.postWrite(userType, registered, obj instanceof CacheObjectImpl ? 0 : obj.hashCode()); + } + + /** * @return Instance. * @throws BinaryObjectException In case of error. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java index 53d414c..6d155fe 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java @@ -17,14 +17,13 @@ package org.apache.ignite.internal.portable; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.binary.Binarylizable; import org.apache.ignite.internal.portable.builder.PortableLazyValue; -import org.apache.ignite.internal.portable.streams.PortableOutputStream; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; -import org.apache.ignite.binary.BinaryObjectException; -import org.apache.ignite.binary.BinaryObject; import org.jetbrains.annotations.Nullable; import org.jsr166.ConcurrentHashMap8; @@ -663,33 +662,6 @@ public class PortableUtils { } /** - * Write portable header. - * - * @param writer Writer. - * @param typeId Type ID. - * @param hashCode Hash code. - * @param clsName Class name (optional). - * @return Position where length should be written. - */ - public static int writeHeader(BinaryWriterExImpl writer, int typeId, int hashCode, @Nullable String clsName) { - PortableOutputStream out = writer.out(); - - out.unsafeEnsure(12); - out.unsafeWriteByte(GridPortableMarshaller.OBJ); - out.unsafeWriteByte(GridPortableMarshaller.PROTO_VER); - out.unsafeWriteShort((short) 0); - out.unsafeWriteInt(typeId); - out.unsafeWriteInt(hashCode); - - int reserved = writer.reserve(12); - - if (clsName != null) - writer.doWriteString(clsName); - - return reserved; - } - - /** * Get portable object length. * * @param in Input stream. http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java index 2ce2416..b2fb7d8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java @@ -199,11 +199,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { */ void serializeTo(BinaryWriterExImpl writer, PortableBuilderSerializer serializer) { try { - PortableUtils.writeHeader(writer, - registeredType ? typeId : UNREGISTERED_TYPE_ID, - hashCode, - registeredType ? null : clsNameToWrite - ); + writer.preWrite(registeredType ? null : clsNameToWrite); Set<Integer> remainsFlds = null; @@ -363,7 +359,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { reader.position(start + PortableUtils.length(reader, start)); } - writer.postWrite(true); + writer.postWrite(true, registeredType, hashCode); // Update metadata if needed. int schemaId = writer.schemaId(); http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableAbstractOutputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableAbstractOutputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableAbstractOutputStream.java index b68e9d1..7efc942 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableAbstractOutputStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableAbstractOutputStream.java @@ -239,7 +239,7 @@ public abstract class PortableAbstractOutputStream extends PortableAbstractStrea @Override public void position(int pos) { ensureCapacity(pos); - this.pos = pos; + unsafePosition(pos); } /** {@inheritDoc} */ @@ -253,6 +253,11 @@ public abstract class PortableAbstractOutputStream extends PortableAbstractStrea } /** {@inheritDoc} */ + @Override public void unsafePosition(int pos) { + this.pos = pos; + } + + /** {@inheritDoc} */ @Override public void unsafeWriteBoolean(boolean val) { unsafeWriteByte(val ? BYTE_ONE : BYTE_ZERO); } http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableOutputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableOutputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableOutputStream.java index 3a2e9e1..e516ff5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableOutputStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableOutputStream.java @@ -172,6 +172,13 @@ public interface PortableOutputStream extends PortableStream, AutoCloseable { @Override public void close(); /** + * Set position in unsafe mode. + * + * @param pos Position. + */ + public void unsafePosition(int pos); + + /** * Ensure capacity for unsafe writes. * * @param cap Capacity. http://git-wip-us.apache.org/repos/asf/ignite/blob/462f8332/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/memory/PlatformOutputStreamImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/memory/PlatformOutputStreamImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/memory/PlatformOutputStreamImpl.java index 670dd28..59d8981 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/memory/PlatformOutputStreamImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/memory/PlatformOutputStreamImpl.java @@ -186,7 +186,7 @@ public class PlatformOutputStreamImpl implements PlatformOutputStream { @Override public void position(int pos) { ensureCapacity(pos); - this.pos = pos; + unsafePosition(pos); } /** {@inheritDoc} */ @@ -228,6 +228,11 @@ public class PlatformOutputStreamImpl implements PlatformOutputStream { } /** {@inheritDoc} */ + @Override public void unsafePosition(int pos) { + this.pos = pos; + } + + /** {@inheritDoc} */ @Override public void unsafeWriteByte(byte val) { UNSAFE.putByte(data + pos++, val); }
