docs: protected void addRow(final KeyValue row) {
      long last_ts = 0;
      if (rows.size() != 0) {
        // Verify that we have the same metric id and tags.
        final byte[] key = row.key();
        final iRowSeq last = rows.get(rows.size() - 1);
        final short metric_width = tsdb.metrics.width();
        final short tags_offset = 
            (short) (Const.SALT_WIDTH() + metric_width + Const.TIMESTAMP_BYTES);
        final short tags_bytes = (short) (key.length - tags_offset);
        String error = null;
        if (key.length != last.key().length) {
          error = "row key length mismatch";
        } else if (
            Bytes.memcmp(key, last.key(), Const.SALT_WIDTH(), metric_width) != 0) {
          error = "metric ID mismatch";
        } else if (Bytes.memcmp(key, last.key(), tags_offset, tags_bytes) != 0) {
          error = "tags mismatch";
        }
        if (error != null) {
          throw new IllegalArgumentException(error + ". "
              + "This Span's last row key is " + Arrays.toString(last.key())
              + " whereas the row key being added is " + Arrays.toString(key)
              + " and metric_width=" + metric_width);
        }
        last_ts = last.timestamp(last.size() - 1);  // O(n)
      }
  
      final RowSeq rowseq = new RowSeq(tsdb);
      rowseq.setRow(row);
      sorted = false;
      if (last_ts >= rowseq.timestamp(0)) {
        // scan to see if we need to merge into an existing row
        for (final iRowSeq rs : rows) {
          if (Bytes.memcmp(rs.key(), row.key(), Const.SALT_WIDTH(), 
              (rs.key().length - Const.SALT_WIDTH())) == 0) {
            rs.addRow(row);
            return;
          }
        }
      }
      
      rows.add(rowseq);
    }