You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/05/26 11:07:19 UTC
[2/2] ignite git commit: IGNITE-4575: Improved binary enums support.
This closes #1968.
IGNITE-4575: Improved binary enums support. This closes #1968.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b5c7b6f5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b5c7b6f5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b5c7b6f5
Branch: refs/heads/master
Commit: b5c7b6f5ed81a9cee242e3abb052c29ec571a9a9
Parents: d38ca8b
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Fri May 26 14:07:06 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri May 26 14:07:06 2017 +0300
----------------------------------------------------------------------
.../java/org/apache/ignite/IgniteBinary.java | 23 ++-
.../org/apache/ignite/binary/BinaryObject.java | 8 +
.../org/apache/ignite/binary/BinaryType.java | 5 +
.../ignite/binary/BinaryTypeConfiguration.java | 26 +++
.../binary/BinaryCachingMetadataHandler.java | 5 +
.../internal/binary/BinaryClassDescriptor.java | 4 +-
.../ignite/internal/binary/BinaryContext.java | 60 +++++--
.../internal/binary/BinaryEnumObjectImpl.java | 30 +++-
.../internal/binary/BinaryFieldAccessor.java | 10 ++
.../ignite/internal/binary/BinaryMetadata.java | 93 +++++++++-
.../internal/binary/BinaryMetadataHandler.java | 9 +
.../binary/BinaryNoopMetadataHandler.java | 5 +
.../internal/binary/BinaryObjectExImpl.java | 5 +
.../internal/binary/BinaryReaderExImpl.java | 18 ++
.../ignite/internal/binary/BinaryTypeImpl.java | 15 ++
.../ignite/internal/binary/BinaryTypeProxy.java | 6 +
.../ignite/internal/binary/BinaryUtils.java | 104 ++++++++++-
.../internal/binary/BinaryWriterExImpl.java | 18 +-
.../internal/binary/GridBinaryMarshaller.java | 3 +
.../binary/builder/BinaryBuilderSerializer.java | 10 +-
.../binary/builder/BinaryObjectBuilderImpl.java | 2 +-
.../binary/CacheObjectBinaryProcessor.java | 21 ++-
.../binary/CacheObjectBinaryProcessorImpl.java | 72 +++++++-
.../cache/binary/IgniteBinaryImpl.java | 26 +++
.../processors/cacheobject/NoOpBinary.java | 12 ++
.../platform/PlatformContextImpl.java | 29 ++-
.../binary/PlatformBinaryProcessor.java | 25 +++
.../internal/binary/BinaryEnumsSelfTest.java | 146 ++++++++++++++-
.../binary/TestCachingMetadataHandler.java | 5 +
.../platform/PlatformComputeEchoTask.java | 13 ++
.../Binary/BinaryBuilderSelfTest.cs | 88 +++++++--
.../Compute/ComputeApiTest.cs | 25 +++
.../Binary/BinaryTypeConfiguration.cs | 3 +-
.../dotnet/Apache.Ignite.Core/Binary/IBinary.cs | 24 +++
.../Apache.Ignite.Core/Binary/IBinaryObject.cs | 8 +
.../Apache.Ignite.Core/Binary/IBinaryType.cs | 6 +
.../Apache.Ignite.Core/Impl/Binary/Binary.cs | 67 ++++++-
.../Impl/Binary/BinaryEnum.cs | 11 +-
.../Impl/Binary/BinaryObject.cs | 13 +-
.../Impl/Binary/BinaryProcessor.cs | 65 ++++++-
.../Impl/Binary/BinaryReader.cs | 10 +-
.../Impl/Binary/BinarySystemHandlers.cs | 25 +--
.../Impl/Binary/BinaryUtils.cs | 19 ++
.../Impl/Binary/BinaryWriter.cs | 4 +-
.../Impl/Binary/Marshaller.cs | 88 ++++-----
.../Impl/Binary/Metadata/BinaryType.cs | 179 ++++++++++++++++++-
.../Impl/Binary/Metadata/BinaryTypeHolder.cs | 44 +++--
47 files changed, 1338 insertions(+), 149 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
index 1d1c0c3..3550ff5 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.ignite.binary.BinaryObjectBuilder;
@@ -374,11 +375,29 @@ public interface IgniteBinary {
public Collection<BinaryType> types() throws BinaryObjectException;
/**
- * Create enum object.
+ * Create enum object using value.
*
* @param typeName Type name.
* @param ord Ordinal.
* @return Enum object.
*/
- public BinaryObject buildEnum(String typeName, int ord);
+ public BinaryObject buildEnum(String typeName, int ord) throws BinaryObjectException;
+
+ /**
+ * Create enum object using name.
+ *
+ * @param typeName Type name.
+ * @param name Name.
+ * @return Enum object.
+ */
+ public BinaryObject buildEnum(String typeName, String name) throws BinaryObjectException;
+
+ /**
+ * Register enum type.
+ *
+ * @param typeName Type name.
+ * @param vals Mapping of enum constant names to ordinals.
+ * @return Binary type for registered enum.
+ */
+ public BinaryType registerEnum(String typeName, Map<String, Integer> vals) throws BinaryObjectException;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
index 3d99757..b9e653f 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
@@ -162,4 +162,12 @@ public interface BinaryObject extends Serializable, Cloneable {
* @throws BinaryObjectException If object is not enum.
*/
public int enumOrdinal() throws BinaryObjectException;
+
+ /**
+ * Get name for this enum object. Use {@link BinaryType#isEnum()} to check if object is of enum type.
+ *
+ * @return Name.
+ * @throws BinaryObjectException If object is not enum.
+ */
+ public String enumName() throws BinaryObjectException;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
index f184a8c..f4bc206 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
@@ -79,4 +79,9 @@ public interface BinaryType {
* @return {@code True} if type is enum.
*/
public boolean isEnum();
+
+ /**
+ * @return Collection of enum values.
+ */
+ public Collection<BinaryObject> enumValues();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
index 54b853c..2d00bd2 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
@@ -23,6 +23,9 @@ import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
/**
* Defines configuration properties for a specific binary type. Providing per-type
* configuration is optional, as it is generally enough, and also optional, to provide global binary
@@ -46,6 +49,9 @@ public class BinaryTypeConfiguration {
/** Enum flag. */
private boolean isEnum;
+ /** Enum names to ordinals mapping. */
+ private Map<String, Integer> enumValues;
+
/**
* Constructor.
*/
@@ -64,6 +70,7 @@ public class BinaryTypeConfiguration {
idMapper = other.idMapper;
isEnum = other.isEnum;
serializer = other.serializer;
+ enumValues = other.enumValues != null ? new LinkedHashMap<>(other.enumValues) : null;
typeName = other.typeName;
}
@@ -179,6 +186,25 @@ public class BinaryTypeConfiguration {
return this;
}
+ /**
+ * Set enum ordinal to names mapping.
+ *
+ * @param values Map of enum name to ordinal.
+ * @return {@code this} for chaining.
+ */
+ public BinaryTypeConfiguration setEnumValues(@Nullable Map<String, Integer> values) {
+ this.enumValues = values;
+
+ return this;
+ }
+
+ /**
+ * @return Enum name to ordinal mapping
+ */
+ @Nullable public Map<String, Integer> getEnumValues() {
+ return enumValues;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(BinaryTypeConfiguration.class, this, super.toString());
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
index 24a393d..27cccaa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
@@ -69,6 +69,11 @@ public class BinaryCachingMetadataHandler implements BinaryMetadataHandler {
}
/** {@inheritDoc} */
+ @Override public synchronized BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+ return ((BinaryTypeImpl)metas.get(typeId)).metadata();
+ }
+
+ /** {@inheritDoc} */
@Override public synchronized BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
BinaryTypeImpl type = (BinaryTypeImpl) metas.get(typeId);
return type.metadata().hasSchema(schemaId) ? type : null;
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 7194f49..adfdcfc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -758,7 +758,7 @@ public class BinaryClassDescriptor {
BinarySchema newSchema = collector.schema();
BinaryMetadata meta = new BinaryMetadata(typeId, typeName, collector.meta(),
- affKeyFieldName, Collections.singleton(newSchema), false);
+ affKeyFieldName, Collections.singleton(newSchema), false, null);
ctx.updateMetadata(typeId, meta);
@@ -779,7 +779,7 @@ public class BinaryClassDescriptor {
if (userType && !stableSchemaPublished) {
// Update meta before write object with new schema
BinaryMetadata meta = new BinaryMetadata(typeId, typeName, stableFieldsMeta,
- affKeyFieldName, Collections.singleton(stableSchema), false);
+ affKeyFieldName, Collections.singleton(stableSchema), false, null);
ctx.updateMetadata(typeId, meta);
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index da46496..70bc2f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -461,17 +461,17 @@ public class BinaryContext {
for (String clsName0 : classesInPackage(pkgName))
descs.add(clsName0, mapper, serializer, identity, affFields.get(clsName0),
- typeCfg.isEnum(), true);
+ typeCfg.isEnum(), typeCfg.getEnumValues(), true);
}
else
descs.add(clsName, mapper, serializer, identity, affFields.get(clsName),
- typeCfg.isEnum(), false);
+ typeCfg.isEnum(), typeCfg.getEnumValues(), false);
}
}
for (TypeDescriptor desc : descs.descriptors())
registerUserType(desc.clsName, desc.mapper, desc.serializer, desc.identity, desc.affKeyFieldName,
- desc.isEnum);
+ desc.isEnum, desc.enumMap);
BinaryInternalMapper globalMapper = resolveMapper(globalNameMapper, globalIdMapper);
@@ -649,7 +649,8 @@ public class BinaryContext {
desc0.typeName(),
desc0.fieldsMeta(),
desc0.affFieldKeyName(),
- schemas, desc0.isEnum());
+ schemas, desc0.isEnum(),
+ cls.isEnum() ? enumMap(cls) : null);
metaHnd.addMeta(desc0.typeId(), meta.wrap(this));
@@ -799,8 +800,8 @@ public class BinaryContext {
);
if (!deserialize)
- metaHnd.addMeta(typeId,
- new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, null, desc.isEnum()).wrap(this));
+ metaHnd.addMeta(typeId, new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, null,
+ desc.isEnum(), cls.isEnum() ? enumMap(cls) : null).wrap(this));
descByCls.put(cls, desc);
@@ -1095,6 +1096,7 @@ public class BinaryContext {
* @param identity Type identity.
* @param affKeyFieldName Affinity key field name.
* @param isEnum If enum.
+ * @param enumMap Enum name to ordinal mapping.
* @throws BinaryObjectException In case of error.
*/
@SuppressWarnings("ErrorNotRethrown")
@@ -1103,8 +1105,8 @@ public class BinaryContext {
@Nullable BinarySerializer serializer,
@Nullable BinaryIdentityResolver identity,
@Nullable String affKeyFieldName,
- boolean isEnum)
- throws BinaryObjectException {
+ boolean isEnum,
+ @Nullable Map<String, Integer> enumMap) throws BinaryObjectException {
assert mapper != null;
Class<?> cls = null;
@@ -1172,7 +1174,8 @@ public class BinaryContext {
predefinedTypes.put(id, desc);
}
- metaHnd.addMeta(id, new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, null, isEnum).wrap(this));
+ metaHnd.addMeta(id,
+ new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, null, isEnum, enumMap).wrap(this));
}
/**
@@ -1222,6 +1225,16 @@ public class BinaryContext {
}
/**
+ *
+ * @param typeId Type ID
+ * @return Meta data.
+ * @throws BinaryObjectException In case of error.
+ */
+ @Nullable public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+ return metaHnd != null ? metaHnd.metadata0(typeId) : null;
+ }
+
+ /**
* @param typeId Type ID.
* @param schemaId Schema ID.
* @return Meta data.
@@ -1351,6 +1364,24 @@ public class BinaryContext {
}
/**
+ *
+ * @param cls Class
+ * @return Enum name to ordinal mapping.
+ */
+ private static Map<String, Integer> enumMap(Class<?> cls) {
+ assert cls.isEnum();
+
+ Object[] enumVals = cls.getEnumConstants();
+
+ Map<String, Integer> enumMap = new LinkedHashMap<>(enumVals.length);
+
+ for (Object enumVal : enumVals)
+ enumMap.put(((Enum)enumVal).name(), ((Enum)enumVal).ordinal());
+
+ return enumMap;
+ }
+
+ /**
* Type descriptors.
*/
private static class TypeDescriptors {
@@ -1366,6 +1397,7 @@ public class BinaryContext {
* @param identity Key hashing mode.
* @param affKeyFieldName Affinity key field name.
* @param isEnum Enum flag.
+ * @param enumMap Enum constants mapping.
* @param canOverride Whether this descriptor can be override.
* @throws BinaryObjectException If failed.
*/
@@ -1375,6 +1407,7 @@ public class BinaryContext {
BinaryIdentityResolver identity,
String affKeyFieldName,
boolean isEnum,
+ Map<String, Integer> enumMap,
boolean canOverride)
throws BinaryObjectException {
TypeDescriptor desc = new TypeDescriptor(clsName,
@@ -1383,6 +1416,7 @@ public class BinaryContext {
identity,
affKeyFieldName,
isEnum,
+ enumMap,
canOverride);
TypeDescriptor oldDesc = descs.get(clsName);
@@ -1425,6 +1459,9 @@ public class BinaryContext {
/** Enum flag. */
private boolean isEnum;
+ /** Enum ordinal to name mapping. */
+ private Map<String, Integer> enumMap;
+
/** Whether this descriptor can be override. */
private boolean canOverride;
@@ -1436,17 +1473,19 @@ public class BinaryContext {
* @param identity Key hashing mode.
* @param affKeyFieldName Affinity key field name.
* @param isEnum Enum type.
+ * @param enumMap Mapping of enum names to ordinals.
* @param canOverride Whether this descriptor can be override.
*/
private TypeDescriptor(String clsName, BinaryInternalMapper mapper,
BinarySerializer serializer, BinaryIdentityResolver identity, String affKeyFieldName, boolean isEnum,
- boolean canOverride) {
+ Map<String, Integer> enumMap, boolean canOverride) {
this.clsName = clsName;
this.mapper = mapper;
this.serializer = serializer;
this.identity = identity;
this.affKeyFieldName = affKeyFieldName;
this.isEnum = isEnum;
+ this.enumMap = enumMap;
this.canOverride = canOverride;
}
@@ -1465,6 +1504,7 @@ public class BinaryContext {
identity = other.identity;
affKeyFieldName = other.affKeyFieldName;
isEnum = other.isEnum;
+ enumMap = other.enumMap;
canOverride = other.canOverride;
}
else if (!other.canOverride)
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
index cc9941e..f889e45 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
@@ -97,9 +97,18 @@ public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, Cac
public BinaryEnumObjectImpl(BinaryContext ctx, byte[] arr) {
assert ctx != null;
assert arr != null;
- assert arr[0] == GridBinaryMarshaller.ENUM;
- valBytes = arr;
+ if (arr[0] == GridBinaryMarshaller.ENUM)
+ valBytes = arr;
+ else {
+ assert arr[0] == GridBinaryMarshaller.BINARY_ENUM;
+
+ valBytes = new byte[arr.length];
+
+ valBytes[0] = GridBinaryMarshaller.ENUM;
+
+ U.arrayCopy(arr, 1, valBytes, 1, arr.length - 1);
+ }
this.ctx = ctx;
@@ -187,6 +196,23 @@ public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, Cac
}
/** {@inheritDoc} */
+ @Override public String enumName() throws BinaryObjectException {
+ BinaryMetadata metadata = ctx.metadata0(typeId);
+
+ if (metadata == null)
+ throw new BinaryObjectException("Failed to get metadata for enum [typeId=" +
+ typeId + ", typeName='" + clsName + "', ordinal=" + ord + "]");
+
+ String name = metadata.getEnumNameByOrdinal(ord);
+
+ if (name == null)
+ throw new BinaryObjectException("Unable to resolve enum constant name [typeId=" +
+ typeId + ", typeName='" + metadata.typeName() + "', ordinal=" + ord + "]");
+
+ return name;
+ }
+
+ /** {@inheritDoc} */
@Override public int hashCode() {
return 31 * typeId + ord;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
index f7d35f0..567bee1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
@@ -647,6 +647,11 @@ public abstract class BinaryFieldAccessor {
break;
+ case BINARY_ENUM:
+ writer.doWriteBinaryEnum((BinaryEnumObjectImpl)val);
+
+ break;
+
case ENUM_ARR:
writer.writeEnumArrayField((Object[])val);
@@ -863,6 +868,11 @@ public abstract class BinaryFieldAccessor {
break;
+ case BINARY_ENUM:
+ val = reader.readBinaryEnum(id);
+
+ break;
+
case BINARY:
case OBJECT:
val = reader.readObject(id);
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
index a8b7fcb..ead00b7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
@@ -27,9 +27,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
+
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +44,9 @@ public class BinaryMetadata implements Externalizable {
/** */
private static final long serialVersionUID = 0L;
+ /** */
+ private static final int VERSION = 1;
+
/** Type ID. */
@GridToStringInclude(sensitive = true)
private int typeId;
@@ -67,6 +73,12 @@ public class BinaryMetadata implements Externalizable {
/** Whether this is enum type. */
private boolean isEnum;
+ /** Enum name to ordinal mapping. */
+ private Map<String, Integer> nameToOrdinal;
+
+ /** Enum ordinal to name mapping. */
+ private Map<Integer, String> ordinalToName;
+
/**
* For {@link Externalizable}.
*/
@@ -83,9 +95,11 @@ public class BinaryMetadata implements Externalizable {
* @param affKeyFieldName Affinity key field name.
* @param schemas Schemas.
* @param isEnum Enum flag.
+ * @param enumMap Enum name to ordinal mapping.
*/
public BinaryMetadata(int typeId, String typeName, @Nullable Map<String, BinaryFieldMetadata> fields,
- @Nullable String affKeyFieldName, @Nullable Collection<BinarySchema> schemas, boolean isEnum) {
+ @Nullable String affKeyFieldName, @Nullable Collection<BinarySchema> schemas, boolean isEnum,
+ @Nullable Map<String, Integer> enumMap) {
assert typeName != null;
this.typeId = typeId;
@@ -104,6 +118,15 @@ public class BinaryMetadata implements Externalizable {
schemaIds = Collections.emptySet();
this.isEnum = isEnum;
+
+ if (enumMap != null) {
+ this.nameToOrdinal = new LinkedHashMap<>(enumMap);
+
+ this.ordinalToName = new LinkedHashMap<>(enumMap.size());
+
+ for (Map.Entry<String, Integer> e: nameToOrdinal.entrySet())
+ this.ordinalToName.put(e.getValue(), e.getKey());
+ }
}
/**
@@ -197,6 +220,7 @@ public class BinaryMetadata implements Externalizable {
* @exception IOException Includes any I/O exceptions that may occur.
*/
public void writeTo(DataOutput out) throws IOException {
+ out.writeByte(VERSION);
out.writeInt(typeId);
U.writeString(out, typeName);
@@ -224,6 +248,18 @@ public class BinaryMetadata implements Externalizable {
}
out.writeBoolean(isEnum);
+
+ if (isEnum) {
+ Map<String, Integer> map = enumMap();
+
+ out.writeInt(map.size());
+
+ for (Map.Entry<String, Integer> e : map.entrySet()) {
+ U.writeString(out, e.getKey());
+
+ out.writeInt(e.getValue());
+ }
+ }
}
/** {@inheritDoc} */
@@ -242,6 +278,8 @@ public class BinaryMetadata implements Externalizable {
* @exception IOException if I/O errors occur.
*/
public void readFrom(DataInput in) throws IOException {
+ in.readByte(); //skip version
+
typeId = in.readInt();
typeName = U.readString(in);
@@ -285,6 +323,59 @@ public class BinaryMetadata implements Externalizable {
}
isEnum = in.readBoolean();
+
+ if (isEnum) {
+ int size = in.readInt();
+
+ if (size >= 0) {
+ ordinalToName = new LinkedHashMap<>(size);
+ nameToOrdinal = new LinkedHashMap<>(size);
+
+ for (int idx = 0; idx < size; idx++) {
+ String name = U.readString(in);
+
+ int ord = in.readInt();
+
+ ordinalToName.put(ord, name);
+ nameToOrdinal.put(name, ord);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets enum constant name given its ordinal value.
+ *
+ * @param ord Enum constant ordinal value.
+ * @return Enum constant name.
+ */
+ public String getEnumNameByOrdinal(int ord) {
+ if (ordinalToName == null)
+ return null;
+
+ return ordinalToName.get(ord);
+ }
+
+ /**
+ * Gets enum constant ordinal value given its name.
+ *
+ * @param name Enum constant name.
+ * @return Enum constant ordinal value.
+ */
+ public Integer getEnumOrdinalByName(String name) {
+ assert name != null;
+
+ return nameToOrdinal.get(name);
+ }
+
+ /**
+ * @return Name to ordinal mapping.
+ */
+ public Map<String, Integer> enumMap() {
+ if (nameToOrdinal == null)
+ return Collections.emptyMap();
+
+ return nameToOrdinal;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
index 748a283..e565338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
@@ -43,6 +43,15 @@ public interface BinaryMetadataHandler {
public BinaryType metadata(int typeId) throws BinaryObjectException;
/**
+ * Gets unwrapped meta data for provided type ID.
+ *
+ * @param typeId Type ID.
+ * @return Metadata.
+ * @throws BinaryObjectException In case of error.
+ */
+ public BinaryMetadata metadata0(int typeId) throws BinaryObjectException;
+
+ /**
* Gets metadata for provided type ID and schema ID.
*
* @param typeId Type ID.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
index 770d9c8..39c942a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
@@ -52,6 +52,11 @@ public class BinaryNoopMetadataHandler implements BinaryMetadataHandler {
}
/** {@inheritDoc} */
+ @Override public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+ return null;
+ }
+
+ /** {@inheritDoc} */
@Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
index ae9a160..b5e066b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
@@ -77,6 +77,11 @@ public abstract class BinaryObjectExImpl implements BinaryObjectEx {
throw new BinaryObjectException("Object is not enum.");
}
+ /** {@inheritDoc} */
+ @Override public String enumName() throws BinaryObjectException {
+ throw new BinaryObjectException("Object is not enum.");
+ }
+
/**
* Get offset of data begin.
*
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
index c8ca803..2b7964c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
@@ -41,6 +41,7 @@ import org.apache.ignite.internal.util.typedef.internal.SB;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BINARY_ENUM;
import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BINARY_OBJ;
import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BOOLEAN;
import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BOOLEAN_ARR;
@@ -1426,6 +1427,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
/**
* @param fieldId Field ID.
+ * @return Binary Enum
+ * @throws BinaryObjectException If failed.
+ */
+ @Nullable BinaryEnumObjectImpl readBinaryEnum(int fieldId) throws BinaryObjectException {
+ return findFieldById(fieldId) ? BinaryUtils.doReadBinaryEnum(in, ctx) : null;
+ }
+
+ /**
+ * @param fieldId Field ID.
* @param cls Class.
* @return Value.
* @throws BinaryObjectException In case of error.
@@ -1930,6 +1940,14 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
break;
+ case BINARY_ENUM:
+ obj = BinaryUtils.doReadBinaryEnum(in, ctx);
+
+ if (!GridBinaryMarshaller.KEEP_BINARIES.get())
+ obj = ((BinaryObject)obj).deserialize();
+
+ break;
+
case CLASS:
obj = BinaryUtils.doReadClass(in, ctx, ldr);
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
index 132702c..fac1ff9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
@@ -17,9 +17,12 @@
package org.apache.ignite.internal.binary;
+import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryType;
+import java.util.ArrayList;
import java.util.Collection;
+
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -80,6 +83,18 @@ public class BinaryTypeImpl implements BinaryType {
return meta.isEnum();
}
+ /** {@inheritDoc} */
+ @Override public Collection<BinaryObject> enumValues() {
+ Collection<Integer> ordinals = meta.enumMap().values();
+
+ ArrayList<BinaryObject> enumValues = new ArrayList<>(ordinals.size());
+
+ for (Integer ord: ordinals)
+ enumValues.add(new BinaryEnumObjectImpl(ctx, typeId(), typeName(), ord));
+
+ return enumValues;
+ }
+
/**
* @return Context.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
index df9901e..3a51050 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.binary;
import org.apache.ignite.binary.BinaryField;
+import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryType;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -92,6 +93,11 @@ public class BinaryTypeProxy implements BinaryType {
return target().isEnum();
}
+ /** {@inheritDoc} */
+ @Override public Collection<BinaryObject> enumValues() {
+ return target().enumValues();
+ }
+
/**
* @return Target type.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index f36c137..00b15da 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -266,6 +266,7 @@ public class BinaryUtils {
FIELD_TYPE_NAMES[GridBinaryMarshaller.TIME_ARR] = "Time[]";
FIELD_TYPE_NAMES[GridBinaryMarshaller.OBJ_ARR] = "Object[]";
FIELD_TYPE_NAMES[GridBinaryMarshaller.ENUM_ARR] = "Enum[]";
+ FIELD_TYPE_NAMES[GridBinaryMarshaller.BINARY_ENUM] = "Enum";
if (wrapTrees()) {
CLS_TO_WRITE_REPLACER.put(TreeMap.class, new BinaryTreeMapWriteReplacer());
@@ -975,6 +976,14 @@ public class BinaryUtils {
boolean changed = false;
+ Map<String, Integer> mergedEnumMap = null;
+
+ if (!F.isEmpty(newMeta.enumMap())) {
+ mergedEnumMap = mergeEnumValues(oldMeta.typeName(), oldMeta.enumMap(), newMeta.enumMap());
+
+ changed = mergedEnumMap.size() > oldMeta.enumMap().size();
+ }
+
for (Map.Entry<String, BinaryFieldMetadata> newField : newFields.entrySet()) {
BinaryFieldMetadata oldFieldMeta = mergedFields.put(newField.getKey(), newField.getValue());
@@ -1005,7 +1014,7 @@ public class BinaryUtils {
// Return either old meta if no changes detected, or new merged meta.
return changed ? new BinaryMetadata(oldMeta.typeId(), oldMeta.typeName(), mergedFields,
- oldMeta.affinityKeyFieldName(), mergedSchemas, oldMeta.isEnum()) : oldMeta;
+ oldMeta.affinityKeyFieldName(), mergedSchemas, oldMeta.isEnum(), mergedEnumMap) : oldMeta;
}
}
@@ -1106,6 +1115,8 @@ public class BinaryUtils {
return BinaryWriteMode.MAP;
else if (cls.isEnum())
return BinaryWriteMode.ENUM;
+ else if (cls == BinaryEnumObjectImpl.class)
+ return BinaryWriteMode.BINARY_ENUM;
else if (cls == Class.class)
return BinaryWriteMode.CLASS;
else if (Proxy.class.isAssignableFrom(cls))
@@ -1627,6 +1638,17 @@ public class BinaryUtils {
*
* @param in Input stream.
* @param ctx Binary context.
+ * @return Enum.
+ */
+ public static BinaryEnumObjectImpl doReadBinaryEnum(BinaryInputStream in, BinaryContext ctx) {
+ return doReadBinaryEnum(in, ctx, doReadEnumType(in));
+ }
+
+ /**
+ * Read binary enum.
+ *
+ * @param in Input stream.
+ * @param ctx Binary context.
* @param type Plain type.
* @return Enum.
*/
@@ -1903,6 +1925,7 @@ public class BinaryUtils {
return doReadBinaryObject(in, ctx, detach);
case GridBinaryMarshaller.ENUM:
+ case GridBinaryMarshaller.BINARY_ENUM:
return doReadBinaryEnum(in, ctx, doReadEnumType(in));
case GridBinaryMarshaller.ENUM_ARR:
@@ -2356,6 +2379,85 @@ public class BinaryUtils {
}
/**
+ * Checks enum values mapping.
+ *
+ * @param typeName Name of the type.
+ * @param enumValues Enum name to ordinal mapping.
+ * @throws BinaryObjectException
+ */
+ public static void validateEnumValues(String typeName, @Nullable Map<String, Integer> enumValues)
+ throws BinaryObjectException {
+
+ if (enumValues == null)
+ return;
+
+ Map<Integer, String> tmpMap = new LinkedHashMap<>(enumValues.size());
+ for (Map.Entry<String, Integer> e: enumValues.entrySet()) {
+
+ String prevName = tmpMap.put(e.getValue(), e.getKey());
+
+ if (prevName != null)
+ throw new BinaryObjectException("Conflicting enum values. Name '" + e.getKey() +
+ "' uses ordinal value (" + e.getValue() +
+ ") that is also used for name '" + prevName +
+ "' [typeName='" + typeName + "']");
+ }
+ }
+
+ /**
+ * Merges enum value mappings and checks for conflicts.
+ *
+ * Possible conflicts:
+ * - same name is used for different ordinal values.
+ * - ordinal value is used more than once.
+ *
+ * @param typeName Name of the type.
+ * @param oldValues Old enum value mapping.
+ * @param newValues New enum value mapping.
+ * @throws BinaryObjectException in case of name or value conflict.
+ */
+ public static Map<String, Integer> mergeEnumValues(String typeName,
+ @Nullable Map<String, Integer> oldValues,
+ Map<String, Integer> newValues)
+ throws BinaryObjectException {
+
+ assert newValues != null;
+
+ int size = (oldValues != null) ? oldValues.size() + newValues.size() : newValues.size();
+
+ Map<Integer, String> revMap = new LinkedHashMap<>(size);
+ Map<String, Integer> mergedMap = new LinkedHashMap<>(size);
+
+ if (oldValues != null) {
+ //assuming that old values were validated earlier once.
+ for (Map.Entry<String, Integer> e : oldValues.entrySet()) {
+ revMap.put(e.getValue(), e.getKey());
+ mergedMap.put(e.getKey(), e.getValue());
+ }
+ }
+
+ for (Map.Entry<String, Integer> e: newValues.entrySet()) {
+ String prevName = revMap.put(e.getValue(), e.getKey());
+
+ if (prevName != null && !prevName.equals(e.getKey()))
+ throw new BinaryObjectException("Conflicting enum values. Name '" + e.getKey() +
+ "' uses ordinal value (" + e.getValue() +
+ ") that is also used for name '" + prevName +
+ "' [typeName='" + typeName + "']");
+
+ Integer prevVal = mergedMap.put(e.getKey(), e.getValue());
+
+ if (prevVal != null && !prevVal.equals(e.getValue()))
+ throw new BinaryObjectException("Conflicting enum values. Value (" + e.getValue() +
+ ") has name '" + e.getKey() +
+ "' that is also used for value '" + prevVal +
+ "' [typeName='" + typeName + "']");
+ }
+
+ return mergedMap;
+ }
+
+ /**
* Enum type.
*/
private static class EnumType {
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
index 7efe4b3..f2ba779 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
@@ -820,15 +820,23 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
int typeId = val.typeId();
- out.unsafeEnsure(1 + 4);
+ if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) {
+ out.unsafeEnsure(1 + 4 + 4);
- out.unsafeWriteByte(GridBinaryMarshaller.ENUM);
- out.unsafeWriteInt(typeId);
+ out.unsafeWriteByte(GridBinaryMarshaller.BINARY_ENUM);
+ out.unsafeWriteInt(typeId);
+ out.unsafeWriteInt(val.enumOrdinal());
+ }
+ else {
+ out.unsafeEnsure(1 + 4);
+
+ out.unsafeWriteByte(GridBinaryMarshaller.BINARY_ENUM);
+ out.unsafeWriteInt(typeId);
- if (typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
doWriteString(val.className());
- out.writeInt(val.enumOrdinal());
+ out.writeInt(val.enumOrdinal());
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
index d4b0ff4..291c638 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
@@ -153,6 +153,9 @@ public class GridBinaryMarshaller {
/** Time array. */
public static final byte TIME_ARR = 37;
+ /** Binary enum */
+ public static final byte BINARY_ENUM = 38;
+
/** */
public static final byte NULL = (byte)101;
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
index 6974176..b1a8da9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.binary.builder;
import java.util.Collection;
import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.internal.binary.BinaryMetadata;
@@ -115,7 +116,14 @@ class BinaryBuilderSerializer {
int typeId = writer.context().typeId(clsName);
String typeName = writer.context().userTypeName(clsName);
- BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true);
+ Object[] enumVals = val.getClass().getEnumConstants();
+
+ Map<String, Integer> enumMap = new LinkedHashMap<>(enumVals.length);
+
+ for (Object enumVal : enumVals)
+ enumMap.put(((Enum)enumVal).name(), ((Enum)enumVal).ordinal());
+
+ BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true, enumMap);
writer.context().updateMetadata(typeId, meta);
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
index 02e06fd..d6cd5ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
@@ -350,7 +350,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
BinarySchema curSchema = writer.currentSchema();
ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldsMeta,
- ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema), false));
+ ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema), false, null));
schemaReg.addSchema(curSchema.schemaId(), curSchema);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
index 1564ff3..4d285ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
@@ -59,10 +59,12 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor {
* @param affKeyFieldName Affinity key field name.
* @param fieldTypeIds Fields map.
* @param isEnum Enum flag.
+ * @param enumMap Enum name to ordinal mapping.
* @throws IgniteException In case of error.
*/
public void updateMetadata(int typeId, String typeName, @Nullable String affKeyFieldName,
- Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum) throws IgniteException;
+ Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum, @Nullable Map<String, Integer> enumMap)
+ throws IgniteException;
/**
* @param typeId Type ID.
@@ -102,6 +104,23 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor {
public BinaryObject buildEnum(String typeName, int ord) throws IgniteException;
/**
+ * @param typeName Type name.
+ * @param name Name.
+ * @return Enum object.
+ * @throws IgniteException If failed.
+ */
+ public BinaryObject buildEnum(String typeName, String name) throws IgniteException;
+
+ /**
+ * Register enum type
+ *
+ * @param typeName Type name.
+ * @param vals Mapping of enum constant names to ordinals.
+ * @return Binary Type for registered enum.
+ */
+ public BinaryType registerEnum(String typeName, Map<String, Integer> vals) throws IgniteException;
+
+ /**
* @return Binaries interface.
* @throws IgniteException If failed.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index 636d149..14947e9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -71,6 +71,7 @@ import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T1;
import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteClosure;
@@ -170,6 +171,10 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
return CacheObjectBinaryProcessorImpl.this.metadata(typeId);
}
+ @Override public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+ return CacheObjectBinaryProcessorImpl.this.metadata0(typeId);
+ }
+
@Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
return CacheObjectBinaryProcessorImpl.this.metadata(typeId, schemaId);
}
@@ -207,6 +212,9 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
c.isEnum()
)
);
+
+ if (c.isEnum())
+ BinaryUtils.validateEnumValues(c.getTypeName(), c.getEnumValues());
}
map.put("typeCfgs", typeCfgsMap);
@@ -399,8 +407,10 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
/** {@inheritDoc} */
@Override public void updateMetadata(int typeId, String typeName, @Nullable String affKeyFieldName,
- Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum) throws BinaryObjectException {
- BinaryMetadata meta = new BinaryMetadata(typeId, typeName, fieldTypeIds, affKeyFieldName, null, isEnum);
+ Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum, @Nullable Map<String, Integer> enumMap)
+ throws BinaryObjectException {
+ BinaryMetadata meta = new BinaryMetadata(typeId, typeName, fieldTypeIds, affKeyFieldName, null, isEnum,
+ enumMap);
binaryCtx.updateMetadata(typeId, meta);
}
@@ -433,6 +443,17 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
/** {@inheritDoc} */
@Nullable @Override public BinaryType metadata(final int typeId) {
+ BinaryMetadata meta = metadata0(typeId);
+
+ return meta != null ? meta.wrap(binaryCtx) : null;
+ }
+
+ /**
+ * @param typeId Type ID.
+ * @return Meta data.
+ * @throws IgniteException In case of error.
+ */
+ @Nullable public BinaryMetadata metadata0(final int typeId) {
BinaryMetadataHolder holder = metadataLocCache.get(typeId);
if (holder == null) {
@@ -466,7 +487,7 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
}
}
- return holder.metadata().wrap(binaryCtx);
+ return holder.metadata();
}
else
return null;
@@ -547,17 +568,58 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
}
/** {@inheritDoc} */
- @Override public BinaryObject buildEnum(String typeName, int ord) throws IgniteException {
+ @Override public BinaryObject buildEnum(String typeName, int ord) throws BinaryObjectException {
+ A.notNullOrEmpty(typeName, "enum type name");
+
int typeId = binaryCtx.typeId(typeName);
typeName = binaryCtx.userTypeName(typeName);
- updateMetadata(typeId, typeName, null, null, true);
+ updateMetadata(typeId, typeName, null, null, true, null);
return new BinaryEnumObjectImpl(binaryCtx, typeId, null, ord);
}
/** {@inheritDoc} */
+ @Override public BinaryObject buildEnum(String typeName, String name) throws BinaryObjectException {
+ A.notNullOrEmpty(typeName, "enum type name");
+ A.notNullOrEmpty(name, "enum name");
+
+ int typeId = binaryCtx.typeId(typeName);
+
+ BinaryMetadata metadata = metadata0(typeId);
+
+ if (metadata == null)
+ throw new BinaryObjectException("Failed to get metadata for type [typeId=" +
+ typeId + ", typeName='" + typeName + "']");
+
+ Integer ordinal = metadata.getEnumOrdinalByName(name);
+
+ typeName = binaryCtx.userTypeName(typeName);
+
+ if (ordinal == null)
+ throw new BinaryObjectException("Failed to resolve enum ordinal by name [typeId=" +
+ typeId + ", typeName='" + typeName + "', name='" + name + "']");
+
+ return new BinaryEnumObjectImpl(binaryCtx, typeId, null, ordinal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public BinaryType registerEnum(String typeName, Map<String, Integer> vals) throws BinaryObjectException {
+ A.notNullOrEmpty(typeName, "enum type name");
+
+ int typeId = binaryCtx.typeId(typeName);
+
+ typeName = binaryCtx.userTypeName(typeName);
+
+ BinaryUtils.validateEnumValues(typeName, vals);
+
+ updateMetadata(typeId, typeName, null, null, true, vals);
+
+ return binaryCtx.metadata(typeId);
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteBinary binary() throws IgniteException {
return binaries;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
index 1a2d0a9..e88819b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
@@ -18,6 +18,8 @@
package org.apache.ignite.internal.processors.cache.binary;
import java.util.Collection;
+import java.util.Map;
+
import org.apache.ignite.IgniteBinary;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
@@ -155,6 +157,30 @@ public class IgniteBinaryImpl implements IgniteBinary {
}
}
+ /** {@inheritDoc} */
+ @Override public BinaryObject buildEnum(String typeName, String name) {
+ guard();
+
+ try {
+ return proc.buildEnum(typeName, name);
+ }
+ finally {
+ unguard();
+ }
+ }
+
+ /** {@inheritDoc} */
+ public BinaryType registerEnum(String typeName, Map<String, Integer> vals) {
+ guard();
+
+ try {
+ return proc.registerEnum(typeName, vals);
+ }
+ finally {
+ unguard();
+ }
+ }
+
/**
* @return Binary processor.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
index c1c8fed..32c3be6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.processors.cacheobject;
import java.util.Collection;
+import java.util.Map;
+
import org.apache.ignite.IgniteBinary;
import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryObjectBuilder;
@@ -74,6 +76,16 @@ public class NoOpBinary implements IgniteBinary {
}
/** {@inheritDoc} */
+ @Override public BinaryObject buildEnum(String typeName, String name) {
+ throw unsupported();
+ }
+
+ /** {@inheritDoc} */
+ @Override public BinaryType registerEnum(String typeName, Map<String, Integer> vals) {
+ throw unsupported();
+ }
+
+ /** {@inheritDoc} */
private BinaryObjectException unsupported() {
return new BinaryObjectException("Binary marshaller is not configured.");
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
index 090f382..f115a9c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
@@ -82,6 +82,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -371,8 +372,19 @@ public class PlatformContextImpl implements PlatformContext {
}
});
+ Map<String, Integer> enumMap = null;
+
boolean isEnum = reader.readBoolean();
+ if (isEnum) {
+ int size = reader.readInt();
+
+ enumMap = new LinkedHashMap<>(size);
+
+ for (int idx = 0; idx < size; idx++)
+ enumMap.put(reader.readString(), reader.readInt());
+ }
+
// Read schemas
int schemaCnt = reader.readInt();
@@ -393,7 +405,7 @@ public class PlatformContextImpl implements PlatformContext {
}
}
- return new BinaryMetadata(typeId, typeName, fields, affKey, schemas, isEnum);
+ return new BinaryMetadata(typeId, typeName, fields, affKey, schemas, isEnum, enumMap);
}
}
);
@@ -474,7 +486,20 @@ public class PlatformContextImpl implements PlatformContext {
writer.writeInt(e.getValue().fieldId());
}
- writer.writeBoolean(meta.isEnum());
+ if (meta.isEnum()) {
+ writer.writeBoolean(true);
+
+ Map<String, Integer> enumMap = meta0.enumMap();
+
+ writer.writeInt(enumMap.size());
+
+ for (Map.Entry<String, Integer> e: enumMap.entrySet()) {
+ writer.writeString(e.getKey());
+ writer.writeInt(e.getValue());
+ }
+ }
+ else
+ writer.writeBoolean(false);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
index 8d95ac8..be43848 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
@@ -19,12 +19,16 @@ package org.apache.ignite.internal.processors.platform.binary;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryType;
import org.apache.ignite.internal.MarshallerPlatformIds;
import org.apache.ignite.internal.binary.BinaryRawReaderEx;
import org.apache.ignite.internal.binary.BinaryRawWriterEx;
import org.apache.ignite.internal.processors.platform.PlatformAbstractTarget;
import org.apache.ignite.internal.processors.platform.PlatformContext;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Platform binary processor.
*/
@@ -47,6 +51,9 @@ public class PlatformBinaryProcessor extends PlatformAbstractTarget {
/** */
private static final int OP_GET_TYPE = 6;
+ /** */
+ private static final int OP_REGISTER_ENUM = 7;
+
/**
* Constructor.
*
@@ -122,6 +129,24 @@ public class PlatformBinaryProcessor extends PlatformAbstractTarget {
break;
}
+ case OP_REGISTER_ENUM: {
+ String name = reader.readString();
+
+ int cnt = reader.readInt();
+
+ Map<String, Integer> vals = new HashMap<>(cnt);
+
+ for (int i = 0; i< cnt; i++) {
+ vals.put(reader.readString(), reader.readInt());
+ }
+
+ BinaryType binaryType = platformCtx.kernalContext().grid().binary().registerEnum(name, vals);
+
+ platformCtx.writeMetadata(writer, binaryType.typeId());
+
+ break;
+ }
+
default:
super.processInStreamOutStream(type, reader, writer);
break;
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
index a223022..fd26d4a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
@@ -19,10 +19,14 @@ package org.apache.ignite.internal.binary;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryTypeConfiguration;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.configuration.BinaryConfiguration;
@@ -31,7 +35,9 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
/**
@@ -42,6 +48,9 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
/** Cache name. */
private static String CACHE_NAME = "cache";
+ /** Name of the node that starts with bad config */
+ private static String WRONG_CONF_NODE_NAME = "WrongConfNode";
+
/** Whether to register types or not. */
private boolean register;
@@ -81,8 +90,20 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
BinaryConfiguration bCfg = new BinaryConfiguration();
BinaryTypeConfiguration enumCfg = new BinaryTypeConfiguration(EnumType.class.getName());
+
enumCfg.setEnum(true);
+ if (igniteInstanceName.equals(WRONG_CONF_NODE_NAME))
+ enumCfg.setEnumValues(F.asMap(EnumType.ONE.name(),
+ EnumType.ONE.ordinal(),
+ EnumType.TWO.name(),
+ EnumType.ONE.ordinal()));
+ else
+ enumCfg.setEnumValues(F.asMap(EnumType.ONE.name(),
+ EnumType.ONE.ordinal(),
+ EnumType.TWO.name(),
+ EnumType.TWO.ordinal()));
+
bCfg.setTypeConfigurations(Arrays.asList(enumCfg, new BinaryTypeConfiguration(EnumHolder.class.getName())));
cfg.setBinaryConfiguration(bCfg);
@@ -317,11 +338,14 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
public void checkSimpleBuilder(boolean registered) throws Exception {
startUp(registered);
- BinaryObject binary = node1.binary().buildEnum(EnumType.class.getName(), EnumType.ONE.ordinal());
+ BinaryObject binaryOne = node1.binary().buildEnum(EnumType.class.getName(), EnumType.ONE.ordinal());
+ BinaryObject binaryTwo = node1.binary().buildEnum(EnumType.class.getName(), EnumType.TWO.ordinal());
- cacheBinary1.put(1, binary);
+ cacheBinary1.put(EnumType.ONE.ordinal(), binaryOne);
+ cacheBinary1.put(EnumType.TWO.ordinal(), binaryTwo);
- validateSimple(1, EnumType.ONE, registered);
+ validateSimple(EnumType.ONE.ordinal(), EnumType.ONE, registered);
+ validateSimple(EnumType.TWO.ordinal(), EnumType.TWO, registered);
}
/**
@@ -409,6 +433,112 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
}
/**
+ * Checks ability to get a collection of binary enums from binary type
+ *
+ * @throws Exception
+ */
+ public void testBinaryTypeEnumValues() throws Exception {
+ startUp(false);
+
+ defineEnum();
+
+ BinaryObject binaryOne = node1.binary().buildEnum(EnumType.class.getName(), EnumType.ONE.ordinal());
+ BinaryObject binaryTwo = node1.binary().buildEnum(EnumType.class.getName(), EnumType.TWO.name());
+
+ Collection<BinaryObject> vals = binaryOne.type().enumValues();
+
+ assertEqualsCollections(F.asList(binaryOne, binaryTwo), vals);
+ }
+
+ /**
+ * Checks the enum configuration validation during start up
+ *
+ * @throws Exception
+ */
+ public void testEnumWrongBinaryConfig() throws Exception {
+ this.register = true;
+
+ GridTestUtils.assertThrows(log, new Callable<Object> (){
+ @Override public Object call() throws Exception {
+ startGrid(WRONG_CONF_NODE_NAME);
+
+ return null;
+ }
+ }, IgniteCheckedException.class, "Conflicting enum values");
+ }
+
+ /**
+ * Checks the enum validation during type registration
+ *
+ * @throws Exception
+ */
+ public void testEnumValidation() throws Exception {
+ startUp(false);
+
+ GridTestUtils.assertThrows(log, new Callable<Object> (){
+
+ @Override public Object call() throws Exception {
+
+ node1.binary().registerEnum("invalidEnumType1",
+ F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal(),
+ EnumType.TWO.name(), EnumType.ONE.ordinal()));
+
+ return null;
+ }
+ }, BinaryObjectException.class, "Conflicting enum values");
+ }
+
+ /**
+ * Checks the enum merge
+ *
+ * @throws Exception
+ */
+ public void testEnumMerge() throws Exception {
+ startUp(false);
+
+ final String enumName = "mergedEnum";
+
+ node1.binary().registerEnum(enumName,
+ F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal()));
+
+ GridTestUtils.assertThrows(log, new Callable<Object> (){
+
+ @Override public Object call() throws Exception {
+
+ node2.binary().registerEnum(enumName,
+ F.asMap(EnumType.TWO.name(), EnumType.ONE.ordinal()));
+
+ return null;
+ }
+ }, BinaryObjectException.class, "Conflicting enum values. Name ");
+
+ GridTestUtils.assertThrows(log, new Callable<Object> (){
+ @Override public Object call() throws Exception {
+
+ node2.binary().registerEnum(enumName,
+ F.asMap(EnumType.ONE.name(), EnumType.TWO.ordinal()));
+
+ return null;
+ }
+ }, BinaryObjectException.class, "Conflicting enum values. Value ");
+
+ node2.binary().registerEnum(enumName,
+ F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal(),
+ EnumType.TWO.name(), EnumType.TWO.ordinal()));
+
+ Collection<BinaryObject> vals = node1.binary().type(enumName).enumValues();
+ BinaryObject[] values = vals.toArray(new BinaryObject[vals.size()]);
+
+ assertEquals(2, values.length);
+
+ assertEquals(EnumType.ONE.ordinal(), values[0].enumOrdinal());
+ assertEquals(EnumType.TWO.ordinal(), values[1].enumOrdinal());
+
+ assertEquals(EnumType.ONE.name(), values[0].enumName());
+ assertEquals(EnumType.TWO.name(), values[1].enumName());
+ }
+
+ /**
* Validate simple array.
*
* @param registered Registered flag.
@@ -472,6 +602,16 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
assertEquals(node2.binary().typeId(EnumType.class.getName()), obj.type().typeId());
assertEquals(val.ordinal(), obj.enumOrdinal());
+
+ if (register)
+ assertEquals(val.name(), obj.enumName());
+ }
+
+ /** Register enum */
+ private void defineEnum() {
+ node1.binary().registerEnum(EnumType.class.getName(),
+ F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal(),
+ EnumType.TWO.name(), EnumType.TWO.ordinal()));
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
index 704c8f3..77cbffe 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
@@ -44,6 +44,11 @@ public class TestCachingMetadataHandler implements BinaryMetadataHandler {
}
/** {@inheritDoc} */
+ @Override public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+ return null;
+ }
+
+ /** {@inheritDoc} */
@Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
index a5a35c1..984cf62 100644
--- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
+++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
@@ -110,6 +110,9 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object>
/** Type: ignite uuid. */
private static final int TYPE_IGNITE_UUID = 22;
+ /** Type: binary enum. */
+ private static final int TYPE_BINARY_ENUM = 23;
+
/** Default cache name. */
public static final String DEFAULT_CACHE_NAME = "default";
@@ -228,6 +231,16 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object>
case TYPE_IGNITE_UUID:
return ignite.cache(DEFAULT_CACHE_NAME).get(TYPE_IGNITE_UUID);
+ case TYPE_BINARY_ENUM: {
+ Map<String, Integer> values = new HashMap<>(2);
+ values.put("JavaFoo", 1);
+ values.put("JavaBar", 2);
+
+ ignite.binary().registerEnum("JavaDynEnum", values);
+
+ return ignite.binary().buildEnum("JavaDynEnum", "JavaFoo");
+ }
+
default:
throw new IgniteException("Unknown type: " + type);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
index a7794c6..61f90a3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
@@ -1140,6 +1140,9 @@ namespace Apache.Ignite.Core.Tests.Binary
Assert.AreEqual(new[] { TestEnum.Two }, obj.FEnumArr);
}
+ /// <summary>
+ /// Tests the enum metadata.
+ /// </summary>
[Test]
public void TestEnumMeta()
{
@@ -1148,14 +1151,21 @@ namespace Apache.Ignite.Core.Tests.Binary
// Put to cache to populate metas
var binEnum = bin.ToBinary<IBinaryObject>(TestEnumRegistered.One);
- Assert.AreEqual(_marsh.GetDescriptor(typeof (TestEnumRegistered)).TypeId, binEnum.GetBinaryType().TypeId);
+ Assert.AreEqual(_marsh.GetDescriptor(typeof(TestEnumRegistered)).TypeId, binEnum.GetBinaryType().TypeId);
Assert.AreEqual(0, binEnum.EnumValue);
+ Assert.AreEqual("One", binEnum.EnumName);
var meta = binEnum.GetBinaryType();
Assert.IsTrue(meta.IsEnum);
- Assert.AreEqual(GetTypeName(typeof (TestEnumRegistered)), meta.TypeName);
+ Assert.AreEqual(GetTypeName(typeof(TestEnumRegistered)), meta.TypeName);
Assert.AreEqual(0, meta.Fields.Count);
+
+ var enumValues = meta.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+ Assert.AreEqual(0, enumValues[0].EnumValue);
+ Assert.AreEqual("One", enumValues[0].EnumName);
+ Assert.AreEqual(1, enumValues[1].EnumValue);
+ Assert.AreEqual("Two", enumValues[1].EnumName);
}
/// <summary>
@@ -1653,26 +1663,30 @@ namespace Apache.Ignite.Core.Tests.Binary
{
var binary = _grid.GetBinary();
- int val = (int)TestEnumRegistered.Two;
+ var enumVal = TestEnumRegistered.Two;
+ var intVal = (int) enumVal;
var typeName = GetTypeName(typeof(TestEnumRegistered));
var typeId = BinaryUtils.GetStringHashCode(typeName);
var binEnums = new[]
{
- binary.BuildEnum(typeof (TestEnumRegistered), val),
- binary.BuildEnum(typeName, val)
+ binary.BuildEnum(typeof (TestEnumRegistered), intVal),
+ binary.BuildEnum(typeName, intVal),
+ binary.BuildEnum(typeof (TestEnumRegistered), enumVal.ToString()),
+ binary.BuildEnum(typeName, enumVal.ToString())
};
foreach (var binEnum in binEnums)
{
Assert.IsTrue(binEnum.GetBinaryType().IsEnum);
- Assert.AreEqual(val, binEnum.EnumValue);
+ Assert.AreEqual(intVal, binEnum.EnumValue);
+ Assert.AreEqual(enumVal.ToString(), binEnum.EnumName);
Assert.AreEqual(string.Format("{0} [typeId={1}, enumValue={2}, enumValueName={3}]",
- typeName, typeId, val, (TestEnumRegistered) val), binEnum.ToString());
+ typeName, typeId, intVal, enumVal), binEnum.ToString());
- Assert.AreEqual((TestEnumRegistered)val, binEnum.Deserialize<TestEnumRegistered>());
+ Assert.AreEqual(enumVal, binEnum.Deserialize<TestEnumRegistered>());
}
Assert.AreEqual(binEnums[0], binEnums[1]);
@@ -1687,6 +1701,60 @@ namespace Apache.Ignite.Core.Tests.Binary
}
/// <summary>
+ /// Tests enum registration.
+ /// </summary>
+ [Test]
+ public void TestRegisterEnum()
+ {
+ var binary = _grid.GetBinary();
+
+ // Register enum and verify resulting type.
+ const string typeName = "DotNetDynEnum";
+ var binType = binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Baz", 3}, {"Bar", 4}});
+
+ Assert.AreEqual(typeName, binType.TypeName);
+ Assert.IsTrue(binType.IsEnum);
+
+ var enumFields = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+ Assert.AreEqual(new[] {3, 4}, enumFields.Select(x => x.EnumValue));
+ Assert.AreEqual(new[] {"Baz", "Bar"}, enumFields.Select(x => x.EnumName));
+
+ // Build enum values.
+ var binEnum1 = binary.BuildEnum(typeName, 3);
+ var binEnum2 = binary.BuildEnum(typeName, "Baz");
+
+ Assert.AreEqual(binEnum1, binEnum2);
+ Assert.AreEqual("Baz", binEnum1.EnumName);
+ Assert.AreEqual(3, binEnum2.EnumValue);
+
+ // Register additional value explicitly.
+ binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Foo", 6}});
+ binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Foo", 6}, {"Baz", 3}});
+ binType = binary.GetBinaryType(typeName);
+
+ Assert.AreEqual(typeName, binType.TypeName);
+ Assert.IsTrue(binType.IsEnum);
+
+ enumFields = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+ Assert.AreEqual(new[] { 3, 4, 6 }, enumFields.Select(x => x.EnumValue));
+ Assert.AreEqual(new[] { "Baz", "Bar", "Foo" }, enumFields.Select(x => x.EnumName));
+
+ // Register existing value with different name.
+ var ex = Assert.Throws<BinaryObjectException>(
+ () => binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Baz1", 3}}));
+
+ Assert.AreEqual(string.Format("Conflicting enum values. Name 'Baz1' uses ordinal value (3) that " +
+ "is also used for name 'Baz' [typeName='{0}']", typeName), ex.Message);
+
+ // Register different value with existing name.
+ ex = Assert.Throws<BinaryObjectException>(
+ () => binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Baz", 33}}));
+
+ Assert.AreEqual(string.Format("Conflicting enum values. Value (33) has name 'Baz' that is " +
+ "also used for value '3' [typeName='{0}']", typeName), ex.Message);
+ }
+
+ /// <summary>
/// Tests the compact footer setting.
/// </summary>
[Test]
@@ -2102,13 +2170,13 @@ namespace Apache.Ignite.Core.Tests.Binary
/** <inheritdoc /> */
public int GetTypeId(string typeName)
{
- return typeName == TestTypeName ? TestTypeId : 0;
+ return typeName == TestTypeName ? TestTypeId : BinaryUtils.GetStringHashCode(typeName);
}
/** <inheritdoc /> */
public int GetFieldId(int typeId, string fieldName)
{
- return 0;
+ return BinaryUtils.GetStringHashCode(fieldName);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
index b9b7a04..1d8ceb9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -122,6 +122,9 @@ namespace Apache.Ignite.Core.Tests.Compute
/** Echo type: IgniteUuid. */
private const int EchoTypeIgniteUuid = 22;
+ /** Echo type: binary enum (created with builder). */
+ private const int EchoTypeBinaryEnum = 23;
+
/** */
private const string DefaultCacheName = "default";
@@ -940,6 +943,28 @@ namespace Apache.Ignite.Core.Tests.Compute
/// Tests the echo task returning enum.
/// </summary>
[Test]
+ public void TestEchoTaskBinaryEnum()
+ {
+ var res = _grid1.GetCompute().WithKeepBinary()
+ .ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinaryEnum);
+
+ Assert.AreEqual("JavaFoo", res.EnumName);
+ Assert.AreEqual(1, res.EnumValue);
+
+ var binType = res.GetBinaryType();
+
+ Assert.IsTrue(binType.IsEnum);
+ Assert.AreEqual("JavaDynEnum", binType.TypeName);
+
+ var vals = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+ Assert.AreEqual(new[] {1, 2}, vals.Select(x => x.EnumValue));
+ Assert.AreEqual(new[] {"JavaFoo", "JavaBar"}, vals.Select(x => x.EnumName));
+ }
+
+ /// <summary>
+ /// Tests the echo task returning enum.
+ /// </summary>
+ [Test]
public void TestEchoTaskEnumFromCache()
{
var cache = _grid1.GetCache<int, PlatformComputeEnum>(DefaultCacheName);
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
index c36b9fd..2d299f3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
@@ -18,6 +18,7 @@
namespace Apache.Ignite.Core.Binary
{
using System;
+ using Apache.Ignite.Core.Impl.Binary;
using Apache.Ignite.Core.Impl.Common;
/// <summary>
@@ -51,7 +52,7 @@ namespace Apache.Ignite.Core.Binary
IgniteArgumentCheck.NotNull(type, "type");
TypeName = type.AssemblyQualifiedName;
- IsEnum = type.IsEnum;
+ IsEnum = BinaryUtils.IsIgniteEnum(type);
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
index f269681..671efa4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
@@ -131,5 +131,29 @@ namespace Apache.Ignite.Core.Binary
/// <param name="value">Enum int value.</param>
/// <returns>Binary representation of the specified enum value.</returns>
IBinaryObject BuildEnum(Type type, int value);
+
+ /// <summary>
+ /// Converts enum to a binary form.
+ /// </summary>
+ /// <param name="typeName">Enum type name.</param>
+ /// <param name="valueName">Enum value name.</param>
+ /// <returns>Binary representation of the specified enum value.</returns>
+ IBinaryObject BuildEnum(string typeName, string valueName);
+
+ /// <summary>
+ /// Converts enum to a binary form.
+ /// </summary>
+ /// <param name="type">Enum type.</param>
+ /// <param name="valueName">Enum value name.</param>
+ /// <returns>Binary representation of the specified enum value.</returns>
+ IBinaryObject BuildEnum(Type type, string valueName);
+
+ /// <summary>
+ /// Registers enum type.
+ /// </summary>
+ /// <param name="typeName">Name of the type.</param>
+ /// <param name="values">Mapping of enum value names to int values.</param>
+ /// <returns>Binary type for registered enum.</returns>
+ IBinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values);
}
}