Skip to content

Commit

Permalink
IGNITE-2099: Fixed serialization of custom collections.
Browse files Browse the repository at this point in the history
  • Loading branch information
vozerov-gridgain committed Dec 10, 2015
1 parent be17c9e commit 6cdd580
Show file tree
Hide file tree
Showing 24 changed files with 465 additions and 614 deletions.
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.ignite.binary;

import java.util.Collection;

/**
* Collection factory.
*/
public interface BinaryCollectionFactory<K> {
/**
* Create collection.
*
* @param size Amount of elements in collection.
* @return Collection.
*/
public Collection<K> create(int size);
}
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.ignite.binary;

import java.util.Map;

/**
* Map factory.
*/
public interface BinaryMapFactory<K, V> {
/**
* Create collection.
*
* @param size Amount of elements in collection.
* @return Collection.
*/
public Map<K, V> create(int size);
}
Expand Up @@ -206,11 +206,11 @@ public interface BinaryRawReader {
@Nullable public <T> Collection<T> readCollection() throws BinaryObjectException; @Nullable public <T> Collection<T> readCollection() throws BinaryObjectException;


/** /**
* @param colCls Collection class. * @param factory Collection factory.
* @return Collection. * @return Collection.
* @throws BinaryObjectException In case of error. * @throws BinaryObjectException In case of error.
*/ */
@Nullable public <T> Collection<T> readCollection(Class<? extends Collection<T>> colCls) @Nullable public <T> Collection<T> readCollection(BinaryCollectionFactory<T> factory)
throws BinaryObjectException; throws BinaryObjectException;


/** /**
Expand All @@ -220,11 +220,11 @@ public interface BinaryRawReader {
@Nullable public <K, V> Map<K, V> readMap() throws BinaryObjectException; @Nullable public <K, V> Map<K, V> readMap() throws BinaryObjectException;


/** /**
* @param mapCls Map class. * @param factory Map factory.
* @return Map. * @return Map.
* @throws BinaryObjectException In case of error. * @throws BinaryObjectException In case of error.
*/ */
@Nullable public <K, V> Map<K, V> readMap(Class<? extends Map<K, V>> mapCls) throws BinaryObjectException; @Nullable public <K, V> Map<K, V> readMap(BinaryMapFactory<K, V> factory) throws BinaryObjectException;


/** /**
* @return Value. * @return Value.
Expand Down
Expand Up @@ -242,11 +242,11 @@ public interface BinaryReader {


/** /**
* @param fieldName Field name. * @param fieldName Field name.
* @param colCls Collection class. * @param factory Collection factory.
* @return Collection. * @return Collection.
* @throws BinaryObjectException In case of error. * @throws BinaryObjectException In case of error.
*/ */
public <T> Collection<T> readCollection(String fieldName, Class<? extends Collection<T>> colCls) public <T> Collection<T> readCollection(String fieldName, BinaryCollectionFactory<T> factory)
throws BinaryObjectException; throws BinaryObjectException;


/** /**
Expand All @@ -258,12 +258,11 @@ public <T> Collection<T> readCollection(String fieldName, Class<? extends Collec


/** /**
* @param fieldName Field name. * @param fieldName Field name.
* @param mapCls Map class. * @param factory Map factory.
* @return Map. * @return Map.
* @throws BinaryObjectException In case of error. * @throws BinaryObjectException In case of error.
*/ */
public <K, V> Map<K, V> readMap(String fieldName, Class<? extends Map<K, V>> mapCls) public <K, V> Map<K, V> readMap(String fieldName, BinaryMapFactory<K, V> factory) throws BinaryObjectException;
throws BinaryObjectException;


/** /**
* @param fieldName Field name. * @param fieldName Field name.
Expand Down
Expand Up @@ -17,17 +17,18 @@


package org.apache.ignite.internal.portable; package org.apache.ignite.internal.portable;


import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.internal.U;
import sun.misc.Unsafe;

import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.internal.U;
import sun.misc.Unsafe;


/** /**
* Field accessor to speedup access. * Field accessor to speedup access.
Expand Down Expand Up @@ -607,11 +608,6 @@ private static class DefaultFinalClassAccessor extends BinaryFieldAccessor {


break; break;


case MAP_ENTRY:
writer.writeMapEntryField((Map.Entry<?, ?>)val);

break;

case PORTABLE_OBJ: case PORTABLE_OBJ:
writer.writePortableObjectField((BinaryObjectImpl)val); writer.writePortableObjectField((BinaryObjectImpl)val);


Expand Down Expand Up @@ -813,11 +809,6 @@ protected Object readFixedType(BinaryReaderExImpl reader) throws BinaryObjectExc


break; break;


case MAP_ENTRY:
val = reader.readMapEntry(id);

break;

case PORTABLE_OBJ: case PORTABLE_OBJ:
val = reader.readPortableObject(id); val = reader.readPortableObject(id);


Expand Down
Expand Up @@ -26,8 +26,11 @@
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;

import org.apache.ignite.binary.BinaryCollectionFactory;
import org.apache.ignite.binary.BinaryIdMapper; import org.apache.ignite.binary.BinaryIdMapper;
import org.apache.ignite.binary.BinaryInvalidTypeException; import org.apache.ignite.binary.BinaryInvalidTypeException;
import org.apache.ignite.binary.BinaryMapFactory;
import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryRawReader; import org.apache.ignite.binary.BinaryRawReader;
Expand Down Expand Up @@ -62,7 +65,6 @@
import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG; import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG_ARR;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP; import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP_ENTRY;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL; import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ; import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ;
import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR; import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR;
Expand Down Expand Up @@ -308,24 +310,6 @@ public Object unmarshal(int offset) throws BinaryObjectException {
return findFieldById(fieldId) ? PortableUtils.unmarshal(in, ctx, ldr, this) : null; return findFieldById(fieldId) ? PortableUtils.unmarshal(in, ctx, ldr, this) : null;
} }


/**
* @param fieldId Field ID.
* @return Value.
* @throws BinaryObjectException On case of error.
*/
@Nullable Map.Entry<?, ?> readMapEntry(int fieldId) throws BinaryObjectException {
if (findFieldById(fieldId)) {
Flag flag = checkFlag(MAP_ENTRY);

if (flag == Flag.NORMAL)
return PortableUtils.doReadMapEntry(in, ctx, ldr, this, true);
else if (flag == Flag.HANDLE)
return readHandleField();
}

return null;
}

/** /**
* @param fieldId Field ID. * @param fieldId Field ID.
* @return Portable object. * @return Portable object.
Expand Down Expand Up @@ -1236,20 +1220,20 @@ private Object[] readEnumArray0(@Nullable Class<?> cls) throws BinaryObjectExcep
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
@Nullable @Override public <T> Collection<T> readCollection(String fieldName, @Nullable @Override public <T> Collection<T> readCollection(String fieldName, BinaryCollectionFactory<T> factory)
Class<? extends Collection<T>> colCls) throws BinaryObjectException { throws BinaryObjectException {
return findFieldByName(fieldName) ? readCollection0(colCls) : null; return findFieldByName(fieldName) ? readCollection0(factory) : null;
} }


/** /**
* @param fieldId Field ID. * @param fieldId Field ID.
* @param colCls Collection class. * @param factory Collection factory.
* @return Value. * @return Value.
* @throws BinaryObjectException In case of error. * @throws BinaryObjectException In case of error.
*/ */
@Nullable <T> Collection<T> readCollection(int fieldId, @Nullable Class<? extends Collection> colCls) @Nullable <T> Collection<T> readCollection(int fieldId, @Nullable BinaryCollectionFactory<T> factory)
throws BinaryObjectException { throws BinaryObjectException {
return findFieldById(fieldId) ? (Collection<T>)readCollection0(colCls) : null; return findFieldById(fieldId) ? (Collection<T>)readCollection0(factory) : null;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
Expand All @@ -1258,26 +1242,41 @@ private Object[] readEnumArray0(@Nullable Class<?> cls) throws BinaryObjectExcep
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
@Nullable @Override public <T> Collection<T> readCollection(Class<? extends Collection<T>> colCls) @Nullable @Override public <T> Collection<T> readCollection(BinaryCollectionFactory<T> factory)
throws BinaryObjectException { throws BinaryObjectException {
return readCollection0(colCls); return readCollection0(factory);
} }


/** /**
* Internal read collection routine. * Internal read collection routine.
* *
* @param cls Collection class. * @param factory Collection factory.
* @return Value. * @return Value.
* @throws BinaryObjectException If failed. * @throws BinaryObjectException If failed.
*/ */
private Collection readCollection0(@Nullable Class<? extends Collection> cls) private Collection readCollection0(@Nullable BinaryCollectionFactory factory)
throws BinaryObjectException { throws BinaryObjectException {
switch (checkFlag(COL)) { switch (checkFlag(COL)) {
case NORMAL: case NORMAL:
return (Collection)PortableUtils.doReadCollection(in, ctx, ldr, this, true, cls); return (Collection)PortableUtils.doReadCollection(in, ctx, ldr, this, true, factory);


case HANDLE: case HANDLE: {
return readHandleField(); int handlePos = PortableUtils.positionForHandle(in) - in.readInt();

Object obj = getHandle(handlePos);

if (obj == null) {
int retPos = in.position();

streamPosition(handlePos);

obj = readCollection0(factory);

streamPosition(retPos);
}

return (Collection)obj;
}


default: default:
return null; return null;
Expand All @@ -1290,19 +1289,19 @@ private Collection readCollection0(@Nullable Class<? extends Collection> cls)
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
@Nullable @Override public <K, V> Map<K, V> readMap(String fieldName, Class<? extends Map<K, V>> mapCls) @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName, BinaryMapFactory<K, V> factory)
throws BinaryObjectException { throws BinaryObjectException {
return findFieldByName(fieldName) ? readMap0(mapCls) : null; return findFieldByName(fieldName) ? readMap0(factory) : null;
} }


/** /**
* @param fieldId Field ID. * @param fieldId Field ID.
* @param mapCls Map class. * @param factory Factory.
* @return Value. * @return Value.
* @throws BinaryObjectException In case of error. * @throws BinaryObjectException In case of error.
*/ */
@Nullable Map<?, ?> readMap(int fieldId, @Nullable Class<? extends Map> mapCls) throws BinaryObjectException { @Nullable Map<?, ?> readMap(int fieldId, @Nullable BinaryMapFactory factory) throws BinaryObjectException {
return findFieldById(fieldId) ? readMap0(mapCls) : null; return findFieldById(fieldId) ? readMap0(factory) : null;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
Expand All @@ -1311,25 +1310,40 @@ private Collection readCollection0(@Nullable Class<? extends Collection> cls)
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
@Nullable @Override public <K, V> Map<K, V> readMap(Class<? extends Map<K, V>> mapCls) @Nullable @Override public <K, V> Map<K, V> readMap(BinaryMapFactory<K, V> factory)
throws BinaryObjectException { throws BinaryObjectException {
return readMap0(mapCls); return readMap0(factory);
} }


/** /**
* Internal read map routine. * Internal read map routine.
* *
* @param cls Map class. * @param factory Factory.
* @return Value. * @return Value.
* @throws BinaryObjectException If failed. * @throws BinaryObjectException If failed.
*/ */
private Map readMap0(@Nullable Class<? extends Map> cls) throws BinaryObjectException { private Map readMap0(@Nullable BinaryMapFactory factory) throws BinaryObjectException {
switch (checkFlag(MAP)) { switch (checkFlag(MAP)) {
case NORMAL: case NORMAL:
return (Map)PortableUtils.doReadMap(in, ctx, ldr, this, true, cls); return (Map)PortableUtils.doReadMap(in, ctx, ldr, this, true, factory);


case HANDLE: case HANDLE: {
return readHandleField(); int handlePos = PortableUtils.positionForHandle(in) - in.readInt();

Object obj = getHandle(handlePos);

if (obj == null) {
int retPos = in.position();

streamPosition(handlePos);

obj = readMap0(factory);

streamPosition(retPos);
}

return (Map)obj;
}


default: default:
return null; return null;
Expand Down Expand Up @@ -1584,11 +1598,6 @@ else if (flag == NULL)


break; break;


case MAP_ENTRY:
obj = PortableUtils.doReadMapEntry(in, ctx, ldr, this, true);

break;

case PORTABLE_OBJ: case PORTABLE_OBJ:
obj = PortableUtils.doReadPortableObject(in, ctx); obj = PortableUtils.doReadPortableObject(in, ctx);


Expand Down
Expand Up @@ -132,9 +132,6 @@ public enum BinaryWriteMode {
/** */ /** */
MAP(GridPortableMarshaller.MAP), MAP(GridPortableMarshaller.MAP),


/** */
MAP_ENTRY(GridPortableMarshaller.MAP_ENTRY),

/** */ /** */
PORTABLE_OBJ(GridPortableMarshaller.OBJ), PORTABLE_OBJ(GridPortableMarshaller.OBJ),


Expand Down

0 comments on commit 6cdd580

Please sign in to comment.