Author: stack
Date: Sat Sep 10 17:57:19 2011
New Revision: 1167569

URL: http://svn.apache.org/viewvc?rev=1167569&view=rev
Log:
HBASE-4347 Remove duplicated code from Put, Delete, Get, Scan, MultiPut

Added:
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Attributes.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Mutation.java
    
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Delete.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Put.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Scan.java

Modified: hbase/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1167569&r1=1167568&r2=1167569&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Sat Sep 10 17:57:19 2011
@@ -472,6 +472,8 @@ Release 0.91.0 - Unreleased
    HBASE-4342  Update Thrift to 0.7.0 (Moaz Reyad)
    HBASE-4260  Expose a command to manually trigger an HLog roll
                (ramkrishna.s.vasudevan)
+   HBASE-4347  Remove duplicated code from Put, Delete, Get, Scan, MultiPut
+               (Lars Hofhansl)
 
   TASKS
    HBASE-3559  Move report of split to master OFF the heartbeat channel

Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Attributes.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Attributes.java?rev=1167569&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Attributes.java 
(added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Attributes.java 
Sat Sep 10 17:57:19 2011
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * 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.hadoop.hbase.client;
+
+import java.util.Map;
+
+public interface Attributes {
+  /**
+   * Sets an attribute.
+   * In case value = null attribute is removed from the attributes map.
+   * @param name attribute name
+   * @param value attribute value
+   */
+  public void setAttribute(String name, byte[] value);
+
+  /**
+   * Gets an attribute
+   * @param name attribute name
+   * @return attribute value if attribute is set, <tt>null</tt> otherwise
+   */
+  public byte[] getAttribute(String name);
+
+  /**
+   * Gets all attributes
+   * @return unmodifiable map of all attributes
+   */
+  public Map<String, byte[]> getAttributesMap();
+}

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Delete.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Delete.java?rev=1167569&r1=1167568&r2=1167569&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Delete.java 
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Delete.java Sat 
Sep 10 17:57:19 2011
@@ -24,20 +24,13 @@ import org.apache.hadoop.hbase.HConstant
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.Writable;
-import org.apache.hadoop.io.WritableUtils;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
 
 /**
  * Used to perform Delete operations on a single row.
@@ -71,21 +64,10 @@ import java.util.UUID;
  * deleteFamily -- then you need to use the method overrides that take a
  * timestamp.  The constructor timestamp is not referenced.
  */
-public class Delete extends Operation
+public class Delete extends Mutation
   implements Writable, Row, Comparable<Row> {
   private static final byte DELETE_VERSION = (byte)3;
 
-  private byte [] row = null;
-  // This ts is only used when doing a deleteRow.  Anything less,
-  private long ts;
-  private long lockId = -1L;
-  private boolean writeToWAL = true;
-  private final Map<byte [], List<KeyValue>> familyMap =
-    new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
-
-  // a opaque blob that can be passed into a Delete. 
-  private Map<String, byte[]> attributes;
-
   /** Constructor for Writable.  DO NOT USE */
   public Delete() {
     this((byte [])null);
@@ -136,18 +118,6 @@ public class Delete extends Operation
     this.writeToWAL = d.writeToWAL;
   }
 
-  public int compareTo(final Row d) {
-    return Bytes.compareTo(this.getRow(), d.getRow());
-  }
-
-  /**
-   * Method to check if the familyMap is empty
-   * @return true if empty, false otherwise
-   */
-  public boolean isEmpty() {
-    return familyMap.isEmpty();
-  }
-
   /**
    * Delete all versions of all columns of the specified family.
    * <p>
@@ -246,47 +216,6 @@ public class Delete extends Operation
   }
 
   /**
-   * Method for retrieving the delete's familyMap
-   * @return familyMap
-   */
-  public Map<byte [], List<KeyValue>> getFamilyMap() {
-    return this.familyMap;
-  }
-
-  /**
-   *  Method for retrieving the delete's row
-   * @return row
-   */
-  public byte [] getRow() {
-    return this.row;
-  }
-
-  /**
-   * Method for retrieving the delete's RowLock
-   * @return RowLock
-   */
-  public RowLock getRowLock() {
-    return new RowLock(this.row, this.lockId);
-  }
-
-  /**
-   * Method for retrieving the delete's lock ID.
-   *
-   * @return The lock ID.
-   */
-  public long getLockId() {
-       return this.lockId;
-  }
-
-  /**
-   * Method for retrieving the delete's timestamp
-   * @return timestamp
-   */
-  public long getTimeStamp() {
-    return this.ts;
-  }
-
-  /**
    * Set the timestamp of the delete.
    * 
    * @param timestamp
@@ -295,115 +224,12 @@ public class Delete extends Operation
     this.ts = timestamp;
   }
 
-  /**
-   * Sets arbitrary delete's attribute.
-   * In case value = null attribute is removed from the attributes map.
-   * @param name attribute name
-   * @param value attribute value
-   */
-  public void setAttribute(String name, byte[] value) {
-    if (attributes == null && value == null) {
-      return;
-    }
-
-    if (attributes == null) {
-      attributes = new HashMap<String, byte[]>();
-    }
-
-    if (value == null) {
-      attributes.remove(name);
-      if (attributes.isEmpty()) {
-        this.attributes = null;
-      }
-    } else {
-      attributes.put(name, value);
-    }
-  }
-
-  /**
-   * Gets put's attribute
-   * @param name attribute name
-   * @return attribute value if attribute is set, <tt>null</tt> otherwise
-   */
-  public byte[] getAttribute(String name) {
-    if (attributes == null) {
-      return null;
-    }
-    return attributes.get(name);
-  }
-
-  /**
-   * Gets all scan's attributes
-   * @return unmodifiable map of all attributes
-   */
-  public Map<String, byte[]> getAttributesMap() {
-    if (attributes == null) {
-      return Collections.emptyMap();
-    }
-    return Collections.unmodifiableMap(attributes);
-  }
-
-  /**
-   * Compile the column family (i.e. schema) information
-   * into a Map. Useful for parsing and aggregation by debugging,
-   * logging, and administration tools.
-   * @return Map
-   */
-  @Override
-  public Map<String, Object> getFingerprint() {
-    Map<String, Object> map = new HashMap<String, Object>();
-    List<String> families = new ArrayList<String>();
-    // ideally, we would also include table information, but that information
-    // is not stored in each Operation instance.
-    map.put("families", families);
-    for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) 
{
-      families.add(Bytes.toStringBinary(entry.getKey()));
-    }
-    return map;
-  }
-
-  /**
-   * Compile the details beyond the scope of getFingerprint (row, columns,
-   * timestamps, etc.) into a Map along with the fingerprinted information.
-   * Useful for debugging, logging, and administration tools.
-   * @param maxCols a limit on the number of columns output prior to truncation
-   * @return Map
-   */
   @Override
   public Map<String, Object> toMap(int maxCols) {
     // we start with the fingerprint map and build on top of it.
-    Map<String, Object> map = getFingerprint();
-    // replace the fingerprint's simple list of families with a 
-    // map from column families to lists of qualifiers and kv details
-    Map<String, List<Map<String, Object>>> columns =
-      new HashMap<String, List<Map<String, Object>>>();
-    map.put("families", columns);
-    map.put("row", Bytes.toStringBinary(this.row));
+    Map<String, Object> map = super.toMap(maxCols);
+    // why is put not doing this?
     map.put("ts", this.ts);
-    int colCount = 0;
-    // iterate through all column families affected by this Delete
-    for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) 
{
-      // map from this family to details for each kv affected within the family
-      List<Map<String, Object>> qualifierDetails =
-        new ArrayList<Map<String, Object>>();
-      columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
-      colCount += entry.getValue().size();
-      if (maxCols <= 0) {
-        continue;
-      }
-      // add details for each kv
-      for (KeyValue kv : entry.getValue()) {
-        if (--maxCols <= 0 ) {
-          continue;
-        }
-        Map<String, Object> kvMap = kv.toStringMap();
-        // row and family information are already available in the bigger map
-        kvMap.remove("row");
-        kvMap.remove("family");
-        qualifierDetails.add(kvMap);
-      }
-    }
-    map.put("totalColumns", colCount);
     return map;
   }
 
@@ -433,15 +259,7 @@ public class Delete extends Operation
       this.familyMap.put(family, list);
     }
     if (version > 1) {
-      int numAttributes = in.readInt();
-      if (numAttributes > 0) {
-        this.attributes = new HashMap<String, byte[]>();
-        for(int i=0; i<numAttributes; i++) {
-          String name = WritableUtils.readString(in);
-          byte[] value = Bytes.readByteArray(in);
-          this.attributes.put(name, value);
-        }
-      }
+      readAttributes(in);
     }
   }
 
@@ -460,15 +278,7 @@ public class Delete extends Operation
         kv.write(out);
       }
     }
-    if (this.attributes == null) {
-      out.writeInt(0);
-    } else {
-      out.writeInt(this.attributes.size());
-      for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
-        WritableUtils.writeString(out, attr.getKey());
-        Bytes.writeByteArray(out, attr.getValue());
-      }
-    }
+    writeAttributes(out);
   }
 
   /**
@@ -498,42 +308,4 @@ public class Delete extends Operation
     this.deleteColumn(parts[0], parts[1], HConstants.LATEST_TIMESTAMP);
     return this;
   }
-
-  /**
-   * @return true if edits should be applied to WAL, false if not
-   */
-  public boolean getWriteToWAL() {
-    return this.writeToWAL;
-  }
-
-  /**
-   * Set whether this Delete should be written to the WAL or not.
-   * Not writing the WAL means you may lose edits on server crash.
-   * @param write true if edits should be written to WAL, false if not
-   */
-  public void setWriteToWAL(boolean write) {
-    this.writeToWAL = write;
-  }
-
-  /**
-   * Set the replication custer id.
-   * @param clusterId
-   */
-  public void setClusterId(UUID clusterId) {
-    byte[] val = new byte[2*Bytes.SIZEOF_LONG];
-    Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
-    Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
-    setAttribute(HConstants.CLUSTER_ID_ATTR, val);
-  }
-
-  /**
-   * @return The replication cluster id.
-   */
-  public UUID getClusterId() {
-    byte[] attr = getAttribute(HConstants.CLUSTER_ID_ATTR);
-    if (attr == null) {
-      return HConstants.DEFAULT_CLUSTER_ID;
-    }
-    return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, 
Bytes.SIZEOF_LONG));
-  }
 }

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java?rev=1167569&r1=1167568&r2=1167569&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java Sat Sep 
10 17:57:19 2011
@@ -26,13 +26,11 @@ import org.apache.hadoop.hbase.io.TimeRa
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.Writable;
 import org.apache.hadoop.io.WritableFactories;
-import org.apache.hadoop.io.WritableUtils;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -65,7 +63,7 @@ import java.util.TreeSet;
  * <p>
  * To add a filter, execute {@link #setFilter(Filter) setFilter}.
  */
-public class Get extends Operation
+public class Get extends OperationWithAttributes
   implements Writable, Row, Comparable<Row> {
   private static final byte GET_VERSION = (byte)2;
 
@@ -77,7 +75,6 @@ public class Get extends Operation
   private TimeRange tr = new TimeRange();
   private Map<byte [], NavigableSet<byte []>> familyMap =
     new TreeMap<byte [], NavigableSet<byte []>>(Bytes.BYTES_COMPARATOR);
-  private Map<String, byte[]> attributes;
 
   /** Constructor for Writable.  DO NOT USE */
   public Get() {}
@@ -307,54 +304,6 @@ public class Get extends Operation
   }
 
   /**
-   * Sets arbitrary get's attribute.
-   * In case value = null attribute is removed from the attributes map.
-   * @param name attribute name
-   * @param value attribute value
-   */
-  public void setAttribute(String name, byte[] value) {
-    if (attributes == null && value == null) {
-      return;
-    }
-
-    if (attributes == null) {
-      attributes = new HashMap<String, byte[]>();
-    }
-
-    if (value == null) {
-      attributes.remove(name);
-      if (attributes.isEmpty()) {
-        this.attributes = null;
-      }
-    } else {
-      attributes.put(name, value);
-    }
-  }
-
-  /**
-   * Gets get's attribute
-   * @param name attribute name
-   * @return attribute value if attribute is set, <tt>null</tt> otherwise
-   */
-  public byte[] getAttribute(String name) {
-    if (attributes == null) {
-      return null;
-    }
-    return attributes.get(name);
-  }
-
-  /**
-   * Gets all scan's attributes
-   * @return unmodifiable map of all attributes
-   */
-  public Map<String, byte[]> getAttributesMap() {
-    if (attributes == null) {
-      return Collections.emptyMap();
-    }
-    return Collections.unmodifiableMap(attributes);
-  }
-
-  /**
    * Compile the table and column family (i.e. schema) information
    * into a String. Useful for parsing and aggregation by debugging,
    * logging, and administration tools.
@@ -462,15 +411,7 @@ public class Get extends Operation
       }
       this.familyMap.put(family, set);
     }
-    int numAttributes = in.readInt();
-    if (numAttributes > 0) {
-      this.attributes = new HashMap<String, byte[]>();
-      for(int i=0; i<numAttributes; i++) {
-        String name = WritableUtils.readString(in);
-        byte[] value = Bytes.readByteArray(in);
-        this.attributes.put(name, value);
-      }
-    }
+    readAttributes(in);
   }
 
   public void write(final DataOutput out)
@@ -503,15 +444,7 @@ public class Get extends Operation
         }
       }
     }
-    if (this.attributes == null) {
-      out.writeInt(0);
-    } else {
-      out.writeInt(this.attributes.size());
-      for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
-        WritableUtils.writeString(out, attr.getKey());
-        Bytes.writeByteArray(out, attr.getValue());
-      }
-    }    
+    writeAttributes(out);
   }
 
   @SuppressWarnings("unchecked")

Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Mutation.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Mutation.java?rev=1167569&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Mutation.java 
(added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Mutation.java Sat 
Sep 10 17:57:19 2011
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * 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.hadoop.hbase.client;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.util.Bytes;
+
+public abstract class Mutation extends OperationWithAttributes {
+  protected byte [] row = null;
+  protected long ts = HConstants.LATEST_TIMESTAMP;
+  protected long lockId = -1L;
+  protected boolean writeToWAL = true;
+  protected Map<byte [], List<KeyValue>> familyMap =
+      new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
+
+  /**
+   * Compile the column family (i.e. schema) information
+   * into a Map. Useful for parsing and aggregation by debugging,
+   * logging, and administration tools.
+   * @return Map
+   */
+  @Override
+  public Map<String, Object> getFingerprint() {
+    Map<String, Object> map = new HashMap<String, Object>();
+    List<String> families = new ArrayList<String>();
+    // ideally, we would also include table information, but that information
+    // is not stored in each Operation instance.
+    map.put("families", families);
+    for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) 
{
+      families.add(Bytes.toStringBinary(entry.getKey()));
+    } 
+    return map;
+  }
+
+  /**
+   * Compile the details beyond the scope of getFingerprint (row, columns,
+   * timestamps, etc.) into a Map along with the fingerprinted information.
+   * Useful for debugging, logging, and administration tools.
+   * @param maxCols a limit on the number of columns output prior to truncation
+   * @return Map
+   */
+  @Override
+  public Map<String, Object> toMap(int maxCols) {
+    // we start with the fingerprint map and build on top of it.
+    Map<String, Object> map = getFingerprint();
+    // replace the fingerprint's simple list of families with a 
+    // map from column families to lists of qualifiers and kv details
+    Map<String, List<Map<String, Object>>> columns =
+      new HashMap<String, List<Map<String, Object>>>();
+    map.put("families", columns);
+    map.put("row", Bytes.toStringBinary(this.row));
+    int colCount = 0;
+    // iterate through all column families affected
+    for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) 
{
+      // map from this family to details for each kv affected within the family
+      List<Map<String, Object>> qualifierDetails =
+        new ArrayList<Map<String, Object>>();
+      columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
+      colCount += entry.getValue().size();
+      if (maxCols <= 0) {
+        continue;
+      }
+      // add details for each kv
+      for (KeyValue kv : entry.getValue()) {
+        if (--maxCols <= 0 ) {
+          continue;
+        }
+        Map<String, Object> kvMap = kv.toStringMap();
+        // row and family information are already available in the bigger map
+        kvMap.remove("row");
+        kvMap.remove("family");
+        qualifierDetails.add(kvMap);
+      }
+    }
+    map.put("totalColumns", colCount);
+    return map;
+  }
+
+  /**
+   * @return true if edits should be applied to WAL, false if not
+   */
+  public boolean getWriteToWAL() {
+    return this.writeToWAL;
+  }
+
+  /**
+   * Set whether this Delete should be written to the WAL or not.
+   * Not writing the WAL means you may lose edits on server crash.
+   * @param write true if edits should be written to WAL, false if not
+   */
+  public void setWriteToWAL(boolean write) {
+    this.writeToWAL = write;
+  }
+
+  /**
+   * Method for retrieving the put's familyMap
+   * @return familyMap
+   */
+  public Map<byte [], List<KeyValue>> getFamilyMap() {
+    return this.familyMap;
+  }
+
+  /**
+   * Method to check if the familyMap is empty
+   * @return true if empty, false otherwise
+   */
+  public boolean isEmpty() {
+    return familyMap.isEmpty();
+  }
+
+  /**
+   * Method for retrieving the delete's row
+   * @return row
+   */
+  public byte [] getRow() {
+    return this.row;
+  }
+
+  public int compareTo(final Row d) {
+    return Bytes.compareTo(this.getRow(), d.getRow());
+  }
+
+  /**
+   * Method for retrieving the delete's RowLock
+   * @return RowLock
+   */
+  public RowLock getRowLock() {
+    return new RowLock(this.row, this.lockId);
+  }
+
+  /**
+   * Method for retrieving the delete's lock ID.
+   *
+   * @return The lock ID.
+   */
+  public long getLockId() {
+  return this.lockId;
+  }
+
+  /**
+   * Method for retrieving the timestamp
+   * @return timestamp
+   */
+  public long getTimeStamp() {
+    return this.ts;
+  }
+
+  /**
+   * Set the replication custer id.
+   * @param clusterId
+   */
+  public void setClusterId(UUID clusterId) {
+    byte[] val = new byte[2*Bytes.SIZEOF_LONG];
+    Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
+    Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
+    setAttribute(HConstants.CLUSTER_ID_ATTR, val);
+  }
+
+  /**
+   * @return The replication cluster id.
+   */
+  public UUID getClusterId() {
+    byte[] attr = getAttribute(HConstants.CLUSTER_ID_ATTR);
+    if (attr == null) {
+      return HConstants.DEFAULT_CLUSTER_ID;
+    }
+    return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, 
Bytes.SIZEOF_LONG));
+  }
+}

Added: 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java?rev=1167569&view=auto
==============================================================================
--- 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
 (added)
+++ 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
 Sat Sep 10 17:57:19 2011
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * 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.hadoop.hbase.client;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.ClassSize;
+import org.apache.hadoop.io.WritableUtils;
+
+public abstract class OperationWithAttributes extends Operation implements 
Attributes {
+  // a opaque blob of attributes
+  private Map<String, byte[]> attributes;
+
+  public void setAttribute(String name, byte[] value) {
+    if (attributes == null && value == null) {
+      return;
+    }
+
+    if (attributes == null) {
+      attributes = new HashMap<String, byte[]>();
+    }
+
+    if (value == null) {
+      attributes.remove(name);
+      if (attributes.isEmpty()) {
+        this.attributes = null;
+      }
+    } else {
+      attributes.put(name, value);
+    }
+  }
+
+  public byte[] getAttribute(String name) {
+    if (attributes == null) {
+      return null;
+    }
+
+    return attributes.get(name);
+  }
+
+  public Map<String, byte[]> getAttributesMap() {
+    if (attributes == null) {
+      return Collections.emptyMap();
+    }
+    return Collections.unmodifiableMap(attributes);
+  }
+
+  protected long getAttributeSize() {
+    long size = 0;
+    if (attributes != null) {
+      size += ClassSize.align(this.attributes.size() * ClassSize.MAP_ENTRY);
+      for(Map.Entry<String, byte[]> entry : this.attributes.entrySet()) {
+        size += ClassSize.align(ClassSize.STRING + entry.getKey().length());
+        size += ClassSize.align(ClassSize.ARRAY + entry.getValue().length);
+      }
+    }
+    return size;
+  }
+
+  protected void writeAttributes(final DataOutput out) throws IOException {
+    if (this.attributes == null) {
+      out.writeInt(0);
+    } else {
+      out.writeInt(this.attributes.size());
+      for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
+        WritableUtils.writeString(out, attr.getKey());
+        Bytes.writeByteArray(out, attr.getValue());
+      }
+    }
+  }
+  
+  protected void readAttributes(final DataInput in) throws IOException {
+    int numAttributes = in.readInt();
+    if (numAttributes > 0) {
+      this.attributes = new HashMap<String, byte[]>();
+      for(int i=0; i<numAttributes; i++) {
+        String name = WritableUtils.readString(in);
+        byte[] value = Bytes.readByteArray(in);
+        this.attributes.put(name, value);
+      }
+    }
+  }
+}

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Put.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Put.java?rev=1167569&r1=1167568&r2=1167569&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Put.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Put.java Sat Sep 
10 17:57:19 2011
@@ -26,22 +26,15 @@ import org.apache.hadoop.hbase.io.HeapSi
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.ClassSize;
 import org.apache.hadoop.io.Writable;
-import org.apache.hadoop.io.WritableUtils;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
-
 
 /**
  * Used to perform Put operations for a single row.
@@ -50,21 +43,10 @@ import java.util.UUID;
  * for each column to be inserted, execute {@link #add(byte[], byte[], byte[]) 
add} or
  * {@link #add(byte[], byte[], long, byte[]) add} if setting the timestamp.
  */
-public class Put extends Operation
+public class Put extends Mutation
   implements HeapSize, Writable, Row, Comparable<Row> {
   private static final byte PUT_VERSION = (byte)2;
 
-  private byte [] row = null;
-  private long timestamp = HConstants.LATEST_TIMESTAMP;
-  private long lockId = -1L;
-  private boolean writeToWAL = true;
-
-  private Map<byte [], List<KeyValue>> familyMap =
-    new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
-
-  // a opaque blob that can be passed into a Put. 
-  private Map<String, byte[]> attributes;
-
   private static final long OVERHEAD = ClassSize.align(
       ClassSize.OBJECT + 2 * ClassSize.REFERENCE +
       2 * Bytes.SIZEOF_LONG + Bytes.SIZEOF_BOOLEAN +
@@ -111,7 +93,7 @@ public class Put extends Operation
       throw new IllegalArgumentException("Row key is invalid");
     }
     this.row = Arrays.copyOf(row, row.length);
-    this.timestamp = ts;
+    this.ts = ts;
     if(rowLock != null) {
       this.lockId = rowLock.getLockId();
     }
@@ -122,7 +104,7 @@ public class Put extends Operation
    * @param putToCopy put to copy
    */
   public Put(Put putToCopy) {
-    this(putToCopy.getRow(), putToCopy.timestamp, putToCopy.getRowLock());
+    this(putToCopy.getRow(), putToCopy.ts, putToCopy.getRowLock());
     this.familyMap =
       new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
     for(Map.Entry<byte [], List<KeyValue>> entry :
@@ -140,7 +122,7 @@ public class Put extends Operation
    * @return this
    */
   public Put add(byte [] family, byte [] qualifier, byte [] value) {
-    return add(family, qualifier, this.timestamp, value);
+    return add(family, qualifier, this.ts, value);
   }
 
   /**
@@ -207,7 +189,7 @@ public class Put extends Operation
    * existing KeyValue object in the family map.
    */
   public boolean has(byte [] family, byte [] qualifier) {
-  return has(family, qualifier, this.timestamp, new byte[0], true, true);
+  return has(family, qualifier, this.ts, new byte[0], true, true);
   }
 
   /**
@@ -237,7 +219,7 @@ public class Put extends Operation
    * existing KeyValue object in the family map.
    */
   public boolean has(byte [] family, byte [] qualifier, byte [] value) {
-    return has(family, qualifier, this.timestamp, value, true, false);
+    return has(family, qualifier, this.ts, value, true, false);
   }
 
   /**
@@ -337,53 +319,6 @@ public class Put extends Operation
   }
 
   /**
-   * Method for retrieving the put's familyMap
-   * @return familyMap
-   */
-  public Map<byte [], List<KeyValue>> getFamilyMap() {
-    return this.familyMap;
-  }
-
-  /**
-   * Method for retrieving the put's row
-   * @return row
-   */
-  public byte [] getRow() {
-    return this.row;
-  }
-
-  /**
-   * Method for retrieving the put's RowLock
-   * @return RowLock
-   */
-  public RowLock getRowLock() {
-    return new RowLock(this.row, this.lockId);
-  }
-
-  /**
-   * Method for retrieving the put's lockId
-   * @return lockId
-   */
-  public long getLockId() {
-       return this.lockId;
-  }
-
-  /**
-   * Method to check if the familyMap is empty
-   * @return true if empty, false otherwise
-   */
-  public boolean isEmpty() {
-    return familyMap.isEmpty();
-  }
-
-  /**
-   * @return Timestamp
-   */
-  public long getTimeStamp() {
-    return this.timestamp;
-  }
-
-  /**
    * @return the number of different families included in this put
    */
   public int numFamilies() {
@@ -401,138 +336,6 @@ public class Put extends Operation
     return size;
   }
 
-  /**
-   * @return true if edits should be applied to WAL, false if not
-   */
-  public boolean getWriteToWAL() {
-    return this.writeToWAL;
-  }
-
-  /**
-   * Set whether this Put should be written to the WAL or not.
-   * Not writing the WAL means you may lose edits on server crash.
-   * @param write true if edits should be written to WAL, false if not
-   */
-  public void setWriteToWAL(boolean write) {
-    this.writeToWAL = write;
-  }
-
-  /**
-   * Sets arbitrary put's attribute.
-   * In case value = null attribute is removed from the attributes map.
-   * @param name attribute name
-   * @param value attribute value
-   */
-  public void setAttribute(String name, byte[] value) {
-    if (attributes == null && value == null) {
-      return;
-    }
-
-    if (attributes == null) {
-      attributes = new HashMap<String, byte[]>();
-    }
-
-    if (value == null) {
-      attributes.remove(name);
-      if (attributes.isEmpty()) {
-        this.attributes = null;
-      }
-    } else {
-      attributes.put(name, value);
-    }
-  }
-
-  /**
-   * Gets put's attribute
-   * @param name attribute name
-   * @return attribute value if attribute is set, <tt>null</tt> otherwise
-   */
-  public byte[] getAttribute(String name) {
-    if (attributes == null) {
-      return null;
-    }
-
-    return attributes.get(name);
-  }
-
-  /**
-   * Gets all scan's attributes
-   * @return unmodifiable map of all attributes
-   */
-  public Map<String, byte[]> getAttributesMap() {
-    if (attributes == null) {
-      return Collections.emptyMap();
-    }
-    return Collections.unmodifiableMap(attributes);
-  }
-
-  /**
-   * Compile the column family (i.e. schema) information
-   * into a Map. Useful for parsing and aggregation by debugging,
-   * logging, and administration tools.
-   * @return Map
-   */
-  @Override
-  public Map<String, Object> getFingerprint() {
-    Map<String, Object> map = new HashMap<String, Object>();
-    List<String> families = new ArrayList<String>();
-    // ideally, we would also include table information, but that information
-    // is not stored in each Operation instance.
-    map.put("families", families);
-    for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) 
{
-      families.add(Bytes.toStringBinary(entry.getKey()));
-    } 
-    return map;
-  }
-
-  /**
-   * Compile the details beyond the scope of getFingerprint (row, columns,
-   * timestamps, etc.) into a Map along with the fingerprinted information.
-   * Useful for debugging, logging, and administration tools.
-   * @param maxCols a limit on the number of columns output prior to truncation
-   * @return Map
-   */
-  @Override
-  public Map<String, Object> toMap(int maxCols) {
-    // we start with the fingerprint map and build on top of it.
-    Map<String, Object> map = getFingerprint();
-    // replace the fingerprint's simple list of families with a 
-    // map from column families to lists of qualifiers and kv details
-    Map<String, List<Map<String, Object>>> columns =
-      new HashMap<String, List<Map<String, Object>>>();
-    map.put("families", columns);
-    map.put("row", Bytes.toStringBinary(this.row));
-    int colCount = 0;
-    // iterate through all column families affected by this Put
-    for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) 
{
-      // map from this family to details for each kv affected within the family
-      List<Map<String, Object>> qualifierDetails =
-        new ArrayList<Map<String, Object>>();
-      columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
-      colCount += entry.getValue().size();
-      if (maxCols <= 0) {
-        continue;
-      }
-      // add details for each kv
-      for (KeyValue kv : entry.getValue()) {
-        if (--maxCols <= 0 ) {
-          continue;
-        }
-        Map<String, Object> kvMap = kv.toStringMap();
-        // row and family information are already available in the bigger map
-        kvMap.remove("row");
-        kvMap.remove("family");
-        qualifierDetails.add(kvMap);
-      }
-    }
-    map.put("totalColumns", colCount);
-    return map;
-  }
-
-  public int compareTo(Row p) {
-    return Bytes.compareTo(this.getRow(), p.getRow());
-  }
-
   //HeapSize
   public long heapSize() {
     long heapsize = OVERHEAD;
@@ -559,13 +362,8 @@ public class Put extends Operation
         heapsize += kv.heapSize();
       }
     }
-    if (attributes != null) {
-      heapsize += ClassSize.align(this.attributes.size() * 
ClassSize.MAP_ENTRY);
-      for(Map.Entry<String, byte[]> entry : this.attributes.entrySet()) {
-        heapsize += ClassSize.align(ClassSize.STRING + 
entry.getKey().length());
-        heapsize += ClassSize.align(ClassSize.ARRAY + entry.getValue().length);
-      }
-    }
+    heapsize += getAttributeSize();
+
     return ClassSize.align((int)heapsize);
   }
 
@@ -577,7 +375,7 @@ public class Put extends Operation
       throw new IOException("version not supported");
     }
     this.row = Bytes.readByteArray(in);
-    this.timestamp = in.readLong();
+    this.ts = in.readLong();
     this.lockId = in.readLong();
     this.writeToWAL = in.readBoolean();
     int numFamilies = in.readInt();
@@ -598,15 +396,7 @@ public class Put extends Operation
       this.familyMap.put(family, keys);
     }
     if (version > 1) {
-      int numAttributes = in.readInt();
-      if (numAttributes > 0) {
-        this.attributes = new HashMap<String, byte[]>();
-        for(int i=0; i<numAttributes; i++) {
-          String name = WritableUtils.readString(in);
-          byte[] value = Bytes.readByteArray(in);
-          this.attributes.put(name, value);
-        }
-      }
+      readAttributes(in);
     }
   }
 
@@ -614,7 +404,7 @@ public class Put extends Operation
   throws IOException {
     out.writeByte(PUT_VERSION);
     Bytes.writeByteArray(out, this.row);
-    out.writeLong(this.timestamp);
+    out.writeLong(this.ts);
     out.writeLong(this.lockId);
     out.writeBoolean(this.writeToWAL);
     out.writeInt(familyMap.size());
@@ -632,15 +422,7 @@ public class Put extends Operation
         out.write(kv.getBuffer(), kv.getOffset(), kv.getLength());
       }
     }
-    if (this.attributes == null) {
-      out.writeInt(0);
-    } else {
-      out.writeInt(this.attributes.size());
-      for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
-        WritableUtils.writeString(out, attr.getKey());
-        Bytes.writeByteArray(out, attr.getValue());
-      }
-    }
+    writeAttributes(out);
   }
 
   /**
@@ -657,26 +439,4 @@ public class Put extends Operation
     byte [][] parts = KeyValue.parseColumn(column);
     return add(parts[0], parts[1], ts, value);
   }
-
-  /**
-   * Set the replication custer id.
-   * @param clusterId
-   */
-  public void setClusterId(UUID clusterId) {
-    byte[] val = new byte[2*Bytes.SIZEOF_LONG];
-    Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
-    Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
-    setAttribute(HConstants.CLUSTER_ID_ATTR, val);
-  }
-
-  /**
-   * @return The replication cluster id.
-   */
-  public UUID getClusterId() {
-    byte[] attr = getAttribute(HConstants.CLUSTER_ID_ATTR);
-    if (attr == null) {
-      return HConstants.DEFAULT_CLUSTER_ID;
-    }
-    return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, 
Bytes.SIZEOF_LONG));
-  }
 }

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Scan.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Scan.java?rev=1167569&r1=1167568&r2=1167569&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Scan.java 
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Scan.java Sat Sep 
10 17:57:19 2011
@@ -29,13 +29,11 @@ import org.apache.hadoop.hbase.io.TimeRa
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.Writable;
 import org.apache.hadoop.io.WritableFactories;
-import org.apache.hadoop.io.WritableUtils;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -83,13 +81,12 @@ import java.util.TreeSet;
  * Expert: To explicitly disable server-side block caching for this scan,
  * execute {@link #setCacheBlocks(boolean)}.
  */
-public class Scan extends Operation implements Writable {
+public class Scan extends OperationWithAttributes implements Writable {
   private static final byte SCAN_VERSION = (byte)2;
   private byte [] startRow = HConstants.EMPTY_START_ROW;
   private byte [] stopRow  = HConstants.EMPTY_END_ROW;
   private int maxVersions = 1;
   private int batch = -1;
-  private Map<String, byte[]> attributes;
 
   /*
    * -1 means no caching
@@ -447,55 +444,6 @@ public class Scan extends Operation impl
   }
 
   /**
-   * Sets arbitrary scan's attribute.
-   * In case value = null attribute is removed from the attributes map.
-   * @param name attribute name
-   * @param value attribute value
-   */
-  public void setAttribute(String name, byte[] value) {
-    if (attributes == null && value == null) {
-      return;
-    }
-
-    if (attributes == null) {
-      attributes = new HashMap<String, byte[]>();
-    }
-
-    if (value == null) {
-      attributes.remove(name);
-      if (attributes.isEmpty()) {
-        this.attributes = null;
-      }
-    } else {
-      attributes.put(name, value);
-    }
-  }
-
-  /**
-   * Gets scan's attribute
-   * @param name attribute name
-   * @return attribute value if attribute is set, <tt>null</tt> otherwise
-   */
-  public byte[] getAttribute(String name) {
-    if (attributes == null) {
-      return null;
-    }
-
-    return attributes.get(name);
-  }
-
-  /**
-   * Gets all scan's attributes
-   * @return unmodifiable map of all attributes
-   */
-  public Map<String, byte[]> getAttributesMap() {
-    if (attributes == null) {
-      return Collections.emptyMap();
-    }
-    return Collections.unmodifiableMap(attributes);
-  }
-
-  /**
    * Compile the table and column family (i.e. schema) information
    * into a String. Useful for parsing and aggregation by debugging,
    * logging, and administration tools.
@@ -616,15 +564,7 @@ public class Scan extends Operation impl
     }
 
     if (version > 1) {
-      int numAttributes = in.readInt();
-      if (numAttributes > 0) {
-        this.attributes = new HashMap<String, byte[]>();
-        for(int i=0; i<numAttributes; i++) {
-          String name = WritableUtils.readString(in);
-          byte[] value = Bytes.readByteArray(in);
-          this.attributes.put(name, value);
-        }
-      }
+      readAttributes(in);
     }
   }
 
@@ -658,16 +598,7 @@ public class Scan extends Operation impl
         out.writeInt(0);
       }
     }
-
-    if (this.attributes == null) {
-      out.writeInt(0);
-    } else {
-      out.writeInt(this.attributes.size());
-      for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
-        WritableUtils.writeString(out, attr.getKey());
-        Bytes.writeByteArray(out, attr.getValue());
-      }
-    }
+    writeAttributes(out);
   }
 
    /**


Reply via email to