code: public static byte[] rowKeyFromTSUID(final TSDB tsdb, final byte[] tsuid, 
        final long timestamp) {
      if (tsuid.length < tsdb.metrics.width()) {
        throw new IllegalArgumentException("TSUID appears to be missing the metric");
      }
      final long base_time;
      if ((timestamp & Const.SECOND_MASK) != 0) {
        // drop the ms timestamp to seconds to calculate the base timestamp
        base_time = ((timestamp / 1000) - 
            ((timestamp / 1000) % Const.MAX_TIMESPAN));
      } else {
        base_time = (timestamp - (timestamp % Const.MAX_TIMESPAN));
      }
      final byte[] row = 
          new byte[Const.SALT_WIDTH() + tsuid.length + Const.TIMESTAMP_BYTES];
      System.arraycopy(tsuid, 0, row, Const.SALT_WIDTH(), tsdb.metrics.width());
      Bytes.setInt(row, (int) base_time, Const.SALT_WIDTH() + tsdb.metrics.width());
      System.arraycopy(tsuid, tsdb.metrics.width(), row, 
          Const.SALT_WIDTH() + tsdb.metrics.width() + Const.TIMESTAMP_BYTES, 
          tsuid.length - tsdb.metrics.width());
      RowKey.prefixKeyWithSalt(row);
      return row;
    }
docs: Generates a row key given a TSUID and an absolute timestamp. The timestamp
  will be normalized to an hourly base time. If salting is enabled then
  empty salt bytes will be prepended to the key and must be filled in later.
  @param tsdb The TSDB to use for fetching tag widths
  @param tsuid The TSUID to use for the key
  @param timestamp An absolute time from which we generate the row base time
  @return A row key for use in fetching data from OpenTSDB
  @throws IllegalArgumentException if the TSUID is too short, i.e. doesn't
  contain a metric
  @since 2.0