IGNITE-1770: WIP on schema.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/69faf96f Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/69faf96f Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/69faf96f Branch: refs/heads/ignite-1770 Commit: 69faf96f61de5adf8335207b4adcb44e09b06886 Parents: 22e5015 Author: vozerov-gridgain <[email protected]> Authored: Wed Oct 28 17:44:23 2015 +0300 Committer: vozerov-gridgain <[email protected]> Committed: Wed Oct 28 17:44:23 2015 +0300 ---------------------------------------------------------------------- .../portable/PortableClassDescriptor.java | 62 ------------- .../internal/portable/PortableContext.java | 95 ++++++++++++++++++++ .../internal/portable/PortableReaderExImpl.java | 71 ++++++++++++--- .../java/org/apache/ignite/MyBenchmark.java | 41 ++++++--- 4 files changed, 181 insertions(+), 88 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/69faf96f/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 02c408e..5005e68 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 @@ -106,9 +106,6 @@ public class PortableClassDescriptor { /** */ private final boolean excluded; - /** Object schemas. */ - private volatile Object schemas; - /** * @param ctx Context. * @param cls Class. @@ -324,65 +321,6 @@ public class PortableClassDescriptor { } /** - * Get schema for the given schema ID. - * - * @param schemaId Schema ID. - * @return Schema or {@code null} if there are no such schema. - */ - @SuppressWarnings("unchecked") - @Nullable public PortableObjectSchema schema(int schemaId) { - Object schemas0 = schemas; - - if (schemas0 instanceof IgniteBiTuple) { - // The most common case goes first. - IgniteBiTuple<Integer, PortableObjectSchema> curSchema = - (IgniteBiTuple<Integer, PortableObjectSchema>)schemas0; - - if (curSchema.get1() == schemaId) - return curSchema.get2(); - } - else if (schemas0 instanceof Map) { - Map<Integer, PortableObjectSchema> curSchemas = (Map<Integer, PortableObjectSchema>)schemas0; - - return curSchemas.get(schemaId); - } - - return null; - } - - /** - * Add schema. - * - * @param schemaId Schema ID. - * @param fields Fields. - */ - @SuppressWarnings("unchecked") - public void addSchema(int schemaId, Map<Integer, Integer> fields) { - synchronized (this) { - if (schemas == null) - schemas = new IgniteBiTuple<>(schemaId, new PortableObjectSchema(schemaId, fields)); - else if (schemas instanceof IgniteBiTuple) { - IgniteBiTuple<Integer, PortableObjectSchema> curSchema = - (IgniteBiTuple<Integer, PortableObjectSchema>)schemas; - - if (curSchema.get1() != schemaId) { - Map newSchemas = new HashMap(); - - newSchemas.put(curSchema.get1(), curSchema.get2()); - newSchemas.put(schemaId, new PortableObjectSchema(schemaId, fields)); - - schemas = newSchemas; - } - } - else { - Map<Integer, PortableObjectSchema> curSchemas = (Map<Integer, PortableObjectSchema>)schemas; - - curSchemas.put(schemaId, new PortableObjectSchema(schemaId, fields)); - } - } - } - - /** * @return portableWriteReplace() method */ @Nullable Method getWriteReplaceMethod() { http://git-wip-us.apache.org/repos/asf/ignite/blob/69faf96f/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java index b0405ac..15e1162 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java @@ -150,6 +150,9 @@ public class PortableContext implements Externalizable { /** */ private boolean keepDeserialized; + /** Object schemas. */ + private volatile Map<Integer, Object> schemas; + /** * For {@link Externalizable}. */ @@ -832,6 +835,98 @@ public class PortableContext implements Externalizable { } /** + * Get schema for the given schema ID. + * + * @param schemaId Schema ID. + * @return Schema or {@code null} if there are no such schema. + */ + @SuppressWarnings("unchecked") + @Nullable public PortableObjectSchema schema(int typeId, int schemaId) { + Map<Integer, Object> schemas0 = schemas; + + if (schemas0 != null) { + Object typeSchemas = schemas0.get(typeId); + + if (typeSchemas instanceof IgniteBiTuple) { + // The most common case goes first. + IgniteBiTuple<Integer, PortableObjectSchema> schema = + (IgniteBiTuple<Integer, PortableObjectSchema>)typeSchemas; + + if (schema.get1() == schemaId) + return schema.get2(); + } + else if (typeSchemas instanceof Map) { + Map<Integer, PortableObjectSchema> curSchemas = (Map<Integer, PortableObjectSchema>)typeSchemas; + + return curSchemas.get(schemaId); + } + } + + return null; + } + + /** + * Add schema. + * + * @param schemaId Schema ID. + * @param newTypeSchema New schema. + */ + @SuppressWarnings("unchecked") + public void addSchema(int typeId, int schemaId, PortableObjectSchema newTypeSchema) { + synchronized (this) { + if (schemas == null) { + // This is the very first schema recorded. + Map<Integer, Object> newSchemas = new HashMap<>(); + + newSchemas.put(typeId, new IgniteBiTuple<>(schemaId, newTypeSchema)); + + schemas = newSchemas; + } + else { + Object typeSchemas = schemas.get(typeId); + + if (typeSchemas == null) { + // This is the very first object schema. + Map<Integer, Object> newSchemas = new HashMap<>(schemas); + + newSchemas.put(typeId, new IgniteBiTuple<>(schemaId, newTypeSchema)); + + schemas = newSchemas; + } + else if (typeSchemas instanceof IgniteBiTuple) { + IgniteBiTuple<Integer, PortableObjectSchema> typeSchema = + (IgniteBiTuple<Integer, PortableObjectSchema>)typeSchemas; + + if (typeSchema.get1() != schemaId) { + Map<Integer, PortableObjectSchema> newTypeSchemas = new HashMap(); + + newTypeSchemas.put(typeSchema.get1(), typeSchema.get2()); + newTypeSchemas.put(schemaId, newTypeSchema); + + Map<Integer, Object> newSchemas = new HashMap<>(schemas); + + newSchemas.put(typeId, newTypeSchemas); + + schemas = newSchemas; + } + } + else { + Map<Integer, PortableObjectSchema> newTypeSchemas = + new HashMap((Map<Integer, PortableObjectSchema>)typeSchemas); + + newTypeSchemas.put(schemaId, newTypeSchema); + + Map<Integer, Object> newSchemas = new HashMap<>(schemas); + + newSchemas.put(typeId, newTypeSchemas); + + schemas = newSchemas; + } + } + } + } + + /** * Returns instance of {@link OptimizedMarshaller}. * * @return Optimized marshaller. http://git-wip-us.apache.org/repos/asf/ignite/blob/69faf96f/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java index 861e649..12ef3bf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java @@ -47,6 +47,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Properties; @@ -156,6 +157,12 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx /** ID mapper. */ private PortableIdMapper idMapper; + /** Schema Id. */ + private int schemaId; + + /** Object schema. */ + private PortableObjectSchema schema; + /** * @param ctx Context. * @param arr Array. @@ -220,6 +227,8 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx footerStart = footer.get1(); footerEnd = footer.get2(); + schemaId = in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_ID_POS); + rawOff = PortableUtils.rawOffsetAbsolute(in, start); if (typeId == UNREGISTERED_TYPE_ID) { @@ -2524,27 +2533,63 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx * @return Field offset. */ private boolean hasField(int id) { - assert hdrLen != 0; + if (schema == null) { + PortableObjectSchema schema0 = ctx.schema(typeId, schemaId); - int searchHead = footerStart; - int searchTail = footerEnd; + if (schema0 == null) { + Map<Integer, Integer> fields = new HashMap<>(256, 0.5f); - while (true) { - if (searchHead >= searchTail) - return false; + int searchPos = footerStart; - int id0 = in.readIntPositioned(searchHead); + while (searchPos < footerEnd) { + int fieldId = in.readIntPositioned(searchPos); - if (id0 == id) { - int offset = in.readIntPositioned(searchHead + 4); + fields.put(fieldId, searchPos + 4 - footerStart); - in.position(start + offset); + searchPos += 8; + } + + schema0 = new PortableObjectSchema(schemaId, fields); - return true; + ctx.addSchema(typeId, schemaId, schema0); } - searchHead += 8; + schema = schema0; } + + int fieldOffsetPos = schema.fieldOffsetPosition(id); + + if (fieldOffsetPos != 0) { + int fieldOffset = in.readIntPositioned(start + footerStart + fieldOffsetPos); + + in.position(start + fieldOffset); + + return true; + } + else + return false; + +// assert hdrLen != 0; +// +// int searchHead = footerStart; +// int searchTail = footerEnd; +// +// while (true) { +// if (searchHead >= searchTail) +// return false; +// +// int id0 = in.readIntPositioned(searchHead); +// +// if (id0 == id) { +// int offset = in.readIntPositioned(searchHead + 4); +// +// in.position(start + offset); +// +// return true; +// } +// +// searchHead += 8; +// } } /** {@inheritDoc} */ @@ -2635,7 +2680,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx /** {@inheritDoc} */ @Override public long skip(long n) throws IOException { - return skipBytes((int)n); + return skipBytes((int) n); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/69faf96f/modules/microbench/src/main/java/org/apache/ignite/MyBenchmark.java ---------------------------------------------------------------------- diff --git a/modules/microbench/src/main/java/org/apache/ignite/MyBenchmark.java b/modules/microbench/src/main/java/org/apache/ignite/MyBenchmark.java index 662acee..fb9710f 100644 --- a/modules/microbench/src/main/java/org/apache/ignite/MyBenchmark.java +++ b/modules/microbench/src/main/java/org/apache/ignite/MyBenchmark.java @@ -107,14 +107,10 @@ public class MyBenchmark { optMarsh = new OptimizedMarshaller(); optMarsh.setContext(new MarshallerContextMicrobenchImpl(null)); - marshAddrBytes = marsh.marshal(new Address()); + marshAddrBytes = marsh.marshal(new ManyFields()); marshPortable = new PortableObjectImpl(U.<GridPortableMarshaller>field(marsh, "impl").context(), marshAddrBytes, 0); - - byte[] data = marsh.marshal(new Address()); - - System.out.println(data.length); } // @Benchmark @@ -122,22 +118,26 @@ public class MyBenchmark { // return marsh.marshal(new Address()); // } -// @Benchmark -// public Address testAddressRead() throws Exception { -// return marsh.unmarshal(marshAddrBytes, null); -// } - @Benchmark - public Object testFieldRead() throws Exception { - return marshPortable.field("street"); + public Object testRead() throws Exception { + return marsh.unmarshal(marshAddrBytes, null); } +// @Benchmark +// public Object testFieldRead() throws Exception { +// return marshPortable.field("street"); +// } + private static final Address addr = new Address(); public static void main(String[] args) throws Exception { // setup(); -// while (true) +// while (true) { // marsh.unmarshal(marshAddrBytes, null); +//// String val = marshPortable.field("street"); +//// +//// System.out.println(val); +// } Options opts = new OptionsBuilder().include(MyBenchmark.class.getSimpleName()).build(); new Runner(opts).run(); @@ -166,6 +166,21 @@ public class MyBenchmark { return customer; } + static class ManyFields { + public int field1 = 1; + public int field2 = 2; + public int field3 = 3; + public int field4 = 4; + public int field5 = 5; + + public int field6 = 6; + public int field7 = 7; + public int field8 = 8; + public int field9 = 9; + public int field10 = 10; + + } + static class Address implements PortableMarshalAware, Externalizable { public int streetNum = 49; public int flatNum = 30;
