Example #1
0
  public int selectBestBlockForDownload(Friend remoteFriend) throws IOException {
    if (T.t) {
      T.debug("Selecting best block for download. Remote: " + remoteFriend);
    }
    BlockMask bm = blockMasks.get(remoteFriend.getGuid());
    if (bm == null) {
      if (T.t) {
        T.info("Ehh. Don't know anything about this friends block mask. Can't download.");
      }
      return -1;
    }

    BitSet interestingBlocks = getInterestingBlocks(bm);

    // remove bocks in progress from interesting blocks:
    BlockFile bf = storage.getBlockFile(root);
    BitSet blocksInProgress = bf == null ? new BitSet() : bf.getBlocksInProgress();
    blocksInProgress.flip(0, fd.getNumberOfBlocks());
    blocksInProgress.and(interestingBlocks);

    if (blocksInProgress.cardinality() > 0) {
      // there are blocks of interest that are NOT in progress. Take one of these
      interestingBlocks = blocksInProgress;
    } // else there are only blocks in progress. Use any of them

    int highestBlockNumber = 0;
    if (bf != null) {
      highestBlockNumber = bf.getHighestCompleteBlock();
    }
    highestBlockNumber += manager.getCore().getSettings().getInternal().getMaxfileexpandinblocks();
    // we prefer to load blocks below highestBlockNumber
    if (interestingBlocks.nextSetBit(0) < highestBlockNumber) {
      // we're good - there are interesting blocks below the highest block number.

      // remove all blocks above highest block number:
      if (highestBlockNumber + 1 < fd.getNumberOfBlocks()) {
        interestingBlocks.clear(highestBlockNumber + 1, fd.getNumberOfBlocks());
      }
    }

    // select a random block of the ones we're interested in - change this to rarest first in the
    // future
    int c = interestingBlocks.cardinality();
    int n = (int) (Math.random() * c);
    for (int i = interestingBlocks.nextSetBit(0), j = 0;
        i >= 0;
        i = interestingBlocks.nextSetBit(i + 1), j++) {
      if (j == n) {
        return i;
      }
    }

    if (T.t) {
      T.trace("Can't find any block to download from " + remoteFriend);
    }
    return -1;
  }