From bd2a8a050fd69e8cc2f40d3f0174fd44a3090c1c Mon Sep 17 00:00:00 2001 From: maoling Date: Thu, 14 Jun 2018 10:52:11 +0800 Subject: [PATCH] HBase-20623:Introduce the helper method "getCellBuilder()" to Mutation --- .../org/apache/hadoop/hbase/client/Append.java | 7 ++ .../org/apache/hadoop/hbase/client/Delete.java | 7 ++ .../org/apache/hadoop/hbase/client/Increment.java | 7 ++ .../org/apache/hadoop/hbase/client/Mutation.java | 101 +++++++++++++++++ .../java/org/apache/hadoop/hbase/client/Put.java | 8 ++ .../hbase/client/TestMutationGetCellBuilder.java | 119 +++++++++++++++++++++ src/main/asciidoc/_chapters/datamodel.adoc | 21 ++++ 7 files changed, 270 insertions(+) create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMutationGetCellBuilder.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 3a08d68..86c141e 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 @@ -23,6 +23,8 @@ import java.util.Map; import java.util.NavigableMap; import java.util.UUID; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellBuilder; +import org.apache.hadoop.hbase.CellBuilderType; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.security.access.Permission; @@ -249,4 +251,9 @@ public class Append extends Mutation { public Append setTTL(long ttl) { return (Append) super.setTTL(ttl); } + + @Override + public CellBuilder getCellBuilder(CellBuilderType type) { + return getCellBuilder(type, Cell.Type.Put); + } } 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 7c32a68..59b293e 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 @@ -25,6 +25,8 @@ import java.util.Map; import java.util.NavigableMap; import java.util.UUID; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellBuilder; +import org.apache.hadoop.hbase.CellBuilderType; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.security.access.Permission; @@ -349,4 +351,9 @@ public class Delete extends Mutation { public Delete setPriority(int priority) { return (Delete) super.setPriority(priority); } + + @Override + public CellBuilder getCellBuilder(CellBuilderType type) { + return getCellBuilder(type, Cell.Type.Delete); + } } 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 d7d1116..b0a4724 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 @@ -25,6 +25,8 @@ import java.util.NavigableMap; import java.util.TreeMap; import java.util.UUID; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellBuilder; +import org.apache.hadoop.hbase.CellBuilderType; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.io.TimeRange; @@ -352,4 +354,9 @@ public class Increment extends Mutation { public Increment setPriority(int priority) { return (Increment) super.setPriority(priority); } + + @Override + public CellBuilder getCellBuilder(CellBuilderType type) { + return getCellBuilder(type, Cell.Type.Put); + } } 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 dc8199d..174b522 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 @@ -32,6 +32,9 @@ import java.util.TreeMap; import java.util.UUID; import java.util.stream.Collectors; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellBuilder; +import org.apache.hadoop.hbase.CellBuilderFactory; +import org.apache.hadoop.hbase.CellBuilderType; import org.apache.hadoop.hbase.CellScannable; import org.apache.hadoop.hbase.CellScanner; import org.apache.hadoop.hbase.CellUtil; @@ -808,6 +811,104 @@ public abstract class Mutation extends OperationWithAttributes implements Row, C return this; } + /** + * get a CellBuilder instance that already has relevant Type and Row set. + * @param cellBuilderType e.g CellBuilderType.SHALLOW_COPY + * @return CellBuilder which already has relevant Type and Row set. + */ + public abstract CellBuilder getCellBuilder(CellBuilderType cellBuilderType); + + /** + * get a CellBuilder instance that already has relevant Type and Row set. + * the default CellBuilderType is CellBuilderType.SHALLOW_COPY + * @return CellBuilder which already has relevant Type and Row set. + */ + public CellBuilder getCellBuilder() { + return getCellBuilder(CellBuilderType.SHALLOW_COPY); + } + + /** + * get a CellBuilder instance that already has relevant Type and Row set. + * @param cellBuilderType e.g CellBuilderType.SHALLOW_COPY + * @param cellType e.g Cell.Type.Put + * @return CellBuilder which already has relevant Type and Row set. + */ + protected CellBuilder getCellBuilder(CellBuilderType cellBuilderType, Cell.Type cellType) { + CellBuilder builder = CellBuilderFactory.create(cellBuilderType).setRow(row).setType(cellType); + return new CellBuilder() { + @Override + public CellBuilder setRow(byte[] row) { + return this; + } + + @Override + public CellBuilder setType(Cell.Type type) { + return this; + } + + @Override + public CellBuilder setRow(byte[] row, int rOffset, int rLength) { + return this; + } + + @Override + public CellBuilder setFamily(byte[] family) { + builder.setFamily(family); + return this; + } + + @Override + public CellBuilder setFamily(byte[] family, int fOffset, int fLength) { + builder.setFamily(family, fOffset, fLength); + return this; + } + + @Override + public CellBuilder setQualifier(byte[] qualifier) { + builder.setQualifier(qualifier); + return this; + } + + @Override + public CellBuilder setQualifier(byte[] qualifier, int qOffset, int qLength) { + builder.setQualifier(qualifier, qOffset, qLength); + return this; + } + + @Override + public CellBuilder setTimestamp(long timestamp) { + builder.setTimestamp(timestamp); + return this; + } + + @Override + public CellBuilder setValue(byte[] value) { + builder.setValue(value); + return this; + } + + @Override + public CellBuilder setValue(byte[] value, int vOffset, int vLength) { + builder.setValue(value, vOffset, vLength); + return this; + } + + @Override + public Cell build() { + return builder.build(); + } + + @Override + public CellBuilder clear() { + builder.clear(); + // reset the row and type + builder.setRow(row); + builder.setType(cellType); + return this; + } + }; + } + private static final class CellWrapper implements ExtendedCell { private static final long FIXED_OVERHEAD = ClassSize.align( ClassSize.OBJECT // object header 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 db8eec5..78062e8 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 @@ -26,6 +26,8 @@ import java.util.Map; import java.util.NavigableMap; import java.util.UUID; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellBuilder; +import org.apache.hadoop.hbase.CellBuilderType; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.IndividualBytesFieldCell; import org.apache.hadoop.hbase.KeyValue; @@ -339,4 +341,10 @@ public class Put extends Mutation implements HeapSize { public Put setTTL(long ttl) { return (Put) super.setTTL(ttl); } + + @Override + public CellBuilder getCellBuilder(CellBuilderType type) { + return getCellBuilder(type, Cell.Type.Put); + } + } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMutationGetCellBuilder.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMutationGetCellBuilder.java new file mode 100644 index 0000000..166a3c2 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMutationGetCellBuilder.java @@ -0,0 +1,119 @@ +/** + * 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.assertTrue; + +import java.util.Arrays; +import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellBuilder; +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.testclassification.ClientTests; +import org.apache.hadoop.hbase.testclassification.MediumTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; + +@Category({MediumTests.class, ClientTests.class}) +public class TestMutationGetCellBuilder { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestMutationGetCellBuilder.class); + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + + @Rule + public TestName name = new TestName(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TEST_UTIL.startMiniCluster(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + @Test + public void testMutationGetCellBuilder() throws Exception { + final TableName tableName = TableName.valueOf(name.getMethodName()); + final byte[] rowKey = Bytes.toBytes("12345678"); + final byte[] family = Bytes.toBytes("cf"); + final byte[] qualifier = Bytes.toBytes("foo"); + final long now = System.currentTimeMillis(); + Table table = TEST_UTIL.createTable(tableName, family); + TEST_UTIL.waitTableAvailable(tableName.getName(), 5000); + try { + // put one row + Put put = new Put(rowKey); + CellBuilder cell = put.getCellBuilder(); + cell.clear(); + //setRow setType is useless + cell.setRow(Bytes.toBytes("123")); + cell.setType(Cell.Type.Delete); + cell.setQualifier(qualifier); + cell.setFamily(family); + cell.setValue(Bytes.toBytes("bar")); + cell.setTimestamp(now); + put.add(cell.build()); + table.put(put); + + // get the row back and assert the values + Get get = new Get(rowKey); + get.setTimestamp(now); + Result result = table.get(get); + assertTrue("row key must be same", Arrays.equals(result.getRow(), rowKey)); + assertTrue("Column foo value should be bar", + Bytes.toString(result.getValue(family, qualifier)).equals("bar")); + + //to check cell.setRow is useless + get = new Get(Bytes.toBytes("123")); + get.setTimestamp(now); + result = table.get(get); + assertTrue("row key should be not exist", result.getRow() == null); + + //Delete that row + Delete delete = new Delete(rowKey); + cell = delete.getCellBuilder(); + cell.setQualifier(qualifier); + cell.setFamily(family); + delete.add(cell.build()); + table.delete(delete); + + //check this row whether exist + get = new Get(rowKey); + get.setTimestamp(now); + result = table.get(get); + assertTrue("Column foo should not exist", + result.getValue(family, qualifier) == null); + } finally { + table.close(); + } + } +} + + diff --git a/src/main/asciidoc/_chapters/datamodel.adoc b/src/main/asciidoc/_chapters/datamodel.adoc index ba4961a..67c1444 100644 --- a/src/main/asciidoc/_chapters/datamodel.adoc +++ b/src/main/asciidoc/_chapters/datamodel.adoc @@ -471,6 +471,27 @@ Caution: the version timestamp is used internally by HBase for things like time- It's usually best to avoid setting this timestamp yourself. Prefer using a separate timestamp attribute of the row, or have the timestamp as a part of the row key, or both. +===== Cell Version Example + +The following Put uses a method getCellBuilder() to get a CellBuilder instance +that already has relevant Type and Row set. + +[source,java] +---- + +public static final byte[] CF = "cf".getBytes(); +public static final byte[] ATTR = "attr".getBytes(); +... + +Put put = new Put(Bytes.toBytes(row)); +CellBuilder cell = put.getCellBuilder(); +cell.setQualifier(ATTR); +cell.setFamily(CF); +cell.setValue(Bytes.toBytes(data)); +put.add(cell.build()); +table.put(put); +---- + [[version.delete]] ==== Delete -- 1.8.3.1