@Override public void write(DataOutput output) throws IOException { Bytes.writeByteArray(output, name.getBytes()); WritableUtils.writeVInt(output, type.ordinal()); WritableUtils.writeVLong(output, sequenceNumber); output.writeLong(timeStamp); Bytes.writeByteArray( output, pkName == null ? ByteUtil.EMPTY_BYTE_ARRAY : Bytes.toBytes(pkName)); WritableUtils.writeVInt(output, allColumns.size()); for (int i = 0; i < allColumns.size(); i++) { PColumn column = allColumns.get(i); column.write(output); } stats.write(output); }
@Override public String toString() { return name.getString(); }
@Override public int newKey(ImmutableBytesWritable key, byte[][] values) { int i = 0; TrustedByteArrayOutputStream os = new TrustedByteArrayOutputStream(SchemaUtil.estimateKeyLength(this)); try { List<PColumn> columns = getPKColumns(); int nColumns = columns.size(); PColumn lastPKColumn = columns.get(nColumns - 1); while (i < values.length && i < nColumns) { PColumn column = columns.get(i); PDataType type = column.getDataType(); // This will throw if the value is null and the type doesn't allow null byte[] byteValue = values[i++]; if (byteValue == null) { byteValue = ByteUtil.EMPTY_BYTE_ARRAY; } // An empty byte array return value means null. Do this, // since a type may have muliple representations of null. // For example, VARCHAR treats both null and an empty string // as null. This way we don't need to leak that part of the // implementation outside of PDataType by checking the value // here. if (byteValue.length == 0 && !column.isNullable()) { throw new ConstraintViolationException( name.getString() + "." + column.getName().getString() + " may not be null"); } Integer byteSize = column.getByteSize(); if (type.isFixedWidth()) { // TODO: handle multi-byte characters if (byteValue.length != byteSize) { throw new ConstraintViolationException( name.getString() + "." + column.getName().getString() + " must be " + byteSize + " bytes (" + SchemaUtil.toString(type, byteValue) + ")"); } } else if (byteSize != null && byteValue.length > byteSize) { throw new ConstraintViolationException( name.getString() + "." + column.getName().getString() + " may not exceed " + byteSize + " bytes (" + SchemaUtil.toString(type, byteValue) + ")"); } os.write(byteValue, 0, byteValue.length); // Separate variable length column values in key with zero byte if (!type.isFixedWidth() && column != lastPKColumn) { os.write(SEPARATOR_BYTE); } } // If some non null pk values aren't set, then throw if (i < nColumns) { PColumn column = columns.get(i); PDataType type = column.getDataType(); if (type.isFixedWidth() || !column.isNullable()) { throw new ConstraintViolationException( name.getString() + "." + column.getName().getString() + " may not be null"); } // Separate variable length column values in key with zero byte if (column != lastPKColumn) { os.write(SEPARATOR_BYTE); } } key.set(os.getBuffer(), 0, os.size()); return i; } finally { try { os.close(); } catch (IOException e) { throw new RuntimeException(e); // Impossible } } }