You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by cu...@apache.org on 2011/05/30 11:01:34 UTC
svn commit: r1129077 - in /avro/branches/branch-1.5: ./
lang/csharp/src/apache/main/Protocol/ lang/csharp/src/apache/main/Schema/
lang/csharp/src/apache/test/Protocol/
Author: cutting
Date: Mon May 30 09:01:33 2011
New Revision: 1129077
URL: http://svn.apache.org/viewvc?rev=1129077&view=rev
Log:
Merge -c 1129071 from trunk to 1.5 branch. Fixes: AVRO-826.
Modified:
avro/branches/branch-1.5/ (props changed)
avro/branches/branch-1.5/CHANGES.txt
avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Message.cs
avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Protocol.cs
avro/branches/branch-1.5/lang/csharp/src/apache/main/Schema/RecordSchema.cs
avro/branches/branch-1.5/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
Propchange: avro/branches/branch-1.5/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon May 30 09:01:33 2011
@@ -1 +1 @@
-/avro/trunk:1075938,1075993,1078917,1079055,1079060,1079063,1083246,1085921,1086727,1086730,1086866,1087076,1087129,1087136,1087439-1087440,1087463,1087472,1087792,1089128,1089131,1089550,1094812,1095206-1095208,1095493,1095529,1095548,1095550,1096798,1097916,1097927,1097968,1097974,1102332,1102335,1124127,1124971,1129053
+/avro/trunk:1075938,1075993,1078917,1079055,1079060,1079063,1083246,1085921,1086727,1086730,1086866,1087076,1087129,1087136,1087439-1087440,1087463,1087472,1087792,1089128,1089131,1089550,1094812,1095206-1095208,1095493,1095529,1095548,1095550,1096798,1097916,1097927,1097968,1097974,1102332,1102335,1124127,1124971,1129053,1129071
Modified: avro/branches/branch-1.5/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.5/CHANGES.txt?rev=1129077&r1=1129076&r2=1129077&view=diff
==============================================================================
--- avro/branches/branch-1.5/CHANGES.txt (original)
+++ avro/branches/branch-1.5/CHANGES.txt Mon May 30 09:01:33 2011
@@ -14,6 +14,9 @@ Avro 1.5.2 (unreleased)
while writing data to a file and then continue writing to that
file. (scottcarey & cutting)
+ AVRO-826. C#: Add MD5 and hashcode functions to Protocol.
+ (Dona Alvarez via cutting)
+
BUG FIXES
AVRO-818. C: Fix data file corruption bug in C library (dcreager)
Modified: avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Message.cs
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Message.cs?rev=1129077&r1=1129076&r2=1129077&view=diff
==============================================================================
--- avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Message.cs (original)
+++ avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Message.cs Mon May 30 09:01:33 2011
@@ -141,5 +141,45 @@ namespace Avro
writer.WriteEndObject();
}
+
+ /// <summary>
+ /// Tests equality of this Message object with the passed object
+ /// </summary>
+ /// <param name="obj"></param>
+ /// <returns></returns>
+ public override bool Equals(Object obj)
+ {
+ if (obj == this) return true;
+ if (!(obj is Message)) return false;
+
+ Message that = obj as Message;
+ return this.Name.Equals(that.Name) &&
+ this.Request.Equals(that.Request) &&
+ areEqual(this.Response, that.Response) &&
+ areEqual(this.Error, that.Error);
+ }
+
+ /// <summary>
+ /// Returns the hash code of this Message object
+ /// </summary>
+ /// <returns></returns>
+ public override int GetHashCode()
+ {
+ return Name.GetHashCode() +
+ Request.GetHashCode() +
+ (Response == null ? 0 : Response.GetHashCode()) +
+ (Error == null ? 0 : Error.GetHashCode());
+ }
+
+ /// <summary>
+ /// Tests equality of two objects taking null values into account
+ /// </summary>
+ /// <param name="o1"></param>
+ /// <param name="o2"></param>
+ /// <returns></returns>
+ protected static bool areEqual(object o1, object o2)
+ {
+ return o1 == null ? o2 == null : o1.Equals(o2);
+ }
}
}
Modified: avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Protocol.cs
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Protocol.cs?rev=1129077&r1=1129076&r2=1129077&view=diff
==============================================================================
--- avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Protocol.cs (original)
+++ avro/branches/branch-1.5/lang/csharp/src/apache/main/Protocol/Protocol.cs Mon May 30 09:01:33 2011
@@ -51,6 +51,24 @@ namespace Avro
/// </summary>
public IDictionary<string,Message> Messages { get; set; }
+ private byte[] md5;
+ public byte[] MD5
+ {
+ get
+ {
+ try
+ {
+ if (md5 == null)
+ md5 = System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(ToString()));
+ }
+ catch (Exception ex)
+ {
+ throw new AvroRuntimeException("MD5 get exception", ex);
+ }
+ return md5;
+ }
+ }
+
/// <summary>
/// Constructor for Protocol class
/// </summary>
@@ -187,5 +205,90 @@ namespace Avro
writer.WriteEndObject();
writer.WriteEndObject();
}
+
+ /// <summary>
+ /// Tests equality of this protocol object with the passed object
+ /// </summary>
+ /// <param name="obj"></param>
+ /// <returns></returns>
+ public override bool Equals(object obj)
+ {
+ if (obj == this) return true;
+ if (!(obj is Protocol)) return false;
+
+ Protocol that = obj as Protocol;
+
+ return this.Name.Equals(that.Name) && this.Namespace.Equals(that.Namespace) &&
+ TypesEquals(that.Types) && MessagesEquals(that.Messages);
+ }
+
+ /// <summary>
+ /// Test equality of this protocols Types list with the passed Types list.
+ /// Order of schemas does not matter, as long as all types in this protocol
+ /// are also defined in the passed protocol
+ /// </summary>
+ /// <param name="that"></param>
+ /// <returns></returns>
+ private bool TypesEquals(IList<Schema> that)
+ {
+ if (Types.Count != that.Count) return false;
+ foreach (Schema schema in Types)
+ if (!that.Contains(schema)) return false;
+ return true;
+ }
+
+ /// <summary>
+ /// Test equality of this protocols Message map with the passed Message map
+ /// Order of messages does not matter, as long as all messages in this protocol
+ /// are also defined in the passed protocol
+ /// </summary>
+ /// <param name="that"></param>
+ /// <returns></returns>
+ private bool MessagesEquals(IDictionary<string, Message> that)
+ {
+ if (Messages.Count != that.Count) return false;
+ foreach (KeyValuePair<string, Message> pair in Messages)
+ {
+ if (!that.ContainsKey(pair.Key))
+ return false;
+ if (!pair.Value.Equals(that[pair.Key]))
+ return false;
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Returns the hash code of this protocol object
+ /// </summary>
+ /// <returns></returns>
+ public override int GetHashCode()
+ {
+ return Name.GetHashCode() + Namespace.GetHashCode() +
+ GetTypesHashCode() + GetMessagesHashCode();
+ }
+
+ /// <summary>
+ /// Returns the hash code of the Types list
+ /// </summary>
+ /// <returns></returns>
+ private int GetTypesHashCode()
+ {
+ int hash = Types.Count;
+ foreach (Schema schema in Types)
+ hash += schema.GetHashCode();
+ return hash;
+ }
+
+ /// <summary>
+ /// Returns the hash code of the Messages map
+ /// </summary>
+ /// <returns></returns>
+ private int GetMessagesHashCode()
+ {
+ int hash = Messages.Count;
+ foreach (KeyValuePair<string, Message> pair in Messages)
+ hash += (pair.Key.GetHashCode() + pair.Value.GetHashCode());
+ return hash;
+ }
}
}
Modified: avro/branches/branch-1.5/lang/csharp/src/apache/main/Schema/RecordSchema.cs
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.5/lang/csharp/src/apache/main/Schema/RecordSchema.cs?rev=1129077&r1=1129076&r2=1129077&view=diff
==============================================================================
--- avro/branches/branch-1.5/lang/csharp/src/apache/main/Schema/RecordSchema.cs (original)
+++ avro/branches/branch-1.5/lang/csharp/src/apache/main/Schema/RecordSchema.cs Mon May 30 09:01:33 2011
@@ -249,13 +249,13 @@ namespace Avro
/// <returns></returns>
public override int GetHashCode()
{
- return protect(() =>
+ return protect(() => 0, () =>
{
int result = SchemaName.GetHashCode();
foreach (Field f in Fields) result += 29 * f.GetHashCode();
result += getHashCode(Props);
return result;
- }, () => 0, this);
+ }, this);
}
/// <summary>
Modified: avro/branches/branch-1.5/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.5/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs?rev=1129077&r1=1129076&r2=1129077&view=diff
==============================================================================
--- avro/branches/branch-1.5/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs (original)
+++ avro/branches/branch-1.5/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs Mon May 30 09:01:33 2011
@@ -180,5 +180,266 @@ namespace Avro.Test
Assert.AreEqual(json,json2);
}
+
+ // Protocols match
+ [TestCase(
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+ true,true)]
+ // Protocols match, order of schemas in 'types' are different
+ [TestCase(
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+ false,true)]
+ // Name of protocol is different
+ [TestCase(
+@"{
+ ""protocol"": ""TestProtocol1"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+ false,false)]
+ // Name of a message request is different: 'hi'
+ [TestCase(
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hi"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+ false,false)]
+ // Name of a type is different : Curse1
+ [TestCase(
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse1"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse1""]
+ }
+ }
+}",
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hi"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+ false,false)]
+ // Name of a record field is different: 'mymessage'
+ [TestCase(
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hello"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+@"{
+ ""protocol"": ""TestProtocol"",
+ ""namespace"": ""com.acme"",
+
+ ""types"": [
+ {""name"": ""Greeting"", ""type"": ""record"", ""fields"": [
+ {""name"": ""message"", ""type"": ""string""}]},
+ {""name"": ""Curse"", ""type"": ""error"", ""fields"": [
+ {""name"": ""mymessage"", ""type"": ""string""}]}
+ ],
+
+ ""messages"": {
+ ""hi"": {
+ ""request"": [{""name"": ""greeting"", ""type"": ""Greeting"" }],
+ ""response"": ""Greeting"",
+ ""errors"": [""Curse""]
+ }
+ }
+}",
+ false,false)]
+ public static void TestProtocolHash(string str1, string str2, bool md5_equal, bool hash_equal)
+ {
+ Protocol protocol1 = Protocol.Parse(str1);
+ Protocol protocol2 = Protocol.Parse(str2);
+
+ byte[] md51 = protocol1.MD5;
+ byte[] md52 = protocol2.MD5;
+
+ int hash1 = protocol1.GetHashCode();
+ int hash2 = protocol2.GetHashCode();
+
+ Assert.AreEqual(md5_equal, md51.SequenceEqual(md52));
+ Assert.AreEqual(hash_equal, hash1 == hash2);
+ }
}
}