You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/06/30 12:52:07 UTC
[46/50] [abbrv] incubator-ignite git commit: ignite-950: protocol
optimizations
ignite-950: protocol optimizations
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/2e8bdec6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/2e8bdec6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/2e8bdec6
Branch: refs/heads/ignite-950
Commit: 2e8bdec625337ca33b3c58fbd70fae6f40104d2f
Parents: f746e4b
Author: Denis Magda <dm...@gridgain.com>
Authored: Mon Jun 29 11:00:03 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Mon Jun 29 11:00:03 2015 +0300
----------------------------------------------------------------------
.../cache/CacheIndexedObjectImpl.java | 13 +-
.../IgniteCacheObjectProcessorImpl.java | 4 +-
.../ignite/internal/util/io/GridDataInput.java | 9 ++
.../internal/util/io/GridUnsafeDataInput.java | 5 +
.../optimized/OptimizedClassDescriptor.java | 15 +-
.../OptimizedMarshalAwareMetaCollector.java | 2 +-
.../optimized/OptimizedMarshallerExt.java | 10 +-
.../optimized/OptimizedObjectInputStream.java | 101 ++++++------
.../optimized/OptimizedObjectMetadata.java | 159 +++++++------------
.../optimized/OptimizedObjectOutputStream.java | 73 ++++-----
.../OptimizedObjectOutputStreamExt.java | 86 ++--------
.../OptimizedMarshallerExtSelfTest.java | 29 +++-
12 files changed, 211 insertions(+), 295 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java
index c51d98c..8cf7085 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java
@@ -27,6 +27,7 @@ import sun.misc.*;
import java.io.*;
import java.nio.*;
+import java.util.concurrent.*;
/**
* Cache object implementation for classes that support footer injection is their serialized form thus enabling fields
@@ -92,6 +93,9 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter {
public CacheIndexedObjectImpl(Object val, byte[] valBytes, int start, int len) {
assert val != null || (valBytes != null && start >= 0 && len > 0);
+ if (valBytes != null && val != null)
+ val = null;
+
this.val = val;
this.valBytes = valBytes;
this.start = start;
@@ -200,8 +204,8 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter {
Object val = ctx.processor().unmarshal(ctx, valBytes, start, len,
ctx.kernalContext().config().getClassLoader());
- if (ctx.storeValue())
- this.val = val;
+ //if (ctx.storeValue())
+ // this.val = val;
return val;
}
@@ -326,7 +330,8 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter {
* @return {@code true} if detached.
*/
protected boolean detached() {
- return start == 0 && len == valBytes.length;
+ return true;
+ //return start == 0 && len == valBytes.length;
}
/**
@@ -343,6 +348,8 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter {
start = 0;
len = valBytes.length;
+
+ val = null;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
index 5456fad..730b5d5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
@@ -511,7 +511,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
try {
toMarshaledFormIfNeeded(ctx);
- if (ctx.storeValue()) {
+ /*if (ctx.storeValue()) {
ClassLoader ldr = ctx.p2pEnabled() ?
IgniteUtils.detectClass(this.val).getClassLoader() : val.getClass().getClassLoader();
@@ -519,7 +519,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
ctx.processor().unmarshal(ctx, valBytes, start, len, ldr);
return new CacheIndexedObjectImpl(val, valBytes, start, len);
- }
+ }*/
return new CacheIndexedObjectImpl(null, valBytes, start, len);
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridDataInput.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridDataInput.java b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridDataInput.java
index 975fb68..4d06d81 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridDataInput.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridDataInput.java
@@ -194,4 +194,13 @@ public interface GridDataInput extends DataInput {
* @return Integer value.
*/
public int readInt(int pos);
+
+ /**
+ * Fast read of long value at {@code pos}.
+ *
+ * @param pos Position in array.
+ *
+ * @return Long value.
+ */
+ public long readLong(int pos);
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
index ed04cfe..5c15c4c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java
@@ -511,6 +511,11 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput {
return UNSAFE.getInt(buf, byteArrOff + pos);
}
+ /** {@inheritDoc} */
+ @Override public long readLong(int pos) {
+ return UNSAFE.getLong(buf, byteArrOff + pos);
+ }
+
/**
* Reads in the "body" (i.e., the UTF representation minus the 2-byte
* or 8-byte length header) of a UTF encoding, which occupies the next
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/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 9773d40..3596548 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
@@ -436,7 +436,6 @@ public class OptimizedClassDescriptor {
fieldInfo = new FieldInfo(null,
serField.getName(),
-1,
- resolveFieldId(serField.getName()),
fieldType(serField.getType()));
}
else {
@@ -445,7 +444,6 @@ public class OptimizedClassDescriptor {
fieldInfo = new FieldInfo(f,
serField.getName(),
UNSAFE.objectFieldOffset(f),
- resolveFieldId(serField.getName()),
fieldType(serField.getType()));
}
@@ -471,7 +469,6 @@ public class OptimizedClassDescriptor {
FieldInfo fieldInfo = new FieldInfo(f,
f.getName(),
UNSAFE.objectFieldOffset(f),
- resolveFieldId(f.getName()),
fieldType(f.getType()));
clsFields.add(fieldInfo);
@@ -891,8 +888,6 @@ public class OptimizedClassDescriptor {
/** Field name. */
private final String fieldName;
- /** ID calculated from field's name. */
- private final int fieldId;
/**
* @param field Field.
@@ -900,19 +895,11 @@ public class OptimizedClassDescriptor {
* @param offset Field offset.
* @param type Grid optimized field type.
*/
- FieldInfo(Field field, String name, long offset, int fieldId, OptimizedFieldType type) {
+ FieldInfo(Field field, String name, long offset, OptimizedFieldType type) {
this.field = field;
fieldOffs = offset;
fieldType = type;
fieldName = name;
- this.fieldId = fieldId;
- }
-
- /**
- * @return Field ID.
- */
- public int id() {
- return fieldId;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshalAwareMetaCollector.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshalAwareMetaCollector.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshalAwareMetaCollector.java
index c4fb9d4..79c5f24 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshalAwareMetaCollector.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshalAwareMetaCollector.java
@@ -174,6 +174,6 @@ class OptimizedMarshalAwareMetaCollector implements OptimizedFieldsWriter {
* @param type Field type.
*/
private void putFieldToMeta(String fieldName, OptimizedFieldType type) {
- meta.addMeta(OptimizedMarshallerUtils.resolveFieldId(fieldName), type);
+ meta.addField(fieldName, type);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExt.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExt.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExt.java
index fd0fa47..91e5a9a 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExt.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExt.java
@@ -40,16 +40,16 @@ public class OptimizedMarshallerExt extends OptimizedMarshaller {
static final byte FOOTER_LEN_OFF = 2;
/** */
- static final int FOOTER_BODY_LEN_MASK = 0x3FFFFFFF;
+ static final byte FOOTER_HANDLES_FLAG_OFF = 3;
/** */
- static final int FOOTER_BODY_IS_HANDLE_MASK = 0x40000000;
+ static final int FOOTER_BODY_OFF_MASK = 0x3FFFFFFF;
/** */
- static final byte FOOTER_BODY_HANDLE_MASK_BIT = 30;
+ static final int FOOTER_BODY_IS_HANDLE_MASK = 0x40000000;
/** */
- public static final byte VARIABLE_LEN = -1;
+ static final byte FOOTER_BODY_HANDLE_MASK_BIT = 30;
/** */
private final static ConcurrentHashMap<Class<?>, Boolean> indexingEnabledCache = new ConcurrentHashMap<>();
@@ -173,7 +173,7 @@ public class OptimizedMarshallerExt extends OptimizedMarshaller {
for (ClassFields clsFields : desc.fields().fieldsList())
for (FieldInfo info : clsFields.fieldInfoList())
- meta.addMeta(info.id(), info.type());
+ meta.addField(info.name(), info.type());
metaHandler.addMeta(desc.typeId(), meta);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
index 6e7d7d6..5a35586 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
@@ -500,15 +500,15 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt
* @throws ClassNotFoundException In case of error.
* @throws IOException In case of error.
*/
- HashMap<Integer, Object> readFields( OptimizedObjectMetadata meta) throws ClassNotFoundException,
+ HashMap<Integer, Object> readFields(OptimizedObjectMetadata meta) throws ClassNotFoundException,
IOException {
HashMap<Integer, Object> fieldsValues = new HashMap<>();
- for (OptimizedObjectMetadata.FieldInfo fieldInfo : meta.getMeta()) {
+ for (Map.Entry<Integer, OptimizedObjectMetadata.FieldInfo> entry : meta.metaList()) {
Object val;
- switch ((fieldInfo.type())) {
+ switch ((entry.getValue().type())) {
case BYTE:
readFieldType();
@@ -572,10 +572,10 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt
break;
default:
- throw new IgniteException("Unknown field type: " + fieldInfo.type());
+ throw new IgniteException("Unknown field type: " + entry.getValue().type());
}
- fieldsValues.put(fieldInfo.id(), val);
+ fieldsValues.put(entry.getKey(), val);
}
return fieldsValues;
@@ -1315,7 +1315,15 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt
if (type != SERIALIZABLE && type != MARSHAL_AWARE)
return false;
- FieldRange range = fieldRange(fieldName, start);
+ FieldRange range;
+
+ try {
+ range = fieldRange(fieldName, start);
+ }
+ catch (IgniteFieldNotFoundException e) {
+ // Ignore
+ return false;
+ }
return range != null && range.start >= 0;
}
@@ -1368,17 +1376,14 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt
* @param start Object's start offset.
* @return positive range or {@code null} if the object doesn't have such a field.
* @throws IOException in case of error.
+ * @throws IgniteFieldNotFoundException In case if there is no such a field.
*/
- private FieldRange fieldRange(String fieldName, int start) throws IOException {
+ private FieldRange fieldRange(String fieldName, int start) throws IOException, IgniteFieldNotFoundException {
int pos = start + 1;
- int fieldId = resolveFieldId(fieldName);
-
int typeId = in.readInt(pos);
pos += 4;
- int clsNameLen = 0;
-
if (typeId == 0) {
int oldPos = in.position();
@@ -1386,8 +1391,6 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt
typeId = OptimizedMarshallerUtils.resolveTypeId(readUTF(), mapper);
- clsNameLen = in.position() - pos;
-
in.position(oldPos);
}
@@ -1402,58 +1405,58 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt
short footerLen = in.readShort(end - FOOTER_LEN_OFF);
if (footerLen == EMPTY_FOOTER)
- return null;
+ throw new IgniteFieldNotFoundException("Object doesn't have a field named: " + fieldName);
+
+ if (range == null)
+ range = new FieldRange();
- // Calculating footer offset. +2 - skipping length at the beginning
+ // Calculating start footer offset. +2 - skipping length at the beginning
pos = (end - footerLen) + 2;
- int fieldOff = 0;
+ int fieldIdx = meta.fieldIndex(fieldName);
+ int fieldsCnt = meta.size();
- for (OptimizedObjectMetadata.FieldInfo info : meta.getMeta()) {
- int len;
- boolean isHandle;
+ if (fieldIdx >= fieldsCnt)
+ throw new IOException("Wrong field index for field name [idx=" + fieldIdx + ", name=" + fieldName + "]");
- if (info.length() == VARIABLE_LEN) {
- int fieldInfo = in.readInt(pos);
+ boolean hasHandles = in.readByte(end - FOOTER_HANDLES_FLAG_OFF) == 1;
- pos += 4;
- len = fieldInfo & FOOTER_BODY_LEN_MASK;
- isHandle = ((fieldInfo & FOOTER_BODY_IS_HANDLE_MASK) >> FOOTER_BODY_HANDLE_MASK_BIT) == 1;
- }
- else {
- len = info.length();
- isHandle = false;
- }
+ if (hasHandles) {
+ long fieldInfo = in.readLong(pos + fieldIdx * 8);
- if (info.id() == fieldId) {
- if (range == null)
- range = new FieldRange();
+ boolean isHandle = ((fieldInfo & FOOTER_BODY_IS_HANDLE_MASK) >> FOOTER_BODY_HANDLE_MASK_BIT) == 1;
- if (!isHandle) {
- //object header len: 1 - for type, 4 - for type ID, 2 - for checksum.
- fieldOff += 1 + 4 + clsNameLen + 2;
+ range.start = (int)(fieldInfo & FOOTER_BODY_OFF_MASK);
- range.start = start + fieldOff;
- range.len = len;
- }
- else {
- range.start = in.readInt(pos);
- range.len = in.readInt(pos + 4);
- }
+ if (isHandle) {
+ range.len = (int)(fieldInfo >>> 32);
+
+ if (range.len == 0)
+ // Field refers to its object.
+ range.len = (end - start) - footerLen;
return range;
}
- else {
- fieldOff += len;
+ }
+ else
+ range.start = in.readInt(pos + fieldIdx * 4) & FOOTER_BODY_OFF_MASK;
- if (isHandle) {
- pos += 8;
- fieldOff += 8;
- }
+ if (fieldIdx == 0) {
+ if (fieldsCnt > 1) {
+ int nextFieldOff = in.readInt(pos + (fieldIdx + 1) * 4);
+ range.len = nextFieldOff - range.start;
}
+ else
+ range.len = (end - footerLen) - range.start;
+ }
+ else if (fieldIdx == fieldsCnt - 1)
+ range.len = (end - footerLen) - range.start;
+ else {
+ int nextFieldOff = in.readInt(pos + (fieldIdx + 1) * 4);
+ range.len = nextFieldOff - range.start;
}
- return null;
+ return range;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java
index 97facca..9e5a18a 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java
@@ -17,21 +17,21 @@
package org.apache.ignite.marshaller.optimized;
-import org.apache.ignite.*;
-
import java.io.*;
import java.util.*;
/**
- * Metadata that keeps fields information. Used in conjunction with the footer that is added to some objects during
- * marshalling.
+ * Metadata that keeps fields' name to id mapping.
*/
public class OptimizedObjectMetadata implements Externalizable {
/** */
private static final long serialVersionUID = 0L;
/** */
- private List<FieldInfo> fieldsInfo;
+ private LinkedHashMap<Integer, FieldInfo> indexes;
+
+ /** */
+ private short counter;
/** Constructor. */
public OptimizedObjectMetadata() {
@@ -39,143 +39,92 @@ public class OptimizedObjectMetadata implements Externalizable {
}
/**
- * Adds meta for a new field.
+ * Adds field to metadata list assigning an index to it that is used to locate field bucket in the footer of
+ * object's serialized form.
+ *
+ * @param fieldName Field name.
+ */
+ public void addField(String fieldName, OptimizedFieldType type) {
+ if (indexes == null)
+ indexes = new LinkedHashMap<>();
+
+ indexes.put(OptimizedMarshallerUtils.resolveFieldId(fieldName), new FieldInfo(type, counter++));
+ }
+
+ /**
+ * Returns an index assigned to the field. The index is used to locate field bucket in the footer of
+ * object's serialized form.
*
- * @param fieldId Field ID.
- * @param fieldType Field type.
+ * @param fieldName Field name.
+ * @return Index.
+ * @throws IgniteFieldNotFoundException If object doesn't have such a field.
*/
- public void addMeta(int fieldId, OptimizedFieldType fieldType) {
- if (fieldsInfo == null)
- fieldsInfo = new ArrayList<>();
+ public int fieldIndex(String fieldName) throws IgniteFieldNotFoundException {
+ if (indexes == null)
+ throw new IgniteFieldNotFoundException("Object doesn't have field named: " + fieldName);
+ FieldInfo info = indexes.get(OptimizedMarshallerUtils.resolveFieldId(fieldName));
+ if (info == null)
+ throw new IgniteFieldNotFoundException("Object doesn't have field named: " + fieldName);
- fieldsInfo.add(new FieldInfo(fieldId, fieldType));
+ return info.index();
}
/**
- * Gets {@link OptimizedObjectMetadata.FieldInfo} at the {@code index}.
+ * Returns meta list.
*
- * @param index Position.
- * @return Field meta info.
+ * @return Meta list.
*/
- public FieldInfo getMeta(int index) {
- return fieldsInfo.get(index);
+ public Set<Map.Entry<Integer, FieldInfo>> metaList() {
+ return indexes.entrySet();
}
+
/**
- * Returns all the metadata stored for the object.
+ * Returns number of fields.
*
- * @return Metadata collection.
+ * @return Number of fields.
*/
- public List<FieldInfo> getMeta() {
- return Collections.unmodifiableList(fieldsInfo);
+ public int size() {
+ return indexes.size();
}
/** {@inheritDoc} */
@Override public void writeExternal(ObjectOutput out) throws IOException {
- if (fieldsInfo == null) {
- out.writeInt(0);
- return;
- }
-
- out.writeInt(fieldsInfo.size());
-
- for (FieldInfo fieldInfo : fieldsInfo) {
- out.writeInt(fieldInfo.id);
- out.writeByte(fieldInfo.type.ordinal());
- }
+ out.writeObject(indexes);
}
/** {@inheritDoc} */
@Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- int size = in.readInt();
-
- fieldsInfo = new ArrayList<>(size);
-
- for (int i = 0; i < size; i++)
- fieldsInfo.add(new FieldInfo(in.readInt(), OptimizedFieldType.values()[in.readByte()]));
+ indexes = (LinkedHashMap<Integer, FieldInfo>)in.readObject();
}
/**
* Field info.
*/
- public static class FieldInfo {
- /** Field ID. */
- private int id;
-
- /** Field len. */
- private int len;
-
- /** Field type. */
+ public static class FieldInfo implements Serializable {
+ /** */
private OptimizedFieldType type;
+ /** */
+ private short index;
+
/**
* Constructor.
- *
- * @param id Field ID.
- * @param type Field len.
+ * @param type
+ * @param index
*/
- public FieldInfo(int id, OptimizedFieldType type) {
- this.id = id;
+ public FieldInfo(OptimizedFieldType type, short index) {
this.type = type;
-
- len = 1;
-
- switch (type) {
- case BYTE:
- case BOOLEAN:
- len += 1;
- break;
-
- case SHORT:
- case CHAR:
- len += 2;
- break;
-
- case INT:
- case FLOAT:
- len += 4;
- break;
-
- case LONG:
- case DOUBLE:
- len += 8;
- break;
-
- case OTHER:
- len = OptimizedMarshallerExt.VARIABLE_LEN;
- break;
-
- default:
- throw new IgniteException("Unknown field type: " + type);
- }
-
- assert len != 1;
+ this.index = index;
}
- /**
- * Returns ID.
- * @return ID.
- */
- public int id() {
- return id;
- }
-
- /**
- * Returns length.
- * @return Lenght.
- */
- public int length() {
- return len;
- }
-
- /**
- * Returns field type.
- *
- * @return Field type.
- */
public OptimizedFieldType type() {
return type;
}
+
+ public short index() {
+ return index;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/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 2bb71e9..c697c2e 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
@@ -538,12 +538,12 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
@SuppressWarnings("ForLoopReplaceableByForEach")
private void writeFields(Object obj, OptimizedClassDescriptor.ClassFields fields, Footer footer)
throws IOException {
- int size;
+ int off;
for (int i = 0; i < fields.size(); i++) {
OptimizedClassDescriptor.FieldInfo t = fields.get(i);
- size = out.size();
+ off = out.offset();
switch (t.type()) {
case BYTE:
@@ -631,17 +631,14 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
GridHandleTable.ObjectInfo objInfo = writeObject0(getObject(obj, t.offset()));
if (footer != null && objInfo != null) {
- footer.putHandle(t.id(), objInfo);
+ footer.addNextHandleField(objInfo.position(), objInfo.length());
continue;
}
}
}
- if (footer != null && t.field() != null) {
- int fieldLen = out.size() - size;
-
- footer.put(t.id(), t.type(), fieldLen);
- }
+ if (footer != null && t.field() != null)
+ footer.addNextFieldOff(off);
}
}
@@ -832,13 +829,13 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
if (curPut == null)
throw new NotActiveException("putFields() was not called.");
- int size;
+ int off;
Footer footer = curPut.curFooter;
for (IgniteBiTuple<OptimizedClassDescriptor.FieldInfo, Object> t : curPut.objs) {
- size = out.size();
+ off = out.offset();
switch (t.get1().type()) {
case BYTE:
@@ -909,16 +906,13 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
GridHandleTable.ObjectInfo objInfo = writeObject0(t.get2());
if (footer != null && objInfo != null) {
- footer.putHandle(t.get1().id(), objInfo);
+ footer.addNextHandleField(objInfo.position(), objInfo.length());
continue;
}
}
- if (footer != null) {
- int fieldLen = out.size() - size;
-
- footer.put(t.get1().id(), t.get1().type(), fieldLen);
- }
+ if (footer != null)
+ footer.addNextFieldOff(off);
}
}
@@ -955,58 +949,58 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
/** {@inheritDoc} */
@Override public void writeByte(String fieldName, byte val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(BYTE);
out.writeByte(val);
- putFieldToFooter(fieldName, OptimizedFieldType.BYTE, 1);
}
/** {@inheritDoc} */
@Override public void writeShort(String fieldName, short val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(SHORT);
out.writeShort(val);
- putFieldToFooter(fieldName, OptimizedFieldType.SHORT, 2);
}
/** {@inheritDoc} */
@Override public void writeInt(String fieldName, int val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(INT);
out.writeInt(val);
- putFieldToFooter(fieldName, OptimizedFieldType.INT, 4);
}
/** {@inheritDoc} */
@Override public void writeLong(String fieldName, long val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(LONG);
out.writeLong(val);
- putFieldToFooter(fieldName, OptimizedFieldType.LONG, 8);
}
/** {@inheritDoc} */
@Override public void writeFloat(String fieldName, float val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(FLOAT);
out.writeFloat(val);
- putFieldToFooter(fieldName, OptimizedFieldType.FLOAT, 4);
}
/** {@inheritDoc} */
@Override public void writeDouble(String fieldName, double val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(DOUBLE);
out.writeDouble(val);
- putFieldToFooter(fieldName, OptimizedFieldType.DOUBLE, 8);
}
/** {@inheritDoc} */
@Override public void writeChar(String fieldName, char val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(CHAR);
out.writeChar(val);
- putFieldToFooter(fieldName, OptimizedFieldType.CHAR, 2);
}
/** {@inheritDoc} */
@Override public void writeBoolean(String fieldName, boolean val) throws IOException {
+ putFieldOffsetToFooter(out.offset());
writeFieldType(BOOLEAN);
out.writeBoolean(val);
- putFieldToFooter(fieldName, OptimizedFieldType.BOOLEAN, 1);
}
/** {@inheritDoc} */
@@ -1016,10 +1010,8 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
/** {@inheritDoc} */
@Override public void writeObject(String fieldName, @Nullable Object obj) throws IOException {
- int pos = out.offset();
-
+ putFieldOffsetToFooter(out.offset());
writeObject(obj);
- putFieldToFooter(fieldName, OptimizedFieldType.OTHER, out.offset() - pos);
}
/** {@inheritDoc} */
@@ -1093,14 +1085,12 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
}
/**
- * Puts field to the footer.
+ * Puts field's offset to the footer.
*
- * @param fieldName Field name.
- * @param type Field type.
- * @param len Field length.
+ * @param off Field offset.
*/
- private void putFieldToFooter(String fieldName, OptimizedFieldType type, int len) {
- marshalAwareFooters.peek().put(OptimizedMarshallerUtils.resolveFieldId(fieldName), type, len);
+ private void putFieldOffsetToFooter(int off) {
+ marshalAwareFooters.peek().addNextFieldOff(off);
}
/**
@@ -1230,22 +1220,19 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O
void indexingSupported(boolean indexingSupported);
/**
- * Puts type ID and its value len to the footer.
+ * Adds offset of a field that must be placed next to the footer.
*
- * @param fieldId Field ID.
- * @param fieldType Field type.
- * @param len Total number of bytes occupied by type's value.
+ * @param off Field offset.
*/
- void put(int fieldId, OptimizedFieldType fieldType, int len);
-
+ void addNextFieldOff(int off);
/**
- * Puts handle ID for the given field ID.
+ * Adds handle's offset of a field that must be placed next to the footer.
*
- * @param fieldId Field ID.
- * @param objInfo Object's, referred by handle, info.
+ * @param handleOff Handle offset.
+ * @param handleLen Handle length.
*/
- void putHandle(int fieldId, GridHandleTable.ObjectInfo objInfo);
+ void addNextHandleField(int handleOff, int handleLen);
/**
* Writes footer content to the OutputStream.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStreamExt.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStreamExt.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStreamExt.java
index 9833e98..ad5b515 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStreamExt.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStreamExt.java
@@ -58,10 +58,7 @@ public class OptimizedObjectOutputStreamExt extends OptimizedObjectOutputStream
*/
private class FooterImpl implements OptimizedObjectOutputStream.Footer {
/** */
- private ArrayList<Meta> data;
-
- /** */
- private HashMap<Integer, GridHandleTable.ObjectInfo> handles;
+ private ArrayList<Long> data;
/** */
private boolean hasHandles;
@@ -75,28 +72,15 @@ public class OptimizedObjectOutputStreamExt extends OptimizedObjectOutputStream
}
/** {@inheritDoc} */
- @Override public void put(int fieldId, OptimizedFieldType fieldType, int len) {
- if (data == null)
- return;
-
- if (fieldType == OptimizedFieldType.OTHER)
- data.add(new Meta(fieldId, len));
+ @Override public void addNextFieldOff(int off) {
+ data.add((long)(off & ~FOOTER_BODY_IS_HANDLE_MASK));
}
/** {@inheritDoc} */
- @Override public void putHandle(int fieldId, GridHandleTable.ObjectInfo objInfo) {
- if (data == null)
- return;
+ @Override public void addNextHandleField(int handleOff, int handleLength) {
+ hasHandles = true;
- if (!hasHandles) {
- hasHandles = true;
- handles = new HashMap<>();
- }
-
- handles.put(fieldId, objInfo);
-
- // length of handle fields is 5 bytes.
- put(fieldId, OptimizedFieldType.OTHER, 5);
+ data.add(((long)handleLength << 32) | (handleOff | FOOTER_BODY_IS_HANDLE_MASK));
}
/** {@inheritDoc} */
@@ -104,61 +88,25 @@ public class OptimizedObjectOutputStreamExt extends OptimizedObjectOutputStream
if (data == null)
writeShort(EMPTY_FOOTER);
else {
- int bodyEnd = out.offset();
-
- // +4 - 2 bytes for footer len at the beginning, 2 bytes for footer len at the end.
- short footerLen = (short)(data.size() * 4 + 4);
-
- if (hasHandles)
- footerLen += handles.size() * 8;
+ // +5 - 2 bytes for footer len at the beginning, 2 bytes for footer len at the end, 1 byte for handles
+ // indicator flag.
+ short footerLen = (short)(data.size() * (hasHandles ? 8 : 4) + 5);
writeShort(footerLen);
if (hasHandles) {
- for (Meta fieldMeta : data) {
- GridHandleTable.ObjectInfo objInfo = handles.get(fieldMeta.fieldId);
-
- if (objInfo == null)
- writeInt(fieldMeta.fieldLen & ~FOOTER_BODY_IS_HANDLE_MASK);
- else {
- writeInt(fieldMeta.fieldLen | FOOTER_BODY_IS_HANDLE_MASK);
- writeInt(objInfo.position());
-
- if (objInfo.length() == 0)
- // field refers to its own object that hasn't set total length yet.
- writeInt((bodyEnd - objInfo.position()) + footerLen);
- else
- writeInt(objInfo.length());
- }
- }
+ for (long body : data)
+ writeLong(body);
+ }
+ else {
+ for (long body : data)
+ writeInt((int)body);
}
- else
- for (Meta fieldMeta : data)
- // writing field len and resetting is handle mask
- writeInt(fieldMeta.fieldLen & ~FOOTER_BODY_IS_HANDLE_MASK);
+
+ writeByte(hasHandles ? 1 : 0);
writeShort(footerLen);
}
}
}
-
- /**
- *
- */
- private static class Meta {
- /** */
- int fieldId;
-
- /** */
- int fieldLen;
-
- /**
- * @param fieldId
- * @param fieldLen
- */
- public Meta(int fieldId, int fieldLen) {
- this.fieldId = fieldId;
- this.fieldLen = fieldLen;
- }
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e8bdec6/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java
index 0e9fb61..94a7523 100644
--- a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java
@@ -22,6 +22,7 @@ import org.apache.ignite.marshaller.*;
import org.apache.ignite.testframework.junits.common.*;
import java.io.*;
+import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
@@ -106,11 +107,19 @@ public class OptimizedMarshallerExtSelfTest extends OptimizedMarshallerSelfTest
// Must be returned in a wrapped form, since metadata was added enabling the footer.
CacheIndexedObjectImpl cacheObject = marsh.readField("o2", arr, 0, arr.length, null);
+
arr = cacheObject.valueBytes(null);
+ Field start = cacheObject.getClass().getDeclaredField("start");
+ start.setAccessible(true);
+
+ Field len = cacheObject.getClass().getDeclaredField("len");
+ len.setAccessible(true);
+
// Check enclosed objects fields
- assertTrue(marsh.hasField("i", arr, 0, arr.length));
- assertEquals(testObj.o2.i, (int)marsh.readField("i", arr, 0, arr.length, null));
+ assertTrue(marsh.hasField("i", arr, start.getInt(cacheObject), len.getInt(cacheObject)));
+ assertEquals(testObj.o2.i, (int)marsh.readField("i", arr, start.getInt(cacheObject), len.getInt(cacheObject),
+ null));
}
/**
@@ -174,14 +183,26 @@ public class OptimizedMarshallerExtSelfTest extends OptimizedMarshallerSelfTest
CacheIndexedObjectImpl cacheObj = marsh.readField("aware", arr, 0, arr.length, null);
byte[] cacheObjArr = cacheObj.valueBytes(null);
- Date date = marsh.readField("date", cacheObjArr, 0, cacheObjArr.length, null);
+ Field start = cacheObj.getClass().getDeclaredField("start");
+ start.setAccessible(true);
+
+ Field len = cacheObj.getClass().getDeclaredField("len");
+ len.setAccessible(true);
+
+ Date date = marsh.readField("date", cacheObjArr, start.getInt(cacheObj), len.getInt(cacheObj), null);
assertEquals(test.aware.date, date);
cacheObj = marsh.readField("testObject2", arr, 0, arr.length, null);
cacheObjArr = cacheObj.valueBytes(null);
- int n = marsh.readField("i", cacheObjArr, 0, cacheObjArr.length, null);
+ start = cacheObj.getClass().getDeclaredField("start");
+ start.setAccessible(true);
+
+ len = cacheObj.getClass().getDeclaredField("len");
+ len.setAccessible(true);
+
+ int n = marsh.readField("i", cacheObjArr, start.getInt(cacheObj), len.getInt(cacheObj), null);
assertEquals(test.testObject2.i, n);