Repository: hbase
Updated Branches:
  refs/heads/branch-2 a28156be9 -> 4aec7a491


HBASE-19575 add copy constructor to Mutation


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/4aec7a49
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/4aec7a49
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/4aec7a49

Branch: refs/heads/branch-2
Commit: 4aec7a491a15edac33bcb192f8c347b299b3990c
Parents: a28156b
Author: Chia-Ping Tsai <chia7...@gmail.com>
Authored: Fri Dec 22 03:13:03 2017 +0800
Committer: Chia-Ping Tsai <chia7...@gmail.com>
Committed: Fri Dec 22 03:19:47 2017 +0800

----------------------------------------------------------------------
 .../org/apache/hadoop/hbase/client/Append.java  |  32 ++-
 .../org/apache/hadoop/hbase/client/Delete.java  |  32 ++-
 .../apache/hadoop/hbase/client/Increment.java   |  32 ++-
 .../apache/hadoop/hbase/client/Mutation.java    |  45 +++-
 .../hbase/client/OperationWithAttributes.java   |  21 +-
 .../org/apache/hadoop/hbase/client/Put.java     |  30 ++-
 .../hadoop/hbase/client/TestMutation.java       | 239 +++++++++++++++++++
 .../org/apache/hadoop/hbase/client/TestPut.java | 125 ----------
 .../hbase/regionserver/TestMetricsRegion.java   |   2 +-
 9 files changed, 387 insertions(+), 171 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Append.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Append.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Append.java
index 24e9512..0cb51a2 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Append.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Append.java
@@ -112,17 +112,11 @@ public class Append extends Mutation {
   }
   /**
    * Copy constructor
-   * @param a
+   * @param appendToCopy append to copy
    */
-  public Append(Append a) {
-    this.row = a.getRow();
-    this.ts = a.getTimeStamp();
-    this.tr = a.getTimeRange();
-    this.familyMap.putAll(a.getFamilyCellMap());
-    for (Map.Entry<String, byte[]> entry : a.getAttributesMap().entrySet()) {
-      this.setAttribute(entry.getKey(), entry.getValue());
-    }
-    this.setPriority(a.getPriority());
+  public Append(Append appendToCopy) {
+    super(appendToCopy);
+    this.tr = appendToCopy.getTimeRange();
   }
 
   /** Create a Append operation for the specified row.
@@ -138,6 +132,18 @@ public class Append extends Mutation {
   }
 
   /**
+   * Construct the Append with user defined data. NOTED:
+   * 1) all cells in the familyMap must have the DataType.Put
+   * 2) the row of each cell must be same with passed row.
+   * @param row row. CAN'T be null
+   * @param ts timestamp
+   * @param familyMap the map to collect all cells internally. CAN'T be null
+   */
+  public Append(byte[] row, long ts, NavigableMap<byte [], List<Cell>> 
familyMap) {
+    super(row, ts, familyMap);
+  }
+
+  /**
    * Add the specified column and value to this Append operation.
    * @param family family name
    * @param qualifier column qualifier
@@ -202,6 +208,12 @@ public class Append extends Mutation {
     return (Append) super.setDurability(d);
   }
 
+  /**
+   * Method for setting the Append's familyMap
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Use {@link Append#Append(byte[], long, NavigableMap)} instead
+   */
+  @Deprecated
   @Override
   public Append setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
     return (Append) super.setFamilyCellMap(map);

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java
index 2d296fb..57f5648 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java
@@ -135,17 +135,23 @@ public class Delete extends Mutation implements 
Comparable<Row> {
   }
 
   /**
-   * @param d Delete to clone.
+   * @param deleteToCopy delete to copy
    */
-  public Delete(final Delete d) {
-    this.row = d.getRow();
-    this.ts = d.getTimeStamp();
-    this.familyMap.putAll(d.getFamilyCellMap());
-    this.durability = d.durability;
-    for (Map.Entry<String, byte[]> entry : d.getAttributesMap().entrySet()) {
-      this.setAttribute(entry.getKey(), entry.getValue());
-    }
-    super.setPriority(d.getPriority());
+  public Delete(final Delete deleteToCopy) {
+    super(deleteToCopy);
+  }
+
+  /**
+   * Construct the Delete with user defined data. NOTED:
+   * 1) all cells in the familyMap must have the delete type.
+   * see {@link org.apache.hadoop.hbase.Cell.DataType}
+   * 2) the row of each cell must be same with passed row.
+   * @param row row. CAN'T be null
+   * @param ts timestamp
+   * @param familyMap the map to collect all cells internally. CAN'T be null
+   */
+  public Delete(byte[] row, long ts, NavigableMap<byte [], List<Cell>> 
familyMap) {
+    super(row, ts, familyMap);
   }
 
   /**
@@ -314,6 +320,12 @@ public class Delete extends Mutation implements 
Comparable<Row> {
     return (Delete) super.setDurability(d);
   }
 
+  /**
+   * Method for setting the Delete's familyMap
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Use {@link Delete#Delete(byte[], long, NavigableMap)} instead
+   */
+  @Deprecated
   @Override
   public Delete setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
     return (Delete) super.setFamilyCellMap(map);

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Increment.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Increment.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Increment.java
index 27cdafe..e9ae8fb 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Increment.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Increment.java
@@ -72,17 +72,23 @@ public class Increment extends Mutation implements 
Comparable<Row> {
   }
   /**
    * Copy constructor
-   * @param i
+   * @param incrementToCopy increment to copy
    */
-  public Increment(Increment i) {
-    this.row = i.getRow();
-    this.ts = i.getTimeStamp();
-    this.tr = i.getTimeRange();
-    this.familyMap.putAll(i.getFamilyCellMap());
-    for (Map.Entry<String, byte[]> entry : i.getAttributesMap().entrySet()) {
-      this.setAttribute(entry.getKey(), entry.getValue());
-    }
-    super.setPriority(i.getPriority());
+  public Increment(Increment incrementToCopy) {
+    super(incrementToCopy);
+    this.tr = incrementToCopy.getTimeRange();
+  }
+
+  /**
+   * Construct the Increment with user defined data. NOTED:
+   * 1) all cells in the familyMap must have the DataType.Put
+   * 2) the row of each cell must be same with passed row.
+   * @param row row. CAN'T be null
+   * @param ts timestamp
+   * @param familyMap the map to collect all cells internally. CAN'T be null
+   */
+  public Increment(byte[] row, long ts, NavigableMap<byte [], List<Cell>> 
familyMap) {
+    super(row, ts, familyMap);
   }
 
   /**
@@ -309,6 +315,12 @@ public class Increment extends Mutation implements 
Comparable<Row> {
     return (Increment) super.setDurability(d);
   }
 
+  /**
+   * Method for setting the Increment's familyMap
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Use {@link Increment#Increment(byte[], long, NavigableMap)} 
instead
+   */
+  @Deprecated
   @Override
   public Increment setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
     return (Increment) super.setFamilyCellMap(map);

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java
index ba8f6cc..3983f35 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import java.util.NavigableMap;
 import java.util.TreeMap;
 import java.util.UUID;
+import java.util.stream.Collectors;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellScannable;
 import org.apache.hadoop.hbase.CellScanner;
@@ -49,6 +50,7 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.ClassSize;
 import org.apache.yetus.audience.InterfaceAudience;
 
+import org.apache.hadoop.hbase.shaded.com.google.common.base.Preconditions;
 import 
org.apache.hadoop.hbase.shaded.com.google.common.collect.ArrayListMultimap;
 import org.apache.hadoop.hbase.shaded.com.google.common.collect.ListMultimap;
 import org.apache.hadoop.hbase.shaded.com.google.common.io.ByteArrayDataInput;
@@ -87,12 +89,48 @@ public abstract class Mutation extends 
OperationWithAttributes implements Row, C
 
   private static final String RETURN_RESULTS = "_rr_";
 
+  // TODO: row should be final
   protected byte [] row = null;
   protected long ts = HConstants.LATEST_TIMESTAMP;
   protected Durability durability = Durability.USE_DEFAULT;
 
+  // TODO: familyMap should be final
   // A Map sorted by column family.
-  protected NavigableMap<byte [], List<Cell>> familyMap = new 
TreeMap<>(Bytes.BYTES_COMPARATOR);
+  protected NavigableMap<byte [], List<Cell>> familyMap;
+
+  /**
+   * empty construction.
+   * We need this empty construction to keep binary compatibility.
+   */
+  protected Mutation() {
+    this.familyMap = new TreeMap<>(Bytes.BYTES_COMPARATOR);
+  }
+
+  protected Mutation(Mutation clone) {
+    super(clone);
+    this.row = clone.getRow();
+    this.ts = clone.getTimeStamp();
+    this.familyMap = clone.getFamilyCellMap().entrySet().stream()
+      .collect(Collectors.toMap(e -> e.getKey(), e -> new 
ArrayList<>(e.getValue()),
+        (k, v) -> {
+          throw new RuntimeException("collisions!!!");
+        }, () -> new TreeMap(Bytes.BYTES_COMPARATOR)));
+  }
+
+  /**
+   * Construct the mutation with user defined data.
+   * @param row row. CAN'T be null
+   * @param ts timestamp
+   * @param familyMap the map to collect all cells internally. CAN'T be null
+   */
+  protected Mutation(byte[] row, long ts, NavigableMap<byte [], List<Cell>> 
familyMap) {
+    this.row = Preconditions.checkNotNull(row);
+    if (row.length == 0) {
+      throw new IllegalArgumentException("Row can't be empty");
+    }
+    this.ts = ts;
+    this.familyMap = Preconditions.checkNotNull(familyMap);
+  }
 
   @Override
   public CellScanner cellScanner() {
@@ -260,8 +298,11 @@ public abstract class Mutation extends 
OperationWithAttributes implements Row, C
   }
 
   /**
-   * Method for setting the put's familyMap
+   * Method for setting the mutation's familyMap
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Use {@link Mutation#Mutation(byte[], long, NavigableMap)} 
instead
    */
+  @Deprecated
   public Mutation setFamilyCellMap(NavigableMap<byte [], List<Cell>> map) {
     // TODO: Shut this down or move it up to be a Constructor.  Get new object 
rather than change
     // this internal data member.

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
index fc1f417..7342e65 100644
--- 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
+++ 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OperationWithAttributes.java
@@ -22,11 +22,12 @@ package org.apache.hadoop.hbase.client;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-
+import java.util.TreeMap;
+import java.util.stream.Collectors;
 import org.apache.hadoop.hbase.HConstants;
-import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.ClassSize;
+import org.apache.yetus.audience.InterfaceAudience;
 
 @InterfaceAudience.Public
 public abstract class OperationWithAttributes extends Operation implements 
Attributes {
@@ -37,6 +38,22 @@ public abstract class OperationWithAttributes extends 
Operation implements Attri
   public static final String ID_ATRIBUTE = "_operation.attributes.id";
   private int priority = HConstants.PRIORITY_UNSET;
 
+  /**
+   * empty construction.
+   * We need this empty construction to keep binary compatibility.
+   */
+  protected OperationWithAttributes() {
+  }
+
+  protected OperationWithAttributes(OperationWithAttributes clone) {
+    this.attributes = clone.getAttributesMap() == null ? null :
+      clone.getAttributesMap().entrySet().stream()
+        .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue(), (k, v) 
-> {
+          throw new RuntimeException("collisions!!!");
+        }, () -> new TreeMap<>()));
+    this.priority = clone.getPriority();
+  }
+
   @Override
   public OperationWithAttributes setAttribute(String name, byte[] value) {
     if (attributes == null && value == null) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Put.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Put.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Put.java
index 73da4c8..1a1176f 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Put.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Put.java
@@ -21,11 +21,9 @@ package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableMap;
-import java.util.TreeMap;
 import java.util.UUID;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
@@ -155,15 +153,19 @@ public class Put extends Mutation implements HeapSize, 
Comparable<Row> {
    * @param putToCopy put to copy
    */
   public Put(Put putToCopy) {
-    this(putToCopy.getRow(), putToCopy.ts);
-    this.familyMap = new TreeMap<>(Bytes.BYTES_COMPARATOR);
-    for(Map.Entry<byte [], List<Cell>> entry: 
putToCopy.getFamilyCellMap().entrySet()) {
-      this.familyMap.put(entry.getKey(), new ArrayList<>(entry.getValue()));
-    }
-    this.durability = putToCopy.durability;
-    for (Map.Entry<String, byte[]> entry : 
putToCopy.getAttributesMap().entrySet()) {
-      this.setAttribute(entry.getKey(), entry.getValue());
-    }
+    super(putToCopy);
+  }
+
+  /**
+   * Construct the Put with user defined data. NOTED:
+   * 1) all cells in the familyMap must have the DataType.Put
+   * 2) the row of each cell must be same with passed row.
+   * @param row row. CAN'T be null
+   * @param ts timestamp
+   * @param familyMap the map to collect all cells internally. CAN'T be null
+   */
+  public Put(byte[] row, long ts, NavigableMap<byte [], List<Cell>> familyMap) 
{
+    super(row, ts, familyMap);
   }
 
   /**
@@ -321,6 +323,12 @@ public class Put extends Mutation implements HeapSize, 
Comparable<Row> {
     return (Put) super.setDurability(d);
   }
 
+  /**
+   * Method for setting the put's familyMap
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Use {@link Put#Put(byte[], long, NavigableMap)} instead
+   */
+  @Deprecated
   @Override
   public Put setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
     return (Put) super.setFamilyCellMap(map);

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestMutation.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestMutation.java 
b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestMutation.java
new file mode 100644
index 0000000..111634a
--- /dev/null
+++ 
b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestMutation.java
@@ -0,0 +1,239 @@
+/**
+ *
+ * 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 static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.Cell.DataType;
+import org.apache.hadoop.hbase.CellBuilderFactory;
+import org.apache.hadoop.hbase.CellBuilderType;
+import org.apache.hadoop.hbase.CellUtil;
+import org.apache.hadoop.hbase.io.TimeRange;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category({ SmallTests.class, ClientTests.class })
+public class TestMutation {
+
+  @Test
+  public void testAppendCopyConstructor() throws IOException {
+    Append origin = new Append(Bytes.toBytes("ROW-01"));
+    origin.setPriority(100);
+    byte[] family = Bytes.toBytes("CF-01");
+
+    origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+      .setRow(origin.getRow())
+      .setFamily(family)
+      .setQualifier(Bytes.toBytes("q"))
+      .setType(DataType.Put)
+      .setValue(Bytes.toBytes(100))
+      .build());
+    origin.addColumn(family, Bytes.toBytes("q0"), Bytes.toBytes("value"));
+    origin.setTimeRange(100, 1000);
+    Append clone = new Append(origin);
+    assertEquals(origin, clone);
+    origin.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("value"));
+
+    //They should have different cell lists
+    assertNotEquals(origin.getCellList(family), clone.getCellList(family));
+  }
+
+  @Test
+  public void testIncrementCopyConstructor() throws IOException {
+    Increment origin = new Increment(Bytes.toBytes("ROW-01"));
+    origin.setPriority(100);
+    byte[] family = Bytes.toBytes("CF-01");
+
+    origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+      .setRow(origin.getRow())
+      .setFamily(family)
+      .setQualifier(Bytes.toBytes("q"))
+      .setType(DataType.Put)
+      .setValue(Bytes.toBytes(100))
+      .build());
+    origin.addColumn(family, Bytes.toBytes("q0"), 4);
+    origin.setTimeRange(100, 1000);
+    Increment clone = new Increment(origin);
+    assertEquals(origin, clone);
+    origin.addColumn(family, Bytes.toBytes("q1"), 3);
+
+    //They should have different cell lists
+    assertNotEquals(origin.getCellList(family), clone.getCellList(family));
+  }
+
+  @Test
+  public void testDeleteCopyConstructor() throws IOException {
+    Delete origin = new Delete(Bytes.toBytes("ROW-01"));
+    origin.setPriority(100);
+    byte[] family = Bytes.toBytes("CF-01");
+
+    origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+      .setRow(origin.getRow())
+      .setFamily(family)
+      .setQualifier(Bytes.toBytes("q"))
+      .setType(DataType.Delete)
+      .build());
+    origin.addColumn(family, Bytes.toBytes("q0"));
+    origin.addColumns(family, Bytes.toBytes("q1"));
+    origin.addFamily(family);
+    origin.addColumns(family, Bytes.toBytes("q2"), 100);
+    origin.addFamilyVersion(family, 1000);
+    Delete clone = new Delete(origin);
+    assertEquals(origin, clone);
+    origin.addColumn(family, Bytes.toBytes("q3"));
+
+    //They should have different cell lists
+    assertNotEquals(origin.getCellList(family), clone.getCellList(family));
+  }
+
+  @Test
+  public void testPutCopyConstructor() throws IOException {
+    Put origin = new Put(Bytes.toBytes("ROW-01"));
+    origin.setPriority(100);
+    byte[] family = Bytes.toBytes("CF-01");
+
+    origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+      .setRow(origin.getRow())
+      .setFamily(family)
+      .setQualifier(Bytes.toBytes("q"))
+      .setType(DataType.Put)
+      .setValue(Bytes.toBytes("value"))
+      .build());
+    origin.addColumn(family, Bytes.toBytes("q0"), Bytes.toBytes("V-01"));
+    origin.addColumn(family, Bytes.toBytes("q1"), 100, Bytes.toBytes("V-01"));
+    Put clone = new Put(origin);
+    assertEquals(origin, clone);
+    origin.addColumn(family, Bytes.toBytes("q2"), Bytes.toBytes("V-02"));
+
+    //They should have different cell lists
+    assertNotEquals(origin.getCellList(family), clone.getCellList(family));
+  }
+
+  private void assertEquals(Mutation origin, Mutation clone) {
+    Assert.assertEquals(origin.getFamilyCellMap().size(), 
clone.getFamilyCellMap().size());
+    for (byte[] family : origin.getFamilyCellMap().keySet()) {
+      List<Cell> originCells = origin.getCellList(family);
+      List<Cell> cloneCells = clone.getCellList(family);
+      Assert.assertEquals(originCells.size(), cloneCells.size());
+      for (int i = 0; i != cloneCells.size(); ++i) {
+        Cell originCell = originCells.get(i);
+        Cell cloneCell = cloneCells.get(i);
+        assertTrue(CellUtil.equals(originCell, cloneCell));
+        assertTrue(CellUtil.matchingValue(originCell, cloneCell));
+      }
+    }
+    Assert.assertEquals(origin.getAttributesMap().size(), 
clone.getAttributesMap().size());
+    for (String name : origin.getAttributesMap().keySet()) {
+      byte[] originValue = origin.getAttributesMap().get(name);
+      byte[] cloneValue = clone.getAttributesMap().get(name);
+      assertTrue(Bytes.equals(originValue, cloneValue));
+    }
+    Assert.assertEquals(origin.getTimeStamp(), clone.getTimeStamp());
+    Assert.assertEquals(origin.getPriority(), clone.getPriority());
+    if (origin instanceof Append) {
+      assertEquals(((Append)origin).getTimeRange(), 
((Append)clone).getTimeRange());
+    }
+    if (origin instanceof Increment) {
+      assertEquals(((Increment)origin).getTimeRange(), 
((Increment)clone).getTimeRange());
+    }
+  }
+
+  private static void assertEquals(TimeRange origin, TimeRange clone) {
+    Assert.assertEquals(origin.getMin(), clone.getMin());
+    Assert.assertEquals(origin.getMax(), clone.getMax());
+  }
+
+  // HBASE-14881
+  @Test
+  public void testRowIsImmutableOrNot() {
+    byte[] rowKey = Bytes.toBytes("immutable");
+
+    // Test when row key is immutable
+    Put putRowIsImmutable = new Put(rowKey, true);
+    assertTrue(rowKey == putRowIsImmutable.getRow());  // No local copy is made
+
+    // Test when row key is not immutable
+    Put putRowIsNotImmutable = new Put(rowKey, 1000L, false);
+    assertTrue(rowKey != putRowIsNotImmutable.getRow());  // A local copy is 
made
+  }
+
+  // HBASE-14882
+  @Test
+  public void testAddImmutableToPut() throws IOException {
+    byte[] row        = Bytes.toBytes("immutable-row");
+    byte[] family     = Bytes.toBytes("immutable-family");
+
+    byte[] qualifier0 = Bytes.toBytes("immutable-qualifier-0");
+    byte[] value0     = Bytes.toBytes("immutable-value-0");
+
+    byte[] qualifier1 = Bytes.toBytes("immutable-qualifier-1");
+    byte[] value1     = Bytes.toBytes("immutable-value-1");
+    long   ts1        = 5000L;
+
+    // "true" indicates that the input row is immutable
+    Put put = new Put(row, true);
+    put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+            .setRow(row)
+            .setFamily(family)
+            .setQualifier(qualifier0)
+            .setTimestamp(put.getTimeStamp())
+            .setType(DataType.Put)
+            .setValue(value0)
+            .build())
+        .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
+            .setRow(row)
+            .setFamily(family)
+            .setQualifier(qualifier1)
+            .setTimestamp(ts1)
+            .setType(DataType.Put)
+            .setValue(value1)
+            .build());
+
+    // Verify the cell of family:qualifier0
+    Cell cell0 = put.get(family, qualifier0).get(0);
+
+    // Verify no local copy is made for family, qualifier or value
+    assertTrue(cell0.getFamilyArray()    == family);
+    assertTrue(cell0.getQualifierArray() == qualifier0);
+    assertTrue(cell0.getValueArray()     == value0);
+
+    // Verify timestamp
+    assertTrue(cell0.getTimestamp()      == put.getTimeStamp());
+
+    // Verify the cell of family:qualifier1
+    Cell cell1 = put.get(family, qualifier1).get(0);
+
+    // Verify no local copy is made for family, qualifier or value
+    assertTrue(cell1.getFamilyArray()    == family);
+    assertTrue(cell1.getQualifierArray() == qualifier1);
+    assertTrue(cell1.getValueArray()     == value1);
+
+    // Verify timestamp
+    assertTrue(cell1.getTimestamp()      == ts1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestPut.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestPut.java 
b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestPut.java
deleted file mode 100644
index 0ae2dfa..0000000
--- a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestPut.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- *
- * 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-
-import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.Cell.DataType;
-import org.apache.hadoop.hbase.CellBuilderFactory;
-import org.apache.hadoop.hbase.CellBuilderType;
-import org.apache.hadoop.hbase.testclassification.ClientTests;
-import org.apache.hadoop.hbase.testclassification.SmallTests;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-@Category({ SmallTests.class, ClientTests.class })
-public class TestPut {
-  @Test
-  public void testCopyConstructor() {
-    Put origin = new Put(Bytes.toBytes("ROW-01"));
-    byte[] family = Bytes.toBytes("CF-01");
-    byte[] qualifier = Bytes.toBytes("Q-01");
-
-    origin.addColumn(family, qualifier, Bytes.toBytes("V-01"));
-    Put clone = new Put(origin);
-
-    assertEquals(origin.getCellList(family), clone.getCellList(family));
-    origin.addColumn(family, qualifier, Bytes.toBytes("V-02"));
-
-    //They should have different cell lists
-    assertNotEquals(origin.getCellList(family), clone.getCellList(family));
-
-  }
-
-  // HBASE-14881
-  @Test
-  public void testRowIsImmutableOrNot() {
-    byte[] rowKey = Bytes.toBytes("immutable");
-
-    // Test when row key is immutable
-    Put putRowIsImmutable = new Put(rowKey, true);
-    assertTrue(rowKey == putRowIsImmutable.getRow());  // No local copy is made
-
-    // Test when row key is not immutable
-    Put putRowIsNotImmutable = new Put(rowKey, 1000L, false);
-    assertTrue(rowKey != putRowIsNotImmutable.getRow());  // A local copy is 
made
-  }
-
-  // HBASE-14882
-  @Test
-  public void testAddImmutable() throws IOException {
-    byte[] row        = Bytes.toBytes("immutable-row");
-    byte[] family     = Bytes.toBytes("immutable-family");
-
-    byte[] qualifier0 = Bytes.toBytes("immutable-qualifier-0");
-    byte[] value0     = Bytes.toBytes("immutable-value-0");
-
-    byte[] qualifier1 = Bytes.toBytes("immutable-qualifier-1");
-    byte[] value1     = Bytes.toBytes("immutable-value-1");
-    long   ts1        = 5000L;
-
-    // "true" indicates that the input row is immutable
-    Put put = new Put(row, true);
-    put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
-            .setRow(row)
-            .setFamily(family)
-            .setQualifier(qualifier0)
-            .setTimestamp(put.getTimeStamp())
-            .setType(DataType.Put)
-            .setValue(value0)
-            .build())
-        .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
-            .setRow(row)
-            .setFamily(family)
-            .setQualifier(qualifier1)
-            .setTimestamp(ts1)
-            .setType(DataType.Put)
-            .setValue(value1)
-            .build());
-
-    // Verify the cell of family:qualifier0
-    Cell cell0 = put.get(family, qualifier0).get(0);
-
-    // Verify no local copy is made for family, qualifier or value
-    assertTrue(cell0.getFamilyArray()    == family);
-    assertTrue(cell0.getQualifierArray() == qualifier0);
-    assertTrue(cell0.getValueArray()     == value0);
-
-    // Verify timestamp
-    assertTrue(cell0.getTimestamp()      == put.getTimeStamp());
-
-    // Verify the cell of family:qualifier1
-    Cell cell1 = put.get(family, qualifier1).get(0);
-
-    // Verify no local copy is made for family, qualifier or value
-    assertTrue(cell1.getFamilyArray()    == family);
-    assertTrue(cell1.getQualifierArray() == qualifier1);
-    assertTrue(cell1.getValueArray()     == value1);
-
-    // Verify timestamp
-    assertTrue(cell1.getTimestamp()      == ts1);
-  }
-}

http://git-wip-us.apache.org/repos/asf/hbase/blob/4aec7a49/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegion.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegion.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegion.java
index 6552808..e86f1e5 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegion.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegion.java
@@ -83,7 +83,7 @@ public class TestMetricsRegion {
         "filteredReadRequestCount",
       107, agg);
     HELPER.assertCounter(
-      
"namespace_TestNS_table_MetricsRegionWrapperStub_region_DEADBEEF001_metric_replicaid",
 
+      
"namespace_TestNS_table_MetricsRegionWrapperStub_region_DEADBEEF001_metric_replicaid",
       1, agg);
     HELPER.assertCounter(
       
"namespace_TestNS_table_MetricsRegionWrapperStub_region_DEADBEEF001_metric_compactionsQueuedCount",

Reply via email to