private int actualizeBufferAndGetPosition(InputStream input, int offset, int align) {
    int blockLength = Xxh3Impl.getBlockLength();
    int requestedBlock = (offset + align) / blockLength;
    int positionInBuffer = offset % blockLength;

    if (isLatestBlockRead) {
      return offset - zeroPositionOffset;
    }
    else if (requestedBlock == currentBlock) {
      return positionInBuffer;
    }
    else if (requestedBlock > currentBlock) {
      try {
        // If it's the penultimate block, we need to read until the end of the stream.
        // There are some cases of hashing algorithm then for the latest block it requested data that is
        // located in between of two blocks. To support this case, it was decided at the penultimate block
        // to read until the end of the stream.
        // For the last block we can use the same logic except the fact that its buffer will be less or equal
        // size of `Xxh3Impl.getBlockLength()`
        if (requestedBlock + 2 == roundedUpTotalBlocks || requestedBlock + 1 == roundedUpTotalBlocks) {
          int remainingBufferSize = totalStreamLength - requestedBlock * blockLength;
          buffer = new byte[remainingBufferSize];
          readDataFromStreamToBuffer(input);
          zeroPositionOffset = requestedBlock * blockLength;
          isLatestBlockRead = true;
          currentBlock++;
          return positionInBuffer;
        }
        readDataFromStreamToBuffer(input);
        currentBlock++;
        return positionInBuffer;
      }
      catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
    else {
      throw new IllegalStateException("Unexpected state at InputStream hashing");
    }
  }
private int actualizeBufferAndGetPosition(InputStream input, int offset, int align)