下面列出了怎么用org.apache.hadoop.hbase.CellBuilder的API类实例代码及写法,或者点击链接到github查看源代码。
private static Cell adaptFirstCellFromMutation(Mutation m) {
if (m != null && m.getFamilyCellMap() != null &&
m.getFamilyCellMap().firstEntry() != null &&
m.getFamilyCellMap().firstEntry().getValue() != null
&& m.getFamilyCellMap().firstEntry().getValue().get(0) != null) {
//have to replace the column family with WALEdit.METAFAMILY to make sure
//that IndexedKeyValues don't get replicated. The superclass KeyValue fields
//like row, qualifier and value are placeholders to prevent NPEs
// when using the KeyValue APIs. See PHOENIX-5188 / 5455
Cell mutationCell = m.getFamilyCellMap().firstEntry().getValue().get(0);
CellBuilder builder = CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY);
return builder.setFamily(WALEdit.METAFAMILY).
setQualifier(mutationCell.getQualifierArray()).
setRow(m.getRow()).
setTimestamp(mutationCell.getTimestamp()).
setValue(mutationCell.getValueArray()).setType(Cell.Type.Put).build();
} else {
throw new IllegalArgumentException("Tried to create an IndexedKeyValue with a " +
"Mutation with no Cells!");
}
}
public static Put addLocation(Put p, ServerName sn, long openSeqNum, int replicaId)
throws IOException {
CellBuilder builder = CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY);
return p.add(builder.clear()
.setRow(p.getRow())
.setFamily(CATALOG_FAMILY)
.setQualifier(getServerColumn(replicaId))
.setTimestamp(p.getTimestamp())
.setType(Cell.Type.Put)
.setValue(Bytes.toBytes(sn.getAddress().toString()))
.build())
.add(builder.clear()
.setRow(p.getRow())
.setFamily(CATALOG_FAMILY)
.setQualifier(getStartCodeColumn(replicaId))
.setTimestamp(p.getTimestamp())
.setType(Cell.Type.Put)
.setValue(Bytes.toBytes(sn.getStartcode()))
.build())
.add(builder.clear()
.setRow(p.getRow())
.setFamily(CATALOG_FAMILY)
.setQualifier(getSeqNumColumn(replicaId))
.setTimestamp(p.getTimestamp())
.setType(Cell.Type.Put)
.setValue(Bytes.toBytes(openSeqNum))
.build());
}
private String createHFileForFamilies(byte[] row, byte[] value,
Configuration clusterConfig) throws IOException {
CellBuilder cellBuilder = CellBuilderFactory.create(CellBuilderType.DEEP_COPY);
cellBuilder.setRow(row)
.setFamily(TestReplicationBase.famName)
.setQualifier(Bytes.toBytes("1"))
.setValue(value)
.setType(Cell.Type.Put);
HFile.WriterFactory hFileFactory = HFile.getWriterFactoryNoCache(clusterConfig);
// TODO We need a way to do this without creating files
File hFileLocation = testFolder.newFile();
FSDataOutputStream out =
new FSDataOutputStream(new FileOutputStream(hFileLocation), null);
try {
hFileFactory.withOutputStream(out);
hFileFactory.withFileContext(new HFileContextBuilder().build());
HFile.Writer writer = hFileFactory.create();
try {
writer.append(new KeyValue(cellBuilder.build()));
} finally {
writer.close();
}
} finally {
out.close();
}
return hFileLocation.getAbsoluteFile().getAbsolutePath();
}
@Override
public CellBuilder getCellBuilder(CellBuilderType cellBuilderType) {
if (action instanceof Mutation) {
return ((Mutation) action).getCellBuilder();
}
throw new UnsupportedOperationException();
}
/**
* Test filter. Filter will filter out any write time that is <= 5 (BOUNDARY). We count how many
* items we filter out and we count how many cells make it through for distribution way down below
* in the Table#batch implementation. Puts in place a custom DevNullConnection so we can insert
* our counting Table.
* @throws IOException
*/
@Test
public void testWALEntryFilter() throws IOException {
Configuration conf = HBaseConfiguration.create();
// Make it so our filter is instantiated on construction of ReplicationSink.
conf.setClass(DummyConnectionRegistry.REGISTRY_IMPL_CONF_KEY, DevNullConnectionRegistry.class,
DummyConnectionRegistry.class);
conf.setClass(WALEntrySinkFilter.WAL_ENTRY_FILTER_KEY,
IfTimeIsGreaterThanBOUNDARYWALEntrySinkFilterImpl.class, WALEntrySinkFilter.class);
conf.setClass(ClusterConnectionFactory.HBASE_SERVER_CLUSTER_CONNECTION_IMPL,
DevNullAsyncClusterConnection.class, AsyncClusterConnection.class);
ReplicationSink sink = new ReplicationSink(conf, STOPPABLE);
// Create some dumb walentries.
List<AdminProtos.WALEntry> entries = new ArrayList<>();
AdminProtos.WALEntry.Builder entryBuilder = AdminProtos.WALEntry.newBuilder();
// Need a tablename.
ByteString tableName =
ByteString.copyFromUtf8(TableName.valueOf(this.name.getMethodName()).toString());
// Add WALEdit Cells to Cells List. The way edits arrive at the sink is with protos
// describing the edit with all Cells from all edits aggregated in a single CellScanner.
final List<Cell> cells = new ArrayList<>();
int count = BOUNDARY * 2;
for (int i = 0; i < count; i++) {
byte[] bytes = Bytes.toBytes(i);
// Create a wal entry. Everything is set to the current index as bytes or int/long.
entryBuilder.clear();
entryBuilder.setKey(entryBuilder.getKeyBuilder().setLogSequenceNumber(i)
.setEncodedRegionName(ByteString.copyFrom(bytes)).setWriteTime(i).setTableName(tableName)
.build());
// Lets have one Cell associated with each WALEdit.
entryBuilder.setAssociatedCellCount(1);
entries.add(entryBuilder.build());
// We need to add a Cell per WALEdit to the cells array.
CellBuilder cellBuilder = CellBuilderFactory.create(CellBuilderType.DEEP_COPY);
// Make cells whose row, family, cell, value, and ts are == 'i'.
Cell cell = cellBuilder.setRow(bytes).setFamily(bytes).setQualifier(bytes)
.setType(Cell.Type.Put).setTimestamp(i).setValue(bytes).build();
cells.add(cell);
}
// Now wrap our cells array in a CellScanner that we can pass in to replicateEntries. It has
// all Cells from all the WALEntries made above.
CellScanner cellScanner = new CellScanner() {
// Set to -1 because advance gets called before current.
int index = -1;
@Override
public Cell current() {
return cells.get(index);
}
@Override
public boolean advance() throws IOException {
index++;
return index < cells.size();
}
};
// Call our sink.
sink.replicateEntries(entries, cellScanner, null, null, null);
// Check what made it through and what was filtered.
assertTrue(FILTERED.get() > 0);
assertTrue(UNFILTERED.get() > 0);
assertEquals(count, FILTERED.get() + UNFILTERED.get());
}
@Test
public void testMutationGetCellBuilder() throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
final byte[] rowKey = Bytes.toBytes("12345678");
final byte[] uselessRowKey = Bytes.toBytes("123");
final byte[] family = Bytes.toBytes("cf");
final byte[] qualifier = Bytes.toBytes("foo");
final long now = System.currentTimeMillis();
try (Table table = TEST_UTIL.createTable(tableName, family)) {
TEST_UTIL.waitTableAvailable(tableName.getName(), 5000);
// put one row
Put put = new Put(rowKey);
CellBuilder cellBuilder = put.getCellBuilder().setQualifier(qualifier)
.setFamily(family).setValue(Bytes.toBytes("bar")).setTimestamp(now);
//setRow is useless
cellBuilder.setRow(uselessRowKey);
put.add(cellBuilder.build());
byte[] cloneRow = CellUtil.cloneRow(cellBuilder.build());
assertTrue("setRow must be useless", !Arrays.equals(cloneRow, uselessRowKey));
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"));
//Delete that row
Delete delete = new Delete(rowKey);
cellBuilder = delete.getCellBuilder().setQualifier(qualifier)
.setFamily(family);
//if this row has been deleted,then can check setType is useless.
cellBuilder.setType(Cell.Type.Put);
delete.add(cellBuilder.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);
}
}
@Test
public void testCorruptOutOfOrderHFileWrite() throws IOException {
Path path = new Path(ROOT_DIR, testName.getMethodName());
FSDataOutputStream mockedOutputStream = Mockito.mock(FSDataOutputStream.class);
String columnFamily = "MyColumnFamily";
String tableName = "MyTableName";
HFileContext fileContext = new HFileContextBuilder()
.withHFileName(testName.getMethodName() + "HFile")
.withBlockSize(minBlockSize)
.withColumnFamily(Bytes.toBytes(columnFamily))
.withTableName(Bytes.toBytes(tableName))
.withHBaseCheckSum(false)
.withCompression(Compression.Algorithm.NONE)
.withCompressTags(false)
.build();
HFileWriterImpl writer = new HFileWriterImpl(conf, cacheConf, path, mockedOutputStream,
fileContext);
CellBuilder cellBuilder = CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY);
byte[] row = Bytes.toBytes("foo");
byte[] qualifier = Bytes.toBytes("qualifier");
byte[] cf = Bytes.toBytes(columnFamily);
byte[] val = Bytes.toBytes("fooVal");
long firstTS = 100L;
long secondTS = 101L;
Cell firstCell = cellBuilder.setRow(row).setValue(val).setTimestamp(firstTS)
.setQualifier(qualifier).setFamily(cf).setType(Cell.Type.Put).build();
Cell secondCell= cellBuilder.setRow(row).setValue(val).setTimestamp(secondTS)
.setQualifier(qualifier).setFamily(cf).setType(Cell.Type.Put).build();
//second Cell will sort "higher" than the first because later timestamps should come first
writer.append(firstCell);
try {
writer.append(secondCell);
} catch(IOException ie){
String message = ie.getMessage();
Assert.assertTrue(message.contains("not lexically larger"));
Assert.assertTrue(message.contains(tableName));
Assert.assertTrue(message.contains(columnFamily));
return;
}
Assert.fail("Exception wasn't thrown even though Cells were appended in the wrong order!");
}
@Override
public CellBuilder getCellBuilder(CellBuilderType type) {
return getCellBuilder(type, Cell.Type.Put);
}
@Override
public CellBuilder getCellBuilder(CellBuilderType type) {
return getCellBuilder(type, Cell.Type.Delete);
}
@Override
public CellBuilder getCellBuilder(CellBuilderType type) {
return getCellBuilder(type, Cell.Type.Put);
}
@Override
public CellBuilder getCellBuilder(CellBuilderType type) {
return getCellBuilder(type, Cell.Type.Put);
}
/**
* 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);
}