下面列出了org.apache.hadoop.hbase.Cell#getRowArray ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private boolean inBounds(final Cell cell) {
final GeoWaveKeyImpl cellKey =
new GeoWaveKeyImpl(
cell.getRowArray(),
indexStrategy.getPartitionKeyLength(),
cell.getRowOffset(),
cell.getRowLength());
final byte[] sortKey = cellKey.getSortKey();
final byte[] partitionKey = cellKey.getPartitionKey();
final MultiDimensionalCoordinates coordinates =
indexStrategy.getCoordinatesPerDimension(partitionKey, sortKey);
return rangeCache.inBounds(coordinates);
}
public ValueGetter createGetterFromKeyValues(final byte[] rowKey, Collection<? extends Cell> pendingUpdates) {
final Map<ReferencingColumn, ImmutableBytesPtr> valueMap = Maps.newHashMapWithExpectedSize(pendingUpdates
.size());
for (Cell kv : pendingUpdates) {
// create new pointers to each part of the kv
ImmutableBytesPtr family = new ImmutableBytesPtr(kv.getRowArray(),kv.getFamilyOffset(),kv.getFamilyLength());
ImmutableBytesPtr qual = new ImmutableBytesPtr(kv.getRowArray(), kv.getQualifierOffset(), kv.getQualifierLength());
ImmutableBytesPtr value = new ImmutableBytesPtr(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength());
valueMap.put(new ReferencingColumn(family, qual), value);
}
return new ValueGetter() {
@Override
public ImmutableBytesPtr getLatestValue(ColumnReference ref) {
if(ref.equals(dataEmptyKeyValueRef)) return null;
return valueMap.get(ReferencingColumn.wrap(ref));
}
@Override
public byte[] getRowKey() {
return rowKey;
}
};
}
public ProjectedValueTuple projectResults(Tuple tuple, boolean useNewValueQualifier) {
long maxTS = tuple.getValue(0).getTimestamp();
int nCells = tuple.size();
for (int i = 1; i < nCells; i++) {
long ts = tuple.getValue(i).getTimestamp();
if (ts > maxTS) {
maxTS = ts;
}
}
byte[] bytesValue = schema.toBytes(tuple, getExpressions(), valueSet, ptr);
Cell base = tuple.getValue(0);
if (useNewValueQualifier) {
return new ProjectedValueTuple(base.getRowArray(), base.getRowOffset(), base.getRowLength(), maxTS, bytesValue, 0, bytesValue.length, valueSet.getEstimatedLength());
} else {
return new OldProjectedValueTuple(base.getRowArray(), base.getRowOffset(), base.getRowLength(), maxTS, bytesValue, 0, bytesValue.length, valueSet.getEstimatedLength());
}
}
public static void mutatePutValue(Put somePut, byte[] family, byte[] qualifier, byte[] newValue) {
NavigableMap<byte[], List<Cell>> familyCellMap = somePut.getFamilyCellMap();
List<Cell> cells = familyCellMap.get(family);
List<Cell> newCells = Lists.newArrayList();
if (cells != null) {
for (Cell cell : cells) {
if (Bytes.compareTo(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(),
qualifier, 0, qualifier.length) == 0) {
Cell replacementCell = new KeyValue(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength(),
cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength(), cell.getQualifierArray(),
cell.getQualifierOffset(), cell.getQualifierLength(), cell.getTimestamp(),
KeyValue.Type.codeToType(cell.getType().getCode()), newValue, 0, newValue.length);
newCells.add(replacementCell);
} else {
newCells.add(cell);
}
}
familyCellMap.put(family, newCells);
}
}
/**
* Returns true if the specified KeyValue is contained by the specified range.
*/
public static boolean isKeyValueInRange(Cell kv, Pair<byte[], byte[]> range) {
byte[] kvBuffer = kv.getRowArray(); // TODO JL SAR
int rowKeyOffset = kv.getRowOffset();
short rowKeyLength = kv.getRowLength();
byte[] start = range.getFirst();
byte[] stop = range.getSecond();
return (start.length == 0 || Bytes.compareTo(start, 0, start.length, kvBuffer, rowKeyOffset, rowKeyLength) <= 0) &&
(stop.length == 0 || Bytes.compareTo(stop, 0, stop.length, kvBuffer, rowKeyOffset, rowKeyLength) >= 0);
}
private boolean isSatisfiedMidKeyCondition(Cell kv) {
if (CellUtil.isDelete(kv) && kv.getValueLength() == 0) {
// In case of a Delete type KV, let it be going to both the daughter regions.
// No problems in doing so. In the correct daughter region where it belongs to, this delete
// tomb will really delete a KV. In the other it will just hang around there with no actual
// kv coming for which this is a delete tomb. :)
return true;
}
ImmutableBytesWritable rowKey =
new ImmutableBytesWritable(kv.getRowArray(), kv.getRowOffset() + offset,
kv.getRowLength() - offset);
Entry<ImmutableBytesWritable, IndexMaintainer> entry = indexMaintainers.entrySet().iterator().next();
IndexMaintainer indexMaintainer = entry.getValue();
byte[] viewIndexId = indexMaintainer.getViewIndexIdFromIndexRowKey(rowKey);
IndexMaintainer actualIndexMaintainer = indexMaintainers.get(new ImmutableBytesWritable(viewIndexId));
byte[] dataRowKey = actualIndexMaintainer.buildDataRowKey(rowKey, this.viewConstants);
int compareResult = Bytes.compareTo(dataRowKey, splitRow);
if (top) {
if (compareResult >= 0) {
return true;
}
} else {
if (compareResult < 0) {
return true;
}
}
return false;
}
/**
* Binary search for latest column value without allocating memory in the process
* @param kvBuilder TODO
* @param kvs
* @param family
* @param qualifier
*/
public static Cell getColumnLatest(KeyValueBuilder kvBuilder, List<Cell>kvs, byte[] family, byte[] qualifier) {
if (kvs.size() == 0) {
return null;
}
Cell row = kvs.get(0);
Comparator<Cell> comp = new SearchComparator(kvBuilder,
row.getRowArray(), row.getRowOffset(), row.getRowLength(), family, qualifier);
// pos === ( -(insertion point) - 1)
int pos = Collections.binarySearch(kvs, null, comp);
// never will exact match
if (pos < 0) {
pos = (pos+1) * -1;
// pos is now insertion point
}
if (pos == kvs.size()) {
return null; // doesn't exist
}
Cell kv = kvs.get(pos);
if (Bytes.compareTo(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength(),
family, 0, family.length) != 0) {
return null;
}
if (Bytes.compareTo(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength(),
qualifier, 0, qualifier.length) != 0) {
return null;
}
return kv;
}
/**
* Binary search for latest column value without allocating memory in the process
* @param kvBuilder TODO
* @param kvs
* @param family
* @param qualifier
*/
public static Cell getColumnLatest(KeyValueBuilder kvBuilder, Cell[] kvs, byte[] family, byte[] qualifier) {
if (kvs.length == 0) {
return null;
}
Cell kvForRow = kvs[0];
Comparator<Cell> comp = new SearchComparator(kvBuilder, kvForRow.getRowArray(),
kvForRow.getRowOffset(), kvForRow.getRowLength(), family, qualifier);
// pos === ( -(insertion point) - 1)
int pos = Arrays.binarySearch(kvs, null, comp);
// never will exact match
if (pos < 0) {
pos = (pos+1) * -1;
// pos is now insertion point
}
if (pos == kvs.length) {
return null; // doesn't exist
}
Cell kv = kvs[pos];
if (Bytes.compareTo(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength(),
family, 0, family.length) != 0) {
return null;
}
if (Bytes.compareTo(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength(),
qualifier, 0, qualifier.length) != 0) {
return null;
}
return kv;
}
private boolean containedInScan(Cell kv) {
byte[] rowArray = kv.getRowArray();
int rowOffset = kv.getRowOffset();
int rowLength = kv.getRowLength();
if(Bytes.compareTo(scan.getStartRow(),0,scan.getStartRow().length,rowArray,rowOffset,rowLength)>0) return false;
if(Bytes.compareTo(scan.getStopRow(),0,scan.getStopRow().length,rowArray,rowOffset,rowLength)<=0) return false;
byte[] family = CellUtil.cloneFamily(kv);
Map<byte[], NavigableSet<byte[]>> familyMap = scan.getFamilyMap();
if(familyMap.size()<=0) return true;
if(!familyMap.containsKey(family)) return false;
NavigableSet<byte[]> qualifiersToFetch = familyMap.get(family);
if(qualifiersToFetch.size()<=0) return true;
return qualifiersToFetch.contains(CellUtil.cloneQualifier(kv));
}
private static Cell newTransactionTimeStampKeyValue(Cell element, byte[] value) {
return new KeyValue(element.getRowArray(),
element.getRowOffset(),
element.getRowLength(),
SIConstants.DEFAULT_FAMILY_BYTES,0,1,
SIConstants.COMMIT_TIMESTAMP_COLUMN_BYTES,0,1,
element.getTimestamp(),KeyValue.Type.Put,
value,0,value==null?0:value.length);
}
@SuppressWarnings("deprecation")
private static KeyValue addSaltByte(Cell keyValue, int nSaltBuckets) {
byte[] buf = keyValue.getRowArray();
int length = keyValue.getRowLength();
int offset = keyValue.getRowOffset();
boolean isViewSeq = length > SEQ_PREFIX_BYTES.length && Bytes.compareTo(SEQ_PREFIX_BYTES, 0, SEQ_PREFIX_BYTES.length, buf, offset, SEQ_PREFIX_BYTES.length) == 0;
if (!isViewSeq && nSaltBuckets == 0) {
return null;
}
byte[] newBuf;
if (isViewSeq) { // We messed up the name for the sequences for view indexes so we'll take this opportunity to fix it
if (buf[length-1] == 0) { // Global indexes on views have trailing null byte
length--;
}
byte[][] rowKeyMetaData = new byte[3][];
SchemaUtil.getVarChars(buf, offset, length, 0, rowKeyMetaData);
byte[] schemaName = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
byte[] unprefixedSchemaName = new byte[schemaName.length - MetaDataUtil.VIEW_INDEX_SEQUENCE_PREFIX_BYTES.length];
System.arraycopy(schemaName, MetaDataUtil.VIEW_INDEX_SEQUENCE_PREFIX_BYTES.length, unprefixedSchemaName, 0, unprefixedSchemaName.length);
byte[] tableName = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
PName physicalName = PNameFactory.newName(unprefixedSchemaName);
// Reformulate key based on correct data
newBuf = MetaDataUtil.getViewIndexSequenceKey(tableName == null ? null : Bytes.toString(tableName),
physicalName, nSaltBuckets, false).getKey();
} else {
newBuf = new byte[length + 1];
System.arraycopy(buf, offset, newBuf, SaltingUtil.NUM_SALTING_BYTES, length);
newBuf[0] = SaltingUtil.getSaltingByte(newBuf, SaltingUtil.NUM_SALTING_BYTES, length, nSaltBuckets);
}
return new KeyValue(newBuf, 0, newBuf.length,
buf, keyValue.getFamilyOffset(), keyValue.getFamilyLength(),
buf, keyValue.getQualifierOffset(), keyValue.getQualifierLength(),
keyValue.getTimestamp(), KeyValue.Type.codeToType(keyValue.getTypeByte()),
buf, keyValue.getValueOffset(), keyValue.getValueLength());
}
/** Handle the entire row at one time */
@Override
public void filterRowCells(final List<Cell> rowCells) throws IOException {
if (!rowCells.isEmpty()) {
final Iterator<Cell> it = rowCells.iterator();
GeoWaveKeyImpl rowKey = null;
commonData = new MultiFieldPersistentDataset<>();
while (it.hasNext()) {
final Cell cell = it.next();
// Grab rowkey from first cell
if (rowKey == null) {
rowKey =
new GeoWaveKeyImpl(
cell.getRowArray(),
partitionKeyLength,
cell.getRowOffset(),
cell.getRowLength());
}
unreadData = aggregateFieldData(cell, commonData);
}
final ReturnCode code = applyFilter(rowKey);
if (code == ReturnCode.SKIP) {
rowCells.clear();
}
}
}
protected ReturnCode applyFilter(final Cell cell) {
final GeoWaveKeyImpl rowKey =
new GeoWaveKeyImpl(
cell.getRowArray(),
partitionKeyLength,
cell.getRowOffset(),
cell.getRowLength());
return applyFilter(rowKey);
}
public boolean filterRowKey(Cell cell) {
byte[] row = cell.getRowArray();
return filterRowKey(row, cell.getRowOffset(), cell.getRowLength());
}
public ProjectedValueTuple projectResults(Tuple tuple) {
byte[] bytesValue = schema.toBytes(tuple, getExpressions(), valueSet, ptr);
Cell base = tuple.getValue(0);
return new ProjectedValueTuple(base.getRowArray(), base.getRowOffset(), base.getRowLength(), base.getTimestamp(), bytesValue, 0, bytesValue.length, valueSet.getEstimatedLength());
}
@Override
public boolean filterRowKey(Cell firstRowCell) {
if (filterAllRemaining()) return true;
// N.b. We can only do this after we're iterating over records. If we try to do
// it before, the Scan (and this filter) may not yet be fully initialized. This is a
// wart on Filter and something that'd be nice to clean up (like CP's in HBase2.0)
if (!ranges.isInitialized()) {
ranges.initialize(isReversed());
}
// If it is the first time of running, calculate the current range index for
// the row key. If index is out of bound which happens when the start row
// user sets is after the largest stop row of the ranges, stop the scan.
// If row key is after the current range, find the next range and update index.
byte[] rowArr = firstRowCell.getRowArray();
int length = firstRowCell.getRowLength();
int offset = firstRowCell.getRowOffset();
if (!ranges.hasFoundFirstRange() || !range.contains(rowArr, offset, length)) {
byte[] rowkey = CellUtil.cloneRow(firstRowCell);
index = ranges.getNextRangeIndex(rowkey);
if (ranges.isIterationComplete(index)) {
done = true;
currentReturnCode = ReturnCode.NEXT_ROW;
return false;
}
if(index != ROW_BEFORE_FIRST_RANGE) {
range = ranges.get(index);
} else {
range = ranges.get(0);
}
if (ranges.isExclusive()) {
ranges.resetExclusive();
currentReturnCode = ReturnCode.NEXT_ROW;
return false;
}
if (!ranges.hasFoundFirstRange()) {
if(index != ROW_BEFORE_FIRST_RANGE) {
currentReturnCode = ReturnCode.INCLUDE;
} else {
currentReturnCode = ReturnCode.SEEK_NEXT_USING_HINT;
}
ranges.setFoundFirstRange();
} else {
if (range.contains(rowArr, offset, length)) {
currentReturnCode = ReturnCode.INCLUDE;
} else {
currentReturnCode = ReturnCode.SEEK_NEXT_USING_HINT;
}
}
} else {
currentReturnCode = ReturnCode.INCLUDE;
}
return false;
}
private boolean isTenantRowCell(Cell cell) {
ImmutableBytesWritable key =
new ImmutableBytesWritable(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
//rows in system.catalog that aren't tenant-owned will have a leading separator byte
return key.get()[key.getOffset()] != QueryConstants.SEPARATOR_BYTE;
}
public ProjectedValueTuple projectResults(Tuple tuple) {
byte[] bytesValue = schema.toBytes(tuple, getExpressions(), valueSet, ptr);
Cell base = tuple.getValue(0);
return new ProjectedValueTuple(base.getRowArray(), base.getRowOffset(), base.getRowLength(), base.getTimestamp(), bytesValue, 0, bytesValue.length, valueSet.getEstimatedLength());
}
/**
* Update the current statistics based on the latest batch of key-values from the underlying scanner
*
* @param results
* next batch of {@link KeyValue}s
* @throws IOException
*/
@Override
public void collectStatistics(final List<Cell> results) {
// A guide posts depth of zero disables the collection of stats
if (guidePostDepth == 0 || results.size() == 0) {
return;
}
Map<ImmutableBytesPtr, Boolean> famMap = Maps.newHashMap();
boolean incrementRow = false;
Cell c = results.get(0);
ImmutableBytesWritable row = new ImmutableBytesWritable(c.getRowArray(), c.getRowOffset(), c.getRowLength());
/*
* During compaction, it is possible that HBase will not return all the key values when
* internalScanner.next() is called. So we need the below check to avoid counting a row more
* than once.
*/
if (currentRow == null || !row.equals(currentRow)) {
currentRow = row;
incrementRow = true;
}
for (Cell cell : results) {
maxTimeStamp = Math.max(maxTimeStamp, cell.getTimestamp());
Pair<Long, GuidePostsInfoBuilder> gps;
if (cachedGuidePosts == null) {
ImmutableBytesPtr cfKey = new ImmutableBytesPtr(cell.getFamilyArray(), cell.getFamilyOffset(),
cell.getFamilyLength());
gps = guidePostsInfoWriterMap.get(cfKey);
if (gps == null) {
gps = new Pair<Long, GuidePostsInfoBuilder>(0l,
new GuidePostsInfoBuilder());
guidePostsInfoWriterMap.put(cfKey, gps);
}
if (famMap.get(cfKey) == null) {
famMap.put(cfKey, true);
gps.getSecond().incrementRowCount();
}
} else {
gps = cachedGuidePosts;
if (incrementRow) {
cachedGuidePosts.getSecond().incrementRowCount();
incrementRow = false;
}
}
int kvLength = KeyValueUtil.getSerializedSize(cell, true);
long byteCount = gps.getFirst() + kvLength;
gps.setFirst(byteCount);
if (byteCount >= guidePostDepth) {
if (gps.getSecond().addGuidePostOnCollection(row, byteCount, gps.getSecond().getRowCount())) {
gps.setFirst(0l);
gps.getSecond().resetRowCount();
}
}
}
}
protected Cell mergeList(final List<Cell> cells) {
synchronized (MUTEX) {
Mergeable currentMergeable = null;
final Cell firstCell = cells.get(0);
for (final Cell cell : cells) {
final Mergeable mergeable =
getMergeable(
cell,
// TODO consider avoiding extra byte array
// allocations (which would require
// persistence utils to be able to use
// bytebuffer instead of byte[])
CellUtil.cloneValue(cell));
if (mergeable != null) {
if (currentMergeable == null) {
currentMergeable = mergeable;
} else {
currentMergeable.merge(mergeable);
}
}
}
final byte[] valueBinary = getBinary(currentMergeable);
// this is basically a lengthy verbose form of cloning
// in-place (without allocating new byte arrays) and
// simply replacing the value with the new mergeable
// value
return new KeyValue(
firstCell.getRowArray(),
firstCell.getRowOffset(),
firstCell.getRowLength(),
firstCell.getFamilyArray(),
firstCell.getFamilyOffset(),
firstCell.getFamilyLength(),
firstCell.getQualifierArray(),
firstCell.getQualifierOffset(),
firstCell.getQualifierLength(),
firstCell.getTimestamp(),
Type.codeToType(firstCell.getTypeByte()),
valueBinary,
0,
valueBinary.length,
firstCell.getTagsArray(),
firstCell.getTagsOffset(),
firstCell.getTagsLength());
}
}