/** * @return Qualifier offset */ @Override public int getQualifierOffset() { return getQualifierOffset(getFamilyOffset()); }
@Override public int getQualifierOffset() { return this.kv.getQualifierOffset(); }
protected static String getQualifierString(final KeyValue kv) { return Bytes.toStringBinary(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength()); }
/** * Produces a string map for this key/value pair. Useful for programmatic use * and manipulation of the data stored in an WALKey, for example, printing * as JSON. Values are left out due to their tendency to be large. If needed, * they can be added manually. * * @return the Map<String,?> containing data from this key */ public Map<String, Object> toStringMap() { Map<String, Object> stringMap = new HashMap<>(); stringMap.put("row", Bytes.toStringBinary(getRowArray(), getRowOffset(), getRowLength())); stringMap.put("family", Bytes.toStringBinary(getFamilyArray(), getFamilyOffset(), getFamilyLength())); stringMap.put("qualifier", Bytes.toStringBinary(getQualifierArray(), getQualifierOffset(), getQualifierLength())); stringMap.put("timestamp", getTimestamp()); stringMap.put("vlen", getValueLength()); Iterator<Tag> tags = getTags(); if (tags != null) { List<String> tagsString = new ArrayList<String>(); while (tags.hasNext()) { tagsString.add(tags.next().toString()); } stringMap.put("tag", tagsString); } return stringMap; }
private static String qualStr(KeyValue kv) { return Bytes.toString(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength()); }
kv1.getQualifierOffset() - KeyValue.ROW_OFFSET, kv1.getQualifierLength(), kv1.getTimestamp(), kv1.getTypeByte(), kv1.getValueArray(), kv1.getValueOffset(), kv1.getValueLength(), kv1.getSequenceId(), kv1.getTagsArray(), kv1.getTagsOffset(), OnheapDecodedCell c2 = new OnheapDecodedCell(kv2.getKey(), kv2.getRowLength(), kv2.getFamilyOffset() - KeyValue.ROW_OFFSET, kv2.getFamilyLength(), kv2.getQualifierOffset() - KeyValue.ROW_OFFSET, kv2.getQualifierLength(), kv2.getTimestamp(), kv2.getTypeByte(), kv2.getValueArray(), kv2.getValueOffset(), kv2.getValueLength(), kv2.getSequenceId(), kv2.getTagsArray(), kv2.getTagsOffset(), c3 = new BufferedDataBlockEncoder.OffheapDecodedExtendedCell(ByteBuffer.wrap(kv2.getKey()), kv2.getRowLength(), kv2.getFamilyOffset() - KeyValue.ROW_OFFSET, kv2.getFamilyLength(), kv2.getQualifierOffset() - KeyValue.ROW_OFFSET, kv2.getQualifierLength(), kv2.getTimestamp(), kv2.getTypeByte(), ByteBuffer.wrap(kv2.getValueArray()), kv2.getValueOffset(), kv2.getValueLength(), kv2.getSequenceId(),
assertTrue(Bytes.equals(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength(), cf, 0, cf.length)); assertTrue(Bytes.equals(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength(), q, 0, q.length)); assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(), value, 0,
private static KeyValue getMutationKeyValue(Mutation headerRow, byte[] key) { List<KeyValue> kvs = headerRow.getFamilyMap().get(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES); if (kvs != null) { for (KeyValue kv : kvs) { if (Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength(), key, 0, key.length) == 0) { return kv; } } } return null; }
@Override public boolean matchingQualifier(KeyValue other) { if (other == null) { return false; } if (other instanceof ClientKeyValue) { ClientKeyValue kv = (ClientKeyValue) other; return this.row.compareTo(kv.row) == 0; } return matchingQualifier(other.getBuffer(), other.getQualifierOffset(), other.getQualifierLength()); }
public static long getSequenceNumber(Mutation tableMutation) { List<KeyValue> kvs = tableMutation.getFamilyMap().get(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES); if (kvs != null) { for (KeyValue kv : kvs) { // list is not ordered, so search. TODO: we could potentially assume the position if (Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength(), PhoenixDatabaseMetaData.TABLE_SEQ_NUM_BYTES, 0, PhoenixDatabaseMetaData.TABLE_SEQ_NUM_BYTES.length) == 0) { return PDataType.LONG.getCodec().decodeLong(kv.getBuffer(), kv.getValueOffset(), null); } } } throw new IllegalStateException(); }
public ReturnCode resolveColumn(KeyValue value) { // Always set key, in case we never find a key value column of interest, // and our expression uses row key columns. setKey(value); byte[] buf = value.getBuffer(); Object ptr = setColumnKey(buf, value.getFamilyOffset(), value.getFamilyLength(), buf, value.getQualifierOffset(), value.getQualifierLength()); KeyValueRef ref = foundColumns.get(ptr); if (ref == null) { // Return INCLUDE here. Although this filter doesn't need this KV // it should still be projected into the Result return ReturnCode.INCLUDE; } // Since we only look at the latest key value for a given column, // we are not interested in older versions // TODO: test with older versions to confirm this doesn't get tripped // This shouldn't be necessary, because a scan only looks at the latest // version if (ref.keyValue != null) { // Can't do NEXT_ROW, because then we don't match the other columns // SKIP, INCLUDE, and NEXT_COL seem to all act the same return ReturnCode.NEXT_COL; } ref.keyValue = value; refCount++; return null; }
public boolean matches(KeyValue kv) { if (matchesFamily(kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength())) { return matchesQualifier(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength()); } return false; }
public static ValueGetter createGetterFromKeyValues(Collection<KeyValue> pendingUpdates) { final Map<ReferencingColumn, ImmutableBytesPtr> valueMap = Maps.newHashMapWithExpectedSize(pendingUpdates .size()); for (KeyValue kv : pendingUpdates) { // create new pointers to each part of the kv ImmutableBytesPtr family = new ImmutableBytesPtr(kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength()); ImmutableBytesPtr qual = new ImmutableBytesPtr(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength()); ImmutableBytesPtr value = new ImmutableBytesPtr(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength()); valueMap.put(new ReferencingColumn(family, qual), value); } return new ValueGetter() { @Override public ImmutableBytesPtr getLatestValue(ColumnReference ref) throws IOException { return valueMap.get(ReferencingColumn.wrap(ref)); } }; }
private static byte[] updateValueIfNecessary(KeyValue keyValue) { byte[] buf = keyValue.getBuffer(); if (Bytes.compareTo( buf, keyValue.getQualifierOffset(), keyValue.getQualifierLength(), PhoenixDatabaseMetaData.DATA_TYPE_BYTES, 0, PhoenixDatabaseMetaData.DATA_TYPE_BYTES.length) == 0) { int sqlType = PDataType.INTEGER.getCodec().decodeInt(buf, keyValue.getValueOffset(), null); // Switch the DATA_TYPE index for TIME types, as they currently don't support negative values // In 3.0, we'll switch them to our serialized LONG type instead, as that way we can easily // support negative types going forward. if (sqlType >= 0 && sqlType < OLD_TO_NEW_DATA_TYPE_3_0.length && OLD_TO_NEW_DATA_TYPE_3_0[sqlType] != null) { return OLD_TO_NEW_DATA_TYPE_3_0[sqlType]; } } return buf; } private static KeyValue upgradeTo3(KeyValue keyValue) {
@Override public KeyValue getHint(KeyValue kv) { return KeyValue.createLastOnRow(kv.getBuffer(), kv.getRowOffset(), kv.getRowLength(), kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength(), kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength()); } }
/** * Check to see if the kvs in the update match any of the passed columns. Generally, this is useful to for an index * codec to determine if a given update should even be indexed. This assumes that for any index, there are going to * small number of kvs, versus the number of columns in any one batch. * <p> * This employs the same logic as {@link #updateMatchesColumns(Collection, List)}, but is flips the iteration logic * to search columns before kvs. */ public static boolean columnMatchesUpdate(List<ColumnReference> columns, Collection<KeyValue> update) { boolean matches = false; outer: for (ColumnReference ref : columns) { for (KeyValue kv : update) { if (ref.matchesFamily(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength()) && ref.matchesQualifier(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength())) { matches = true; // if a single column matches a single kv, we need to build a whole scanner break outer; } } } return matches; }
/** * check to see if the kvs in the update match any of the passed columns. Generally, this is useful to for an index * codec to determine if a given update should even be indexed. This assumes that for any index, there are going to * small number of columns, versus the number of kvs in any one batch. */ public static boolean updateMatchesColumns(Collection<KeyValue> update, List<ColumnReference> columns) { // check to see if the kvs in the new update even match any of the columns requested // assuming that for any index, there are going to small number of columns, versus the number of // kvs in any one batch. boolean matches = false; outer: for (KeyValue kv : update) { for (ColumnReference ref : columns) { if (ref.matchesFamily(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength()) && ref.matchesQualifier(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength())) { matches = true; // if a single column matches a single kv, we need to build a whole scanner break outer; } } } return matches; }
/** * Set ptr to point to the value contained in the first KeyValue without * exploding Result into KeyValue array. * @param r * @param ptr */ public static void getAggregateValue(Tuple r, ImmutableBytesWritable ptr) { if (r.size() == 1) { KeyValue kv = r.getValue(0); // Just one KV for aggregation if (Bytes.compareTo(SINGLE_COLUMN_FAMILY, 0, SINGLE_COLUMN_FAMILY.length, kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength()) == 0) { if (Bytes.compareTo(SINGLE_COLUMN, 0, SINGLE_COLUMN.length, kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength()) == 0) { ptr.set(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength()); return; } } } throw new IllegalStateException("Expected single, aggregated KeyValue from coprocessor, but instead received " + r + ". Ensure aggregating coprocessors are loaded correctly on server"); }
private static KeyValue upgradeTo3(KeyValue keyValue) { byte[] buf = keyValue.getBuffer(); int newLength = keyValue.getRowLength() + 1; byte[] newKey = new byte[newLength]; newKey[0] = QueryConstants.SEPARATOR_BYTE; System.arraycopy(buf, keyValue.getRowOffset(), newKey, 1, keyValue.getRowLength()); byte[] valueBuf = updateValueIfNecessary(keyValue); int valueOffset = keyValue.getValueOffset(); int valueLength = keyValue.getValueLength(); if (valueBuf != buf) { valueOffset = 0; valueLength = valueBuf.length; } return new KeyValue(newKey, 0, newLength, buf, keyValue.getFamilyOffset(), keyValue.getFamilyLength(), buf, keyValue.getQualifierOffset(), keyValue.getQualifierLength(), keyValue.getTimestamp(), Type.codeToType(keyValue.getType()), valueBuf, valueOffset, valueLength); }
@Override public ImmutableBytesPtr getLatestValue(ColumnReference ref) { // Always return null for our empty key value, as this will cause the index // maintainer to always treat this Put as a new row. if (isEmptyKeyValue(table, ref)) { return null; } Map<byte [], List<KeyValue>> familyMap = dataMutation.getFamilyMap(); byte[] family = ref.getFamily(); List<KeyValue> kvs = familyMap.get(family); if (kvs == null) { return null; } byte[] qualifier = ref.getQualifier(); for (KeyValue kv : kvs) { if (Bytes.compareTo(kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength(), family, 0, family.length) == 0 && Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength(), qualifier, 0, qualifier.length) == 0) { return new ImmutableBytesPtr(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength()); } } return null; }