ignite-950: adding handles to footer

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

Branch: refs/heads/ignite-950
Commit: 5e7fcc1f1759bbb2f87dd64cc3d6487cd5722e40
Parents: 25d0da2
Author: Denis Magda <dma...@gridgain.com>
Authored: Thu Jun 18 16:25:22 2015 +0300
Committer: Denis Magda <dma...@gridgain.com>
Committed: Thu Jun 18 16:25:22 2015 +0300

----------------------------------------------------------------------
 .../ignite/internal/util/GridHandleTable.java   | 32 ++++++++--
 .../optimized/OptimizedClassDescriptor.java     |  4 +-
 .../optimized/OptimizedObjectOutputStream.java  | 24 +++----
 .../optimized/ext/OptimizedMarshallerExt.java   |  3 +
 .../ext/OptimizedObjectInputStreamExt.java      | 36 +++++++++--
 .../ext/OptimizedObjectOutputStreamExt.java     | 66 ++++++++++++++------
 6 files changed, 118 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e7fcc1f/modules/core/src/main/java/org/apache/ignite/internal/util/GridHandleTable.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/GridHandleTable.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/GridHandleTable.java
index 05a089c..6b63360 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/GridHandleTable.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/GridHandleTable.java
@@ -47,6 +47,9 @@ public class GridHandleTable {
     /** Maps handle value -> next candidate handle value. */
     private int[] next;
 
+    /** Handle absolute position in the output stream. */
+    private int[] positions;
+
     /** Maps handle value -> associated object. */
     private Object[] objs;
 
@@ -68,6 +71,7 @@ public class GridHandleTable {
         spine = new int[initCap];
         next = new int[initCap];
         objs = new Object[initCap];
+        positions = new int[initCap];
         spineEmpty = new int[initCap];
         nextEmpty = new int[initCap];
 
@@ -84,9 +88,10 @@ public class GridHandleTable {
      * no mapping found.
      *
      * @param obj Object.
+     * @param pos Current absolute position in output stream.
      * @return Handle.
      */
-    public int lookup(Object obj) {
+    public int lookup(Object obj, int pos) {
         int idx = hash(obj) % spine.length;
 
         if (size > 0) {
@@ -101,7 +106,7 @@ public class GridHandleTable {
         if (size >= threshold)
             growSpine();
 
-        insert(obj, size, idx);
+        insert(obj, size, idx, pos);
 
         size++;
 
@@ -109,6 +114,16 @@ public class GridHandleTable {
     }
 
     /**
+     * Returns handle absolute position in output stream.
+     *
+     * @param handle Handle.
+     * @return Absolute position.
+     */
+    public int position(int handle) {
+        return positions[handle];
+    }
+
+    /**
      * Resets table to its initial (empty) state.
      */
     public void clear() {
@@ -116,6 +131,7 @@ public class GridHandleTable {
         UNSAFE.copyMemory(nextEmpty, intArrOff, next, intArrOff, 
nextEmpty.length << 2);
 
         Arrays.fill(objs, null);
+        Arrays.fill(positions, 0);
 
         size = 0;
     }
@@ -134,10 +150,12 @@ public class GridHandleTable {
      * @param obj Object.
      * @param handle Handle.
      * @param idx Index.
+     * @param pos Position in output stream.
      */
-    private void insert(Object obj, int handle, int idx) {
+    private void insert(Object obj, int handle, int idx, int pos) {
         objs[handle] = obj;
         next[handle] = spine[idx];
+        positions[handle] = pos;
         spine[idx] = handle;
     }
 
@@ -161,7 +179,7 @@ public class GridHandleTable {
 
             int idx = hash(obj) % spine.length;
 
-            insert(objs[i], i, idx);
+            insert(objs[i], i, idx, positions[i]);
         }
     }
 
@@ -184,6 +202,12 @@ public class GridHandleTable {
         System.arraycopy(objs, 0, newObjs, 0, size);
 
         objs = newObjs;
+
+        int[] newPositions = new int[newLen];
+
+        UNSAFE.copyMemory(positions, intArrOff, newPositions, intArrOff, size 
<< 2);
+
+        positions = newPositions;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e7fcc1f/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
index ae3ae77..d77551f 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
@@ -724,12 +724,10 @@ public class OptimizedClassDescriptor {
                         "set OptimizedMarshaller.setRequireSerializable() to 
false " +
                         "(note that performance may degrade if object is not 
Serializable): " + name);
 
-                int headerPos = out.out().size() - 1;
-
                 writeTypeData(out);
 
                 out.writeShort(checksum);
-                out.writeSerializable(obj, writeObjMtds, fields, headerPos);
+                out.writeSerializable(obj, writeObjMtds, fields);
 
                 break;
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e7fcc1f/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
index a88da95..90e2a85 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
@@ -154,7 +154,7 @@ public class OptimizedObjectOutputStream extends 
ObjectOutputStream {
      * @param obj Object.
      * @throws IOException In case of error.
      *
-     * @return Handle ID that has already written {@code obj} or -1 if the 
{@code obj} has not been written before.
+     * @return Handle's position in {@link #out} or -1 if the {@code obj} has 
not been written before.
      */
     private int writeObject0(Object obj) throws IOException {
         curObj = null;
@@ -204,7 +204,7 @@ public class OptimizedObjectOutputStream extends 
ObjectOutputStream {
                 }
 
                 if (!desc.isPrimitive() && !desc.isEnum() && !desc.isClass())
-                    handle = handles.lookup(obj);
+                    handle = handles.lookup(obj, out.offset());
 
                 if (obj0 != obj) {
                     obj = obj0;
@@ -218,6 +218,8 @@ public class OptimizedObjectOutputStream extends 
ObjectOutputStream {
                 if (handle >= 0) {
                     writeByte(HANDLE);
                     writeInt(handle);
+
+                    handle = handles.position(handle);
                 }
                 else
                     desc.write(this, obj);
@@ -303,18 +305,15 @@ public class OptimizedObjectOutputStream extends 
ObjectOutputStream {
      * @param obj Object.
      * @param mtds {@code writeObject} methods.
      * @param fields class fields details.
-     * @param headerPos Object's header position in the OutputStream.
      * @throws IOException In case of error.
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
-    void writeSerializable(Object obj, List<Method> mtds, 
OptimizedClassDescriptor.Fields fields, int headerPos)
+    void writeSerializable(Object obj, List<Method> mtds, 
OptimizedClassDescriptor.Fields fields)
         throws IOException {
         Footer footer = createFooter(obj.getClass());
 
-        if (footer != null) {
+        if (footer != null)
             footer.fields(fields);
-            footer.headerPos(headerPos);
-        }
 
         for (int i = 0; i < mtds.size(); i++) {
             Method mtd = mtds.get(i);
@@ -978,13 +977,6 @@ public class OptimizedObjectOutputStream extends 
ObjectOutputStream {
         void fields(OptimizedClassDescriptor.Fields fields);
 
         /**
-         * Sets field's header absolute position.
-         *
-         * @param pos Absolute position.
-         */
-        void headerPos(int pos);
-
-        /**
          * Puts type ID and its value len to the footer.
          *
          * @param fieldId   Field ID.
@@ -998,9 +990,9 @@ public class OptimizedObjectOutputStream extends 
ObjectOutputStream {
          * Puts handle ID for the given field ID.
          *
          * @param fieldId Field ID.
-         * @param handleId Handle ID.
+         * @param handlePos Handle position in output stream.
          */
-        void putHandle(int fieldId, int handleId);
+        void putHandle(int fieldId, int handlePos);
 
         /**
          * Writes footer content to the OutputStream.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e7fcc1f/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
index 1a451e1..a41a331 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java
@@ -41,6 +41,9 @@ public class OptimizedMarshallerExt extends 
OptimizedMarshaller {
     static final byte VARIABLE_LEN = -1;
 
     /** */
+    static final byte NOT_A_HANDLE = -1;
+
+    /** */
     private OptimizedMarshallerExtMetaHandler metaHandler;
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e7fcc1f/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
index 7ab56a2..7c8cc3c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java
@@ -16,6 +16,7 @@
  */
 package org.apache.ignite.marshaller.optimized.ext;
 
+import org.apache.ignite.*;
 import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.util.io.*;
 import org.apache.ignite.marshaller.*;
@@ -167,6 +168,11 @@ public class OptimizedObjectInputStreamExt extends 
OptimizedObjectInputStream {
         if (footerLen == EMPTY_FOOTER)
             return null;
 
+        // reading 'hasHandles' flag. 1 byte - additional offset to get to the 
flag position.
+        in.position(in.position() - FOOTER_LEN_OFF - 1);
+
+        boolean hasHandles = in.readBoolean();
+
         // 4 - skipping length at the beginning
         int footerOff = (end - footerLen) + 4;
         in.position(footerOff);
@@ -175,13 +181,33 @@ public class OptimizedObjectInputStreamExt extends 
OptimizedObjectInputStream {
 
         for (OptimizedObjectMetadata.FieldInfo info : meta.getMeta()) {
             if (info.id == fieldId) {
-                //object header len: 1 - for type, 4 - for type ID, 2 - for 
checksum.
-                fieldOff += 1 + 4 + clsNameLen + 2;
+                int len = info.len == VARIABLE_LEN ? in.readInt() : info.len;
+                int handlePos;
+
+                if (hasHandles && info.len == VARIABLE_LEN)
+                    handlePos = in.readInt();
+                else
+                    handlePos = NOT_A_HANDLE;
+
+                if (handlePos == NOT_A_HANDLE) {
+                    //object header len: 1 - for type, 4 - for type ID, 2 - 
for checksum.
+                    fieldOff += 1 + 4 + clsNameLen + 2;
+
+                    return new FieldRange(start + fieldOff, len);
+                }
+                else {
+                    throw new IgniteException("UNSUPPORTED YET");
+                }
+            }
+            else {
+                fieldOff += info.len == VARIABLE_LEN ? in.readInt() : info.len;
+
+                if (hasHandles) {
+                    in.skipBytes(4);
+                    fieldOff += 4;
+                }
 
-                return new FieldRange(start + fieldOff, info.len == 
VARIABLE_LEN ? in.readShort() : info.len);
             }
-            else
-                fieldOff += info.len == VARIABLE_LEN ? in.readShort() : 
info.len;
         }
 
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e7fcc1f/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectOutputStreamExt.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectOutputStreamExt.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectOutputStreamExt.java
index 823caf5..4ef0d4a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectOutputStreamExt.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectOutputStreamExt.java
@@ -72,37 +72,52 @@ public class OptimizedObjectOutputStreamExt extends 
OptimizedObjectOutputStream
      */
     private class FooterImpl implements OptimizedObjectOutputStream.Footer {
         /** */
-        private ArrayList<Short> data;
+        private ArrayList<Integer> data;
 
         /** */
-        private int headerPos;
+        private ArrayList<Integer> fields;
+
+        /** */
+        private HashMap<Integer, Integer> handles;
+
+        /** */
+        private boolean hasHandles;
 
         /** {@inheritDoc} */
         @Override public void fields(OptimizedClassDescriptor.Fields fields) {
-            if (fields.fieldsIndexingSupported())
+            if (fields.fieldsIndexingSupported()) {
                 data = new ArrayList<>();
+                this.fields = new ArrayList<>();
+            }
             else
                 data = null;
         }
 
         /** {@inheritDoc} */
-        public void headerPos(int pos) {
-            headerPos = pos;
-        }
-
-        /** {@inheritDoc} */
         public void put(int fieldId, OptimizedFieldType fieldType, int len) {
             if (data == null)
                 return;
 
-            // Considering that field's length will be no longer 2^15 (32 MB)
-            if (fieldType == OptimizedFieldType.OTHER)
-                data.add((short)len);
+            if (fieldType == OptimizedFieldType.OTHER) {
+                data.add(len);
+                fields.add(fieldId);
+            }
         }
 
         /** {@inheritDoc} */
-        @Override public void putHandle(int fieldId, int handleId) {
-            disable();
+        @Override public void putHandle(int fieldId, int handlePos) {
+            if (data == null)
+                return;
+
+            if (!hasHandles) {
+                hasHandles = true;
+                handles = new HashMap<>();
+            }
+
+            handles.put(fieldId, handlePos);
+
+            // length of handle fields is 5 bytes.
+            put(fieldId, OptimizedFieldType.OTHER, 5);
         }
 
         /** {@inheritDoc} */
@@ -110,16 +125,29 @@ public class OptimizedObjectOutputStreamExt extends 
OptimizedObjectOutputStream
             if (data == null)
                 writeInt(EMPTY_FOOTER);
             else {
-                //12 - 4 bytes for len at the beginning, 4 bytes for len at 
the end, 4 bytes for object len.
-                int footerLen = data.size() * 2 + 12;
+                //9 - 4 bytes for len at the beginning, 4 bytes for len at the 
end, 1 byte for 'hasHandles' flag
+                int footerLen = data.size() * 4 + 9;
+
+                if (hasHandles)
+                    footerLen += data.size() * 4;
 
                 writeInt(footerLen);
 
-                for (short fieldLen : data)
-                    writeShort(fieldLen);
+                if (hasHandles) {
+                    for (int i = 0; i < data.size(); i++) {
+                        writeInt(data.get(i));
+
+                        Integer handlePos = handles.get(fields.get(i));
+
+                        writeInt(handlePos == null ? NOT_A_HANDLE : handlePos);
+                    }
+                }
+                else {
+                    for (int fieldLen : data)
+                        writeInt(fieldLen);
+                }
 
-                // object total len
-                writeInt((out.size() - headerPos) + 8);
+                writeBoolean(hasHandles);
 
                 writeInt(footerLen);
             }

Reply via email to