ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [2/7] ignite git commit: IGNITE-1814: WIP.
Date Mon, 02 Nov 2015 12:01:59 GMT
IGNITE-1814: WIP.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2c7b61ee
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2c7b61ee
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2c7b61ee

Branch: refs/heads/ignite-1814
Commit: 2c7b61ee4b415a86eb24937b061ad8d3e0c8df22
Parents: 247825e
Author: vozerov-gridgain <vozerov@gridgain.com>
Authored: Mon Nov 2 13:00:40 2015 +0300
Committer: vozerov-gridgain <vozerov@gridgain.com>
Committed: Mon Nov 2 13:00:40 2015 +0300

----------------------------------------------------------------------
 .../internal/portable/PortableFieldImpl.java    | 10 +--
 .../internal/portable/PortableObjectEx.java     |  6 +-
 .../internal/portable/PortableObjectImpl.java   | 48 +++++---------
 .../portable/PortableObjectOffheapImpl.java     |  5 +-
 .../internal/portable/PortableReaderExImpl.java | 61 +++++++++++++----
 .../internal/portable/PortableSchema.java       | 70 ++++++++++----------
 .../ignite/internal/portable/PortableUtils.java | 23 +++++++
 .../internal/portable/PortableWriterExImpl.java | 19 ++----
 8 files changed, 141 insertions(+), 101 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
index 5780b76..12be55c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableFieldImpl.java
@@ -45,7 +45,7 @@ public class PortableFieldImpl implements PortableField {
     @Override public boolean exists(PortableObject obj) {
         PortableObjectEx obj0 = (PortableObjectEx)obj;
 
-        return fieldOffset(obj0) != 0;
+        return fieldOrder(obj0) != 0;
     }
 
     /** {@inheritDoc} */
@@ -53,9 +53,9 @@ public class PortableFieldImpl implements PortableField {
     @Override public <T> T value(PortableObject obj) {
         PortableObjectEx obj0 = (PortableObjectEx)obj;
 
-        int offset = fieldOffset(obj0);
+        int order = fieldOrder(obj0);
 
-        return offset != 0 ? (T)obj0.fieldByOffset(offset) : null;
+        return order != 0 ? (T)obj0.fieldByOrder(order) : null;
     }
 
     /**
@@ -64,7 +64,7 @@ public class PortableFieldImpl implements PortableField {
      * @param obj Object.
      * @return Field offset.
      */
-    private int fieldOffset(PortableObjectEx obj) {
+    private int fieldOrder(PortableObjectEx obj) {
         int schemaId = obj.schemaId();
 
         PortableSchema schema = schemas.schema(schemaId);
@@ -77,6 +77,6 @@ public class PortableFieldImpl implements PortableField {
 
         assert schema != null;
 
-        return schema.offset(fieldId);
+        return schema.order(fieldId);
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
index 42c973b..014bfa1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
@@ -67,12 +67,12 @@ public abstract class PortableObjectEx implements PortableObject {
     @Nullable public abstract <F> F field(int fieldId) throws PortableException;
 
     /**
-     * Get field by offset.
+     * Get field by order.
      *
-     * @param fieldOffset Field offset.
+     * @param order Field order.
      * @return Field value.
      */
-    @Nullable protected abstract <F> F fieldByOffset(int fieldOffset);
+    @Nullable protected abstract <F> F fieldByOrder(int order);
 
     /**
      * @param ctx Reader context.

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
index dfe6d88..de77778 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
@@ -259,15 +259,27 @@ public final class PortableObjectImpl extends PortableObjectEx implements
Extern
 
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    @Nullable @Override protected <F> F fieldByOffset(int fieldOffset) {
-        Object val;
-
+    @Nullable @Override protected <F> F fieldByOrder(int order) {
+        // Get field position
         int schemaOffset = PRIM.readInt(arr, start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
-        int fieldPos = PRIM.readInt(arr, start + schemaOffset + fieldOffset);
+
+        int fieldOffsetSize =
+            PortableUtils.fieldOffsetSize(PRIM.readShort(arr, start + GridPortableMarshaller.FLAGS_POS));
+
+        int fieldPos;
+
+        if (fieldOffsetSize == PortableUtils.OFFSET_1)
+            fieldPos = start + PRIM.readInt(arr, start + schemaOffset + order * 5) &
0xFF;
+        else if (fieldOffsetSize == PortableUtils.OFFSET_2)
+            fieldPos = start + PRIM.readInt(arr, start + schemaOffset + order * 6) &
0xFFFF;
+        else
+            fieldPos = start + PRIM.readInt(arr, start + schemaOffset + order * 8);
 
         // Read header and try performing fast lookup for well-known types (the most common
types go first).
         byte hdr = PRIM.readByte(arr, fieldPos);
 
+        Object val;
+
         switch (hdr) {
             case INT:
                 val = PRIM.readInt(arr, fieldPos + 1);
@@ -309,36 +321,12 @@ public final class PortableObjectImpl extends PortableObjectEx implements
Extern
 
                 break;
 
-//            case DECIMAL:
-//                val = doReadDecimal();
-//
-//                break;
-//
-//            case STRING:
-//                val = doReadString();
-//
-//                break;
-//
-//            case UUID:
-//                val = doReadUuid();
-//
-//                break;
-//
-//            case DATE:
-//                val = doReadDate();
-//
-//                break;
-//
-//            case TIMESTAMP:
-//                val = doReadTimestamp();
-//
-//                break;
+            // TODO: More field types: string, decimal, date, timestamp.
 
             default: {
-                // TODO: Pass absolute offset, not relative.
                 PortableReaderExImpl reader = new PortableReaderExImpl(ctx, arr, start, null);
 
-                val = reader.unmarshalFieldByOffset(fieldOffset);
+                val = reader.unmarshalFieldOnAbsolutePosition(fieldPos);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
index f023f2e..0559c06 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
@@ -179,13 +179,14 @@ public class PortableObjectOffheapImpl extends PortableObjectEx implements
Exter
 
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    @Nullable @Override protected <F> F fieldByOffset(int fieldOffset) {
+    @Nullable @Override protected <F> F fieldByOrder(int order) {
         PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
             new PortableOffheapInputStream(ptr, size, false),
             start,
             null);
 
-        return (F)reader.unmarshalFieldByOffset(fieldOffset);
+        // TODO: Proper position detection.
+        return (F)reader.unmarshalFieldOnAbsolutePosition(order);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/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 aa1519d..f9cbae4 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
@@ -163,6 +163,9 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     /** Schema Id. */
     private int schemaId;
 
+    /** Offset size in bytes. */
+    private int offsetSize;
+
     /** Object schema. */
     private PortableSchema schema;
 
@@ -221,7 +224,9 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
         PortableUtils.checkProtocolVersion(in.readByte());
 
-        in.position(in.position() + 2); // Skip flags.
+        short flags = in.readShort();
+
+        offsetSize = PortableUtils.fieldOffsetSize(flags);
 
         typeId = in.readIntPositioned(start + GridPortableMarshaller.TYPE_ID_POS);
 
@@ -307,16 +312,18 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param fieldOffset Field offset.
+     * Unmarshal field on absolute position.
+     *
+     * @param pos Field position.
      * @return Unmarshalled value.
      * @throws PortableException In case of error.
      */
-    @Nullable Object unmarshalFieldByOffset(int fieldOffset) throws PortableException {
-        assert fieldOffset != 0;
+    @Nullable Object unmarshalFieldOnAbsolutePosition(int pos) throws PortableException {
+        assert pos != 0;
 
         parseHeaderIfNeeded();
 
-        in.position(start + in.readIntPositioned(footerStart + fieldOffset));
+        in.position(pos);
 
         return unmarshal();
     }
@@ -2567,12 +2574,14 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
         int searchPos = footerStart;
         int searchEnd = searchPos + footerLen;
 
+        int idx = 0;
+
         while (searchPos < searchEnd) {
             int fieldId = in.readIntPositioned(searchPos);
 
-            fields.put(fieldId, searchPos + 4 - footerStart);
+            fields.put(fieldId, idx++);
 
-            searchPos += 8;
+            searchPos += 4 + offsetSize;
         }
 
         return new PortableSchema(fields);
@@ -2599,14 +2608,21 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 int id0 = in.readIntPositioned(searchPos);
 
                 if (id0 == id) {
-                    int pos = start + in.readIntPositioned(searchPos + 4);
+                    int pos;
+
+                    if (offsetSize == PortableUtils.OFFSET_1)
+                        pos = start + in.readIntPositioned(searchPos + 1) & 0xFF;
+                    else if (offsetSize == PortableUtils.OFFSET_2)
+                        pos = start + in.readIntPositioned(searchPos + 2) & 0xFFFF;
+                    else
+                        pos = start + in.readIntPositioned(searchPos + 4);
 
                     in.position(pos);
 
                     return pos;
                 }
 
-                searchPos += 8;
+                searchPos += 4 + offsetSize;
             }
         }
         else {
@@ -2624,10 +2640,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 schema = schema0;
             }
 
-            int fieldOffsetPos = schema.offset(id);
+            int order = schema.order(id);
 
-            if (fieldOffsetPos != 0) {
-                int pos = start + in.readIntPositioned(footerStart + fieldOffsetPos);
+            if (order != 0) {
+                int pos = start + fieldPosition(order);
 
                 in.position(pos);
 
@@ -2639,6 +2655,27 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
+     * Get relative field position based on it's order.
+     *
+     * @param order Field order.
+     * @return Relative field position.
+     */
+    private int fieldPosition(int order) {
+        int offsetPos = footerStart + order * (4 + offsetSize);
+
+        int offset;
+
+        if (offsetSize == PortableUtils.OFFSET_1)
+            offset = in.readIntPositioned(offsetPos - 3) & 0xFF;
+        else if (offsetSize == PortableUtils.OFFSET_2)
+            offset = in.readIntPositioned(offsetPos - 2) & 0xFFFF;
+        else
+            offset = in.readIntPositioned(offsetPos);
+
+        return offset;
+    }
+
+    /**
      * Check whether object has low amount of fields.
      *
      * @param footerLen Footer length.

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/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 09bfe35..250598a 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
@@ -39,49 +39,49 @@ public class PortableSchema {
     private final int id1;
 
     /** Offset 1. */
-    private final int offset1;
+    private final int pos1;
 
     /** ID 2. */
     private final int id2;
 
     /** Offset 2. */
-    private final int offset2;
+    private final int pos2;
 
     /** ID 3. */
     private final int id3;
 
     /** Offset 3. */
-    private final int offset3;
+    private final int pos3;
 
     /** ID 4. */
     private final int id4;
 
     /** Offset 4. */
-    private final int offset4;
+    private final int pos4;
 
     /** ID 1. */
     private final int id5;
 
     /** Offset 1. */
-    private final int offset5;
+    private final int pos5;
 
     /** ID 2. */
     private final int id6;
 
     /** Offset 2. */
-    private final int offset6;
+    private final int pos6;
 
     /** ID 3. */
     private final int id7;
 
     /** Offset 3. */
-    private final int offset7;
+    private final int pos7;
 
     /** ID 4. */
     private final int id8;
 
     /** Offset 4. */
-    private final int offset8;
+    private final int pos8;
 
     /**
      * Constructor.
@@ -98,74 +98,74 @@ public class PortableSchema {
 
             if (entry != null) {
                 id1 = entry.getKey();
-                offset1 = entry.getValue();
+                pos1 = entry.getValue();
             }
             else{
                 id1 = 0;
-                offset1 = 0;
+                pos1 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id2 = entry.getKey();
-                offset2 = entry.getValue();
+                pos2 = entry.getValue();
             }
             else{
                 id2 = 0;
-                offset2 = 0;
+                pos2 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id3 = entry.getKey();
-                offset3 = entry.getValue();
+                pos3 = entry.getValue();
             }
             else{
                 id3 = 0;
-                offset3 = 0;
+                pos3 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id4 = entry.getKey();
-                offset4 = entry.getValue();
+                pos4 = entry.getValue();
             }
             else{
                 id4 = 0;
-                offset4 = 0;
+                pos4 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id5 = entry.getKey();
-                offset5 = entry.getValue();
+                pos5 = entry.getValue();
             }
             else{
                 id5 = 0;
-                offset5 = 0;
+                pos5 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id6 = entry.getKey();
-                offset6 = entry.getValue();
+                pos6 = entry.getValue();
             }
             else{
                 id6 = 0;
-                offset6 = 0;
+                pos6 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id7 = entry.getKey();
-                offset7 = entry.getValue();
+                pos7 = entry.getValue();
             }
             else{
                 id7 = 0;
-                offset7 = 0;
+                pos7 = 0;
             }
 
             if ((entry = iter.hasNext() ? iter.next() : null) != null) {
                 id8 = entry.getKey();
-                offset8 = entry.getValue();
+                pos8 = entry.getValue();
             }
             else{
                 id8 = 0;
-                offset8 = 0;
+                pos8 = 0;
             }
 
             map = null;
@@ -174,43 +174,43 @@ public class PortableSchema {
             inline = false;
 
             id1 = id2 = id3 = id4 = id5 = id6 = id7 = id8 = 0;
-            offset1 = offset2 = offset3 = offset4 = offset5 = offset6 = offset7 = offset8
= 0;
+            pos1 = pos2 = pos3 = pos4 = pos5 = pos6 = pos7 = pos8 = 0;
 
             map = new HashMap<>(vals);
         }
     }
 
     /**
-     * Get offset for the given field ID.
+     * Get field position in footer by schema ID.
      *
      * @param id Field ID.
      * @return Offset or {@code 0} if there is no such field.
      */
-    public int offset(int id) {
+    public int order(int id) {
         if (inline) {
             if (id == id1)
-                return offset1;
+                return pos1;
 
             if (id == id2)
-                return offset2;
+                return pos2;
 
             if (id == id3)
-                return offset3;
+                return pos3;
 
             if (id == id4)
-                return offset4;
+                return pos4;
 
             if (id == id5)
-                return offset5;
+                return pos5;
 
             if (id == id6)
-                return offset6;
+                return pos6;
 
             if (id == id7)
-                return offset7;
+                return pos7;
 
             if (id == id8)
-                return offset8;
+                return pos8;
 
             return 0;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/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 c369317..f08b48a 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
@@ -106,6 +106,15 @@ public class PortableUtils {
     /** Flag: offsets take 2 bytes. */
     public static final short FLAG_OFFSET_TWO_BYTES = 0x8;
 
+    /** Offset which fits into 1 byte. */
+    public static final int OFFSET_1 = 1;
+
+    /** Offset which fits into 2 bytes. */
+    public static final int OFFSET_2 = 2;
+
+    /** Offset which fits into 4 bytes. */
+    public static final int OFFSET_4 = 4;
+
     /**
      * Write flags.
      *
@@ -650,4 +659,18 @@ public class PortableUtils {
                 return start + in.readIntPositioned(start + len - 4);
         }
     }
+
+    /**
+     * Get offset size for the given flags.
+     * @param flags Flags.
+     * @return Offset size.
+     */
+    public static int fieldOffsetSize(short flags) {
+        if ((flags & FLAG_OFFSET_ONE_BYTE) == FLAG_OFFSET_ONE_BYTE)
+            return OFFSET_1;
+        else if ((flags & FLAG_OFFSET_TWO_BYTES) == FLAG_OFFSET_TWO_BYTES)
+            return OFFSET_2;
+        else
+            return OFFSET_4;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/2c7b61ee/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
index 5991f18..8128f84 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
@@ -105,15 +105,6 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
     /** Maximum offset which fits in 2 bytes. */
     private static final int MAX_OFFSET_2 = 2 << 16;
 
-    /** Offset which fits into 1 byte. */
-    private static final int OFFSET_1 = 1;
-
-    /** Offset which fits into 2 bytes. */
-    private static final int OFFSET_2 = 2;
-
-    /** Offset which fits into 4 bytes. */
-    private static final int OFFSET_4 = 4;
-
     /** Thread-local schema. */
     private static final ThreadLocal<SchemaHolder> SCHEMA = new ThreadLocal<>();
 
@@ -363,12 +354,12 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
             if (rawOffPos != 0)
                 out.writeInt(rawOffPos - start);
 
-            if (offsetByteCnt == OFFSET_1) {
+            if (offsetByteCnt == PortableUtils.OFFSET_1) {
                 int flags = (userType ? PortableUtils.FLAG_USR_TYP : 0) | PortableUtils.FLAG_OFFSET_ONE_BYTE;
 
                 out.writeShort(start + FLAGS_POS, (short)flags);
             }
-            else if (offsetByteCnt == OFFSET_2) {
+            else if (offsetByteCnt == PortableUtils.OFFSET_2) {
                 int flags = (userType ? PortableUtils.FLAG_USR_TYP : 0) | PortableUtils.FLAG_OFFSET_TWO_BYTES;
 
                 out.writeShort(start + FLAGS_POS, (short)flags);
@@ -1877,7 +1868,7 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
                     writer.writeByte((byte) data[idx0++]);
                 }
 
-                res = OFFSET_1;
+                res = PortableUtils.OFFSET_1;
             }
             else if (lastOffset < MAX_OFFSET_2) {
                 for (int idx0 = startIdx; idx0 < idx; ) {
@@ -1885,7 +1876,7 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
                     writer.writeShort((short)data[idx0++]);
                 }
 
-                res = OFFSET_2;
+                res = PortableUtils.OFFSET_2;
             }
             else {
                 for (int idx0 = startIdx; idx0 < idx; ) {
@@ -1893,7 +1884,7 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
                     writer.writeInt(data[idx0++]);
                 }
 
-                res = OFFSET_4;
+                res = PortableUtils.OFFSET_4;
             }
 
             idx = startIdx;


Mime
View raw message