IGNITE-5455 .NET: Fix binary hash code calculation This closes #2108
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3c5ffd1a Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3c5ffd1a Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3c5ffd1a Branch: refs/heads/ignite-5272 Commit: 3c5ffd1ac7556b99b64aed70aea58b2d90abc51a Parents: 72e2f88 Author: Pavel Tupitsyn <[email protected]> Authored: Fri Jun 9 18:58:44 2017 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Fri Jun 9 18:58:44 2017 +0300 ---------------------------------------------------------------------- .../platform/PlatformComputeEchoTask.java | 4 +- .../Binary/BinaryCompactFooterInteropTest.cs | 8 +- .../Binary/BinaryDynamicRegistrationTest.cs | 7 +- .../Cache/Query/CacheDmlQueriesTest.cs | 197 +++++++++++++++++-- .../Compute/ComputeApiTest.cs | 25 ++- .../Impl/Binary/BinaryArrayEqualityComparer.cs | 6 +- .../Impl/Binary/BinaryObjectHeader.cs | 8 + 7 files changed, 224 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/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 984cf62..12d9e09 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 @@ -187,7 +187,9 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object> return new HashMap<>(Collections.singletonMap(1, 1)); case TYPE_BINARY: - return new PlatformComputeBinarizable(1); + Integer field = (Integer) ignite.cache(DEFAULT_CACHE_NAME).get(TYPE_BINARY); + + return new PlatformComputeBinarizable(field); case TYPE_BINARY_JAVA: return new PlatformComputeJavaBinarizable(1); http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryCompactFooterInteropTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryCompactFooterInteropTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryCompactFooterInteropTest.cs index 735cfff..6f97677 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryCompactFooterInteropTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryCompactFooterInteropTest.cs @@ -71,10 +71,12 @@ namespace Apache.Ignite.Core.Tests.Binary try { - var fromJava = grid.GetCompute().ExecuteJavaTask<PlatformComputeBinarizable>(ComputeApiTest.EchoTask, - ComputeApiTest.EchoTypeBinarizable); + grid.GetOrCreateCache<int, int>("default").Put(ComputeApiTest.EchoTypeBinarizable, i * 99); - Assert.AreEqual(1, fromJava.Field); + var fromJava = grid.GetCompute().ExecuteJavaTask<PlatformComputeBinarizable>( + ComputeApiTest.EchoTask, ComputeApiTest.EchoTypeBinarizable); + + Assert.AreEqual(i * 99, fromJava.Field); return; } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs index 927aa32..4f458f4 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs @@ -316,18 +316,19 @@ namespace Apache.Ignite.Core.Tests.Binary var cache = ignite.CreateCache<int, object>(cacheCfg); // Force dynamic registration for .NET - cache.Put(1, new PlatformComputeBinarizable {Field = 7}); + cache.Put(-1, new PlatformComputeBinarizable {Field = 7}); + cache.Put(ComputeApiTest.EchoTypeBinarizable, 255); // Run Java code that will also perform dynamic registration var fromJava = ignite.GetCompute().ExecuteJavaTask<PlatformComputeBinarizable>(ComputeApiTest.EchoTask, ComputeApiTest.EchoTypeBinarizable); // Check that objects are compatible - Assert.AreEqual(1, fromJava.Field); + Assert.AreEqual(255, fromJava.Field); // Check that Java can read what .NET has put var qryRes = ignite.GetCompute().ExecuteJavaTask<IList>( - BinaryCompactFooterInteropTest.PlatformSqlQueryTask, "Field < 10"); + BinaryCompactFooterInteropTest.PlatformSqlQueryTask, "Field = 7"); Assert.AreEqual(7, qryRes.OfType<PlatformComputeBinarizable>().Single().Field); } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs index d79844e..9d16799 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs @@ -18,11 +18,13 @@ // ReSharper disable UnusedAutoPropertyAccessor.Local namespace Apache.Ignite.Core.Tests.Cache.Query { + using System; using System.Linq; using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Cache.Configuration; using Apache.Ignite.Core.Cache.Query; using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Impl.Binary; using NUnit.Framework; /// <summary> @@ -38,7 +40,8 @@ namespace Apache.Ignite.Core.Tests.Cache.Query { var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration()) { - BinaryConfiguration = new BinaryConfiguration(typeof(Foo), typeof(Key), typeof(Key2)) + // Type registration is required because we call DML first and cache.Get after. + BinaryConfiguration = new BinaryConfiguration(typeof(Foo), typeof(Key), typeof(Key2), typeof(KeyAll)) { NameMapper = GetNameMapper() } @@ -100,33 +103,74 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> + /// Tests all primitive key types. + /// </summary> + [Test] + public void TestPrimitiveKeyAllTypes() + { + TestKey(byte.MinValue, byte.MaxValue); + TestKey(sbyte.MinValue, sbyte.MaxValue); + TestKey(short.MinValue, short.MaxValue); + TestKey(int.MinValue, int.MaxValue); + TestKey(uint.MinValue, uint.MaxValue); + TestKey(long.MinValue, long.MaxValue); + TestKey(ulong.MinValue, ulong.MaxValue); + TestKey(float.MinValue, float.MaxValue); + TestKey(double.MinValue, double.MaxValue); + TestKey(decimal.MinValue, decimal.MaxValue); + TestKey(Guid.NewGuid()); + } + + /// <summary> + /// Tests the key. + /// </summary> + private static void TestKey<T>(params T[] vals) + { + var cfg = new CacheConfiguration("primitive_key_dotnet_" + typeof(T), + new QueryEntity(typeof(T), typeof(string))); + var cache = Ignition.GetIgnite().CreateCache<T, string>(cfg); + + foreach (var val in vals) + { + var res = cache.QueryFields(new SqlFieldsQuery( + "insert into string(_key, _val) values (?, ?)", val, val.ToString())).GetAll(); + + Assert.AreEqual(1, res.Count); + Assert.AreEqual(1, res[0].Count); + Assert.AreEqual(1, res[0][0]); + + Assert.AreEqual(val.ToString(), cache[val]); + } + } + + /// <summary> /// Tests composite key (which requires QueryField.IsKeyField). /// </summary> [Test] - public void TestCompositeKeyArrayEquality() + public void TestCompositeKey() { var cfg = new CacheConfiguration("composite_key_arr", new QueryEntity(typeof(Key), typeof(Foo))); var cache = Ignition.GetIgnite().CreateCache<Key, Foo>(cfg); // Test insert. var res = cache.QueryFields(new SqlFieldsQuery("insert into foo(hi, lo, id, name) " + - "values (1, 2, 3, 'John'), (4, 5, 6, 'Mary')")).GetAll(); + "values (-1, 65500, 3, 'John'), (255, 128, 6, 'Mary')")).GetAll(); Assert.AreEqual(1, res.Count); Assert.AreEqual(1, res[0].Count); Assert.AreEqual(2, res[0][0]); // 2 affected rows - var foos = cache.OrderBy(x => x.Key.Lo).ToArray(); + var foos = cache.OrderByDescending(x => x.Key.Lo).ToArray(); Assert.AreEqual(2, foos.Length); - Assert.AreEqual(1, foos[0].Key.Hi); - Assert.AreEqual(2, foos[0].Key.Lo); + Assert.AreEqual(-1, foos[0].Key.Hi); + Assert.AreEqual(65500, foos[0].Key.Lo); Assert.AreEqual(3, foos[0].Value.Id); Assert.AreEqual("John", foos[0].Value.Name); - Assert.AreEqual(4, foos[1].Key.Hi); - Assert.AreEqual(5, foos[1].Key.Lo); + Assert.AreEqual(255, foos[1].Key.Hi); + Assert.AreEqual(128, foos[1].Key.Lo); Assert.AreEqual(6, foos[1].Value.Id); Assert.AreEqual("Mary", foos[1].Value.Name); @@ -134,33 +178,33 @@ namespace Apache.Ignite.Core.Tests.Cache.Query var binary = cache.Ignite.GetBinary(); var binCache = cache.WithKeepBinary<IBinaryObject, IBinaryObject>(); - Assert.IsTrue(cache.ContainsKey(new Key(2, 1))); + Assert.IsTrue(cache.ContainsKey(new Key(65500, -1))); Assert.IsTrue(cache.ContainsKey(foos[0].Key)); Assert.IsTrue(binCache.ContainsKey( - binary.GetBuilder(typeof(Key)).SetField("hi", 1).SetField("lo", 2).Build())); + binary.GetBuilder(typeof(Key)).SetField("hi", -1).SetField("lo", 65500).Build())); Assert.IsTrue(binCache.ContainsKey( // Fields are sorted. - binary.GetBuilder(typeof(Key)).SetField("lo", 2).SetField("hi", 1).Build())); + binary.GetBuilder(typeof(Key)).SetField("lo", 65500).SetField("hi", -1).Build())); - Assert.IsTrue(cache.ContainsKey(new Key(5, 4))); + Assert.IsTrue(cache.ContainsKey(new Key(128, 255))); Assert.IsTrue(cache.ContainsKey(foos[1].Key)); Assert.IsTrue(binCache.ContainsKey( - binary.GetBuilder(typeof(Key)).SetField("hi", 4).SetField("lo", 5).Build())); + binary.GetBuilder(typeof(Key)).SetField("hi", 255).SetField("lo", 128).Build())); Assert.IsTrue(binCache.ContainsKey( // Fields are sorted. - binary.GetBuilder(typeof(Key)).SetField("lo", 5).SetField("hi", 4).Build())); + binary.GetBuilder(typeof(Key)).SetField("lo", 128).SetField("hi", 255).Build())); } /// <summary> /// Tests composite key (which requires QueryField.IsKeyField). /// </summary> [Test] - public void TestCompositeKeyFieldEquality() + public void TestCompositeKey2() { var cfg = new CacheConfiguration("composite_key_fld", new QueryEntity(typeof(Key2), typeof(Foo))); var cache = Ignition.GetIgnite().CreateCache<Key2, Foo>(cfg); // Test insert. var res = cache.QueryFields(new SqlFieldsQuery("insert into foo(hi, lo, str, id, name) " + - "values (1, 2, 'Foo', 3, 'John'), (4, 5, 'Bar', 6, 'Mary')")).GetAll(); + "values (1, 2, 'ФÑ', 3, 'John'), (4, 5, 'ÐаÑ', 6, 'Mary')")).GetAll(); Assert.AreEqual(1, res.Count); Assert.AreEqual(1, res[0].Count); @@ -172,21 +216,21 @@ namespace Apache.Ignite.Core.Tests.Cache.Query Assert.AreEqual(1, foos[0].Key.Hi); Assert.AreEqual(2, foos[0].Key.Lo); - Assert.AreEqual("Foo", foos[0].Key.Str); + Assert.AreEqual("ФÑ", foos[0].Key.Str); Assert.AreEqual(3, foos[0].Value.Id); Assert.AreEqual("John", foos[0].Value.Name); Assert.AreEqual(4, foos[1].Key.Hi); Assert.AreEqual(5, foos[1].Key.Lo); - Assert.AreEqual("Bar", foos[1].Key.Str); + Assert.AreEqual("ÐаÑ", foos[1].Key.Str); Assert.AreEqual(6, foos[1].Value.Id); Assert.AreEqual("Mary", foos[1].Value.Name); // Existence tests check that hash codes are consistent. - Assert.IsTrue(cache.ContainsKey(new Key2(2, 1, "Foo"))); + Assert.IsTrue(cache.ContainsKey(new Key2(2, 1, "ФÑ"))); Assert.IsTrue(cache.ContainsKey(foos[0].Key)); - Assert.IsTrue(cache.ContainsKey(new Key2(5, 4, "Bar"))); + Assert.IsTrue(cache.ContainsKey(new Key2(5, 4, "ÐаÑ"))); Assert.IsTrue(cache.ContainsKey(foos[1].Key)); } @@ -254,6 +298,59 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> + /// Tests the composite key with fields of all data types. + /// </summary> + [Test] + public void TestCompositeKeyAllDataTypes() + { + var cfg = new CacheConfiguration("composite_key_all", new QueryEntity(typeof(KeyAll), typeof(string))); + var cache = Ignition.GetIgnite().CreateCache<KeyAll, string>(cfg); + + var key = new KeyAll + { + Byte = byte.MaxValue, + SByte = sbyte.MaxValue, + Short = short.MaxValue, + UShort = ushort.MaxValue, + Int = int.MaxValue, + UInt = uint.MaxValue, + Long = long.MaxValue, + ULong = ulong.MaxValue, + Float = float.MaxValue, + Double = double.MaxValue, + Decimal = decimal.MaxValue, + Guid = Guid.NewGuid(), + String = "пÑивеÑ", + Key = new Key(255, 65555) + }; + + // Test insert. + var res = cache.QueryFields(new SqlFieldsQuery( + "insert into string(byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal, " + + "guid, string, key, _val) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", + key.Byte, key.SByte, key.Short, key.UShort, key.Int, key.UInt, key.Long, key.ULong, key.Float, + key.Double, key.Decimal, key.Guid, key.String, key.Key, "VALUE")) + .GetAll(); + + Assert.AreEqual(1, res.Count); + Assert.AreEqual(1, res[0].Count); + Assert.AreEqual(1, res[0][0]); + + // Compare resulting keys. + Assert.AreEqual(key, cache.Single().Key); + + // Compare keys in binary form. + var binKey = cache.Ignite.GetBinary().ToBinary<BinaryObject>(key); + var binKeyRes = cache.WithKeepBinary<BinaryObject, string>().Single().Key; + + Assert.AreEqual(binKey.Header, binKeyRes.Header); + Assert.AreEqual(binKey, binKeyRes); + + // Get by key to verify identity. + Assert.AreEqual("VALUE", cache[key]); + } + + /// <summary> /// Key. /// </summary> private struct Key @@ -293,5 +390,65 @@ namespace Apache.Ignite.Core.Tests.Cache.Query [QuerySqlField] public int Id { get; set; } [QuerySqlField] public string Name { get; set; } } + + /// <summary> + /// Key with all kinds of fields. + /// </summary> + private class KeyAll + { + [QuerySqlField] public byte Byte { get; set; } + [QuerySqlField] public sbyte SByte { get; set; } + [QuerySqlField] public short Short { get; set; } + [QuerySqlField] public ushort UShort { get; set; } + [QuerySqlField] public int Int { get; set; } + [QuerySqlField] public uint UInt { get; set; } + [QuerySqlField] public long Long { get; set; } + [QuerySqlField] public ulong ULong { get; set; } + [QuerySqlField] public float Float { get; set; } + [QuerySqlField] public double Double { get; set; } + [QuerySqlField] public decimal Decimal { get; set; } + [QuerySqlField] public Guid Guid { get; set; } + [QuerySqlField] public string String { get; set; } + [QuerySqlField] public Key Key { get; set; } + + private bool Equals(KeyAll other) + { + return Byte == other.Byte && SByte == other.SByte && Short == other.Short && + UShort == other.UShort && Int == other.Int && UInt == other.UInt && Long == other.Long && + ULong == other.ULong && Float.Equals(other.Float) && Double.Equals(other.Double) && + Decimal == other.Decimal && Guid.Equals(other.Guid) && string.Equals(String, other.String) && + Key.Equals(other.Key); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((KeyAll) obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Byte.GetHashCode(); + hashCode = (hashCode * 397) ^ SByte.GetHashCode(); + hashCode = (hashCode * 397) ^ Short.GetHashCode(); + hashCode = (hashCode * 397) ^ UShort.GetHashCode(); + hashCode = (hashCode * 397) ^ Int; + hashCode = (hashCode * 397) ^ (int) UInt; + hashCode = (hashCode * 397) ^ Long.GetHashCode(); + hashCode = (hashCode * 397) ^ ULong.GetHashCode(); + hashCode = (hashCode * 397) ^ Float.GetHashCode(); + hashCode = (hashCode * 397) ^ Double.GetHashCode(); + hashCode = (hashCode * 397) ^ Decimal.GetHashCode(); + hashCode = (hashCode * 397) ^ Guid.GetHashCode(); + hashCode = (hashCode * 397) ^ String.GetHashCode(); + hashCode = (hashCode * 397) ^ Key.GetHashCode(); + return hashCode; + } + } + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/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 0c6d20e..5427d3d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs @@ -30,6 +30,7 @@ namespace Apache.Ignite.Core.Tests.Compute using Apache.Ignite.Core.Common; using Apache.Ignite.Core.Compute; using Apache.Ignite.Core.Impl; + using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Resource; using NUnit.Framework; @@ -875,9 +876,29 @@ namespace Apache.Ignite.Core.Tests.Compute [Test] public void TestEchoTaskBinarizable() { - var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeBinarizable>(EchoTask, EchoTypeBinarizable); + var values = new[] {int.MinValue, int.MaxValue, 0, 1, -1, byte.MaxValue, byte.MinValue}; + var cache = _grid1.GetCache<int, int>(DefaultCacheName); + var compute = _grid1.GetCompute(); - Assert.AreEqual(1, res.Field); + foreach (var val in values) + { + cache[EchoTypeBinarizable] = val; + + var res = compute.ExecuteJavaTask<PlatformComputeBinarizable>(EchoTask, EchoTypeBinarizable); + Assert.AreEqual(val, res.Field); + + // Binary mode. + var binRes = compute.WithKeepBinary().ExecuteJavaTask<BinaryObject>(EchoTask, EchoTypeBinarizable); + + Assert.AreEqual(val, binRes.GetField<long>("Field")); + + var dotNetBin = _grid1.GetBinary().ToBinary<BinaryObject>(res); + + Assert.AreEqual(dotNetBin.Header.HashCode, binRes.Header.HashCode); + + Func<BinaryObject, byte[]> getData = bo => bo.Data.Skip(bo.Offset).Take(bo.Header.Length).ToArray(); + Assert.AreEqual(getData(dotNetBin), getData(binRes)); + } } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryArrayEqualityComparer.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryArrayEqualityComparer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryArrayEqualityComparer.cs index 8ba409b..d969b8f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryArrayEqualityComparer.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryArrayEqualityComparer.cs @@ -146,11 +146,13 @@ namespace Apache.Ignite.Core.Impl.Binary /** <inheritdoc /> */ public unsafe int Invoke(byte* data, KeyValuePair<int, int> arg) { - var hash = 1; - var ptr = data + arg.Key; + int hash = 1; + sbyte* ptr = (sbyte*) (data + arg.Key); for (var i = 0; i < arg.Value; i++) + { hash = 31 * hash + *(ptr + i); + } return hash; } http://git-wip-us.apache.org/repos/asf/ignite/blob/3c5ffd1a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs index 0f0fafe..d7dd74d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectHeader.cs @@ -357,5 +357,13 @@ namespace Apache.Ignite.Core.Impl.Binary { return !left.Equals(right); } + + /** <inheritdoc /> */ + public override string ToString() + { + return string.Format("BinaryObjectHeader [Header={0}, Version={1}, Flags={2}, TypeId={3}, " + + "HashCode={4}, Length={5}, SchemaId={6}, SchemaOffset={7}]", + Header, Version, Flags, TypeId, HashCode, Length, SchemaId, SchemaOffset); + } } }
