You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/29 07:18:35 UTC
[19/30] ignite git commit: IGNITE-4575: Improved binary enums
support. This closes #1968.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
index 841972d..7ab69e9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
@@ -65,6 +65,14 @@ namespace Apache.Ignite.Core.Binary
int EnumValue { get; }
/// <summary>
+ /// Gets the name of the underlying enum value.
+ /// </summary>
+ /// <value>
+ /// The name of the enum value.
+ /// </value>
+ string EnumName { get; }
+
+ /// <summary>
/// Creates a new <see cref="IBinaryObjectBuilder"/> based on this object.
/// <para />
/// This is equivalent to <see cref="IBinary.GetBuilder(IBinaryObject)"/>.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
index bec863f..df6693d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
@@ -61,5 +61,11 @@ namespace Apache.Ignite.Core.Binary
/// Gets the type identifier.
/// </summary>
int TypeId { get; }
+
+ /// <summary>
+ /// Gets the enum values.
+ /// Only valid when <see cref="IsEnum"/> is true.
+ /// </summary>
+ IEnumerable<IBinaryObject> GetEnumValues();
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
index 4f3156c..bcf6c2d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
@@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Impl.Binary
{
using System;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.IO;
using Apache.Ignite.Core.Binary;
using Apache.Ignite.Core.Common;
@@ -165,7 +166,8 @@ namespace Apache.Ignite.Core.Impl.Binary
public IBinaryObject BuildEnum(Type type, int value)
{
IgniteArgumentCheck.NotNull(type, "type");
- IgniteArgumentCheck.Ensure(type.IsEnum, "type", "Type should be an Enum.");
+ IgniteArgumentCheck.Ensure(BinaryUtils.IsIgniteEnum(type), "type",
+ "Type should be an Enum.");
var desc = Marshaller.GetDescriptor(type);
@@ -176,15 +178,53 @@ namespace Apache.Ignite.Core.Impl.Binary
return new BinaryEnum(desc.TypeId, value, Marshaller);
}
+ /** <inheritDoc /> */
+ public IBinaryObject BuildEnum(string typeName, string valueName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+ IgniteArgumentCheck.NotNullOrEmpty(valueName, "valueName");
+
+ var desc = Marshaller.GetDescriptor(typeName);
+
+ IgniteArgumentCheck.Ensure(desc.IsEnum, "typeName", "Type should be an Enum.");
+
+ _marsh.PutBinaryType(desc);
+
+ var value = GetEnumValueAsInt(typeName, valueName, desc);
+
+ return new BinaryEnum(desc.TypeId, value, Marshaller);
+ }
+
+ /** <inheritDoc /> */
+ public IBinaryObject BuildEnum(Type type, string valueName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(valueName, "valueName");
+
+ var desc = Marshaller.GetDescriptor(type);
+
+ IgniteArgumentCheck.Ensure(desc.IsEnum, "typeName", "Type should be an Enum.");
+
+ _marsh.PutBinaryType(desc);
+
+ var value = GetEnumValueAsInt(type.ToString(), valueName, desc);
+
+ return new BinaryEnum(desc.TypeId, value, Marshaller);
+ }
+
+ /** <inheritDoc /> */
+ public IBinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+ return Marshaller.Ignite.BinaryProcessor.RegisterEnum(typeName, values);
+ }
+
/// <summary>
/// Marshaller.
/// </summary>
internal Marshaller Marshaller
{
- get
- {
- return _marsh;
- }
+ get { return _marsh; }
}
/// <summary>
@@ -199,5 +239,22 @@ namespace Apache.Ignite.Core.Impl.Binary
{
return new BinaryObjectBuilder(this, parent, obj, desc);
}
+
+ /// <summary>
+ /// Gets the enum value as int.
+ /// </summary>
+ private int GetEnumValueAsInt(string typeName, string valueName, IBinaryTypeDescriptor desc)
+ {
+ var type = Marshaller.GetBinaryType(desc.TypeId);
+
+ var value = type.GetEnumValue(valueName);
+
+ IgniteArgumentCheck.Ensure(value != null, "valueName",
+ string.Format("Enum '{0}' does not have a value {1}", typeName, valueName));
+
+ Debug.Assert(value.HasValue);
+
+ return value.Value;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
index 710cf17..2bc4bdf 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
@@ -88,6 +88,12 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/** <inheritdoc /> */
+ public string EnumName
+ {
+ get { return _marsh.GetBinaryType(_typeId).GetEnumName(_enumValue); }
+ }
+
+ /** <inheritdoc /> */
public IBinaryObjectBuilder ToBuilder()
{
throw new NotSupportedException("Builder cannot be created for enum.");
@@ -136,11 +142,8 @@ namespace Apache.Ignite.Core.Impl.Binary
return string.Format("BinaryEnum [typeId={0}, enumValue={1}]", _typeId, _enumValue);
}
- var desc = _marsh.GetDescriptor(true, _typeId);
- var enumValueName = desc != null && desc.Type != null ? Enum.GetName(desc.Type, _enumValue) : null;
-
return string.Format("{0} [typeId={1}, enumValue={2}, enumValueName={3}]",
- meta.TypeName, _typeId, _enumValue, enumValueName);
+ meta.TypeName, _typeId, _enumValue, EnumName);
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
index 480e0e6..8c5cee6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
@@ -131,7 +131,18 @@ namespace Apache.Ignite.Core.Impl.Binary
{
get
{
- throw new NotSupportedException("IBinaryObject.Value is only supported for enums. " +
+ throw new NotSupportedException("IBinaryObject.EnumValue is only supported for enums. " +
+ "Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value.");
+ }
+ }
+
+ /** <inheritdoc /> */
+ [ExcludeFromCodeCoverage]
+ public string EnumName
+ {
+ get
+ {
+ throw new NotSupportedException("IBinaryObject.EnumName is only supported for enums. " +
"Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value.");
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
index 72a1d5b..f48bcc0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
@@ -24,7 +24,7 @@ namespace Apache.Ignite.Core.Impl.Binary
using Apache.Ignite.Core.Impl.Unmanaged;
/// <summary>
- /// Binary metadata processor.
+ /// Binary metadata processor, delegates to PlatformBinaryProcessor in Java.
/// </summary>
internal class BinaryProcessor : PlatformTarget
{
@@ -38,7 +38,8 @@ namespace Apache.Ignite.Core.Impl.Binary
PutMeta = 3,
GetSchema = 4,
RegisterType = 5,
- GetType = 6
+ GetType = 6,
+ RegisterEnum = 7
}
/// <summary>
@@ -54,9 +55,9 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <summary>
/// Gets metadata for specified type.
/// </summary>
- public IBinaryType GetBinaryType(int typeId)
+ public BinaryType GetBinaryType(int typeId)
{
- return DoOutInOp<IBinaryType>((int) Op.GetMeta,
+ return DoOutInOp((int) Op.GetMeta,
writer => writer.WriteInt(typeId),
stream =>
{
@@ -126,8 +127,27 @@ namespace Apache.Ignite.Core.Impl.Binary
w.WriteInt(field.Value.FieldId);
}
+ // Enum data
w.WriteBoolean(meta.IsEnum);
+ if (meta.IsEnum)
+ {
+ if (meta.EnumValuesMap != null)
+ {
+ w.WriteInt(meta.EnumValuesMap.Count);
+
+ foreach (var pair in meta.EnumValuesMap)
+ {
+ w.WriteString(pair.Key);
+ w.WriteInt(pair.Value);
+ }
+ }
+ else
+ {
+ w.WriteInt(0);
+ }
+ }
+
// Send schemas
var desc = meta.Descriptor;
Debug.Assert(desc != null);
@@ -175,6 +195,43 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/// <summary>
+ /// Registers the enum.
+ /// </summary>
+ /// <param name="typeName">Name of the type.</param>
+ /// <param name="values">The values.</param>
+ /// <returns>Resulting binary type.</returns>
+ public BinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values)
+ {
+ Debug.Assert(typeName != null);
+
+ return DoOutInOp((int) Op.RegisterEnum, w =>
+ {
+ w.WriteString(typeName);
+
+ if (values == null)
+ {
+ w.WriteInt(0);
+ }
+ else
+ {
+ var countPos = w.Stream.Position;
+ w.WriteInt(0);
+ var count = 0;
+
+ foreach (var enumPair in values)
+ {
+ w.WriteString(enumPair.Key);
+ w.WriteInt(enumPair.Value);
+
+ count++;
+ }
+
+ w.Stream.WriteInt(countPos, count);
+ }
+ }, s => s.ReadBool() ? new BinaryType(Marshaller.StartUnmarshal(s)) : null);
+ }
+
+ /// <summary>
/// Gets the type by id.
/// </summary>
/// <param name="id">The identifier.</param>
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
index a5c6814..73a0456 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
@@ -401,6 +401,7 @@ namespace Apache.Ignite.Core.Impl.Binary
return default(T);
case BinaryUtils.TypeEnum:
+ case BinaryUtils.TypeBinaryEnum:
// Never read enums in binary mode when reading a field (we do not support half-binary objects)
return ReadEnum0<T>(this, false);
@@ -411,9 +412,9 @@ namespace Apache.Ignite.Core.Impl.Binary
return ReadObject<T>();
default:
- throw new BinaryObjectException(
- string.Format("Invalid header on enum deserialization. Expected: {0} or {1} but was: {2}",
- BinaryUtils.TypeEnum, BinaryUtils.HdrFull, hdr));
+ throw new BinaryObjectException(string.Format(
+ "Invalid header on enum deserialization. Expected: {0} or {1} or {2} but was: {3}",
+ BinaryUtils.TypeEnum, BinaryUtils.TypeBinaryEnum, BinaryUtils.HdrFull, hdr));
}
}
@@ -571,6 +572,7 @@ namespace Apache.Ignite.Core.Impl.Binary
return true;
case BinaryUtils.TypeEnum:
+ case BinaryUtils.TypeBinaryEnum:
res = ReadEnum0<T>(this, _mode != BinaryMode.Deserialize);
return true;
@@ -994,7 +996,9 @@ namespace Apache.Ignite.Core.Impl.Binary
var enumValue = reader.ReadInt();
if (!keepBinary)
+ {
return BinaryUtils.GetEnumValue<T>(enumValue, enumType, reader.Marshaller);
+ }
return TypeCaster<T>.Cast(new BinaryEnum(enumType, enumValue, reader.Marshaller));
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
index 1dfc3b6..95a0be3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
@@ -255,7 +255,7 @@ namespace Apache.Ignite.Core.Impl.Binary
if (elemType == typeof(Guid?))
return new BinarySystemWriteHandler<Guid?[]>(WriteGuidArray, true);
// Enums.
- if (IsIntEnum(elemType) || elemType == typeof(BinaryEnum))
+ if (BinaryUtils.IsIgniteEnum(elemType) || elemType == typeof(BinaryEnum))
return new BinarySystemWriteHandler<object>(WriteEnumArray, true);
// Object array.
@@ -266,23 +266,6 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/// <summary>
- /// Determines whether specified type is an enum which fits into Int32.
- /// </summary>
- private static bool IsIntEnum(Type type)
- {
- if (!type.IsEnum)
- return false;
-
- var underlyingType = Enum.GetUnderlyingType(type);
-
- return underlyingType == typeof(int)
- || underlyingType == typeof(short)
- || underlyingType == typeof(ushort)
- || underlyingType == typeof(byte)
- || underlyingType == typeof(sbyte);
- }
-
- /// <summary>
/// Find write handler for type.
/// </summary>
/// <param name="type">Type.</param>
@@ -294,10 +277,10 @@ namespace Apache.Ignite.Core.Impl.Binary
if (TypeIds.TryGetValue(type, out res))
return res;
- if (type.IsEnum)
+ if (BinaryUtils.IsIgniteEnum(type))
return BinaryUtils.TypeEnum;
- if (type.IsArray && type.GetElementType().IsEnum)
+ if (type.IsArray && BinaryUtils.IsIgniteEnum(type.GetElementType()))
return BinaryUtils.TypeArrayEnum;
return BinaryUtils.TypeObject;
@@ -545,7 +528,7 @@ namespace Apache.Ignite.Core.Impl.Binary
{
var binEnum = obj;
- ctx.Stream.WriteByte(BinaryUtils.TypeEnum);
+ ctx.Stream.WriteByte(BinaryUtils.TypeBinaryEnum);
ctx.WriteInt(binEnum.TypeId);
ctx.WriteInt(binEnum.EnumValue);
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
index a2783ba..2ac617e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -143,6 +143,9 @@ namespace Apache.Ignite.Core.Impl.Binary
/** Type: enum array. */
public const byte TypeArrayEnum = 29;
+ /** Type: binary enum. */
+ public const byte TypeBinaryEnum = 38;
+
/** Type: native job holder. */
public const byte TypeNativeJobHolder = 77;
@@ -1778,6 +1781,22 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/// <summary>
+ /// Determines whether specified type is Ignite-compatible enum (value fits into 4 bytes).
+ /// </summary>
+ public static bool IsIgniteEnum(Type type)
+ {
+ Debug.Assert(type != null);
+
+ if (!type.IsEnum)
+ return false;
+
+ var enumType = Enum.GetUnderlyingType(type);
+
+ return enumType == typeof(int) || enumType == typeof(byte) || enumType == typeof(sbyte)
+ || enumType == typeof(short) || enumType == typeof(ushort) || enumType == typeof(uint);
+ }
+
+ /// <summary>
/// Creates and instance from the type name in reader.
/// </summary>
private static T CreateInstance<T>(BinaryReader reader)
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
index 56774d4..a5fed48 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
@@ -1468,7 +1468,7 @@ namespace Apache.Ignite.Core.Impl.Binary
{
_metas = new Dictionary<int, BinaryType>(1)
{
- {desc.TypeId, new BinaryType(desc, fields)}
+ {desc.TypeId, new BinaryType(desc, _marsh, fields)}
};
}
else
@@ -1478,7 +1478,7 @@ namespace Apache.Ignite.Core.Impl.Binary
if (_metas.TryGetValue(desc.TypeId, out meta))
meta.UpdateFields(fields);
else
- _metas[desc.TypeId] = new BinaryType(desc, fields);
+ _metas[desc.TypeId] = new BinaryType(desc, _marsh, fields);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index ea2964a..8f12acf 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -97,13 +97,13 @@ namespace Apache.Ignite.Core.Impl.Binary
if (typeCfgs != null)
foreach (BinaryTypeConfiguration typeCfg in typeCfgs)
- AddUserType(cfg, typeCfg, typeResolver);
+ AddUserType(typeCfg, typeResolver);
var typeNames = _cfg.Types;
if (typeNames != null)
foreach (string typeName in typeNames)
- AddUserType(cfg, new BinaryTypeConfiguration(typeName), typeResolver);
+ AddUserType(new BinaryTypeConfiguration(typeName), typeResolver);
}
/// <summary>
@@ -289,14 +289,16 @@ namespace Apache.Ignite.Core.Impl.Binary
/// </summary>
/// <param name="typeId">Type ID.</param>
/// <returns>Metadata or null.</returns>
- public IBinaryType GetBinaryType(int typeId)
+ public BinaryType GetBinaryType(int typeId)
{
if (Ignite != null)
{
- IBinaryType meta = Ignite.BinaryProcessor.GetBinaryType(typeId);
+ var meta = Ignite.BinaryProcessor.GetBinaryType(typeId);
if (meta != null)
+ {
return meta;
+ }
}
return BinaryType.Empty;
@@ -314,7 +316,7 @@ namespace Apache.Ignite.Core.Impl.Binary
if (Ignite != null)
{
- ICollection<BinaryType> metas = new[] {new BinaryType(desc)};
+ ICollection<BinaryType> metas = new[] {new BinaryType(desc, this)};
Ignite.BinaryProcessor.PutBinaryTypes(metas);
}
}
@@ -337,7 +339,8 @@ namespace Apache.Ignite.Core.Impl.Binary
IDictionary<int, BinaryTypeHolder> metas0 =
new Dictionary<int, BinaryTypeHolder>(_metas);
- holder = new BinaryTypeHolder(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName, desc.IsEnum);
+ holder = new BinaryTypeHolder(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName,
+ desc.IsEnum, this);
metas0[desc.TypeId] = holder;
@@ -366,16 +369,7 @@ namespace Apache.Ignite.Core.Impl.Binary
{
foreach (var meta in newMetas)
{
- var mergeInfo = new Dictionary<int, Tuple<string, BinaryField>>(meta.GetFieldsMap().Count);
-
- foreach (var fieldMeta in meta.GetFieldsMap())
- {
- int fieldId = BinaryUtils.FieldId(meta.TypeId, fieldMeta.Key, null, null);
-
- mergeInfo[fieldId] = new Tuple<string, BinaryField>(fieldMeta.Key, fieldMeta.Value);
- }
-
- _metas[meta.TypeId].Merge(mergeInfo);
+ _metas[meta.TypeId].Merge(meta);
}
}
@@ -391,7 +385,9 @@ namespace Apache.Ignite.Core.Impl.Binary
BinaryFullTypeDescriptor desc;
if (!_typeToDesc.TryGetValue(type, out desc) || !desc.IsRegistered)
+ {
desc = RegisterType(type, desc);
+ }
return desc;
}
@@ -405,10 +401,14 @@ namespace Apache.Ignite.Core.Impl.Binary
{
BinaryFullTypeDescriptor desc;
- return _typeNameToDesc.TryGetValue(typeName, out desc)
- ? (IBinaryTypeDescriptor) desc
- : new BinarySurrogateTypeDescriptor(_cfg,
- GetTypeId(typeName, _cfg.IdMapper), typeName);
+ if (_typeNameToDesc.TryGetValue(typeName, out desc))
+ {
+ return desc;
+ }
+
+ var typeId = GetTypeId(typeName, _cfg.IdMapper);
+
+ return GetDescriptor(true, typeId, typeName: typeName);
}
/// <summary>
@@ -416,18 +416,18 @@ namespace Apache.Ignite.Core.Impl.Binary
/// </summary>
/// <param name="userType">User type flag.</param>
/// <param name="typeId">Type id.</param>
- /// <param name="requiresType">
- /// If set to true, resulting descriptor must have Type property populated.
+ /// <param name="requiresType">If set to true, resulting descriptor must have Type property populated.
/// <para />
/// When working in binary mode, we don't need Type. And there is no Type at all in some cases.
/// So we should not attempt to call BinaryProcessor right away.
/// Only when we really deserialize the value, requiresType is set to true
- /// and we attempt to resolve the type by all means.
- /// </param>
+ /// and we attempt to resolve the type by all means.</param>
+ /// <param name="typeName">Known type name.</param>
/// <returns>
/// Descriptor.
/// </returns>
- public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId, bool requiresType = false)
+ public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId, bool requiresType = false,
+ string typeName = null)
{
BinaryFullTypeDescriptor desc;
@@ -442,7 +442,7 @@ namespace Apache.Ignite.Core.Impl.Binary
if (requiresType && _ignite != null)
{
// Check marshaller context for dynamically registered type.
- var typeName = _ignite.BinaryProcessor.GetTypeName(typeId);
+ typeName = typeName ?? _ignite.BinaryProcessor.GetTypeName(typeId);
if (typeName != null)
{
@@ -460,15 +460,16 @@ namespace Apache.Ignite.Core.Impl.Binary
if (meta != BinaryType.Empty)
{
- desc = new BinaryFullTypeDescriptor(null, meta.TypeId, meta.TypeName, true, null, null, null, false,
- meta.AffinityKeyFieldName, meta.IsEnum);
-
- _idToDesc.GetOrAdd(typeKey, _ => desc);
+ var typeCfg = new BinaryTypeConfiguration(meta.TypeName)
+ {
+ IsEnum = meta.IsEnum,
+ AffinityKeyFieldName = meta.AffinityKeyFieldName
+ };
- return desc;
+ return AddUserType(typeCfg, new TypeResolver());
}
- return new BinarySurrogateTypeDescriptor(_cfg, typeId, null);
+ return new BinarySurrogateTypeDescriptor(_cfg, typeId, typeName);
}
/// <summary>
@@ -507,7 +508,7 @@ namespace Apache.Ignite.Core.Impl.Binary
desc = desc == null
? new BinaryFullTypeDescriptor(type, typeId, typeName, true, _cfg.NameMapper,
- _cfg.IdMapper, ser, false, null, type.IsEnum, registered)
+ _cfg.IdMapper, ser, false, null, BinaryUtils.IsIgniteEnum(type), registered)
: new BinaryFullTypeDescriptor(desc, type, ser, registered);
if (RegistrationDisabled)
@@ -540,11 +541,10 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <summary>
/// Add user type.
/// </summary>
- /// <param name="cfg">The binary configuration.</param>
/// <param name="typeCfg">Type configuration.</param>
/// <param name="typeResolver">The type resolver.</param>
/// <exception cref="BinaryObjectException"></exception>
- private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, TypeResolver typeResolver)
+ private BinaryFullTypeDescriptor AddUserType(BinaryTypeConfiguration typeCfg, TypeResolver typeResolver)
{
// Get converter/mapper/serializer.
IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? _cfg.NameMapper ?? GetDefaultNameMapper();
@@ -560,23 +560,23 @@ namespace Apache.Ignite.Core.Impl.Binary
{
ValidateUserType(type);
- if (typeCfg.IsEnum != type.IsEnum)
+ if (typeCfg.IsEnum != BinaryUtils.IsIgniteEnum(type))
{
throw new BinaryObjectException(
string.Format(
"Invalid IsEnum flag in binary type configuration. " +
- "Configuration value: IsEnum={0}, actual type: IsEnum={1}",
- typeCfg.IsEnum, type.IsEnum));
+ "Configuration value: IsEnum={0}, actual type: IsEnum={1}, type={2}",
+ typeCfg.IsEnum, type.IsEnum, type));
}
// Type is found.
var typeName = GetTypeName(type, nameMapper);
int typeId = GetTypeId(typeName, idMapper);
var affKeyFld = typeCfg.AffinityKeyFieldName ?? GetAffinityKeyFieldNameFromAttribute(type);
- var serializer = GetSerializer(cfg, typeCfg, type, typeId, nameMapper, idMapper, _log);
+ var serializer = GetSerializer(_cfg, typeCfg, type, typeId, nameMapper, idMapper, _log);
- AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer,
- affKeyFld, type.IsEnum);
+ return AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer,
+ affKeyFld, BinaryUtils.IsIgniteEnum(type));
}
else
{
@@ -585,7 +585,7 @@ namespace Apache.Ignite.Core.Impl.Binary
int typeId = GetTypeId(typeName, idMapper);
- AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null,
+ return AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null,
typeCfg.AffinityKeyFieldName, typeCfg.IsEnum);
}
}
@@ -653,7 +653,7 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <param name="serializer">Serializer.</param>
/// <param name="affKeyFieldName">Affinity key field name.</param>
/// <param name="isEnum">Enum flag.</param>
- private void AddType(Type type, int typeId, string typeName, bool userType,
+ private BinaryFullTypeDescriptor AddType(Type type, int typeId, string typeName, bool userType,
bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper,
IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum)
{
@@ -685,6 +685,8 @@ namespace Apache.Ignite.Core.Impl.Binary
_typeNameToDesc.GetOrAdd(typeName, x => descriptor);
_idToDesc.GetOrAdd(typeKey, _ => descriptor);
+
+ return descriptor;
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
index 837c28a..db54ce7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
@@ -17,9 +17,11 @@
namespace Apache.Ignite.Core.Impl.Binary.Metadata
{
+ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
using Apache.Ignite.Core.Binary;
using Apache.Ignite.Core.Impl.Common;
@@ -30,7 +32,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
{
/** Empty metadata. */
public static readonly BinaryType Empty =
- new BinaryType(BinaryUtils.TypeObject, BinaryTypeNames.TypeNameObject, null, null, false);
+ new BinaryType(BinaryUtils.TypeObject, BinaryTypeNames.TypeNameObject, null, null, false, null, null);
/** Empty dictionary. */
private static readonly IDictionary<string, BinaryField> EmptyDict = new Dictionary<string, BinaryField>();
@@ -44,6 +46,12 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/** Fields. */
private readonly IDictionary<string, BinaryField> _fields;
+ /** Enum values. */
+ private readonly IDictionary<string, int> _enumNameToValue;
+
+ /** Enum names. */
+ private readonly IDictionary<int, string> _enumValueToName;
+
/** Enum flag. */
private readonly bool _isEnum;
@@ -59,6 +67,9 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/** Type descriptor. */
private readonly IBinaryTypeDescriptor _descriptor;
+ /** Marshaller. */
+ private readonly Marshaller _marshaller;
+
/// <summary>
/// Initializes the <see cref="BinaryType"/> class.
/// </summary>
@@ -117,7 +128,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/// Initializes a new instance of the <see cref="BinaryType" /> class.
/// </summary>
/// <param name="reader">The reader.</param>
- public BinaryType(IBinaryRawReader reader)
+ public BinaryType(BinaryReader reader)
{
_typeId = reader.ReadInt();
_typeName = reader.ReadString();
@@ -136,15 +147,34 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
}
_isEnum = reader.ReadBoolean();
+
+ if (_isEnum)
+ {
+ var count = reader.ReadInt();
+
+ _enumNameToValue = new Dictionary<string, int>(count);
+
+ for (var i = 0; i < count; i++)
+ {
+ _enumNameToValue[reader.ReadString()] = reader.ReadInt();
+ }
+
+ _enumValueToName = _enumNameToValue.ToDictionary(x => x.Value, x => x.Key);
+ }
+
+ _marshaller = reader.Marshaller;
}
/// <summary>
- /// Initializes a new instance of the <see cref="BinaryType"/> class.
+ /// Initializes a new instance of the <see cref="BinaryType" /> class.
/// </summary>
/// <param name="desc">Descriptor.</param>
+ /// <param name="marshaller">Marshaller.</param>
/// <param name="fields">Fields.</param>
- public BinaryType(IBinaryTypeDescriptor desc, IDictionary<string, BinaryField> fields = null)
- : this (desc.TypeId, desc.TypeName, fields, desc.AffinityKeyFieldName, desc.IsEnum)
+ public BinaryType(IBinaryTypeDescriptor desc, Marshaller marshaller,
+ IDictionary<string, BinaryField> fields = null)
+ : this (desc.TypeId, desc.TypeName, fields, desc.AffinityKeyFieldName, desc.IsEnum,
+ GetEnumValues(desc), marshaller)
{
_descriptor = desc;
}
@@ -157,14 +187,24 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/// <param name="fields">Fields.</param>
/// <param name="affKeyFieldName">Affinity key field name.</param>
/// <param name="isEnum">Enum flag.</param>
+ /// <param name="enumValues">Enum values.</param>
+ /// <param name="marshaller">Marshaller.</param>
public BinaryType(int typeId, string typeName, IDictionary<string, BinaryField> fields,
- string affKeyFieldName, bool isEnum)
+ string affKeyFieldName, bool isEnum, IDictionary<string, int> enumValues, Marshaller marshaller)
{
_typeId = typeId;
_typeName = typeName;
_affinityKeyFieldName = affKeyFieldName;
_fields = fields;
_isEnum = isEnum;
+ _enumNameToValue = enumValues;
+
+ if (_enumNameToValue != null)
+ {
+ _enumValueToName = _enumNameToValue.ToDictionary(x => x.Value, x => x.Key);
+ }
+
+ _marshaller = marshaller;
}
/// <summary>
@@ -232,6 +272,27 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
get { return _isEnum; }
}
+ /** <inheritdoc /> */
+ public IEnumerable<IBinaryObject> GetEnumValues()
+ {
+ if (!_isEnum)
+ {
+ throw new NotSupportedException(
+ "IBinaryObject.Value is only supported for enums. " +
+ "Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value.");
+ }
+
+ if (_marshaller == null)
+ {
+ yield break;
+ }
+
+ foreach (var pair in _enumValueToName)
+ {
+ yield return new BinaryEnum(_typeId, pair.Key, _marshaller);
+ }
+ }
+
/// <summary>
/// Gets the descriptor.
/// </summary>
@@ -250,6 +311,14 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
}
/// <summary>
+ /// Gets the enum values map.
+ /// </summary>
+ public IDictionary<string, int> EnumValuesMap
+ {
+ get { return _enumNameToValue; }
+ }
+
+ /// <summary>
/// Updates the fields.
/// </summary>
public void UpdateFields(IDictionary<string, BinaryField> fields)
@@ -262,5 +331,103 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
foreach (var field in fields)
_fields[field.Key] = field.Value;
}
+
+ /// <summary>
+ /// Gets the enum value by name.
+ /// </summary>
+ public int? GetEnumValue(string valueName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(valueName, "valueName");
+
+ if (!_isEnum)
+ {
+ throw new NotSupportedException("Can't get enum value for a non-enum type: " + _typeName);
+ }
+
+ int res;
+
+ return _enumNameToValue != null && _enumNameToValue.TryGetValue(valueName, out res) ? res : (int?) null;
+ }
+
+ /// <summary>
+ /// Gets the name of the enum value.
+ /// </summary>
+ public string GetEnumName(int value)
+ {
+ if (!_isEnum)
+ {
+ throw new NotSupportedException("Can't get enum value for a non-enum type: " + _typeName);
+ }
+
+ string res;
+
+ return _enumValueToName != null && _enumValueToName.TryGetValue(value, out res) ? res : null;
+ }
+
+ /// <summary>
+ /// Gets the enum values.
+ /// </summary>
+ private static IDictionary<string, int> GetEnumValues(IBinaryTypeDescriptor desc)
+ {
+ if (desc == null || desc.Type == null || !desc.IsEnum)
+ {
+ return null;
+ }
+
+ var enumType = desc.Type;
+
+ var values = Enum.GetValues(enumType);
+ var res = new Dictionary<string, int>(values.Length);
+
+ var underlyingType = Enum.GetUnderlyingType(enumType);
+
+ foreach (var value in values)
+ {
+ var name = Enum.GetName(enumType, value);
+ Debug.Assert(name != null);
+
+ res[name] = GetEnumValueAsInt(underlyingType, value);
+ }
+
+ return res;
+ }
+
+ /// <summary>
+ /// Gets the enum value as int.
+ /// </summary>
+ private static int GetEnumValueAsInt(Type underlyingType, object value)
+ {
+ if (underlyingType == typeof(int))
+ {
+ return (int) value;
+ }
+
+ if (underlyingType == typeof(byte))
+ {
+ return (byte) value;
+ }
+
+ if (underlyingType == typeof(sbyte))
+ {
+ return (sbyte) value;
+ }
+
+ if (underlyingType == typeof(short))
+ {
+ return (short) value;
+ }
+
+ if (underlyingType == typeof(ushort))
+ {
+ return (ushort) value;
+ }
+
+ if (underlyingType == typeof(uint))
+ {
+ return unchecked((int) (uint) value);
+ }
+
+ throw new BinaryObjectException("Unexpected enum underlying type: " + underlyingType);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
index cdbc687..7e1e970 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
@@ -17,8 +17,8 @@
namespace Apache.Ignite.Core.Impl.Binary.Metadata
{
- using System;
using System.Collections.Generic;
+ using System.Diagnostics;
/// <summary>
/// Metadata for particular type.
@@ -37,6 +37,9 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/** Enum flag. */
private readonly bool _isEnum;
+ /** Marshaller. */
+ private readonly Marshaller _marshaller;
+
/** Collection of know field IDs. */
private volatile HashSet<int> _ids;
@@ -46,7 +49,6 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/** Saved flag (set if type metadata was saved at least once). */
private volatile bool _saved;
-
/// <summary>
/// Constructor.
/// </summary>
@@ -54,12 +56,15 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/// <param name="typeName">Type name.</param>
/// <param name="affKeyFieldName">Affinity key field name.</param>
/// <param name="isEnum">Enum flag.</param>
- public BinaryTypeHolder(int typeId, string typeName, string affKeyFieldName, bool isEnum)
+ /// <param name="marshaller">The marshaller.</param>
+ public BinaryTypeHolder(int typeId, string typeName, string affKeyFieldName, bool isEnum,
+ Marshaller marshaller)
{
_typeId = typeId;
_typeName = typeName;
_affKeyFieldName = affKeyFieldName;
_isEnum = isEnum;
+ _marshaller = marshaller;
}
/// <summary>
@@ -100,13 +105,19 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
/// <summary>
/// Merge newly sent field metadatas into existing ones.
/// </summary>
- /// <param name="newMap">New field metadatas map.</param>
- public void Merge(IDictionary<int, Tuple<string, BinaryField>> newMap)
+ /// <param name="meta">Binary type to merge.</param>
+ public void Merge(BinaryType meta)
{
+ Debug.Assert(meta != null);
+
_saved = true;
- if (newMap == null || newMap.Count == 0)
+ var fieldsMap = meta.GetFieldsMap();
+
+ if (fieldsMap.Count == 0)
+ {
return;
+ }
lock (this)
{
@@ -118,20 +129,27 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
IDictionary<string, BinaryField> newFields = meta0 != null
? new Dictionary<string, BinaryField>(meta0.GetFieldsMap())
- : new Dictionary<string, BinaryField>(newMap.Count);
+ : new Dictionary<string, BinaryField>(fieldsMap.Count);
// 2. Add new fields.
- foreach (var newEntry in newMap)
+ foreach (var fieldMeta in fieldsMap)
{
- if (!newIds.Contains(newEntry.Key))
- newIds.Add(newEntry.Key);
+ int fieldId = BinaryUtils.FieldId(meta.TypeId, fieldMeta.Key, null, null);
- if (!newFields.ContainsKey(newEntry.Value.Item1))
- newFields[newEntry.Value.Item1] = newEntry.Value.Item2;
+ if (!newIds.Contains(fieldId))
+ {
+ newIds.Add(fieldId);
+ }
+
+ if (!newFields.ContainsKey(fieldMeta.Key))
+ {
+ newFields[fieldMeta.Key] = fieldMeta.Value;
+ }
}
// 3. Assign new meta. Order is important here: meta must be assigned before field IDs.
- _meta = new BinaryType(_typeId, _typeName, newFields, _affKeyFieldName, _isEnum);
+ _meta = new BinaryType(_typeId, _typeName, newFields, _affKeyFieldName, _isEnum,
+ meta.EnumValuesMap, _marshaller);
_ids = newIds;
}
}