Esempio n. 1
0
  public List<RowLogMessage> next(String subscription, Long minimalTimestamp, boolean problematic)
      throws RowLogException {
    byte[] rowPrefix;
    byte[] subscriptionBytes = Bytes.toBytes(subscription);
    if (problematic) {
      rowPrefix = PROBLEMATIC_MARKER;
      rowPrefix = Bytes.add(rowPrefix, subscriptionBytes);
    } else {
      rowPrefix = subscriptionBytes;
    }
    byte[] startRow = rowPrefix;
    if (minimalTimestamp != null) startRow = Bytes.add(startRow, Bytes.toBytes(minimalTimestamp));
    try {
      List<RowLogMessage> rowLogMessages = new ArrayList<RowLogMessage>();
      Scan scan = new Scan(startRow);
      if (minimalTimestamp != null) scan.setTimeRange(minimalTimestamp, Long.MAX_VALUE);
      scan.addColumn(MESSAGES_CF, MESSAGE_COLUMN);
      ResultScanner scanner = table.getScanner(scan);
      boolean keepScanning = problematic;
      do {
        Result[] results = scanner.next(batchSize);
        if (results.length == 0) {
          keepScanning = false;
        }
        for (Result next : results) {
          byte[] rowKey = next.getRow();
          if (!Bytes.startsWith(rowKey, rowPrefix)) {
            keepScanning = false;
            break; // There were no messages for this subscription
          }
          if (problematic) {
            rowKey = Bytes.tail(rowKey, rowKey.length - PROBLEMATIC_MARKER.length);
          }
          byte[] value = next.getValue(MESSAGES_CF, MESSAGE_COLUMN);
          byte[] messageId = Bytes.tail(rowKey, rowKey.length - subscriptionBytes.length);
          rowLogMessages.add(decodeMessage(messageId, value));
        }
      } while (keepScanning);

      // The scanner is not closed in a finally block, since when we get an IOException from
      // HBase, it is likely that closing the scanner will give problems too. Not closing
      // the scanner is not fatal since HBase will expire it after a while.
      Closer.close(scanner);

      return rowLogMessages;
    } catch (IOException e) {
      throw new RowLogException("Failed to fetch next message from RowLogShard", e);
    }
  }
  @Override
  /**
   * Checks if a blob key (ourStoreKey) is contained in the blob field (theirValue). The blob field
   * can be a multivalue and / or hierarchical field.
   *
   * <p>IMPORTANT: This implementation depends on the byte encodings from ValueTypeImpl,
   * BlobValueType and DataOutputImpl. Any changes there have an impact on this implementation.
   */
  public int compareTo(byte[] theirValue, int fromOffset, int length) {
    byte[] ourStoreKey =
        Bytes.tail(nestingLevelAndValue, nestingLevelAndValue.length - Bytes.SIZEOF_INT);
    if (theirValue == null && ourStoreKey == null) return 0;
    if (length == 0 && ourStoreKey.length == 0) return 0;
    if (length < ourStoreKey.length) return -1;
    if (theirValue[fromOffset] == (byte) (1)) { // First byte indicates if it was deleted or not
      return -1;
    }

    int nestingLevel = Bytes.toInt(nestingLevelAndValue);
    offset = fromOffset + 1;

    return compareBlob(nestingLevel, ourStoreKey, theirValue);
  }
Esempio n. 3
0
 private RowLogMessage decodeMessage(byte[] messageId, byte[] data) {
   long timestamp = Bytes.toLong(messageId);
   long seqNr = Bytes.toLong(messageId, Bytes.SIZEOF_LONG);
   byte[] rowKey = Bytes.tail(messageId, messageId.length - (2 * Bytes.SIZEOF_LONG));
   return new RowLogMessageImpl(timestamp, rowKey, seqNr, data, rowLog);
 }