static byte[] getNextForFuzzyRule(boolean reverse, byte[] row, int offset, int length,
    byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) {
    // To find out the closest next byte array that satisfies fuzzy rule and is after the given one
    // we do the following:
    // 1. setting values on all "fixed" positions to the values from fuzzyKeyBytes
    // 2. if during the first step given row did not increase, then we increase the value at
    // the first "non-fixed" position (where it is not maximum already)

    // It is easier to perform this by using fuzzyKeyBytes copy and setting "non-fixed" position
    // values than otherwise.
    byte[] result = Arrays.copyOf(fuzzyKeyBytes, Math.max(length, fuzzyKeyBytes.length));
    if (reverse) {
      // we need 0xff's instead of 0x00's
      for (int i = 0; i < result.length; i++) {
        if (result[i] == 0) {
          result[i] = (byte) 0xFF;
        }
      }
    }
    int toInc = -1;
    final Order order = Order.orderFor(reverse);

    boolean increased = false;
    for (int i = 0; i < result.length; i++) {
      if (i >= fuzzyKeyMeta.length || fuzzyKeyMeta[i] == 0 /* non-fixed */) {
        result[i] = row[offset + i];
        if (!order.isMax(row[offset + i])) {
          // this is "non-fixed" position and is not at max value, hence we can increase it
          toInc = i;
        }
      } else if (i < fuzzyKeyMeta.length && fuzzyKeyMeta[i] == -1 /* fixed */) {
        if (order.lt((row[i + offset] & 0xFF), (fuzzyKeyBytes[i] & 0xFF))) {
          // if setting value for any fixed position increased the original array,
          // we are OK
          increased = true;
          break;
        }

        if (order.gt((row[i + offset] & 0xFF), (fuzzyKeyBytes[i] & 0xFF))) {
          // if setting value for any fixed position makes array "smaller", then just stop:
          // in case we found some non-fixed position to increase we will do it, otherwise
          // there's no "next" row key that satisfies fuzzy rule and "greater" than given row
          break;
        }
      }
    }

    if (!increased) {
      if (toInc < 0) {
        return null;
      }
      result[toInc] = order.inc(result[toInc]);

      // Setting all "non-fixed" positions to zeroes to the right of the one we increased so
      // that found "next" row key is the smallest possible
      for (int i = toInc + 1; i < result.length; i++) {
        if (i >= fuzzyKeyMeta.length || fuzzyKeyMeta[i] == 0 /* non-fixed */) {
          result[i] = order.min();
        }
      }
    }

    byte[] trailingZerosTrimmed = trimTrailingZeroes(result, fuzzyKeyMeta, toInc);
    if (reverse) {
      // In the reverse case we increase last non-max byte to make sure that the proper row is
      // selected next.
      return PrivateCellUtil.increaseLastNonMaxByte(trailingZerosTrimmed);
    } else {
      return trailingZerosTrimmed;
    }
  }
Find out the closes next byte array that satisfies fuzzy rule and is after the given one. In
the reverse case it returns increased byte array to make sure that the proper row is selected
next.
@return byte array which is after the given row and which satisfies the fuzzy rule if it
        exists, null otherwise
hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java