Java Code Examples for org.apache.phoenix.query.QueryConstants#DESC_SEPARATOR_BYTE

The following examples show how to use org.apache.phoenix.query.QueryConstants#DESC_SEPARATOR_BYTE . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RowKeyValueAccessor.java    From phoenix with Apache License 2.0 5 votes vote down vote up
/**
 * Calculate the length of the PK column value
 * @param keyBuffer the byte array of the row key
 * @param keyOffset the offset in the byte array of where the key begins
 * @param maxOffset maximum offset to use while calculating length 
 * @return the length of the PK column value
 */
public int getLength(byte[] keyBuffer, int keyOffset, int maxOffset) {
    if (!hasSeparator) {
        return maxOffset - keyOffset - (keyBuffer[maxOffset-1] == QueryConstants.DESC_SEPARATOR_BYTE ? 1 : 0);
    }
    int offset = keyOffset;
    // FIXME: offset < maxOffset required because HBase passes bogus keys to filter to position scan (HBASE-6562)
    while (offset < maxOffset && !isSeparatorByte(keyBuffer[offset])) {
        offset++;
    }
    return offset - keyOffset;
}
 
Example 2
Source File: PArrayDataType.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private static boolean isRowKeyOrderOptimized(boolean isFixedWidth, SortOrder sortOrder, byte[] buf, int offset, int length) {
    if (length == 0 || sortOrder == SortOrder.ASC || isFixedWidth) {
        return true;
    }
    int offsetToHeaderOffset = offset + length - Bytes.SIZEOF_BYTE - Bytes.SIZEOF_INT * 2;
    int offsetToSeparatorByte = Bytes.readAsInt(buf, offsetToHeaderOffset, Bytes.SIZEOF_INT) - 1;
    return buf[offsetToSeparatorByte] == QueryConstants.DESC_SEPARATOR_BYTE;
}
 
Example 3
Source File: PDataTypeForArraysTest.java    From phoenix with Apache License 2.0 5 votes vote down vote up
@Test
public void testIsRowKeyOrderOptimized3() {
    Object[] objects = new Object[]{"a", "b", "c"};
    PhoenixArray arr = new PhoenixArray(PVarchar.INSTANCE, objects);
    byte[] bytes = PVarcharArray.INSTANCE.toBytes(arr, SortOrder.DESC);
    for (int i = 0; i < bytes.length; i++) {
        if (bytes[i] == QueryConstants.DESC_SEPARATOR_BYTE) {
            bytes[i] = QueryConstants.SEPARATOR_BYTE;
        }
    }
    assertFalse(PArrayDataType.isRowKeyOrderOptimized(PVarcharArray.INSTANCE, SortOrder.DESC, bytes, 0, bytes.length));
}
 
Example 4
Source File: ScanRanges.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static ScanRanges create(RowKeySchema schema, List<List<KeyRange>> ranges, int[] slotSpan, Integer nBuckets, boolean useSkipScan, int rowTimestampColIndex, Optional<byte[]> scanMinOffset) {
    int offset = nBuckets == null ? 0 : SaltingUtil.NUM_SALTING_BYTES;
    int nSlots = ranges.size();

    if (nSlots == offset && !scanMinOffset.isPresent()) {
        return EVERYTHING;
    } else if ((nSlots == 1 + offset && ranges.get(offset).size() == 1 && ranges.get(offset).get(0) == KeyRange.EMPTY_RANGE)) {
        return NOTHING;
    }
    TimeRange rowTimestampRange = getRowTimestampColumnRange(ranges, schema, rowTimestampColIndex);
    boolean isPointLookup = isPointLookup(schema, ranges, slotSpan, useSkipScan);
    if (isPointLookup) {
        // TODO: consider keeping original to use for serialization as it would be smaller?
        List<byte[]> keys = ScanRanges.getPointKeys(ranges, slotSpan, schema, nBuckets);
        List<KeyRange> keyRanges = Lists.newArrayListWithExpectedSize(keys.size());
        // We have full keys here, so use field from our varbinary schema
        for (byte[] key : keys) {
            keyRanges.add(KeyRange.getKeyRange(key));
        }
        // while doing a point look up if after intersecting with the MinMaxrange there are
        // no more keyranges left then just return
        if (keyRanges.isEmpty()) {
            return NOTHING;
        }
        ranges = Collections.singletonList(keyRanges);
        useSkipScan = keyRanges.size() > 1;
        // Treat as binary if descending because we've got a separator byte at the end
        // which is not part of the value.
        if (keys.size() > 1 || SchemaUtil.getSeparatorByte(schema.rowKeyOrderOptimizable(), false, schema.getField(schema.getFieldCount()-1)) == QueryConstants.DESC_SEPARATOR_BYTE) {
            schema = SchemaUtil.VAR_BINARY_SCHEMA;
            slotSpan = ScanUtil.SINGLE_COLUMN_SLOT_SPAN;
        } else {
            // Keep original schema and don't use skip scan as it's not necessary
            // when there's a single key.
            slotSpan = new int[] {schema.getMaxFields()-1};
        }
    }

    List<List<KeyRange>> sortedRanges = Lists.newArrayListWithExpectedSize(ranges.size());
    for (int i = 0; i < ranges.size(); i++) {
        Field f = schema.getField(i);
        List<KeyRange> sorted = Lists.newArrayList(ranges.get(i));
        Collections.sort(sorted, f.getSortOrder() == SortOrder.ASC ? KeyRange.COMPARATOR : KeyRange.DESC_COMPARATOR);
        sortedRanges.add(ImmutableList.copyOf(sorted));
    }
    
    
    // Don't set minMaxRange for point lookup because it causes issues during intersect
    // by going across region boundaries
    KeyRange scanRange = KeyRange.EVERYTHING_RANGE;
    // if (!isPointLookup && (nBuckets == null || !useSkipScanFilter)) {
    // if (! ( isPointLookup || (nBuckets != null && useSkipScanFilter) ) ) {
    // if (nBuckets == null || (nBuckets != null && (!isPointLookup || !useSkipScanFilter))) {
    if (nBuckets == null || !isPointLookup || !useSkipScan) {
        byte[] minKey = ScanUtil.getMinKey(schema, sortedRanges, slotSpan);
        byte[] maxKey = ScanUtil.getMaxKey(schema, sortedRanges, slotSpan);
        // If the maxKey has crossed the salt byte boundary, then we do not
        // have anything to filter at the upper end of the range
        if (ScanUtil.crossesPrefixBoundary(maxKey, ScanUtil.getPrefix(minKey, offset), offset)) {
            maxKey = KeyRange.UNBOUND;
        }
        // We won't filter anything at the low end of the range if we just have the salt byte
        if (minKey.length <= offset) {
            minKey = KeyRange.UNBOUND;
        }

        //Handle the offset by pushing it into the scanRange
        if(scanMinOffset.isPresent()){

            byte[] minOffset = scanMinOffset.get();
            //If we are salted we have to
            //This should be safe for RVC Offset since we specify a full rowkey which
            // is by definition unique so duplicating the salt bucket is fine
            if(nBuckets != null && nBuckets > 0) {
                minOffset[0] = 0;  //We use 0 for salt bucket for scans
            }

            //If the offset is more selective than the existing ranges
            if(Bytes.BYTES_COMPARATOR.compare(minOffset,minKey) > 0){
                minKey=minOffset;
            }
        }

        scanRange = KeyRange.getKeyRange(minKey, maxKey);
    }

    if (scanRange == KeyRange.EMPTY_RANGE) {
        return NOTHING;
    }
    return new ScanRanges(schema, slotSpan, sortedRanges, scanRange, useSkipScan, isPointLookup, nBuckets, rowTimestampRange);
}
 
Example 5
Source File: TupleUtil.java    From phoenix with Apache License 2.0 4 votes vote down vote up
/** Concatenate results evaluated against a list of expressions
 * 
 * @param result the tuple for expression evaluation
 * @param expressions
 * @return the concatenated byte array as ImmutableBytesWritable
 * @throws IOException
 */
public static ImmutableBytesPtr getConcatenatedValue(Tuple result, List<Expression> expressions) throws IOException {
    ImmutableBytesPtr value = new ImmutableBytesPtr(ByteUtil.EMPTY_BYTE_ARRAY);
    Expression expression = expressions.get(0);
    boolean evaluated = expression.evaluate(result, value);
    
    if (expressions.size() == 1) {
        if (!evaluated) {
            value.set(ByteUtil.EMPTY_BYTE_ARRAY);
        }
        return value;
    } else {
        TrustedByteArrayOutputStream output = new TrustedByteArrayOutputStream(value.getLength() * expressions.size());
        try {
            if (evaluated) {
                output.write(value.get(), value.getOffset(), value.getLength());
            }
            for (int i = 1; i < expressions.size(); i++) {
                if (!expression.getDataType().isFixedWidth()) {
                    output.write(SchemaUtil.getSeparatorByte(true, value.getLength()==0, expression));
                }
                expression = expressions.get(i);
                if (expression.evaluate(result, value)) {
                    output.write(value.get(), value.getOffset(), value.getLength());
                } else if (i < expressions.size()-1 && expression.getDataType().isFixedWidth()) {
                    // This should never happen, because any non terminating nullable fixed width type (i.e. INT or LONG) is
                    // converted to a variable length type (i.e. DECIMAL) to allow an empty byte array to represent null.
                    throw new DoNotRetryIOException("Non terminating null value found for fixed width expression (" + expression + ") in row: " + result);
                }
            }
            // Write trailing separator if last expression was variable length and descending
            if (!expression.getDataType().isFixedWidth() && SchemaUtil.getSeparatorByte(true, value.getLength()==0, expression) == QueryConstants.DESC_SEPARATOR_BYTE) {
                output.write(QueryConstants.DESC_SEPARATOR_BYTE);
            }
            byte[] outputBytes = output.getBuffer();
            value.set(outputBytes, 0, output.size());
            return value;
        } finally {
            output.close();
        }
    }
}
 
Example 6
Source File: RowKeyValueAccessor.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private static boolean isSeparatorByte(byte b) {
    return b == QueryConstants.SEPARATOR_BYTE || b == QueryConstants.DESC_SEPARATOR_BYTE;
}
 
Example 7
Source File: PArrayDataTypeDecoder.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private static boolean isSeparatorByte(byte[] bytes, int initPos, int currOffset) {
    return bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE || bytes[currOffset + initPos] == QueryConstants.DESC_SEPARATOR_BYTE;
}
 
Example 8
Source File: SchemaUtil.java    From phoenix with Apache License 2.0 2 votes vote down vote up
/**
 * Return the separator byte to use based on:
 * @param rowKeyOrderOptimizable whether or not the table may optimize descending row keys. If the
 *  table has no descending row keys, this will be true. Also, if the table has been upgraded (using
 *  a new -u option for psql.py), then it'll be true
 * @param isNullValue whether or not the value is null. We use a null byte still if the value is null
 * regardless of sort order since nulls will always sort first this way.
 * @param sortOrder whether the value sorts ascending or descending.
 * @return the byte to use as the separator
 */
public static byte getSeparatorByte(boolean rowKeyOrderOptimizable, boolean isNullValue, SortOrder sortOrder) {
    return !rowKeyOrderOptimizable || isNullValue || sortOrder == SortOrder.ASC ? SEPARATOR_BYTE : QueryConstants.DESC_SEPARATOR_BYTE;
}