avro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cutt...@apache.org
Subject svn commit: r1129071 - in /avro/trunk: CHANGES.txt lang/csharp/src/apache/main/Protocol/Message.cs lang/csharp/src/apache/main/Protocol/Protocol.cs lang/csharp/src/apache/main/Schema/RecordSchema.cs lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
Date Mon, 30 May 2011 08:58:28 GMT
Author: cutting
Date: Mon May 30 08:58:28 2011
New Revision: 1129071

URL: http://svn.apache.org/viewvc?rev=1129071&view=rev
Log:
AVRO-826. CSharp: Add MD5 and hashcode functions to Protocol.  Contributed by Dona Alvarez.

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/csharp/src/apache/main/Protocol/Message.cs
    avro/trunk/lang/csharp/src/apache/main/Protocol/Protocol.cs
    avro/trunk/lang/csharp/src/apache/main/Schema/RecordSchema.cs
    avro/trunk/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1129071&r1=1129070&r2=1129071&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Mon May 30 08:58:28 2011
@@ -28,6 +28,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/trunk/lang/csharp/src/apache/main/Protocol/Message.cs
URL: http://svn.apache.org/viewvc/avro/trunk/lang/csharp/src/apache/main/Protocol/Message.cs?rev=1129071&r1=1129070&r2=1129071&view=diff
==============================================================================
--- avro/trunk/lang/csharp/src/apache/main/Protocol/Message.cs (original)
+++ avro/trunk/lang/csharp/src/apache/main/Protocol/Message.cs Mon May 30 08:58:28 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/trunk/lang/csharp/src/apache/main/Protocol/Protocol.cs
URL: http://svn.apache.org/viewvc/avro/trunk/lang/csharp/src/apache/main/Protocol/Protocol.cs?rev=1129071&r1=1129070&r2=1129071&view=diff
==============================================================================
--- avro/trunk/lang/csharp/src/apache/main/Protocol/Protocol.cs (original)
+++ avro/trunk/lang/csharp/src/apache/main/Protocol/Protocol.cs Mon May 30 08:58:28 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/trunk/lang/csharp/src/apache/main/Schema/RecordSchema.cs
URL: http://svn.apache.org/viewvc/avro/trunk/lang/csharp/src/apache/main/Schema/RecordSchema.cs?rev=1129071&r1=1129070&r2=1129071&view=diff
==============================================================================
--- avro/trunk/lang/csharp/src/apache/main/Schema/RecordSchema.cs (original)
+++ avro/trunk/lang/csharp/src/apache/main/Schema/RecordSchema.cs Mon May 30 08:58:28 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/trunk/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
URL: http://svn.apache.org/viewvc/avro/trunk/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs?rev=1129071&r1=1129070&r2=1129071&view=diff
==============================================================================
--- avro/trunk/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs (original)
+++ avro/trunk/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs Mon May 30 08:58:28 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);
+        }
     }
 }



Mime
View raw message