/** * Creates a HashPrefixedEntityIdFactory. * * @param format Row key format. */ private HashPrefixedEntityIdFactory(RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.HASH_PREFIX); mRowKeyFormat = format; }
/** * Creates a HashPrefixedEntityId from the specified HBase row key. * * @param hbaseRowKey HBase row key. * @param format Row key hashing specification. * @return a new HashedEntityId with the specified HBase row key. */ static HashPrefixedEntityId fromHBaseRowKey(byte[] hbaseRowKey, RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.HASH_PREFIX); final int hashSize = format.getHashSize(); final byte[] fijiRowKey = Arrays.copyOfRange(hbaseRowKey, hashSize, hbaseRowKey.length); // TODO Paranoid expensive check : rehash the fiji key and compare with the hash? return new HashPrefixedEntityId(fijiRowKey, hbaseRowKey, format); }
/** * Hashes a Fiji row key. * * @param format Hashing specification. * @param fijiRowKey Fiji row key to hash. * @return a hash of the given Fiji row key. */ public static byte[] hashFijiRowKey(RowKeyFormat format, byte[] fijiRowKey) { // TODO refactor into hash factories: switch (format.getHashType()) { case MD5: return Hasher.hash(fijiRowKey); default: throw new RuntimeException(String.format("Unexpected hashing type: '%s'.", format)); } }
/** * Get the hash size for a given row key format. * * @param rowKeyFormat Format of row keys of type RowKeyFormat or RowKeyFormat2. * @return The size of the hash prefix. */ public static int getHashSize(Object rowKeyFormat) { if (rowKeyFormat instanceof RowKeyFormat) { return ((RowKeyFormat) rowKeyFormat).getHashSize(); } else if (rowKeyFormat instanceof RowKeyFormat2) { RowKeyFormat2 format2 = (RowKeyFormat2) rowKeyFormat; if (null == format2.getSalt()) { throw new RuntimeException("This RowKeyFormat2 instance does not specify salt/hashing."); } else { return format2.getSalt().getHashSize(); } } else { throw new RuntimeException("Unsupported Row Key Format"); } } }
/** * Gets a table's row-key hash resolution (in number of bytes) * for use in evenly spacing HBase row keys. * * @param tableLayout the layout of the table * @return the table's hash resolution. */ public static int getRowKeyResolution(TableLayoutDesc tableLayout) { // Get hashSize from layout. int hashSize = 16; // No assumptions make about the RKF. if (RowKeyFormat.class.equals(tableLayout.getKeysFormat().getClass())) { hashSize = ((RowKeyFormat) tableLayout.getKeysFormat()).getHashSize(); } else if (RowKeyFormat2.class.equals(tableLayout.getKeysFormat().getClass())) { RowKeyFormat2 format = (RowKeyFormat2) tableLayout.getKeysFormat(); if (null == format.getSalt()) { throw new IllegalArgumentException( "This table layout defines an entityId format without hashing enabled."); } hashSize = ((RowKeyFormat2) tableLayout.getKeysFormat()).getSalt().getHashSize(); } return hashSize; }
/** * Creates a RawEntityIdFactory. * * @param format Row key format. */ private RawEntityIdFactory(RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.RAW); }
/** * Ensure a row key format (version 1) specified in a layout file is sane. * @param format The RowKeyFormat created from the layout file for a table. * @throws InvalidLayoutException If the format is invalid. */ private void isValidRowKeyFormat1(RowKeyFormat format) throws InvalidLayoutException { RowKeyEncoding rowKeyEncoding = format.getEncoding(); if (rowKeyEncoding != RowKeyEncoding.RAW && rowKeyEncoding != RowKeyEncoding.HASH && rowKeyEncoding != RowKeyEncoding.HASH_PREFIX) { throw new InvalidLayoutException("RowKeyFormat only supports encodings" + "of type RAW, HASH and HASH_PREFIX. Use RowKeyFormat2 instead"); } if (rowKeyEncoding == RowKeyEncoding.HASH || rowKeyEncoding == RowKeyEncoding.HASH_PREFIX) { if (format.getHashSize() < 0 || format.getHashSize() > Hasher.HASH_SIZE_BYTES) { throw new InvalidLayoutException("HASH or HASH_PREFIX row key formats require hash size" + "to be between 1 and " + Hasher.HASH_SIZE_BYTES); } } }
/** * Hashes a Fiji row key. * * @param format Hashing specification. * @param fijiRowKey Fiji row key. * @return a hash of the Fiji row key. */ public static byte[] hashFijiRowKey(RowKeyFormat format, byte[] fijiRowKey) { // TODO refactor into hash factories: switch (format.getHashType()) { case MD5: return Hasher.hash(fijiRowKey); default: throw new RuntimeException(String.format("Unexpected hashing type: '%s'.", format)); } }
/** * Creates a new Hashed Entity ID factory. * * @param format The format for creating the hashed entity ID factory. */ private HashedEntityIdFactory(RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.HASH); mRowKeyFormat = format; }
/** * Creates a HashPrefixedEntityId from the specified Fiji row key. * * @param fijiRowKey Fiji row key. * @param format Row key hashing specification. * @return a new HashPrefixedEntityId with the specified Fiji row key. */ static HashPrefixedEntityId getEntityId(byte[] fijiRowKey, RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.HASH_PREFIX); final byte[] hash = hashFijiRowKey(format, fijiRowKey); final int hashSize = format.getHashSize(); // Prepend a subset of the hash to the Fiji row key: final byte[] hbaseRowKey = new byte[hashSize + fijiRowKey.length]; System.arraycopy(hash, 0, hbaseRowKey, 0, hashSize); System.arraycopy(fijiRowKey, 0, hbaseRowKey, hashSize, fijiRowKey.length); return new HashPrefixedEntityId(fijiRowKey, hbaseRowKey, format); }
/** * Creates a new HashPrefixedEntityId. * * @param fijiRowKey Fiji row key. * @param hbaseRowKey HBase row key. * @param format Row key hashing specification. */ private HashPrefixedEntityId(byte[] fijiRowKey, byte[] hbaseRowKey, RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.HASH_PREFIX); mFijiRowKey = Preconditions.checkNotNull(fijiRowKey); mHBaseRowKey = Preconditions.checkNotNull(hbaseRowKey); }
/** * Creates a new HashedEntityId. * * @param fijiRowKey Fiji row key. * @param hbaseRowKey HBase row key. * @param format Row key hashing specification. */ private HashedEntityId(byte[] fijiRowKey, byte[] hbaseRowKey, RowKeyFormat format) { Preconditions.checkNotNull(format); Preconditions.checkArgument(format.getEncoding() == RowKeyEncoding.HASH); mFijiRowKey = fijiRowKey; mHBaseRowKey = Preconditions.checkNotNull(hbaseRowKey); }
/** * Find the encoding of the row key given the format. * * @param rowKeyFormat Format of row keys of type RowKeyFormat or RowKeyFormat2. * @return The specific row key encoding, e.g. RAW, HASH, etc. */ public static RowKeyEncoding getEncoding(Object rowKeyFormat) { if (rowKeyFormat instanceof RowKeyFormat) { return ((RowKeyFormat) rowKeyFormat).getEncoding(); } else if (rowKeyFormat instanceof RowKeyFormat2) { return ((RowKeyFormat2) rowKeyFormat).getEncoding(); } else { throw new RuntimeException("Unsupported Row Key Format"); } }
/** * Gets row key encoding of a row key format. * * @param keysFormat row key format. * @return row key encoding. * @throws IOException if row key format is unrecognized. */ private static RowKeyEncoding getEncoding(final Object keysFormat) throws IOException { if (keysFormat instanceof RowKeyFormat) { return ((RowKeyFormat) keysFormat).getEncoding(); } else if (keysFormat instanceof RowKeyFormat2) { return ((RowKeyFormat2) keysFormat).getEncoding(); } else { throw new IOException( String.format("Unrecognized row key format: %s", keysFormat.getClass())); } }
/** * Gets row key encoding of a row key format. * * @param keysFormat row key format. * @return row key encoding. * @throws IOException if row key format is unrecognized. */ private static RowKeyEncoding getEncoding(final Object keysFormat) throws IOException { if (keysFormat instanceof RowKeyFormat) { return ((RowKeyFormat) keysFormat).getEncoding(); } else if (keysFormat instanceof RowKeyFormat2) { return ((RowKeyFormat2) keysFormat).getEncoding(); } else { throw new IOException( String.format("Unrecognized row key format: %s", keysFormat.getClass())); } }
/** * Creates an entity ID factory for the specified row key format. * * @param format Row key format of type RowKeyFormat that determines the * type of EntityIdFactory that's created. * @return a new entity ID factory for the specified row key format. */ public static EntityIdFactory getFactory(RowKeyFormat format) { Preconditions.checkNotNull(format); // FORMATTED encoding is legal here but not supported by RowKeyFormat. switch (format.getEncoding()) { case RAW: return new RawEntityIdFactory(format); case HASH: return new HashedEntityIdFactory(format); case HASH_PREFIX: return new HashPrefixedEntityIdFactory(format); case FORMATTED: throw new RuntimeException( "Row key format encoding FORMATTED is not supported with RowKeyFormat specifications. " + "Use RowKeyFormat2 instead."); default: throw new RuntimeException(String.format("Unhandled row key format: '%s'.", format)); } }