コード例 #1
0
ファイル: RowSeq.java プロジェクト: bruceleexiaokan/mon4h
 public long timestamp(final int i) {
   checkIndex(i);
   // Important: Span.addRow assumes this method to work in O(1).
   return baseTime() + (Bytes.getUnsignedShort(qualifiers, i * 2) >>> Const.FLAG_BITS);
 }
コード例 #2
0
ファイル: RowSeq.java プロジェクト: bruceleexiaokan/mon4h
 /**
  * Look a head to see the next timestamp.
  *
  * @throws IndexOutOfBoundsException if we reached the end already.
  */
 long peekNextTimestamp() {
   return base_time + (Bytes.getUnsignedShort(qualifiers, qual_index) >>> Const.FLAG_BITS);
 }
コード例 #3
0
ファイル: RowSeq.java プロジェクト: bruceleexiaokan/mon4h
  /**
   * Merges another HBase row into this one. When two continuous rows in HBase have data points that
   * are close enough together that they could be stored into the same row, it makes sense to merge
   * them into the same {@link RowSeq} instance in memory in order to save RAM.
   *
   * @param row The compacted HBase row to merge into this instance.
   * @throws IllegalStateException if {@link #setRow} wasn't called first.
   * @throws IllegalArgumentException if the data points in the argument aren't close enough to
   *     those in this instance time-wise to be all merged together.
   */
  void addRow(final KeyValue row) {
    if (this.key == null) {
      throw new IllegalStateException("setRow was never called on " + this);
    }

    final byte[] key = row.getRow();
    final long base_time = Bytes.getUnsignedInt(key, UniqueIds.metrics().width());
    final int time_adj = (int) (base_time - baseTime());
    if (time_adj <= 0) {
      // Corner case: if the time difference is 0 and the key is the same, it
      // means we've already added this row, possibly parts of it.  This
      // doesn't normally happen but can happen if the scanner we're using
      // timed out (its lease expired for whatever reason), in which case
      // asynchbase will transparently re-open the scanner and start scanning
      // from the row key we were on at the time the timeout happened.  In
      // that case, the easiest thing to do is to discard everything we know
      // about this row and start over, since we're going to get the full row
      // again anyway.
      if (time_adj != 0 || !Bytes.equals(this.key, key)) {
        throw new IllegalDataException(
            "Attempt to add a row with a base_time="
                + base_time
                + " <= baseTime()="
                + baseTime()
                + "; Row added="
                + row
                + ", this="
                + this);
      }
      this.key = null; // To keep setRow happy.
      this.qualifiers = null; // Throw away our previous work.
      this.values = null; // free();
      setRow(row);
      return;
    }

    final byte[] qual = row.getQualifier();
    final int len = qual.length;
    int last_delta = Bytes.getUnsignedShort(qualifiers, qualifiers.length - 2);
    last_delta >>= Const.FLAG_BITS;

    final int old_qual_len = qualifiers.length;
    final byte[] newquals = new byte[old_qual_len + len];
    System.arraycopy(qualifiers, 0, newquals, 0, old_qual_len);
    // Adjust the delta in all the qualifiers.
    for (int i = 0; i < len; i += 2) {
      short qualifier = Bytes.getShort(qual, i);
      final int time_delta = time_adj + ((qualifier & 0xFFFF) >>> Const.FLAG_BITS);
      if (!canTimeDeltaFit(time_delta)) {
        throw new IllegalDataException(
            "time_delta at index "
                + i
                + " is too large: "
                + time_delta
                + " (qualifier=0x"
                + Integer.toHexString(qualifier & 0xFFFF)
                + " baseTime()="
                + baseTime()
                + ", base_time="
                + base_time
                + ", time_adj="
                + time_adj
                + ") for "
                + row
                + " to be added to "
                + this);
      }
      if (last_delta >= time_delta) {
        LOG.error(
            "new timestamp = "
                + (baseTime() + time_delta)
                + " (index="
                + i
                + ") is < previous="
                + (baseTime() + last_delta)
                + " in addRow with row="
                + row
                + " in this="
                + this);
        return; // Ignore this row, it came out of order.
      }
      qualifier = (short) ((time_delta << Const.FLAG_BITS) | (qualifier & Const.FLAGS_MASK));
      Bytes.setShort(newquals, qualifier, old_qual_len + i);
    }
    this.qualifiers = newquals;

    final byte[] val = row.getValue();
    // If both the current `values' and the new `val' are single values, then
    // we neither of them has a meta data byte so we need to add one to be
    // consistent with what we expect from compacted values.  Otherwise, we
    // need to subtract 1 from the value length.
    final int old_val_len = values.length - (old_qual_len == 2 ? 0 : 1);
    final byte[] newvals =
        new byte
            [old_val_len
                + val.length
                // Only add a meta-data byte if the new values don't have it.
                + (len == 2 ? 1 : 0)];
    System.arraycopy(values, 0, newvals, 0, old_val_len);
    System.arraycopy(val, 0, newvals, old_val_len, val.length);
    assert newvals[newvals.length - 1] == 0
        : "Incorrect meta data byte after merge of "
            + row
            + " resulting qualifiers="
            + Arrays.toString(qualifiers)
            + ", values="
            + Arrays.toString(newvals)
            + ", old values="
            + Arrays.toString(values);
    this.values = newvals;
  }