avro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cutt...@apache.org
Subject svn commit: r1157266 - in /avro/trunk: CHANGES.txt lang/java/avro/src/main/java/org/apache/avro/Schema.java
Date Fri, 12 Aug 2011 21:53:48 GMT
Author: cutting
Date: Fri Aug 12 21:53:48 2011
New Revision: 1157266

URL: http://svn.apache.org/viewvc?rev=1157266&view=rev
Log:
AVRO-853: Java: Cache Schema hash codes. (cutting)

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1157266&r1=1157265&r2=1157266&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Fri Aug 12 21:53:48 2011
@@ -6,6 +6,10 @@ Avro 1.6.0 (unreleased)
 
   NEW FEATURES
 
+  OPTIMIZATIONS
+
+    AVRO-853: Java: Cache Schema hash codes. (cutting)
+
   IMPROVEMENTS
 
     AVRO-836. Python "avro" commandline utility to display and write Avro files.

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java?rev=1157266&r1=1157265&r2=1157266&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java Fri Aug 12 21:53:48
2011
@@ -78,6 +78,8 @@ public abstract class Schema {
   static final JsonFactory FACTORY = new JsonFactory();
   static final ObjectMapper MAPPER = new ObjectMapper(FACTORY);
 
+  private static final int NO_HASHCODE = Integer.MIN_VALUE;
+
   static {
     FACTORY.enable(JsonParser.Feature.ALLOW_COMMENTS);
     FACTORY.setCodec(MAPPER);
@@ -144,6 +146,7 @@ public abstract class Schema {
   }
 
   Props props = new Props(SCHEMA_RESERVED);
+  int hashCode = NO_HASHCODE;
 
   /**
    * Returns the value of the named property in this schema.
@@ -164,6 +167,7 @@ public abstract class Schema {
    */
   public synchronized void addProp(String name, String value) {
     props.add(name, value);
+    hashCode = NO_HASHCODE;
   }
 
   /** Create an anonymous record schema. */
@@ -346,9 +350,21 @@ public abstract class Schema {
     if (!(o instanceof Schema)) return false;
     Schema that = (Schema)o;
     if (!(this.type == that.type)) return false;
-    return props.equals(that.props);
+    return equalCachedHash(that) && props.equals(that.props);
+  }
+  public final int hashCode() {
+    if (hashCode == NO_HASHCODE)
+      hashCode = computeHash();
+    return hashCode;
+  }
+
+  int computeHash() { return getType().hashCode() + props.hashCode(); }
+
+  final boolean equalCachedHash(Schema other) {
+    return (hashCode == other.hashCode)
+           || (hashCode == NO_HASHCODE)
+           || (other.hashCode == NO_HASHCODE);
   }
-  public int hashCode() { return getType().hashCode() + props.hashCode(); }
 
   private static final Set<String> FIELD_RESERVED = new HashSet<String>();
   static {
@@ -418,7 +434,7 @@ public abstract class Schema {
         (order.equals(that.order)) &&
         props.equals(that.props);
     }
-    public int hashCode() { return name.hashCode() + schema.hashCode(); }
+    public int hashCode() { return name.hashCode() + schema.computeHash(); }
     
     @Override
     public String toString() {
@@ -513,8 +529,8 @@ public abstract class Schema {
     public boolean equalNames(NamedSchema that) {
       return this.name.equals(that.name);
     }
-    public int hashCode() {
-      return getType().hashCode() + name.hashCode() + props.hashCode();
+    @Override int computeHash() {
+      return super.computeHash() + name.hashCode();
     }
     public void aliasesToJson(JsonGenerator gen) throws IOException {
       if (aliases == null) return;
@@ -586,11 +602,13 @@ public abstract class Schema {
         ff.add(f);
       }
       this.fields = ff.lock();
+      this.hashCode = NO_HASHCODE;
     }
     public boolean equals(Object o) {
       if (o == this) return true;
       if (!(o instanceof RecordSchema)) return false;
       RecordSchema that = (RecordSchema)o;
+      if (!equalCachedHash(that)) return false;
       if (!equalNames(that)) return false;
       if (!props.equals(that.props)) return false;
       Set seen = SEEN_EQUALS.get();
@@ -604,13 +622,13 @@ public abstract class Schema {
         if (first) seen.clear();
       }
     }
-    public int hashCode() {
+    @Override int computeHash() {
       Map seen = SEEN_HASHCODE.get();
       if (seen.containsKey(this)) return 0;       // prevent stack overflow
       boolean first = seen.isEmpty();
       try {
         seen.put(this, this);
-        return super.hashCode() + fields.hashCode();
+        return super.computeHash() + fields.hashCode();
       } finally {
         if (first) seen.clear();
       }
@@ -682,11 +700,12 @@ public abstract class Schema {
       if (o == this) return true;
       if (!(o instanceof EnumSchema)) return false;
       EnumSchema that = (EnumSchema)o;
-      return equalNames(that)
+      return equalCachedHash(that)
+        && equalNames(that)
         && symbols.equals(that.symbols)
         && props.equals(that.props);
     }
-    public int hashCode() { return super.hashCode() + symbols.hashCode(); }
+    @Override int computeHash() { return super.computeHash() + symbols.hashCode(); }
     void toJson(Names names, JsonGenerator gen) throws IOException {
       if (writeNameRef(names, gen)) return;
       gen.writeStartObject();
@@ -715,10 +734,12 @@ public abstract class Schema {
       if (o == this) return true;
       if (!(o instanceof ArraySchema)) return false;
       ArraySchema that = (ArraySchema)o;
-      return elementType.equals(that.elementType) && props.equals(that.props);
+      return equalCachedHash(that)
+        && elementType.equals(that.elementType)
+        && props.equals(that.props);
     }
-    public int hashCode() {
-      return getType().hashCode() + elementType.hashCode() + props.hashCode();
+    @Override int computeHash() {
+      return super.computeHash() + elementType.computeHash();
     }
     void toJson(Names names, JsonGenerator gen) throws IOException {
       gen.writeStartObject();
@@ -741,10 +762,12 @@ public abstract class Schema {
       if (o == this) return true;
       if (!(o instanceof MapSchema)) return false;
       MapSchema that = (MapSchema)o;
-      return valueType.equals(that.valueType) && props.equals(that.props);
+      return equalCachedHash(that)
+        && valueType.equals(that.valueType)
+        && props.equals(that.props);
     }
-    public int hashCode() {
-      return getType().hashCode() + valueType.hashCode() + props.hashCode();
+    @Override int computeHash() {
+      return super.computeHash() + valueType.computeHash();
     }
     void toJson(Names names, JsonGenerator gen) throws IOException {
       gen.writeStartObject();
@@ -793,10 +816,15 @@ public abstract class Schema {
       if (o == this) return true;
       if (!(o instanceof UnionSchema)) return false;
       UnionSchema that = (UnionSchema)o;
-      return types.equals(that.types) && props.equals(that.props);
+      return equalCachedHash(that)
+        && types.equals(that.types)
+        && props.equals(that.props);
     }
-    public int hashCode() {
-      return getType().hashCode() + types.hashCode() + props.hashCode();
+    @Override int computeHash() {
+      int hash = super.computeHash();
+      for (Schema type : types)
+        hash += type.computeHash();
+      return hash;
     }
     
     @Override
@@ -825,9 +853,12 @@ public abstract class Schema {
       if (o == this) return true;
       if (!(o instanceof FixedSchema)) return false;
       FixedSchema that = (FixedSchema)o;
-      return equalNames(that) && size == that.size && props.equals(that.props);
+      return equalCachedHash(that)
+        && equalNames(that)
+        && size == that.size
+        && props.equals(that.props);
     }
-    public int hashCode() { return super.hashCode() + size; }
+    @Override int computeHash() { return super.computeHash() + size; }
     void toJson(Names names, JsonGenerator gen) throws IOException {
       if (writeNameRef(names, gen)) return;
       gen.writeStartObject();



Mime
View raw message