Repository: ignite Updated Branches: refs/heads/ignite-1816 67e6401e0 -> 58f5737c6
IGNITE-1816: WIP. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/81a8be20 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/81a8be20 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/81a8be20 Branch: refs/heads/ignite-1816 Commit: 81a8be2069060b0e1198533d1de6395c9072ea12 Parents: 67e6401 Author: vozerov-gridgain <[email protected]> Authored: Thu Nov 12 14:53:44 2015 +0300 Committer: vozerov-gridgain <[email protected]> Committed: Thu Nov 12 14:53:44 2015 +0300 ---------------------------------------------------------------------- .../internal/portable/BinaryObjectImpl.java | 6 +- .../portable/BinaryObjectOffheapImpl.java | 6 +- .../internal/portable/BinaryReaderExImpl.java | 75 ++++---- .../internal/portable/PortableSchema.java | 174 +++++++++++++------ .../builder/BinaryObjectBuilderImpl.java | 24 ++- .../portable/builder/PortableBuilderReader.java | 8 + .../marshaller/portable/PortableMarshaller.java | 2 +- ...idBinaryObjectBuilderAdditionalSelfTest.java | 4 +- 8 files changed, 204 insertions(+), 95 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java index 4be9744..6cb56a8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java @@ -279,9 +279,11 @@ public final class BinaryObjectImpl extends BinaryObjectEx implements Externaliz int schemaOffset = PortablePrimitives.readInt(arr, start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS); short flags = PortablePrimitives.readShort(arr, start + GridPortableMarshaller.FLAGS_POS); + + int fieldIdLen = PortableUtils.isCompactFooter(flags) ? 0 : PortableUtils.FIELD_ID_LEN; int fieldOffsetLen = PortableUtils.fieldOffsetLength(flags); - int fieldOffsetPos = start + schemaOffset + order * (4 + fieldOffsetLen) + 4; + int fieldOffsetPos = start + schemaOffset + order * (fieldIdLen + fieldOffsetLen) + fieldIdLen; int fieldPos; @@ -458,7 +460,7 @@ public final class BinaryObjectImpl extends BinaryObjectEx implements Externaliz @Override protected PortableSchema createSchema() { BinaryReaderExImpl reader = new BinaryReaderExImpl(ctx, arr, start, null); - return reader.createSchema(); + return reader.getOrCreateSchema(); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectOffheapImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectOffheapImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectOffheapImpl.java index 0ba4fdb..4b9f226 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectOffheapImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectOffheapImpl.java @@ -136,7 +136,7 @@ public class BinaryObjectOffheapImpl extends BinaryObjectEx implements Externali start, null); - return reader.createSchema(); + return reader.getOrCreateSchema(); } /** {@inheritDoc} */ @@ -206,8 +206,10 @@ public class BinaryObjectOffheapImpl extends BinaryObjectEx implements Externali short flags = PortablePrimitives.readShort(ptr, start + GridPortableMarshaller.FLAGS_POS); + int fieldIdLen = PortableUtils.isCompactFooter(flags) ? 0 : PortableUtils.FIELD_ID_LEN; int fieldOffsetLen = PortableUtils.fieldOffsetLength(flags); - int fieldOffsetPos = start + schemaOffset + order * (4 + fieldOffsetLen) + 4; + + int fieldOffsetPos = start + schemaOffset + order * (fieldIdLen + fieldOffsetLen) + fieldIdLen; int fieldPos; http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java index 78f5258..1b4d0e0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java @@ -2556,13 +2556,52 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje } /** - * Create schema. + * Get or create object schema. * * @return Schema. */ - public PortableSchema createSchema() { + public PortableSchema getOrCreateSchema() { parseHeaderIfNeeded(); + PortableSchema schema = ctx.schemaRegistry(typeId).schema(schemaId); + + if (schema == null) { + if (fieldIdLen != PortableUtils.FIELD_ID_LEN) { + BinaryTypeImpl type = (BinaryTypeImpl)ctx.metaData(typeId); + + if (type == null || type.metadata() == null) + throw new BinaryObjectException("Cannot find metadata for object with compact footer: " + + typeId); + + for (PortableSchema typeSchema : type.metadata().schemas()) { + if (schemaId == typeSchema.schemaId()) { + schema = typeSchema; + + break; + } + } + + if (schema == null) + throw new BinaryObjectException("Cannot find schema for object with compact footer [" + + "typeId=" + typeId + ", schemaId=" + schemaId + ']'); + } + else + schema = createSchema(); + + assert schema != null; + + ctx.schemaRegistry(typeId).addSchema(schemaId, schema); + } + + return schema; + } + + /** + * Create schema. + * + * @return Schema. + */ + private PortableSchema createSchema() { assert fieldIdLen == PortableUtils.FIELD_ID_LEN; PortableSchema.Builder builder = PortableSchema.Builder.newBuilder(); @@ -2617,40 +2656,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje PortableSchema schema0 = schema; if (schema0 == null) { - schema0 = ctx.schemaRegistry(typeId).schema(schemaId); - - if (schema0 == null) { - if (fieldIdLen == 0) { - BinaryTypeImpl type = (BinaryTypeImpl)ctx.metaData(typeId); - - if (type == null || type.metadata() == null) - throw new BinaryObjectException("Cannot find metadata for object with compact footer: " + - typeId); - - for (PortableSchema typeSchema : type.metadata().schemas()) { - if (schemaId == typeSchema.schemaId()) { - schema0 = typeSchema; - - break; - } - } - - if (schema0 == null) - throw new BinaryObjectException("Cannot find schema for object with compact fotter [" + - "typeId=" + typeId + ", schemaId=" + schemaId + ']'); - } - else - schema0 = createSchema(); - - assert schema0 != null; - - ctx.schemaRegistry(typeId).addSchema(schemaId, schema0); - } + schema0 = getOrCreateSchema(); schema = schema0; } - int order = schema.order(id); + int order = schema0.order(id); if (order != PortableSchema.ORDER_NOT_FOUND) { int offsetPos = footerStart + order * (fieldIdLen + fieldOffsetLen) + fieldIdLen; http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java index 3cb191e..86ca5f8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java @@ -44,8 +44,11 @@ public class PortableSchema implements Externalizable { /** Inline flag. */ private boolean inline; - /** Map with offsets. */ - private HashMap<Integer, Integer> map; + /** Map with ID to order. */ + private HashMap<Integer, Integer> idToOrder; + + /** IDs depending on order. */ + private ArrayList<Integer> ids; /** ID 1. */ private int id0; @@ -74,49 +77,11 @@ public class PortableSchema implements Externalizable { /** Schema ID. */ private int schemaId; - /** {@inheritDoc} */ - @Override public void writeExternal(ObjectOutput out) throws IOException { - out.writeInt(schemaId); - - if (inline) { - out.writeBoolean(true); - - out.writeInt(id0); - out.writeInt(id1); - out.writeInt(id2); - out.writeInt(id3); - out.writeInt(id4); - out.writeInt(id5); - out.writeInt(id6); - out.writeInt(id7); - } - else { - out.writeBoolean(false); - U.writeMap(out, map); - } - } - - /** {@inheritDoc} */ - @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - schemaId = in.readInt(); - - if (in.readBoolean()) { - inline = true; - - id0 = in.readInt(); - id1 = in.readInt(); - id2 = in.readInt(); - id3 = in.readInt(); - id4 = in.readInt(); - id5 = in.readInt(); - id6 = in.readInt(); - id7 = in.readInt(); - } - else { - inline = false; - - map = U.readHashMap(in); - } + /** + * {@link Externalizable} support. + */ + public PortableSchema() { + // No-op. } /** @@ -142,17 +107,22 @@ public class PortableSchema implements Externalizable { id6 = iter.hasNext() ? iter.next() : 0; id7 = iter.hasNext() ? iter.next() : 0; - map = null; + idToOrder = null; } else { inline = false; id0 = id1 = id2 = id3 = id4 = id5 = id6 = id7 = 0; - map = new HashMap<>(); + ids = new ArrayList<>(); + idToOrder = new HashMap<>(); - for (int i = 0; i < fieldIds.size(); i++) - map.put(fieldIds.get(i), i); + for (int i = 0; i < fieldIds.size(); i++) { + int fieldId = fieldIds.get(i); + + ids.add(fieldId); + idToOrder.put(fieldId, i); + } } } @@ -164,7 +134,50 @@ public class PortableSchema implements Externalizable { } /** - * Get field position in footer by schema ID. + * Get field ID by order in footer. + * + * @param order Order. + * @return Field ID. + */ + public int fieldId(int order) { + if (inline) { + switch (order) { + case 0: + return id0; + + case 1: + return id1; + + case 2: + return id2; + + case 3: + return id3; + + case 4: + return id4; + + case 5: + return id5; + + case 6: + return id6; + + case 7: + return id7; + + default: + assert false : "Should not reach here."; + + return 0; + } + } + else + return ids.get(order); + } + + /** + * Get field order in footer by field ID. * * @param id Field ID. * @return Offset or {@code 0} if there is no such field. @@ -198,7 +211,7 @@ public class PortableSchema implements Externalizable { return ORDER_NOT_FOUND; } else { - Integer order = map.get(id); + Integer order = idToOrder.get(id); return order != null ? order : ORDER_NOT_FOUND; } @@ -214,6 +227,65 @@ public class PortableSchema implements Externalizable { return o != null && o instanceof PortableSchema && schemaId == ((PortableSchema)o).schemaId; } + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + out.writeInt(schemaId); + + if (inline) { + out.writeBoolean(true); + + out.writeInt(id0); + out.writeInt(id1); + out.writeInt(id2); + out.writeInt(id3); + out.writeInt(id4); + out.writeInt(id5); + out.writeInt(id6); + out.writeInt(id7); + } + else { + out.writeBoolean(false); + + out.writeInt(ids.size()); + + for (Integer id : ids) + out.writeInt(id); + } + } + + /** {@inheritDoc} */ + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + schemaId = in.readInt(); + + if (in.readBoolean()) { + inline = true; + + id0 = in.readInt(); + id1 = in.readInt(); + id2 = in.readInt(); + id3 = in.readInt(); + id4 = in.readInt(); + id5 = in.readInt(); + id6 = in.readInt(); + id7 = in.readInt(); + } + else { + inline = false; + + int size = in.readInt(); + + ids = new ArrayList<>(size); + idToOrder = U.newHashMap(size); + + for (int i = 0; i < size; i++) { + int fieldId = in.readInt(); + + ids.add(fieldId); + idToOrder.put(fieldId, i); + } + } + } + /** * Schema builder. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/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 048044b..330235a 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 @@ -28,6 +28,7 @@ import org.apache.ignite.internal.portable.BinaryObjectOffheapImpl; import org.apache.ignite.internal.portable.BinaryWriterExImpl; import org.apache.ignite.internal.portable.GridPortableMarshaller; import org.apache.ignite.internal.portable.PortableContext; +import org.apache.ignite.internal.portable.PortableSchema; import org.apache.ignite.internal.portable.PortableUtils; import org.apache.ignite.internal.util.GridArgumentCheck; import org.apache.ignite.internal.util.typedef.F; @@ -204,6 +205,8 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { Set<Integer> remainsFlds = null; if (reader != null) { + PortableSchema schema = reader.schema(); + Map<Integer, Object> assignedFldsById; if (assignedVals != null) { @@ -216,7 +219,8 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { } remainsFlds = assignedFldsById.keySet(); - } else + } + else assignedFldsById = Collections.emptyMap(); // Get footer details. @@ -234,8 +238,10 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { // Position reader on data. reader.position(start + hdrLen); + int idx = 0; + while (reader.position() + fieldIdLen < rawPos) { - int fieldId = reader.readIntPositioned(footerPos); + int fieldId = schema.fieldId(idx++); int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldIdLen, fieldOffsetLen).get2(); @@ -296,12 +302,12 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { String name = entry.getKey(); - int fldId = ctx.fieldId(typeId, name); + int fieldId = ctx.fieldId(typeId, name); - if (remainsFlds != null && !remainsFlds.contains(fldId)) + if (remainsFlds != null && !remainsFlds.contains(fieldId)) continue; - writer.writeFieldId(fldId); + writer.writeFieldId(fieldId); serializer.writeValue(writer, val); @@ -419,10 +425,14 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { * Initialize read cache if needed. */ private void ensureReadCacheInit() { + assert reader != null; + if (readCache == null) { int fieldIdLen = PortableUtils.fieldIdLength(flags); int fieldOffsetLen = PortableUtils.fieldOffsetLength(flags); + PortableSchema schema = reader.schema(); + Map<Integer, Object> readCache = new HashMap<>(); IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start); @@ -432,8 +442,10 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { int rawPos = PortableUtils.rawOffsetAbsolute(reader, start); + int idx = 0; + while (footerPos + fieldIdLen < footerEnd) { - int fieldId = reader.readIntPositioned(footerPos); + int fieldId = schema.fieldId(idx++); IgniteBiTuple<Integer, Integer> posAndLen = fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldIdLen, fieldOffsetLen); http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java index 5c6a131..550b8ea 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java @@ -27,6 +27,7 @@ import org.apache.ignite.internal.portable.PortablePositionReadable; import org.apache.ignite.internal.portable.BinaryObjectImpl; import org.apache.ignite.internal.portable.PortablePrimitives; import org.apache.ignite.internal.portable.BinaryReaderExImpl; +import org.apache.ignite.internal.portable.PortableSchema; import org.apache.ignite.internal.portable.PortableUtils; import org.apache.ignite.internal.portable.BinaryWriterExImpl; import org.apache.ignite.binary.BinaryObjectException; @@ -81,6 +82,13 @@ public class PortableBuilderReader implements PortablePositionReadable { } /** + * @return Object's schema. + */ + public PortableSchema schema() { + return reader.getOrCreateSchema(); + } + + /** * @return Read int value. */ public int readInt() { http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java index b84ba68..1704c8a 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java @@ -78,7 +78,7 @@ public class PortableMarshaller extends AbstractMarshaller { public static final boolean DFLT_KEEP_DESERIALIZED = true; /** Default value of "compact footer" flag. */ - public static final boolean DFLT_COMPACT_FOOTER = false; + public static final boolean DFLT_COMPACT_FOOTER = true; // TODO ignite-1282 Move to IgniteConfiguration. /** Class names. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/81a8be20/modules/core/src/test/java/org/apache/ignite/internal/portable/GridBinaryObjectBuilderAdditionalSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridBinaryObjectBuilderAdditionalSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridBinaryObjectBuilderAdditionalSelfTest.java index 11b54ae..7ac0f5c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridBinaryObjectBuilderAdditionalSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridBinaryObjectBuilderAdditionalSelfTest.java @@ -373,7 +373,9 @@ public class GridBinaryObjectBuilderAdditionalSelfTest extends GridCommonAbstrac float[] arr = mutObj.getField("fArr"); arr[0] = 2.0f; - TestObjectAllTypes res = mutObj.build().deserialize(); + BinaryObject resBinary = mutObj.build(); + + TestObjectAllTypes res = resBinary.deserialize(); Assert.assertArrayEquals(new float[] {2.0f, 1.0f, 1.0f}, res.fArr, 0); }
