/** * Builds the 'time' portion of the row key * @param period The ProfilePeriod in which the ProfileMeasurement was taken. */ private static byte[] timeKey(ProfilePeriod period) { return timeKey(period.getPeriod()); }
/** * Calculates a salt value that is used as part of the row key. * * The salt is calculated as 'md5(period) % N' where N is a configurable value that ideally * is close to the number of nodes in the Hbase cluster. * * @param period The period * @param saltDivisor The salt divisor */ public static byte[] getSalt(long period, int saltDivisor) { try { // an MD5 is 16 bytes aka 128 bits MessageDigest digest = MessageDigest.getInstance("MD5"); byte[] hash = digest.digest(timeKey(period)); int salt = Bytes.toShort(hash) % saltDivisor; return Bytes.toBytes(salt); } catch(NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
/** * Build the row key. * @param profile The name of the profile. * @param entity The name of the entity. * @param period The measure period * @param groups The groups. * @return The HBase row key. */ public byte[] rowKey(String profile, String entity, long period, List<Object> groups) { // row key = salt + prefix + group(s) + time byte[] salt = getSalt(period, saltDivisor); byte[] prefixKey = prefixKey(profile, entity); byte[] groupKey = groupKey(groups); byte[] timeKey = timeKey(period); int capacity = salt.length + prefixKey.length + groupKey.length + timeKey.length; return ByteBuffer .allocate(capacity) .put(salt) .put(prefixKey) .put(groupKey) .put(timeKey) .array(); }