public void signalBlockComplete(int blockNumber) throws IOException { signalBlockCompleteCounter++; if (signalBlockCompleteCounter > SEND_BLOCKMASK_UPDATE_INTERVAL_IN_BLOCKS) { signalBlockCompleteCounter = 0; BlockFile bf = storage.getBlockFile(fd.getRootHash()); if (bf == null) { return; } List<Friend> list = manager.getFriendsInterestedIn(root); if (list != null) { for (Friend f : list) { FriendConnection fc = f.getFriendConnection(); if (fc != null) { if (T.t) { T.info( "Friend " + f + " is interested in file " + root + ". Sending updated block mask to him."); } fc.send(new BlockMaskResult(root, bf.getBlockMask())); } } } } }
public String info() { String res = ""; for (T unit : units) { res += unit.info() + "\n"; } return res; }
public void fileDescriptorReceived(DownloadConnection source, FileDescriptor fd) throws IOException { if (this.fd != null) { if (T.t) { T.info("Already has FD. Ignore the new one and start download for this connection."); } if (T.t) { T.ass(source.readyToStartDownload(), "Not ready to start download?"); } if (needsMoreDownloadConnections()) { source.startDownloadingBlock(); } return; } if (T.t) { T.debug("Received file descriptor " + fd); } this.fd = fd; setState(State.DOWNLOADING); ArrayList<DownloadConnection> al = new ArrayList<DownloadConnection>(); for (DownloadConnection c : connections.values()) { al.add(c); } for (DownloadConnection c : al) { if (c.readyToStartDownload() && needsMoreDownloadConnections()) { c.startDownloadingBlock(); } } }
public void removeConnection(DownloadConnection downloadConnection) throws IOException { connections.remove(downloadConnection.getRemoteFriend()); if (connections.size() == 0 && isComplete()) { if (T.t) { T.info("Download is complete"); } manager.downloadComplete(this); } }
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; }
public void route(int dstGuid, RPC rpc) throws IOException { Friend f = netMan.getFriendManager().getFriend(dstGuid); if (f != null && f.getFriendConnection() != null) { if (T.t) { T.info("Rerouting package to friend"); } f.getFriendConnection().send(rpc); } else { // note that one of our friends COULD actually be a closer Route to the destination. But this // way we send // the rpc the same way back as be got it. No biggie probably. rpc.init(this); Packet p = createRPCPacket(rpc); send(new Route(netMan.getFriendManager().getMyGUID(), dstGuid, p)); } }
public void desc(T t) { t.info(); t.did(); }
public void blockMaskReceived(int srcGuid, int hops, BlockMask bm) { if (hops > 0) { if (T.t) { T.debug("Ignoring block mask coming from " + hops + " hops away."); } return; } if (!isInterestedInBlockMasks()) { if (T.t) { T.info("No longer interested in block masks for this download - ignore"); } return; } if (T.t) { T.debug("Received blockmask from " + srcGuid + ": " + bm + " size: " + bm.length()); } blockMasks.put(srcGuid, bm); if (state == State.WAITING_TO_START) { return; } if (connections.size() == 0) { try { if (T.t) { T.info("Got first block mask - starting download."); } openDownloadConnection(srcGuid); } catch (IOException e) { if (T.t) { T.warn("Could not connect to " + srcGuid + ". Waiting for next block mask: " + e); } } } else { if (getConnectionByGUID(srcGuid) == null) { try { if (fd != null && getInterestingBlocks(bm).isEmpty()) { if (T.t) { T.debug("Remote has blocks of file, but no that I'm interested of: " + srcGuid); } } else { if (connections.size() < manager.getMaxConnectionsPerDownload()) { if (T.t) { T.debug("Opening dl connection to another friend"); } openDownloadConnection(srcGuid); } else { if (T.t) { T.trace( "Not opening more connection for download " + this + ". have already: " + connections.size()); } } } } catch (IOException e) { if (T.t) { T.warn("Could not connect to " + srcGuid + ". Waiting for next block mask: " + e); } } } else { if (T.t) { T.info( "Already connected to " + srcGuid + " - no need to open another download connection"); } } } }