You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gora.apache.org by le...@apache.org on 2013/08/24 02:27:41 UTC

svn commit: r1517093 [2/3] - in /gora/branches/GORA_94: ./ bin/ gora-cassandra/ gora-cassandra/src/main/java/org/apache/gora/cassandra/query/ gora-cassandra/src/main/java/org/apache/gora/cassandra/serializers/ gora-cassandra/src/main/java/org/apache/go...

Added: gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java (added)
+++ gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,281 @@
+/**
+ * Autogenerated by Avro
+ * 
+ * DO NOT EDIT DIRECTLY
+ */
+package org.apache.gora.examples.generated;  
+@SuppressWarnings("all")
+/** Record with only immutable or dirtyable fields, used for testing */
+public class ImmutableFields extends org.apache.gora.persistency.impl.PersistentBase implements org.apache.avro.specific.SpecificRecord, org.apache.gora.persistency.Persistent {
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"ImmutableFields\",\"namespace\":\"org.apache.gora.examples.generated\",\"doc\":\"Record with only immutable or dirtyable fields, used for testing\",\"fields\":[{\"name\":\"__g__dirty\",\"type\":\"bytes\",\"doc\":\"Bytes used to represent weather or not a field is dirty.\",\"default\":\"AA==\"},{\"name\":\"v1\",\"type\":\"int\"},{\"name\":\"v2\",\"type\":[{\"type\":\"record\",\"name\":\"V2\",\"fields\":[{\"name\":\"__g__dirty\",\"type\":\"bytes\",\"doc\":\"Bytes used to represent weather or not a field is dirty.\",\"default\":\"AA==\"},{\"name\":\"v3\",\"type\":\"int\"}]},\"null\"]}]}");
+  /** Bytes used to represent weather or not a field is dirty. */
+  private java.nio.ByteBuffer __g__dirty = java.nio.ByteBuffer.wrap(new byte[1]);
+  private int v1;
+  private org.apache.gora.examples.generated.V2 v2;
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call. 
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return __g__dirty;
+    case 1: return v1;
+    case 2: return v2;
+    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+    }
+  }
+  // Used by DatumReader.  Applications should not call. 
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: __g__dirty = (java.nio.ByteBuffer)value$; break;
+    case 1: v1 = (java.lang.Integer)value$; break;
+    case 2: v2 = (org.apache.gora.examples.generated.V2)value$; break;
+    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+    }
+  }
+
+  /**
+   * Gets the value of the 'v1' field.
+   */
+  public java.lang.Integer getV1() {
+    return v1;
+  }
+
+  /**
+   * Sets the value of the 'v1' field.
+   * @param value the value to set.
+   */
+  public void setV1(java.lang.Integer value) {
+    this.v1 = value;
+    setDirty(1);
+  }
+  
+  /**
+   * Checks the dirty status of the 'v1' field. A field is dirty if it represents a change that has not yet been written to the database.
+   * @param value the value to set.
+   */
+  public boolean isV1Dirty(java.lang.Integer value) {
+    return isDirty(1);
+  }
+
+  /**
+   * Gets the value of the 'v2' field.
+   */
+  public org.apache.gora.examples.generated.V2 getV2() {
+    return v2;
+  }
+
+  /**
+   * Sets the value of the 'v2' field.
+   * @param value the value to set.
+   */
+  public void setV2(org.apache.gora.examples.generated.V2 value) {
+    this.v2 = value;
+    setDirty(2);
+  }
+  
+  /**
+   * Checks the dirty status of the 'v2' field. A field is dirty if it represents a change that has not yet been written to the database.
+   * @param value the value to set.
+   */
+  public boolean isV2Dirty(org.apache.gora.examples.generated.V2 value) {
+    return isDirty(2);
+  }
+
+  /** Creates a new ImmutableFields RecordBuilder */
+  public static org.apache.gora.examples.generated.ImmutableFields.Builder newBuilder() {
+    return new org.apache.gora.examples.generated.ImmutableFields.Builder();
+  }
+  
+  /** Creates a new ImmutableFields RecordBuilder by copying an existing Builder */
+  public static org.apache.gora.examples.generated.ImmutableFields.Builder newBuilder(org.apache.gora.examples.generated.ImmutableFields.Builder other) {
+    return new org.apache.gora.examples.generated.ImmutableFields.Builder(other);
+  }
+  
+  /** Creates a new ImmutableFields RecordBuilder by copying an existing ImmutableFields instance */
+  public static org.apache.gora.examples.generated.ImmutableFields.Builder newBuilder(org.apache.gora.examples.generated.ImmutableFields other) {
+    return new org.apache.gora.examples.generated.ImmutableFields.Builder(other);
+  }
+  
+  private static java.nio.ByteBuffer deepCopyToWriteOnlyBuffer(
+      java.nio.ByteBuffer input) {
+    java.nio.ByteBuffer copy = java.nio.ByteBuffer.allocate(input.capacity());
+    int position = input.position();
+    input.reset();
+    int mark = input.position();
+    int limit = input.limit();
+    input.rewind();
+    input.limit(input.capacity());
+    copy.put(input);
+    input.rewind();
+    copy.rewind();
+    input.position(mark);
+    input.mark();
+    copy.position(mark);
+    copy.mark();
+    input.position(position);
+    copy.position(position);
+    input.limit(limit);
+    copy.limit(limit);
+    return copy.asReadOnlyBuffer();
+  }
+  
+  /**
+   * RecordBuilder for ImmutableFields instances.
+   */
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<ImmutableFields>
+    implements org.apache.avro.data.RecordBuilder<ImmutableFields> {
+
+    private java.nio.ByteBuffer __g__dirty;
+    private int v1;
+    private org.apache.gora.examples.generated.V2 v2;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(org.apache.gora.examples.generated.ImmutableFields.SCHEMA$);
+    }
+    
+    /** Creates a Builder by copying an existing Builder */
+    private Builder(org.apache.gora.examples.generated.ImmutableFields.Builder other) {
+      super(other);
+    }
+    
+    /** Creates a Builder by copying an existing ImmutableFields instance */
+    private Builder(org.apache.gora.examples.generated.ImmutableFields other) {
+            super(org.apache.gora.examples.generated.ImmutableFields.SCHEMA$);
+      if (isValidValue(fields()[0], other.__g__dirty)) {
+        this.__g__dirty = (java.nio.ByteBuffer) data().deepCopy(fields()[0].schema(), other.__g__dirty);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.v1)) {
+        this.v1 = (java.lang.Integer) data().deepCopy(fields()[1].schema(), other.v1);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.v2)) {
+        this.v2 = (org.apache.gora.examples.generated.V2) data().deepCopy(fields()[2].schema(), other.v2);
+        fieldSetFlags()[2] = true;
+      }
+    }
+
+    /** Gets the value of the 'v1' field */
+    public java.lang.Integer getV1() {
+      return v1;
+    }
+    
+    /** Sets the value of the 'v1' field */
+    public org.apache.gora.examples.generated.ImmutableFields.Builder setV1(int value) {
+      validate(fields()[1], value);
+      this.v1 = value;
+      fieldSetFlags()[1] = true;
+      return this; 
+    }
+    
+    /** Checks whether the 'v1' field has been set */
+    public boolean hasV1() {
+      return fieldSetFlags()[1];
+    }
+    
+    /** Clears the value of the 'v1' field */
+    public org.apache.gora.examples.generated.ImmutableFields.Builder clearV1() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+    
+    /** Gets the value of the 'v2' field */
+    public org.apache.gora.examples.generated.V2 getV2() {
+      return v2;
+    }
+    
+    /** Sets the value of the 'v2' field */
+    public org.apache.gora.examples.generated.ImmutableFields.Builder setV2(org.apache.gora.examples.generated.V2 value) {
+      validate(fields()[2], value);
+      this.v2 = value;
+      fieldSetFlags()[2] = true;
+      return this; 
+    }
+    
+    /** Checks whether the 'v2' field has been set */
+    public boolean hasV2() {
+      return fieldSetFlags()[2];
+    }
+    
+    /** Clears the value of the 'v2' field */
+    public org.apache.gora.examples.generated.ImmutableFields.Builder clearV2() {
+      v2 = null;
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+    
+    @Override
+    public ImmutableFields build() {
+      try {
+        ImmutableFields record = new ImmutableFields();
+        record.__g__dirty = fieldSetFlags()[0] ? this.__g__dirty : (java.nio.ByteBuffer) defaultValue(fields()[0]);
+        record.v1 = fieldSetFlags()[1] ? this.v1 : (java.lang.Integer) defaultValue(fields()[1]);
+        record.v2 = fieldSetFlags()[2] ? this.v2 : (org.apache.gora.examples.generated.V2) defaultValue(fields()[2]);
+        return record;
+      } catch (Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+  
+  public ImmutableFields.Tombstone getTombstone(){
+  	return TOMBSTONE;
+  }
+
+  private static final Tombstone TOMBSTONE = new Tombstone();
+  
+  public static final class Tombstone extends ImmutableFields implements org.apache.gora.persistency.Tombstone {
+  
+      private Tombstone() { }
+  
+	  				  /**
+	   * Gets the value of the 'v1' field.
+		   */
+	  public java.lang.Integer getV1() {
+	    throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+	  }
+	
+	  /**
+	   * Sets the value of the 'v1' field.
+		   * @param value the value to set.
+	   */
+	  public void setV1(java.lang.Integer value) {
+	    throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+	  }
+	  
+	  /**
+	   * Checks the dirty status of the 'v1' field. A field is dirty if it represents a change that has not yet been written to the database.
+		   * @param value the value to set.
+	   */
+	  public boolean isV1Dirty(java.lang.Integer value) {
+	    throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+	  }
+	
+				  /**
+	   * Gets the value of the 'v2' field.
+		   */
+	  public org.apache.gora.examples.generated.V2 getV2() {
+	    throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+	  }
+	
+	  /**
+	   * Sets the value of the 'v2' field.
+		   * @param value the value to set.
+	   */
+	  public void setV2(org.apache.gora.examples.generated.V2 value) {
+	    throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+	  }
+	  
+	  /**
+	   * Checks the dirty status of the 'v2' field. A field is dirty if it represents a change that has not yet been written to the database.
+		   * @param value the value to set.
+	   */
+	  public boolean isV2Dirty(org.apache.gora.examples.generated.V2 value) {
+	    throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+	  }
+	
+		  
+  }
+  
+}
\ No newline at end of file

Added: gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java (added)
+++ gora/branches/GORA_94/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,199 @@
+/**
+ * Autogenerated by Avro
+ * 
+ * DO NOT EDIT DIRECTLY
+ */
+package org.apache.gora.examples.generated;  
+@SuppressWarnings("all")
+public class V2 extends org.apache.gora.persistency.impl.PersistentBase implements org.apache.avro.specific.SpecificRecord, org.apache.gora.persistency.Persistent {
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"V2\",\"namespace\":\"org.apache.gora.examples.generated\",\"fields\":[{\"name\":\"__g__dirty\",\"type\":\"bytes\",\"doc\":\"Bytes used to represent weather or not a field is dirty.\",\"default\":\"AA==\"},{\"name\":\"v3\",\"type\":\"int\"}]}");
+  /** Bytes used to represent weather or not a field is dirty. */
+  private java.nio.ByteBuffer __g__dirty = java.nio.ByteBuffer.wrap(new byte[1]);
+  private int v3;
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call. 
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return __g__dirty;
+    case 1: return v3;
+    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+    }
+  }
+  // Used by DatumReader.  Applications should not call. 
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: __g__dirty = (java.nio.ByteBuffer)value$; break;
+    case 1: v3 = (java.lang.Integer)value$; break;
+    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+    }
+  }
+
+  /**
+   * Gets the value of the 'v3' field.
+   */
+  public java.lang.Integer getV3() {
+    return v3;
+  }
+
+  /**
+   * Sets the value of the 'v3' field.
+   * @param value the value to set.
+   */
+  public void setV3(java.lang.Integer value) {
+    this.v3 = value;
+    setDirty(1);
+  }
+  
+  /**
+   * Checks the dirty status of the 'v3' field. A field is dirty if it represents a change that has not yet been written to the database.
+   * @param value the value to set.
+   */
+  public boolean isV3Dirty(java.lang.Integer value) {
+    return isDirty(1);
+  }
+
+  /** Creates a new V2 RecordBuilder */
+  public static org.apache.gora.examples.generated.V2.Builder newBuilder() {
+    return new org.apache.gora.examples.generated.V2.Builder();
+  }
+  
+  /** Creates a new V2 RecordBuilder by copying an existing Builder */
+  public static org.apache.gora.examples.generated.V2.Builder newBuilder(org.apache.gora.examples.generated.V2.Builder other) {
+    return new org.apache.gora.examples.generated.V2.Builder(other);
+  }
+  
+  /** Creates a new V2 RecordBuilder by copying an existing V2 instance */
+  public static org.apache.gora.examples.generated.V2.Builder newBuilder(org.apache.gora.examples.generated.V2 other) {
+    return new org.apache.gora.examples.generated.V2.Builder(other);
+  }
+  
+  private static java.nio.ByteBuffer deepCopyToWriteOnlyBuffer(
+      java.nio.ByteBuffer input) {
+    java.nio.ByteBuffer copy = java.nio.ByteBuffer.allocate(input.capacity());
+    int position = input.position();
+    input.reset();
+    int mark = input.position();
+    int limit = input.limit();
+    input.rewind();
+    input.limit(input.capacity());
+    copy.put(input);
+    input.rewind();
+    copy.rewind();
+    input.position(mark);
+    input.mark();
+    copy.position(mark);
+    copy.mark();
+    input.position(position);
+    copy.position(position);
+    input.limit(limit);
+    copy.limit(limit);
+    return copy.asReadOnlyBuffer();
+  }
+  
+  /**
+   * RecordBuilder for V2 instances.
+   */
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<V2>
+    implements org.apache.avro.data.RecordBuilder<V2> {
+
+    private java.nio.ByteBuffer __g__dirty;
+    private int v3;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(org.apache.gora.examples.generated.V2.SCHEMA$);
+    }
+    
+    /** Creates a Builder by copying an existing Builder */
+    private Builder(org.apache.gora.examples.generated.V2.Builder other) {
+      super(other);
+    }
+    
+    /** Creates a Builder by copying an existing V2 instance */
+    private Builder(org.apache.gora.examples.generated.V2 other) {
+            super(org.apache.gora.examples.generated.V2.SCHEMA$);
+      if (isValidValue(fields()[0], other.__g__dirty)) {
+        this.__g__dirty = (java.nio.ByteBuffer) data().deepCopy(fields()[0].schema(), other.__g__dirty);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.v3)) {
+        this.v3 = (java.lang.Integer) data().deepCopy(fields()[1].schema(), other.v3);
+        fieldSetFlags()[1] = true;
+      }
+    }
+
+    /** Gets the value of the 'v3' field */
+    public java.lang.Integer getV3() {
+      return v3;
+    }
+    
+    /** Sets the value of the 'v3' field */
+    public org.apache.gora.examples.generated.V2.Builder setV3(int value) {
+      validate(fields()[1], value);
+      this.v3 = value;
+      fieldSetFlags()[1] = true;
+      return this; 
+    }
+    
+    /** Checks whether the 'v3' field has been set */
+    public boolean hasV3() {
+      return fieldSetFlags()[1];
+    }
+    
+    /** Clears the value of the 'v3' field */
+    public org.apache.gora.examples.generated.V2.Builder clearV3() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+    
+    @Override
+    public V2 build() {
+      try {
+        V2 record = new V2();
+        record.__g__dirty = fieldSetFlags()[0] ? this.__g__dirty : (java.nio.ByteBuffer) defaultValue(fields()[0]);
+        record.v3 = fieldSetFlags()[1] ? this.v3 : (java.lang.Integer) defaultValue(fields()[1]);
+        return record;
+      } catch (Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+  
+  public V2.Tombstone getTombstone(){
+  	return TOMBSTONE;
+  }
+
+  private static final Tombstone TOMBSTONE = new Tombstone();
+  
+  public static final class Tombstone extends V2 implements org.apache.gora.persistency.Tombstone {
+  
+      private Tombstone() { }
+  
+	  				  /**
+	   * Gets the value of the 'v3' field.
+		   */
+	  public java.lang.Integer getV3() {
+	    throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+	  }
+	
+	  /**
+	   * Sets the value of the 'v3' field.
+		   * @param value the value to set.
+	   */
+	  public void setV3(java.lang.Integer value) {
+	    throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+	  }
+	  
+	  /**
+	   * Checks the dirty status of the 'v3' field. A field is dirty if it represents a change that has not yet been written to the database.
+		   * @param value the value to set.
+	   */
+	  public boolean isV3Dirty(java.lang.Integer value) {
+	    throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+	  }
+	
+		  
+  }
+  
+}
\ No newline at end of file

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/avro/store/AvroStore.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/avro/store/AvroStore.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/avro/store/AvroStore.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/avro/store/AvroStore.java Sat Aug 24 00:27:39 2013
@@ -28,7 +28,9 @@ import org.apache.avro.io.BinaryEncoder;
 import org.apache.avro.io.DatumReader;
 import org.apache.avro.io.DatumWriter;
 import org.apache.avro.io.Decoder;
+import org.apache.avro.io.DecoderFactory;
 import org.apache.avro.io.Encoder;
+import org.apache.avro.io.EncoderFactory;
 import org.apache.avro.io.JsonDecoder;
 import org.apache.avro.io.JsonEncoder;
 import org.apache.avro.specific.SpecificDatumReader;
@@ -220,20 +222,19 @@ public class AvroStore<K, T extends Pers
   protected Encoder createEncoder() throws IOException {
     switch(codecType) {
       case BINARY:
-        return new BinaryEncoder(getOrCreateOutputStream());
+        return EncoderFactory.get().binaryEncoder(getOrCreateOutputStream(), null);
       case JSON:
-        return new JsonEncoder(schema, getOrCreateOutputStream());
+        return EncoderFactory.get().jsonEncoder(schema, getOrCreateOutputStream());
     }
     return null;
   }
 
-  @SuppressWarnings("deprecation")
   protected Decoder createDecoder() throws IOException {
     switch(codecType) {
       case BINARY:
-        return new BinaryDecoder(getOrCreateInputStream());
+        return DecoderFactory.get().binaryDecoder(getOrCreateInputStream(), null);
       case JSON:
-        return new JsonDecoder(schema, getOrCreateInputStream());
+        return DecoderFactory.get().jsonDecoder(schema, getOrCreateInputStream());
     }
     return null;
   }

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/GoraMapReduceUtils.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/GoraMapReduceUtils.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/GoraMapReduceUtils.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/GoraMapReduceUtils.java Sat Aug 24 00:27:39 2013
@@ -47,10 +47,6 @@ public class GoraMapReduceUtils {
   public static void setIOSerializations(Configuration conf, boolean reuseObjects) {
     String serializationClass =
       PersistentSerialization.class.getCanonicalName();
-    if (!reuseObjects) {
-      serializationClass =
-        PersistentNonReusingSerialization.class.getCanonicalName();
-    }
     String[] serializations = StringUtils.joinStringArrays(
         conf.getStrings("io.serializations"), 
         "org.apache.hadoop.io.serializer.WritableSerialization",

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentDeserializer.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentDeserializer.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentDeserializer.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentDeserializer.java Sat Aug 24 00:27:39 2013
@@ -23,53 +23,51 @@ import java.io.InputStream;
 import org.apache.avro.Schema;
 import org.apache.avro.io.BinaryDecoder;
 import org.apache.avro.io.DecoderFactory;
-import org.apache.gora.avro.PersistentDatumReader;
+import org.apache.avro.specific.SpecificDatumReader;
 import org.apache.gora.persistency.Persistent;
-import org.apache.gora.persistency.impl.PersistentBase;
 import org.apache.gora.util.AvroUtils;
 import org.apache.hadoop.io.serializer.Deserializer;
 
 /**
-* Hadoop deserializer using {@link PersistentDatumReader}
+* Hadoop deserializer using {@link SpecificDatumReader}
 * with {@link BinaryDecoder}.
 */
 public class PersistentDeserializer
-   implements Deserializer<PersistentBase> {
+   implements Deserializer<Persistent> {
 
   private BinaryDecoder decoder;
-  private Class<? extends PersistentBase> persistentClass;
+  private Class<? extends Persistent> persistentClass;
   private boolean reuseObjects;
-  private PersistentDatumReader<PersistentBase> datumReader;
+  private SpecificDatumReader<Persistent> datumReader;
 
-  public PersistentDeserializer(Class<? extends PersistentBase> c, boolean reuseObjects) {
+  public PersistentDeserializer(Class<? extends Persistent> c, boolean reuseObjects) {
     this.persistentClass = c;
     this.reuseObjects = reuseObjects;
     try {
       Schema schema = AvroUtils.getSchema(persistentClass);
-      datumReader = new PersistentDatumReader<PersistentBase>(schema, true);
+      datumReader = new SpecificDatumReader<Persistent>(schema);
 
     } catch (Exception ex) {
       throw new RuntimeException(ex);
     }
   }
 
-  //@Override
+  @Override
   public void open(InputStream in) throws IOException {
     /* It is very important to use a direct buffer, since Hadoop
-     * supplies an input stream that is only valid until the end of one
-     * record serialization. Each time deserialize() is called, the IS
-     * is advanced to point to the right location, so we should not
-     * buffer the whole input stream at once.
-     */
-    decoder = new DecoderFactory().configureDirectDecoder(true)
-      .createBinaryDecoder(in, decoder);
+* supplies an input stream that is only valid until the end of one
+* record serialization. Each time deserialize() is called, the IS
+* is advanced to point to the right location, so we should not
+* buffer the whole input stream at once.
+*/
+    decoder = DecoderFactory.get().directBinaryDecoder(in, decoder);
   }
 
-  //@Override
+  @Override
   public void close() throws IOException { }
 
   @Override
-  public PersistentBase deserialize(PersistentBase persistent) throws IOException {
+  public Persistent deserialize(Persistent persistent) throws IOException {
     return datumReader.read(reuseObjects ? persistent : null, decoder);
   }
 }

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerialization.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerialization.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerialization.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerialization.java Sat Aug 24 00:27:39 2013
@@ -17,13 +17,13 @@
  */
 package org.apache.gora.mapreduce;
 
-import org.apache.gora.persistency.impl.PersistentBase;
 import org.apache.gora.persistency.Persistent;
 import org.apache.hadoop.io.serializer.Deserializer;
 import org.apache.hadoop.io.serializer.Serialization;
 import org.apache.hadoop.io.serializer.Serializer;
 
-public class PersistentSerialization implements Serialization<PersistentBase> {
+public class PersistentSerialization
+implements Serialization<Persistent> {
 
   @Override
   public boolean accept(Class<?> c) {
@@ -31,12 +31,12 @@ public class PersistentSerialization imp
   }
 
   @Override
-  public Deserializer<PersistentBase> getDeserializer(Class<PersistentBase> c) {
+  public Deserializer<Persistent> getDeserializer(Class<Persistent> c) {
     return new PersistentDeserializer(c, true);
   }
 
   @Override
-  public Serializer<PersistentBase> getSerializer(Class<PersistentBase> c) {
+  public Serializer<Persistent> getSerializer(Class<Persistent> c) {
     return new PersistentSerializer();
   }
 }

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerializer.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerializer.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerializer.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/mapreduce/PersistentSerializer.java Sat Aug 24 00:27:39 2013
@@ -1,57 +1,57 @@
 /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 package org.apache.gora.mapreduce;
 
 import java.io.IOException;
 import java.io.OutputStream;
 
 import org.apache.avro.io.BinaryEncoder;
-import org.apache.gora.avro.PersistentDatumWriter;
-import org.apache.gora.persistency.impl.PersistentBase;
+import org.apache.avro.io.EncoderFactory;
+import org.apache.avro.specific.SpecificDatumWriter;
+import org.apache.gora.persistency.Persistent;
 import org.apache.hadoop.io.serializer.Serializer;
 
 /**
- * Hadoop serializer using {@link PersistentDatumWriter} 
- * with {@link BinaryEncoder}. 
- */
-public class PersistentSerializer implements Serializer<PersistentBase> {
+* Hadoop serializer using {@link SpecificDatumWriter}
+* with {@link BinaryEncoder}.
+*/
+public class PersistentSerializer implements Serializer<Persistent> {
 
-  private PersistentDatumWriter<PersistentBase> datumWriter;
-  private BinaryEncoder encoder;  
+  private SpecificDatumWriter<Persistent> datumWriter;
+  private BinaryEncoder encoder;
   
   public PersistentSerializer() {
-    this.datumWriter = new PersistentDatumWriter<PersistentBase>();
+    this.datumWriter = new SpecificDatumWriter<Persistent>();
   }
   
-  //@Override
+  @Override
   public void close() throws IOException {
     encoder.flush();
   }
 
-  //@Override
+  @Override
   public void open(OutputStream out) throws IOException {
-    encoder = new BinaryEncoder(out);
+    encoder = EncoderFactory.get().directBinaryEncoder(out, null);
   }
 
   @Override
-  public void serialize(PersistentBase persistent) throws IOException {   
+  public void serialize(Persistent persistent) throws IOException {
     datumWriter.setSchema(persistent.getSchema());
-    datumWriter.setPersistent(persistent);
         
     datumWriter.write(persistent, encoder);
   }

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/memory/store/MemStore.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/memory/store/MemStore.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/memory/store/MemStore.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/memory/store/MemStore.java Sat Aug 24 00:27:39 2013
@@ -26,9 +26,11 @@ import java.util.List;
 import java.util.NavigableMap;
 import java.util.TreeMap;
 
+
+import org.apache.avro.Schema.Field;
+
 import org.apache.gora.persistency.Persistent;
 import org.apache.gora.persistency.impl.PersistentBase;
-import org.apache.gora.persistency.impl.StateManagerImpl;
 import org.apache.gora.query.PartitionQuery;
 import org.apache.gora.query.Query;
 import org.apache.gora.query.Result;
@@ -37,6 +39,7 @@ import org.apache.gora.query.impl.QueryB
 import org.apache.gora.query.impl.ResultBase;
 import org.apache.gora.store.DataStore;
 import org.apache.gora.store.impl.DataStoreBase;
+import org.apache.gora.util.AvroUtils;
 
 /**
  * Memory based {@link DataStore} implementation for tests.
@@ -99,19 +102,19 @@ public class MemStore<K, T extends Persi
 
   @Override
   public long deleteByQuery(Query<K, T> query) {
-	try{
-		long deletedRows = 0;
-	    Result<K,T> result = query.execute();
-	
-	    while(result.next()) {
-	      if(delete(result.getKey()))
-	        deletedRows++;
-	    }
-	    return 0;
-	  }
-	catch(Exception e){
-		  return 0;
-	}
+  try{
+    long deletedRows = 0;
+      Result<K,T> result = query.execute();
+
+      while(result.next()) {
+        if(delete(result.getKey()))
+          deletedRows++;
+      }
+      return 0;
+    }
+    catch(Exception e){
+      return 0;
+    }
   }
 
   @Override
@@ -142,15 +145,19 @@ public class MemStore<K, T extends Persi
   /**
    * Returns a clone with exactly the requested fields shallowly copied
    */
-  @SuppressWarnings("unchecked")
   private static<T extends Persistent> T getPersistent(T obj, String[] fields) {
-    if(Arrays.equals(fields, obj.getFields())) {
+    List<Field> otherFields = obj.getSchema().getFields();
+    String[] otherFieldStrings = new String[otherFields.size()];
+    for(int i = 0; i<otherFields.size(); i++ ){
+      otherFieldStrings[i] = otherFields.get(i).name();
+    }
+    if(Arrays.equals(fields, otherFieldStrings)) { 
       return obj;
     }
-    T newObj = (T) obj.newInstance(new StateManagerImpl());
-    for(String field:fields) {
-      int index = newObj.getFieldIndex(field);
-      ((PersistentBase)newObj).put(index, ((PersistentBase)obj).get(index));
+    T newObj = (T) AvroUtils.deepClonePersistent(obj); 
+      for(int i = 0; i<otherFields.size(); i++) {
+      int index = otherFields.get(i).pos(); 
+      newObj.put(index, obj.get(index));
     }
     return newObj;
   }

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Dirtyable.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Dirtyable.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Dirtyable.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Dirtyable.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,41 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.gora.persistency;
+
+/**
+ * Interface designed to accomodate structures that can be dirty, such as maps
+ * and lists, but whose dirtyness should not be set directly because dirtyness
+ * results from structural modification or content change, and which have no
+ * notion of ordered fields (such as Persistent).
+ */
+public interface Dirtyable {
+
+  /**
+   * Returns whether any of the fields of the object has been modified after
+   * construction or loading.
+   * 
+   * @return whether any of the fields of the object has changed
+   */
+  boolean isDirty();
+
+  /**
+   * Clears the dirty state.
+   */
+  void clearDirty();
+
+}

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Persistent.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Persistent.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Persistent.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Persistent.java Sat Aug 24 00:27:39 2013
@@ -1,185 +1,112 @@
 /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 package org.apache.gora.persistency;
 
+import java.util.List;
+
+import org.apache.avro.Schema.Field;
+import org.apache.avro.specific.SpecificRecord;
+
+import org.apache.gora.persistency.Dirtyable;
+
 /**
- * Objects that are persisted by Gora implements this interface.
- */
-public interface Persistent extends Cloneable{
-
-  /**
-   * Returns the StateManager which manages the persistent 
-   * state of the object.
-   * @return the StateManager of the object
-   */
-  StateManager getStateManager();
-
-  /**
-   * Constructs a new instance of the object with the given StateManager.
-   * This method is intended to be used by Gora framework.
-   * @param stateManager the StateManager to manage the persistent state 
-   * of the object
-   * @return a new instance of the object
-   */
-  Persistent newInstance(StateManager stateManager);
-
-  /**
-   * Returns sorted field names of the object
-   * @return the field names of the object as a String[]
-   */
-  String[] getFields();
-  
-  /**
-   * Returns the field name with the given index
-   * @param index the index of the field  
-   * @return the name of the field
-   */
-  String getField(int index);
-  
-  /**
-   * Returns the index of the field with the given name
-   * @param field the name of the field
-   * @return the index of the field
-   */
-  int getFieldIndex(String field);
-  
-  /**
-   * Clears the inner state of the object without any modification
-   * to the actual data on the data store. This method should be called 
-   * before re-using the object to hold the data for another result.  
-   */
+* Objects that are persisted by Gora implements this interface.
+*/
+public interface Persistent extends SpecificRecord, Dirtyable {
+
+  public static String DIRTY_BYTES_FIELD_NAME = "__g__dirty";
+
+  /**
+* Clears the inner state of the object without any modification to the actual
+* data on the data store. This method should be called before re-using the
+* object to hold the data for another result.
+*/
   void clear();
-  
+
   /**
-   * Returns whether the object is newly constructed.
-   * @return true if the object is newly constructed, false if
-   * retrieved from a datastore. 
-   */
-  boolean isNew();
-  
-  /**
-   * Sets the state of the object as new for persistency
-   */
-  void setNew();
-  
-  /**
-   * Clears the new state 
-   */
-  void clearNew();
-  
-  /**
-   * Returns whether any of the fields of the object has been modified 
-   * after construction or loading. 
-   * @return whether any of the fields of the object has changed
-   */
-  boolean isDirty();
-  
-  /**
-   * Returns whether the field has been modified.
-   * @param fieldIndex the offset of the field in the object
-   * @return whether the field has been modified.
-   */
+* Returns whether the field has been modified.
+*
+* @param fieldIndex
+* the offset of the field in the object
+* @return whether the field has been modified.
+*/
   boolean isDirty(int fieldIndex);
 
   /**
-   * Returns whether the field has been modified.
-   * @param field the name of the field
-   * @return whether the field has been modified.
-   */
+* Returns whether the field has been modified.
+*
+* @param field
+* the name of the field
+* @return whether the field has been modified.
+*/
   boolean isDirty(String field);
-  
+
   /**
-   * Sets all the fields of the object as dirty.
-   */
+* Sets all the fields of the object as dirty.
+*/
   void setDirty();
-  
+
   /**
-   * Sets the field as dirty.
-   * @param fieldIndex the offset of the field in the object
-   */
+* Sets the field as dirty.
+*
+* @param fieldIndex
+* the offset of the field in the object
+*/
   void setDirty(int fieldIndex);
- 
+
   /**
-   * Sets the field as dirty.
-   * @param field the name of the field
-   */
+* Sets the field as dirty.
+*
+* @param field
+* the name of the field
+*/
   void setDirty(String field);
-  
+
   /**
-   * Clears the field as dirty.
-   * @param fieldIndex the offset of the field in the object
-   */
+* Clears the field as dirty.
+*
+* @param fieldIndex
+* the offset of the field in the object
+*/
   void clearDirty(int fieldIndex);
-  
+
   /**
-   * Clears the field as dirty.
-   * @param field the name of the field
-   */
+* Clears the field as dirty.
+*
+* @param field
+* the name of the field
+*/
   void clearDirty(String field);
-  
+
+  /**
+* Get an object which can be used to mark this field as deleted (rather than
+* state unknown, which is indicated by null).
+*
+* @return a tombstone.
+*/
+  public abstract Tombstone getTombstone();
+
   /**
-   * Clears the dirty state.
-   */
-  void clearDirty();
-  
-  /**
-   * Returns whether the field has been loaded from the datastore. 
-   * @param fieldIndex the offset of the field in the object
-   * @return whether the field has been loaded 
-   */
-  boolean isReadable(int fieldIndex);
-
-  /**
-   * Returns whether the field has been loaded from the datastore. 
-   * @param field the name of the field
-   * @return whether the field has been loaded 
-   */
-  boolean isReadable(String field);
-  
-  /**
-   * Sets the field as readable.
-   * @param fieldIndex the offset of the field in the object
-   */
-  void setReadable(int fieldIndex);
-
-  /**
-   * Sets the field as readable.
-   * @param field the name of the field
-   */
-  void setReadable(String field);
-
-  /**
-   * Clears the field as readable.
-   * @param fieldIndex the offset of the field in the object
-   */
-  void clearReadable(int fieldIndex);
-  
-  /**
-   * Sets the field as readable.
-   * @param field the name of the field
-   */
-  void clearReadable(String field);
-  
-  /**
-   * Clears the readable state.
-   */
-  void clearReadable();
-  
-  Persistent clone();
+* Get a list of fields from this persistent object's schema that are not
+* managed by Gora.
+*
+* @return the unmanaged fields
+*/
+  public List<Field> getUnmanagedFields();
 
 }
\ No newline at end of file

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstone.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstone.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstone.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstone.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,16 @@
+package org.apache.gora.persistency;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Marker interface used to signal a deletion to Gora.
+ */
+public interface Tombstone {
+
+}

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstones.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstones.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstones.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/Tombstones.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,242 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.gora.persistency;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+public final class Tombstones {
+
+  private Tombstones() {
+
+  }
+
+  public static final class MapTombstone<K, V> implements Tombstone, Map<K, V> {
+
+    private MapTombstone() {
+    }
+
+    private static final Map DELEGATE = Collections.EMPTY_MAP;
+
+    public int size() {
+      return DELEGATE.size();
+    }
+
+    public boolean isEmpty() {
+      return DELEGATE.isEmpty();
+    }
+
+    public boolean containsKey(Object key) {
+      return DELEGATE.containsKey(key);
+    }
+
+    public boolean containsValue(Object value) {
+      return DELEGATE.containsValue(value);
+    }
+
+    @SuppressWarnings("unchecked")
+    public V get(Object key) {
+      return (V) DELEGATE.get(key);
+    }
+
+    @SuppressWarnings("unchecked")
+    public V put(Object key, Object value) {
+      return (V) DELEGATE.put(key, value);
+    }
+
+    @SuppressWarnings("unchecked")
+    public V remove(Object key) {
+      return (V) DELEGATE.remove(key);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void putAll(Map m) {
+      DELEGATE.putAll(m);
+    }
+
+    public void clear() {
+      DELEGATE.clear();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Set keySet() {
+      return DELEGATE.keySet();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection values() {
+      return DELEGATE.values();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Set entrySet() {
+      return DELEGATE.entrySet();
+    }
+
+    public boolean equals(Object o) {
+      return DELEGATE.equals(o);
+    }
+
+    public int hashCode() {
+      return DELEGATE.hashCode();
+    }
+
+  }
+
+  public static final class ListTombstone<T> implements List<T>, Tombstone {
+    
+    private static final List DELEGATE = Collections.EMPTY_LIST;
+
+    private ListTombstone() {
+    }
+
+    public int size() {
+      return DELEGATE.size();
+    }
+
+    public boolean isEmpty() {
+      return DELEGATE.isEmpty();
+    }
+
+    public boolean contains(Object o) {
+      return DELEGATE.contains(o);
+    }
+
+    public Iterator iterator() {
+      return DELEGATE.iterator();
+    }
+
+    public Object[] toArray() {
+      return DELEGATE.toArray();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object[] toArray(Object[] a) {
+      return DELEGATE.toArray(a);
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean add(Object e) {
+      return DELEGATE.add(e);
+    }
+
+    public boolean remove(Object o) {
+      return DELEGATE.remove(o);
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean containsAll(Collection c) {
+      return DELEGATE.containsAll(c);
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean addAll(Collection c) {
+      return DELEGATE.addAll(c);
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean addAll(int index, Collection c) {
+      return DELEGATE.addAll(index, c);
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean removeAll(Collection c) {
+      return DELEGATE.removeAll(c);
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean retainAll(Collection c) {
+      return DELEGATE.retainAll(c);
+    }
+
+    public void clear() {
+      DELEGATE.clear();
+    }
+
+    public boolean equals(Object o) {
+      return DELEGATE.equals(o);
+    }
+
+    public int hashCode() {
+      return DELEGATE.hashCode();
+    }
+
+    @SuppressWarnings("unchecked")
+    public T get(int index) {
+      return (T) DELEGATE.get(index);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object set(int index, Object element) {
+      return DELEGATE.set(index, element);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void add(int index, Object element) {
+      DELEGATE.add(index, element);
+    }
+
+    @SuppressWarnings("unchecked")
+    public T remove(int index) {
+      return (T) DELEGATE.remove(index);
+    }
+
+    public int indexOf(Object o) {
+      return DELEGATE.indexOf(o);
+    }
+
+    public int lastIndexOf(Object o) {
+      return DELEGATE.lastIndexOf(o);
+    }
+
+    public ListIterator listIterator() {
+      return DELEGATE.listIterator();
+    }
+
+    public ListIterator listIterator(int index) {
+      return DELEGATE.listIterator(index);
+    }
+
+    public List subList(int fromIndex, int toIndex) {
+      return DELEGATE.subList(fromIndex, toIndex);
+    }
+
+  }
+
+  public static final MapTombstone MAP_TOMBSTONE = new MapTombstone();
+
+  public static <K, V> MapTombstone<K, V> getMapTombstone() {
+    return MAP_TOMBSTONE;
+  }
+
+  public static final ListTombstone LIST_TOMBSTONE = new ListTombstone();
+
+  public static final <T> ListTombstone<T> getListTombstone() {
+    return LIST_TOMBSTONE;
+  }
+
+  public static boolean isTombstone(Object o) {
+    return (o instanceof Tombstone);
+  }
+
+}

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/BeanFactoryImpl.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/BeanFactoryImpl.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/BeanFactoryImpl.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/BeanFactoryImpl.java Sat Aug 24 00:27:39 2013
@@ -31,16 +31,29 @@ import org.apache.gora.util.ReflectionUt
  */
 public class BeanFactoryImpl<K, T extends Persistent> implements BeanFactory<K, T> {
 
+  /** Class of the key to be used */
   private Class<K> keyClass;
+  
+  /** Class of the persistent objects to be stored */
   private Class<T> persistentClass;
   
+  /** Constructor of the key */
   private Constructor<K> keyConstructor;
   
+  /** Object's key */
   private K key;
+  
+  /** Persistent object of class T */
   private T persistent;
   
+  /** Flag to be used to determine if a key is persistent or not */
   private boolean isKeyPersistent = false;
   
+  /**
+   * 
+   * @param keyClass
+   * @param persistentClass
+   */
   public BeanFactoryImpl(Class<K> keyClass, Class<T> persistentClass) {
     this.keyClass = keyClass;
     this.persistentClass = persistentClass;
@@ -59,21 +72,19 @@ public class BeanFactoryImpl<K, T extend
   }
   
   @Override
-  @SuppressWarnings("unchecked")
   public K newKey() throws Exception {
-    if(isKeyPersistent)
-      return (K)((Persistent)key).newInstance(new StateManagerImpl());
-    else if(keyConstructor == null) {
-      throw new RuntimeException("Key class does not have a no-arg constructor");
-    }
-    else
-      return keyConstructor.newInstance(ReflectionUtils.EMPTY_OBJECT_ARRAY);
+    return keyClass.newInstance();
   }
  
-  @SuppressWarnings("unchecked")
   @Override
   public T newPersistent() {
-    return (T) persistent.newInstance(new StateManagerImpl());
+    try {
+      return persistentClass.newInstance();
+    } catch (InstantiationException e) {
+      throw new RuntimeException(e);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
   }
   
   @Override

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyCollectionWrapper.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyCollectionWrapper.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyCollectionWrapper.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyCollectionWrapper.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,145 @@
+package org.apache.gora.persistency.impl;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.gora.persistency.Dirtyable;
+
+/**
+ * A {@link List} implementation that wraps another list, intercepting
+ * modifications to the list structure and reporting on weather or not the list
+ * has been modified, and also checking list elements for modification.
+ * 
+ * @param <T>
+ *          The type of the list that this wrapper wraps.
+ */
+public class DirtyCollectionWrapper<T> implements Dirtyable,
+    Collection<T> {
+
+  /** The delegate list that the wrapper wraps */
+  private final Collection<T> delegate;
+  /**
+   * The dirty flag, tracks if the structure of the underlying list has been
+   * modified
+   */
+  private DirtyFlag dirtyFlag;
+
+  DirtyCollectionWrapper(Collection<T> delegate2, DirtyFlag dirtyFlag) {
+    this.delegate = delegate2;
+    this.dirtyFlag = dirtyFlag;
+  }
+
+  @Override
+  public boolean isDirty() {
+    boolean anyDirty = false;
+    for (T value : this) {
+      anyDirty = anyDirty || (value instanceof Dirtyable) ? ((Dirtyable) value).isDirty():false;
+    }
+    return anyDirty || dirtyFlag.isDirty();
+  }
+
+  @Override
+  public void clearDirty() {
+    for (T value : this) {
+      if (value instanceof Dirtyable)
+        ((Dirtyable) value).clearDirty();
+    }
+    dirtyFlag.clearDirty();
+  }
+
+  @Override
+  public int size() {
+    return delegate.size();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return delegate.isEmpty();
+  }
+
+  @Override
+  public boolean contains(Object o) {
+    return delegate.contains(o);
+  }
+
+  @Override
+  public Iterator<T> iterator() {
+    return new DirtyIteratorWrapper<T>(delegate.iterator(), dirtyFlag);
+  }
+
+  @Override
+  public Object[] toArray() {
+    return delegate.toArray();
+  }
+
+  @Override
+  public <R> R[] toArray(R[] a) {
+    return delegate.toArray(a);
+  }
+
+  @Override
+  public boolean add(T e) {
+    boolean change = delegate.add(e);
+    dirtyFlag.makeDirty(change);
+    return change;
+  }
+
+  @Override
+  public boolean remove(Object o) {
+    boolean change = delegate.remove(o);
+    dirtyFlag.makeDirty(change);
+    return change;
+  }
+
+  @Override
+  public boolean containsAll(Collection<?> c) {
+    return delegate.containsAll(c);
+  }
+
+  @Override
+  public boolean addAll(Collection<? extends T> c) {
+    boolean change = delegate.addAll(c);
+    dirtyFlag.makeDirty(change);
+    return change;
+  }
+
+  @Override
+  public boolean removeAll(Collection<?> c) {
+    boolean change = delegate.removeAll(c);
+    dirtyFlag.makeDirty(change);
+    return change;
+  }
+
+  @Override
+  public boolean retainAll(Collection<?> c) {
+    boolean change = delegate.retainAll(c);
+    dirtyFlag.makeDirty(change);
+    return change;
+  }
+
+  @Override
+  public void clear() {
+    dirtyFlag.makeDirty(size() > 0);
+    delegate.clear();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return delegate.equals(o);
+  }
+
+  @Override
+  public int hashCode() {
+    return delegate.hashCode();
+  }
+
+  protected Collection<T> getDelegate() {
+    return delegate;
+  }
+
+  protected DirtyFlag getDirtyFlag() {
+    return dirtyFlag;
+  }
+
+}

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyFlag.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyFlag.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyFlag.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyFlag.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gora.persistency.impl;
+
+import org.apache.gora.persistency.Dirtyable;
+
+final class DirtyFlag implements Dirtyable {
+
+  private boolean dirty;
+
+  public DirtyFlag(boolean dirty) {
+    this.dirty = dirty;
+  }
+
+  public DirtyFlag() {
+    this.dirty = false;
+  }
+
+  @Override
+  public boolean isDirty() {
+    return dirty;
+  }
+
+  @Override
+  public void clearDirty() {
+    this.dirty = false;
+  }
+
+  /**
+   * Set this DirtyFlag to dirty if the <tt>dirty</tt> operand is true. If
+   * not, the state of the flag remains unchanged.
+   * 
+   * @param dirty
+   *            Weather or not to set this flag to dirty. If false, the state
+   *            is unchanged.
+   */
+  public void makeDirty(boolean dirty) {
+    this.dirty = this.dirty || dirty;
+  }
+
+}

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyIteratorWrapper.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyIteratorWrapper.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyIteratorWrapper.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyIteratorWrapper.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,35 @@
+package org.apache.gora.persistency.impl;
+
+import java.util.Iterator;
+
+/**
+ * Sets the dirty flag if the iterator's remove method is called.
+ */
+final class DirtyIteratorWrapper<T> implements Iterator<T> {
+
+  private final DirtyFlag dirtyFlag;
+  private Iterator<T> delegateIterator;
+
+  DirtyIteratorWrapper(Iterator<T> delegateIterator,
+      DirtyFlag dirtyFlag) {
+    this.delegateIterator = delegateIterator;
+    this.dirtyFlag = dirtyFlag;
+  }
+
+  @Override
+  public boolean hasNext() {
+    return delegateIterator.hasNext();
+  }
+
+  @Override
+  public T next() {
+    return delegateIterator.next();
+  }
+
+  @Override
+  public void remove() {
+    dirtyFlag.makeDirty(true);
+    delegateIterator.remove();
+  }
+
+}
\ No newline at end of file

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListIterator.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListIterator.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListIterator.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListIterator.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,67 @@
+package org.apache.gora.persistency.impl;
+
+import java.util.ListIterator;
+
+/**
+ * Sets the dirty flag if the list iterator's modification methods (remove,
+ * set, add) are called.
+ */
+final class DirtyListIterator<T> implements ListIterator<T> {
+
+  private final ListIterator<T> iteratorDelegate;
+  private final DirtyFlag dirtyFlag;
+
+  DirtyListIterator(ListIterator<T> delegate, DirtyFlag dirtyFlag) {
+    this.iteratorDelegate = delegate;
+    this.dirtyFlag = dirtyFlag;
+  }
+
+  @Override
+  public boolean hasNext() {
+    return iteratorDelegate.hasNext();
+  }
+
+  @Override
+  public T next() {
+    return iteratorDelegate.next();
+  }
+
+  @Override
+  public boolean hasPrevious() {
+    return iteratorDelegate.hasPrevious();
+  }
+
+  @Override
+  public T previous() {
+    return iteratorDelegate.previous();
+  }
+
+  @Override
+  public int nextIndex() {
+    return iteratorDelegate.nextIndex();
+  }
+
+  @Override
+  public int previousIndex() {
+    return iteratorDelegate.previousIndex();
+  }
+
+  @Override
+  public void remove() {
+    dirtyFlag.makeDirty(true);
+    iteratorDelegate.remove();
+  }
+
+  @Override
+  public void set(T e) {
+    dirtyFlag.makeDirty(true);
+    iteratorDelegate.set(e);
+  }
+
+  @Override
+  public void add(T e) {
+    dirtyFlag.makeDirty(true);
+    iteratorDelegate.add(e);
+  }
+
+}
\ No newline at end of file

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListWrapper.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListWrapper.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListWrapper.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyListWrapper.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,97 @@
+package org.apache.gora.persistency.impl;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.gora.persistency.Dirtyable;
+
+/**
+ * A {@link List} implementation that wraps another list, intercepting
+ * modifications to the list structure and reporting on weather or not the list
+ * has been modified, and also checking list elements for modification.
+ * 
+ * @param <T>
+ *          The type of the list that this wrapper wraps.
+ */
+public class DirtyListWrapper<T> extends DirtyCollectionWrapper<T> implements
+    Dirtyable, List<T> {
+
+  /**
+   * Create a DirtyListWrapper that wraps a getDelegate().
+   * 
+   * @param delegate
+   *          The getDelegate().to wrap.
+   */
+  public DirtyListWrapper(List<T> delegate) {
+    this(delegate, new DirtyFlag());
+  }
+
+  DirtyListWrapper(List<T> delegate, DirtyFlag dirtyFlag) {
+    super(delegate, dirtyFlag);
+  }
+
+  @Override
+  public boolean addAll(int index, Collection<? extends T> c) {
+    boolean change = getDelegate().addAll(index, c);
+    getDirtyFlag().makeDirty(change);
+    return change;
+  }
+
+  @Override
+  public T get(int index) {
+    return getDelegate().get(index);
+  }
+
+  @Override
+  public T set(int index, T element) {
+    getDirtyFlag().makeDirty(true);
+    return getDelegate().set(index, element);
+  }
+
+  @Override
+  public void add(int index, T element) {
+    getDirtyFlag().makeDirty(true);
+    getDelegate().add(index, element);
+  }
+
+  @Override
+  public T remove(int index) {
+    getDirtyFlag().makeDirty(true);
+    return getDelegate().remove(index);
+  }
+
+  @Override
+  public int indexOf(Object o) {
+    return getDelegate().indexOf(o);
+  }
+
+  @Override
+  public int lastIndexOf(Object o) {
+    return getDelegate().lastIndexOf(o);
+  }
+
+  @Override
+  public ListIterator<T> listIterator() {
+    return new DirtyListIterator<T>(getDelegate().listIterator(),
+        getDirtyFlag());
+  }
+
+  @Override
+  public ListIterator<T> listIterator(int index) {
+    return new DirtyListIterator<T>(getDelegate().listIterator(index),
+        getDirtyFlag());
+  }
+
+  @Override
+  public List<T> subList(int fromIndex, int toIndex) {
+    return new DirtyListWrapper<T>(getDelegate().subList(fromIndex, toIndex),
+        getDirtyFlag());
+  }
+
+  @Override
+  protected List<T> getDelegate() {
+    return (List<T>) super.getDelegate();
+  }
+
+}

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyMapWrapper.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyMapWrapper.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyMapWrapper.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtyMapWrapper.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,194 @@
+package org.apache.gora.persistency.impl;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.gora.persistency.Dirtyable;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+
+public class DirtyMapWrapper<K, V> implements Map<K, V>, Dirtyable {
+
+  public static class DirtyEntryWrapper<K, V> implements Entry<K, V>, Dirtyable {
+    private final Entry<K, V> entryDelegate;
+    private DirtyFlag dirtyFlag;
+
+    public DirtyEntryWrapper(Entry<K, V> delegate, DirtyFlag dirtyFlag) {
+      this.entryDelegate = delegate;
+      this.dirtyFlag = dirtyFlag;
+    }
+
+    @Override
+    public K getKey() {
+      return entryDelegate.getKey();
+    }
+
+    @Override
+    public V getValue() {
+      return entryDelegate.getValue();
+    }
+
+    @Override
+    public V setValue(V value) {
+      dirtyFlag.makeDirty(valueChanged(value, entryDelegate.getValue()));
+      return entryDelegate.setValue(value);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      return entryDelegate.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+      return entryDelegate.hashCode();
+    }
+
+    @Override
+    public boolean isDirty() {
+      return dirtyFlag.isDirty() || (entryDelegate instanceof Dirtyable) ? ((Dirtyable) entryDelegate
+          .getValue()).isDirty() : false;
+    }
+
+    @Override
+    public void clearDirty() {
+      dirtyFlag.clearDirty();
+    }
+
+  }
+
+  private final Map<K, V> delegate;
+
+  private final DirtyFlag dirtyFlag;
+
+  public DirtyMapWrapper(Map<K, V> delegate) {
+    this(delegate, new DirtyFlag());
+  }
+
+  DirtyMapWrapper(Map<K, V> delegate, DirtyFlag dirtyFlag) {
+    this.dirtyFlag = dirtyFlag;
+    this.delegate = delegate;
+  }
+
+  @Override
+  public boolean isDirty() {
+    boolean anyDirty = false;
+    for (V v : this.values()) {
+      anyDirty = anyDirty || (v instanceof Dirtyable) ? ((Dirtyable) v)
+          .isDirty() : false;
+    }
+    return anyDirty || dirtyFlag.isDirty();
+  }
+
+  @Override
+  public void clearDirty() {
+    for (V v : this.values()) {
+      if (v instanceof Dirtyable)
+        ((Dirtyable) v).clearDirty();
+    }
+    dirtyFlag.clearDirty();
+  }
+
+  @Override
+  public int size() {
+    return delegate.size();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return delegate.isEmpty();
+  }
+
+  @Override
+  public boolean containsKey(Object key) {
+    return delegate.containsKey(key);
+  }
+
+  @Override
+  public boolean containsValue(Object value) {
+    return delegate.containsValue(value);
+  }
+
+  @Override
+  public V get(Object key) {
+    return delegate.get(key);
+  }
+
+  @Override
+  public V put(K key, V value) {
+    checkPutWillMakeDirty(key, value);
+    return delegate.put(key, value);
+  }
+
+  private void checkPutWillMakeDirty(K key, V value) {
+    if (containsKey(key)) {
+      dirtyFlag.makeDirty(valueChanged(value, get(key)));
+    } else {
+      dirtyFlag.makeDirty(true);
+    }
+  }
+
+  private static <V> boolean valueChanged(V value, V oldValue) {
+    return (value == null && oldValue != null)
+        || (value != null && !value.equals(oldValue));
+  }
+
+  @Override
+  public V remove(Object key) {
+    dirtyFlag.makeDirty(containsKey(key));
+    return delegate.remove(key);
+  }
+
+  @Override
+  public void putAll(Map<? extends K, ? extends V> m) {
+    for (Entry<? extends K, ? extends V> entry : m.entrySet()) {
+      checkPutWillMakeDirty(entry.getKey(), entry.getValue());
+    }
+    delegate.putAll(m);
+  }
+
+  @Override
+  public void clear() {
+    if (delegate.size() != 0) {
+      dirtyFlag.makeDirty(true);
+    }
+    delegate.clear();
+  }
+
+  @Override
+  public Set<K> keySet() {
+    return delegate.keySet();
+  }
+
+  @Override
+  public Collection<V> values() {
+    return new DirtyCollectionWrapper<V>(delegate.values(), dirtyFlag);
+  }
+
+  @Override
+  @SuppressWarnings({ "unchecked", "rawtypes" })
+  public Set<java.util.Map.Entry<K, V>> entrySet() {
+    Collection<DirtyEntryWrapper<K, V>> dirtyEntrySet = Collections2.transform(
+        delegate.entrySet(),
+        new Function<Entry<K, V>, DirtyEntryWrapper<K, V>>() {
+          @Override
+          public DirtyEntryWrapper<K, V> apply(java.util.Map.Entry<K, V> input) {
+            return new DirtyEntryWrapper<K, V>(input, dirtyFlag);
+          }
+        });
+    return new DirtySetWrapper(dirtyEntrySet, dirtyFlag);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return delegate.equals(o);
+  }
+
+  @Override
+  public int hashCode() {
+    return delegate.hashCode();
+  }
+
+}

Added: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtySetWrapper.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtySetWrapper.java?rev=1517093&view=auto
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtySetWrapper.java (added)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/DirtySetWrapper.java Sat Aug 24 00:27:39 2013
@@ -0,0 +1,15 @@
+package org.apache.gora.persistency.impl;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.apache.gora.persistency.Dirtyable;
+
+public class DirtySetWrapper<T extends Dirtyable> extends
+    DirtyCollectionWrapper<T> implements Set<T> {
+
+  DirtySetWrapper(Collection<T> delegate2, DirtyFlag dirtyFlag) {
+    super(delegate2, dirtyFlag);
+  }
+
+}

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/PersistentBase.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/PersistentBase.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/PersistentBase.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/impl/PersistentBase.java Sat Aug 24 00:27:39 2013
@@ -18,310 +18,194 @@
 package org.apache.gora.persistency.impl;
 
 import java.nio.ByteBuffer;
-import java.util.HashMap;
+import java.util.Collection;
 import java.util.List;
-import java.util.Map;
-
 import org.apache.avro.Schema.Field;
-import org.apache.avro.Schema.Type;
-import org.apache.avro.generic.GenericData;
+import org.apache.avro.specific.SpecificData;
 import org.apache.avro.specific.SpecificRecord;
-import org.apache.gora.avro.PersistentDatumReader;
-import org.apache.gora.persistency.ListGenericArray;
+import org.apache.avro.specific.SpecificRecordBase;
+import org.apache.gora.persistency.Dirtyable;
 import org.apache.gora.persistency.Persistent;
-import org.apache.gora.persistency.StateManager;
-import org.apache.gora.persistency.StatefulHashMap;
 
 /**
  * Base classs implementing common functionality for Persistent
  * classes.
  */
-public abstract class PersistentBase implements Persistent, SpecificRecord {
-
-  protected static Map<Class<?>, Map<String, Integer>> FIELD_MAP =
-    new HashMap<Class<?>, Map<String,Integer>>();
-
-  protected static Map<Class<?>, String[]> FIELDS =
-    new HashMap<Class<?>, String[]>();
+public abstract class PersistentBase extends SpecificRecordBase implements Persistent  {
 
-  protected static final PersistentDatumReader<PersistentBase> datumReader =
-    new PersistentDatumReader<PersistentBase>();
-    
-  private StateManager stateManager;
+  public static class PersistentData extends SpecificData {
+    private static final PersistentData INSTANCE = new PersistentData();
 
-  protected PersistentBase() {
-    this(new StateManagerImpl());
-  }
-
-  protected PersistentBase(StateManager stateManager) {
-    this.stateManager = stateManager;
-    stateManager.setManagedPersistent(this);
-  }
-
-  /** Subclasses should call this function for all the persistable fields
-   * in the class to register them.
-   * @param clazz the Persistent class
-   * @param fields the name of the fields of the class
-   */
-  protected static void registerFields(Class<?> clazz, String... fields) {
-    FIELDS.put(clazz, fields);
-    int fieldsLength = fields == null ? 0 :fields.length;
-    HashMap<String, Integer> map = new HashMap<String, Integer>(fieldsLength);
-
-    for(int i=0; i < fieldsLength; i++) {
-      map.put(fields[i], i);
+    public static PersistentData get() {
+      return INSTANCE;
     }
-    FIELD_MAP.put(clazz, map);
-  }
-
-  @Override
-  public StateManager getStateManager() {
-    return stateManager;
-  }
 
-  @Override
-  public String[] getFields() {
-    return FIELDS.get(getClass());
-  }
+    public boolean equals(SpecificRecord obj1, SpecificRecord that) {
+      if (that == obj1)
+        return true; // identical object
+      if (!(that instanceof SpecificRecord))
+        return false; // not a record
+      if (obj1.getClass() != that.getClass())
+        return false; // not same schema
+      return PersistentData.get().compare(obj1, that, obj1.getSchema(), true) == 0;
+    }
 
-  @Override
-  public String getField(int index) {
-    return FIELDS.get(getClass())[index];
   }
 
   @Override
-  public int getFieldIndex(String field) {
-    return FIELD_MAP.get(getClass()).get(field);
+  public void clearDirty() {
+    ByteBuffer dirtyBytes = getDirtyBytes();
+    assert (dirtyBytes.position() == 0);
+    for (int i = 0; i < dirtyBytes.limit(); i++) {
+      dirtyBytes.put(i, (byte) 0);
+    }
+    for (Field field : getSchema().getFields()) {
+      clearDirynessIfFieldIsDirtyable(field.pos());
+    }
   }
 
-  @Override
-  @SuppressWarnings("rawtypes")
-  public void clear() {
-    List<Field> fields = getSchema().getFields();
-
-    for(int i=0; i<getFields().length; i++) {
-      switch(fields.get(i).schema().getType()) {
-        case MAP: 
-          if(get(i) != null) {
-            if (get(i) instanceof StatefulHashMap) {
-              ((StatefulHashMap)get(i)).reuse(); 
-            } else {
-              ((Map)get(i)).clear();
-            }
-          }
-          break;
-        case ARRAY:
-          if(get(i) != null) {
-            if(get(i) instanceof ListGenericArray) {
-              ((ListGenericArray)get(i)).clear();
-            } else {
-              put(i, new ListGenericArray(fields.get(i).schema()));
-            }
-          }
-          break;
-        case RECORD :
-          Persistent field = ((Persistent)get(i));
-          if(field != null) field.clear();
-          break;
-        case BOOLEAN: put(i, false); break;
-        case INT    : put(i, 0); break;
-        case DOUBLE : put(i, 0d); break;
-        case FLOAT  : put(i, 0f); break;
-        case LONG   : put(i, 0l); break;
-        case NULL   : break;
-        default     : put(i, null); break;
-      }
+  private void clearDirynessIfFieldIsDirtyable(int fieldIndex) {
+    if (fieldIndex == 0)
+      return;
+    Object value = get(fieldIndex);
+    if (value instanceof Dirtyable) {
+      ((Dirtyable) value).clearDirty();
     }
-    clearDirty();
-    clearReadable();
   }
 
   @Override
-  public boolean isNew() {
-    return getStateManager().isNew(this);
+  public void clearDirty(int fieldIndex) {
+    ByteBuffer dirtyBytes = getDirtyBytes();
+    assert (dirtyBytes.position() == 0);
+    int byteOffset = fieldIndex / 8;
+    int bitOffset = fieldIndex % 8;
+    byte currentByte = dirtyBytes.get(byteOffset);
+    currentByte = (byte) ((~(1 << bitOffset)) & currentByte);
+    dirtyBytes.put(byteOffset, currentByte);
+    clearDirynessIfFieldIsDirtyable(fieldIndex);
   }
 
   @Override
-  public void setNew() {
-    getStateManager().setNew(this);
+  public void clearDirty(String field) {
+    clearDirty(getSchema().getField(field).pos());
   }
 
   @Override
-  public void clearNew() {
-    getStateManager().clearNew(this);
+  public boolean isDirty() {
+    List<Field> fields = getSchema().getFields();
+    boolean isSubRecordDirty = false;
+    for (Field field : fields) {
+      isSubRecordDirty = isSubRecordDirty || checkIfMutableFieldAndDirty(field);
+    }
+    ByteBuffer dirtyBytes = getDirtyBytes();
+    assert (dirtyBytes.position() == 0);
+    boolean dirty = false;
+    for (int i = 0; i < dirtyBytes.limit(); i++) {
+      dirty = dirty || dirtyBytes.get(i) != 0;
+    }
+    return isSubRecordDirty || dirty;
   }
 
-  @Override
-  public boolean isDirty() {
-    return getStateManager().isDirty(this);
+  private boolean checkIfMutableFieldAndDirty(Field field) {
+    if (field.pos() == 0)
+      return false;
+    switch (field.schema().getType()) {
+    case RECORD:
+    case MAP:
+    case ARRAY:
+      return ((Dirtyable) get(field.pos())).isDirty();
+    case UNION:
+      Object value = get(field.pos());
+      if (value instanceof Dirtyable) {
+        return ((Dirtyable) value).isDirty();
+      }
+    default:
+      // TODO add sufficient logging
+      break;
+    }
+    return false;
   }
 
   @Override
   public boolean isDirty(int fieldIndex) {
-    return getStateManager().isDirty(this, fieldIndex);
+    Field field = getSchema().getFields().get(fieldIndex);
+    boolean isSubRecordDirty = checkIfMutableFieldAndDirty(field);
+    ByteBuffer dirtyBytes = getDirtyBytes();
+    assert (dirtyBytes.position() == 0);
+    int byteOffset = fieldIndex / 8;
+    int bitOffset = fieldIndex % 8;
+    byte currentByte = dirtyBytes.get(byteOffset);
+    return isSubRecordDirty || 0 != ((1 << bitOffset) & currentByte);
   }
 
   @Override
-  public boolean isDirty(String field) {
-    return isDirty(getFieldIndex(field));
+  public boolean isDirty(String fieldName) {
+    Field field = getSchema().getField(fieldName);
+    if(field == null){
+      throw new IndexOutOfBoundsException("Field "+ fieldName + " does not exist in this schema.");
+    }
+    return isDirty(field.pos());
   }
 
   @Override
   public void setDirty() {
-    getStateManager().setDirty(this);
+    ByteBuffer dirtyBytes = getDirtyBytes();
+    assert (dirtyBytes.position() == 0);
+    for (int i = 0; i < dirtyBytes.limit(); i++) {
+      dirtyBytes.put(i, (byte) -128);
+    }
   }
 
   @Override
   public void setDirty(int fieldIndex) {
-    getStateManager().setDirty(this, fieldIndex);
+    ByteBuffer dirtyBytes = getDirtyBytes();
+    assert (dirtyBytes.position() == 0);
+    int byteOffset = fieldIndex / 8;
+    int bitOffset = fieldIndex % 8;
+    byte currentByte = dirtyBytes.get(byteOffset);
+    currentByte = (byte) ((1 << bitOffset) | currentByte);
+    dirtyBytes.put(byteOffset, currentByte);
   }
 
   @Override
   public void setDirty(String field) {
-    setDirty(getFieldIndex(field));
-  }
-
-  @Override
-  public void clearDirty(int fieldIndex) {
-    getStateManager().clearDirty(this, fieldIndex);
-  }
-
-  @Override
-  public void clearDirty(String field) {
-    clearDirty(getFieldIndex(field));
-  }
-
-  @Override
-  public void clearDirty() {
-    getStateManager().clearDirty(this);
-  }
-
-  @Override
-  public boolean isReadable(int fieldIndex) {
-    return getStateManager().isReadable(this, fieldIndex);
-  }
-
-  @Override
-  public boolean isReadable(String field) {
-    return isReadable(getFieldIndex(field));
+    setDirty(getSchema().getField(field).pos());
   }
 
-  @Override
-  public void setReadable(int fieldIndex) {
-    getStateManager().setReadable(this, fieldIndex);
-  }
-
-  @Override
-  public void setReadable(String field) {
-    setReadable(getFieldIndex(field));
+  private ByteBuffer getDirtyBytes() {
+    return (ByteBuffer) get(0);
   }
 
   @Override
-  public void clearReadable() {
-    getStateManager().clearReadable(this);
-  }
-
-  @Override
-  public void clearReadable(int fieldIndex) {
-    getStateManager().clearReadable(this, fieldIndex);
-  }
-
-  @Override
-  public void clearReadable(String field) {
-    clearReadable(getFieldIndex(field));
-  }
-
-  //@Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (!(o instanceof SpecificRecord)) return false;
-
-    SpecificRecord r2 = (SpecificRecord)o;
-    if (!this.getSchema().equals(r2.getSchema())) return false;
-
-    return this.hashCode() == r2.hashCode();
-  }
-
-  //@Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    List<Field> fields = this.getSchema().getFields();
-    int end = fields.size();
-    for (int i = 0; i < end; i++) {
-      result = prime * result + getFieldHashCode(i, fields.get(i));
-    }
-    return result;
-  }
-
-  /**
-   * Computes a (record's) field's hash code.
-   * @param i Index of the field in the actual
-   * @param field
-   * @return
-   */
-  private int getFieldHashCode(int i, Field field) {
-    Object o = get(i);
-    if(o == null)
-      return 0;
-
-    // XXX Union special case: in a field being union we have to check the
-    // inner schemas for Type.BYTES special case, but because it is not a
-    // field we check it this way. Too simple case to create another
-    // private method
-    boolean isUnionField = false ;
-    int unionIndex = -1 ;
-    
-    if (field.schema().getType() == Type.UNION) {
-      isUnionField = true ;
-      unionIndex = GenericData.get().resolveUnion(field.schema(), o);
-    }
-    
-    if(field.schema().getType() == Type.BYTES
-       || (isUnionField
-           && field.schema().getTypes().get(unionIndex).getType() == Type.BYTES)) {
-      // ByteBuffer.hashCode() depends on internal 'position' index, but we must ignore that.
-      return getByteBufferHashCode((ByteBuffer)o);
+  public void clear() {
+    Collection<Field> unmanagedFields = getUnmanagedFields();
+    for (Field field : getSchema().getFields()) {
+      if (!unmanagedFields.contains(field))
+        continue;
+      /*
+* TODO: Its more in the spirit of Gora's clear method to actually clear
+* data structures, but since avro no-longer defaults to having empty
+* structures the way to do this consistently would be complicated.
+*/
+      put(field.pos(), null);
     }
-
-    return o.hashCode();
+    clearDirty();
   }
 
-  /** ByteBuffer.hashCode() takes into account the position of the
-   * buffer, but we do not want that*/
-  private int getByteBufferHashCode(ByteBuffer buf) {
-    int h = 1;
-    int p = buf.arrayOffset();
-    for (int j = buf.limit() - 1; j >= p; j--)
-          h = 31 * h + buf.get(j);
-    return h;
-  }
-  
   @Override
-  public Persistent clone() {
-    return datumReader.clone(this, getSchema());
+  public boolean equals(Object that) {
+    if (that == this) {
+      return true;
+    } else if (that instanceof Persistent) {
+      return PersistentData.get().equals(this, (SpecificRecord) that);
+    } else {
+      return false;
+    }
   }
   
-  //@Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append(super.toString());
-    builder.append(" {\n");
+  public List<Field> getUnmanagedFields(){
     List<Field> fields = getSchema().getFields();
-    for(int i=0; i<fields.size(); i++) {
-      builder.append("  \"").append(fields.get(i).name()).append("\":\"");
-      builder.append(get(i)).append("\"\n");
-    }
-    builder.append("}");
-    return builder.toString();
+    return fields.subList(1, fields.size());
   }
   
-  protected boolean isFieldEqual(int index, Object value) {
-    Object old = get(index);
-    if (old == null && value == null)
-      return true;
-    if (old == null || value == null)
-      return false;
-    return value.equals(old);
-  }
 }

Modified: gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/ws/impl/BeanFactoryWSImpl.java
URL: http://svn.apache.org/viewvc/gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/ws/impl/BeanFactoryWSImpl.java?rev=1517093&r1=1517092&r2=1517093&view=diff
==============================================================================
--- gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/ws/impl/BeanFactoryWSImpl.java (original)
+++ gora/branches/GORA_94/gora-core/src/main/java/org/apache/gora/persistency/ws/impl/BeanFactoryWSImpl.java Sat Aug 24 00:27:39 2013
@@ -91,7 +91,7 @@ public class BeanFactoryWSImpl<K, T exte
   public K newKey() throws Exception {
     // TODO this method should be checked to see how object states will be managed
     if(isKeyPersistent)
-      return (K)((Persistent)key).newInstance(new StateManagerWSImpl());
+      return keyClass.newInstance();
     else if(keyConstructor == null) {
       throw new RuntimeException("Key class does not have a no-arg constructor");
     }
@@ -99,13 +99,19 @@ public class BeanFactoryWSImpl<K, T exte
       return keyConstructor.newInstance(ReflectionUtils.EMPTY_OBJECT_ARRAY);
   }
  
-  @SuppressWarnings("unchecked")
   @Override
   /**
    * Creates a new persistent object
    */
   public T newPersistent() {
-    return (T) persistent.newInstance(new StateManagerWSImpl());
+    try {
+      return (T) persistentClass.newInstance();
+    } catch (InstantiationException e) {
+      throw new RuntimeException(e);
+    } catch (IllegalAccessException e) {
+      e.printStackTrace();
+      throw new RuntimeException(e);
+    }
   }
   
   @Override