Search in sources :

Example 1 with PEPieceImpl

use of com.biglybt.core.peer.impl.PEPieceImpl in project BiglyBT by BiglySoftware.

the class PiecePickerImpl method findPieceToDownload.

/**
 * @param pt the PEPeerTransport we're working on
 * @return int # of blocks that were requested (0 if no requests were made)
 */
protected final int findPieceToDownload(PEPeerTransport pt, int nbWanted) {
    final int pieceNumber = getRequestCandidate(pt);
    if (pieceNumber < 0) {
        // pt.checkInterested();
        return 0;
    }
    int peerSpeed = (int) pt.getStats().getDataReceiveRate() / 1000;
    if (peerSpeed < 0)
        peerSpeed = 0;
    if (pt.isSnubbed())
        peerSpeed = 0;
    final PEPiece pePiece;
    if (pePieces[pieceNumber] != null) {
        pePiece = pePieces[pieceNumber];
    } else {
        // create piece manually
        int[] peer_priority_offsets = pt.getPriorityOffsets();
        int this_offset = peer_priority_offsets == null ? 0 : peer_priority_offsets[pieceNumber];
        // create piece manually
        pePiece = new PEPieceImpl(this, dmPieces[pieceNumber], peerSpeed >> 1);
        // Assign the created piece to the pieces array.
        peerControl.addPiece(pePiece, pieceNumber, pt);
        if (startPriorities != null) {
            pePiece.setResumePriority(startPriorities[pieceNumber] + this_offset);
        } else {
            pePiece.setResumePriority(this_offset);
        }
        if (availability[pieceNumber] <= globalMinOthers)
            nbRarestActive++;
    }
    int[] request_hint = null;
    if (enable_request_hints) {
        request_hint = pt.getRequestHint();
        if (request_hint != null) {
            if (request_hint[0] != pieceNumber) {
                request_hint = null;
            }
        }
        if (request_hint == null) {
            request_hint = global_request_hint;
            if (request_hint != null && request_hint[0] != pieceNumber) {
                request_hint = null;
            }
        }
    }
    if (!pt.isLANLocal() || includeLanPeersInReqLimiting) {
        nbWanted = dispenser.dispense(nbWanted, DiskManager.BLOCK_SIZE);
    }
    final int[] blocksFound = pePiece.getAndMarkBlocks(pt, nbWanted, request_hint, reverse_block_order);
    final int blockNumber = blocksFound[0];
    final int nbBlocks = blocksFound[1];
    if ((!pt.isLANLocal() || includeLanPeersInReqLimiting) && nbBlocks != nbWanted) {
        dispenser.returnUnusedChunks(nbWanted - nbBlocks, DiskManager.BLOCK_SIZE);
    }
    if (nbBlocks <= 0)
        return 0;
    int requested = 0;
    if (reverse_block_order) {
        for (int i = nbBlocks - 1; i >= 0; i--) {
            final int thisBlock = blockNumber + i;
            if (pt.request(pieceNumber, thisBlock * DiskManager.BLOCK_SIZE, pePiece.getBlockSize(thisBlock), true) != null) {
                requested++;
                pt.setLastPiece(pieceNumber);
                pePiece.setLastRequestedPeerSpeed(peerSpeed);
            // have requested a block
            } else {
                pePiece.clearRequested(thisBlock);
            }
        }
    } else {
        for (int i = 0; i < nbBlocks; i++) {
            final int thisBlock = blockNumber + i;
            if (pt.request(pieceNumber, thisBlock * DiskManager.BLOCK_SIZE, pePiece.getBlockSize(thisBlock), true) != null) {
                requested++;
                pt.setLastPiece(pieceNumber);
                pePiece.setLastRequestedPeerSpeed(peerSpeed);
            // have requested a block
            } else {
                pePiece.clearRequested(thisBlock);
            }
        }
    }
    if (requested > 0 && pePiece.getAvailability() <= globalMinOthers && calcRarestAllowed() > 0 && !rarestStartedPieces.contains(pePiece)) {
        rarestStartedPieces.add(pePiece);
    }
    return requested;
}
Also used : PEPieceImpl(com.biglybt.core.peer.impl.PEPieceImpl)

Example 2 with PEPieceImpl

use of com.biglybt.core.peer.impl.PEPieceImpl in project BiglyBT by BiglySoftware.

the class PiecePickerImpl method computeEndGameModeChunks.

private void computeEndGameModeChunks() {
    synchronized (endGameModeChunkLock) {
        for (int i = 0; i < nbPieces; i++) {
            final DiskManagerPiece dmPiece = dmPieces[i];
            if (!dmPiece.isInteresting()) {
                continue;
            }
            PEPiece pePiece = pePieces[i];
            if (pePiece == null) {
                pePiece = new PEPieceImpl(this, dmPiece, 0);
                peerControl.addPiece(pePiece, i, null);
            }
            final boolean[] written = dmPiece.getWritten();
            if (written == null) {
                if (!dmPiece.isDone()) {
                    for (int j = 0; j < pePiece.getNbBlocks(); j++) {
                        EndGameModeChunk chunk = new EndGameModeChunk(pePiece, j);
                        endGameModeChunks.add(chunk);
                        endGameModeChunkMap.put(new Long(((long) i) << 32 | j), chunk);
                    }
                }
            } else {
                for (int j = 0; j < written.length; j++) {
                    if (!written[j]) {
                        EndGameModeChunk chunk = new EndGameModeChunk(pePiece, j);
                        endGameModeChunks.add(chunk);
                        endGameModeChunkMap.put(new Long(((long) i) << 32 | j), chunk);
                    }
                }
            }
        }
        if (reverse_block_order) {
            Collections.reverse(endGameModeChunks);
        }
    }
}
Also used : PEPieceImpl(com.biglybt.core.peer.impl.PEPieceImpl)

Example 3 with PEPieceImpl

use of com.biglybt.core.peer.impl.PEPieceImpl in project BiglyBT by BiglySoftware.

the class PiecePickerImpl method findRTAPieceToDownload.

protected final boolean findRTAPieceToDownload(PEPeerTransport pt, boolean best_uploader, long best_uploader_next_block_eta) {
    if (pt == null || pt.getPeerState() != PEPeer.TRANSFERING) {
        return (false);
    }
    final BitFlags peerHavePieces = pt.getAvailable();
    if (peerHavePieces == null || peerHavePieces.nbSet <= 0) {
        return (false);
    }
    String rta_log_str = LOG_RTA ? pt.getIp() : null;
    try {
        // how many KB/s has the peer has been sending
        final int peerSpeed = (int) pt.getStats().getDataReceiveRate() / 1024;
        final int startI = peerHavePieces.start;
        final int endI = peerHavePieces.end;
        int piece_min_rta_index = -1;
        int piece_min_rta_block = 0;
        long piece_min_rta_time = Long.MAX_VALUE;
        long now = SystemTime.getCurrentTime();
        long my_next_block_eta = now + getNextBlockETAFromNow(pt);
        for (int i = startI; i <= endI; i++) {
            long piece_rta = provider_piece_rtas[i];
            if (peerHavePieces.flags[i] && startPriorities[i] == PRIORITY_REALTIME && piece_rta > 0) {
                final DiskManagerPiece dmPiece = dmPieces[i];
                if (!dmPiece.isDownloadable()) {
                    continue;
                }
                final PEPiece pePiece = pePieces[i];
                if (pePiece != null && pePiece.isDownloaded()) {
                    continue;
                }
                Object realtime_data = null;
                boolean try_allocate_even_though_late = my_next_block_eta > piece_rta && best_uploader_next_block_eta > piece_rta;
                if (piece_rta >= piece_min_rta_time) {
                // piece is less urgent than an already found one
                } else if (my_next_block_eta > piece_rta && !(best_uploader || best_uploader_next_block_eta > piece_rta)) {
                // only allocate if we have a chance of getting this block in time or we're
                // the best uploader we've got/even the best uploader can't get it
                // the second part is important for when we get to the point whereby no peers
                // can get a block in time. Here we need to allocate someone to get it as
                // otherwise we'll concentrate on getting lower priority pieces that we can
                // get in time and leave the stuck ones for just the best uploader to get
                } else if (pePiece == null || (realtime_data = pePiece.getRealTimeData()) == null) {
                    if (LOG_RTA)
                        rta_log_str += "{alloc_new=" + i + ",time=" + (piece_rta - now) + "}";
                    // no real-time block allocated yet
                    piece_min_rta_time = piece_rta;
                    piece_min_rta_index = i;
                    piece_min_rta_block = 0;
                } else {
                    RealTimeData rtd = (RealTimeData) realtime_data;
                    // check the blocks to see if any are now lagging behind their ETA given current peer speed
                    List[] peer_requests = rtd.getRequests();
                    for (int j = 0; j < peer_requests.length; j++) {
                        if (pePiece.isDownloaded(j) || pePiece.isWritten(j)) {
                            continue;
                        }
                        List block_peer_requests = peer_requests[j];
                        long best_eta = Long.MAX_VALUE;
                        boolean pt_already_present = false;
                        // tidy up existing request data
                        Iterator it = block_peer_requests.iterator();
                        while (it.hasNext()) {
                            RealTimePeerRequest pr = (RealTimePeerRequest) it.next();
                            PEPeerTransport this_pt = pr.getPeer();
                            if (this_pt.getPeerState() != PEPeer.TRANSFERING) {
                                if (LOG_RTA)
                                    rta_log_str += "{peer_dead=" + this_pt.getIp() + "}";
                                it.remove();
                                continue;
                            }
                            DiskManagerReadRequest this_request = pr.getRequest();
                            int request_index = this_pt.getRequestIndex(this_request);
                            if (request_index == -1) {
                                if (LOG_RTA)
                                    rta_log_str += "{request_lost=" + this_request.getPieceNumber() + "}";
                                it.remove();
                                continue;
                            }
                            if (this_pt == pt) {
                                pt_already_present = true;
                                break;
                            }
                            long this_up_bps = this_pt.getStats().getDataReceiveRate();
                            if (this_up_bps < 1) {
                                this_up_bps = 1;
                            }
                            int next_block_bytes = (request_index + 1) * DiskManager.BLOCK_SIZE;
                            long this_peer_eta = now + ((next_block_bytes * 1000) / this_up_bps);
                            best_eta = Math.min(best_eta, this_peer_eta);
                        }
                        if (!pt_already_present) {
                            if (block_peer_requests.size() == 0) {
                                if (LOG_RTA)
                                    rta_log_str += "{alloc as no req=" + i + ",block=" + j + ",time=" + (piece_rta - now) + "}";
                                piece_min_rta_time = piece_rta;
                                piece_min_rta_index = i;
                                piece_min_rta_block = j;
                                // earlier blocks always have priority
                                break;
                            } else if (best_eta > piece_rta && (best_uploader || !try_allocate_even_though_late)) {
                                if (LOG_RTA)
                                    rta_log_str += "{lagging=" + i + ",block=" + j + ",time=" + (best_eta - piece_rta) + "}";
                                if (my_next_block_eta < best_eta) {
                                    if (LOG_RTA)
                                        rta_log_str += "{taking over, time=" + (best_eta - my_next_block_eta) + "}";
                                    piece_min_rta_time = piece_rta;
                                    piece_min_rta_index = i;
                                    piece_min_rta_block = j;
                                    // earlier blocks always have priority
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        if (piece_min_rta_index != -1) {
            if (LOG_RTA)
                rta_log_str += ",{select_piece=" + piece_min_rta_index + ",block=" + piece_min_rta_block + ",time=" + (piece_min_rta_time - now) + "}";
            if (dispenser.dispense(1, DiskManager.BLOCK_SIZE) == 1 || (pt.isLANLocal() && !includeLanPeersInReqLimiting)) {
                PEPiece pePiece = pePieces[piece_min_rta_index];
                if (pePiece == null) {
                    // create piece manually
                    pePiece = new PEPieceImpl(this, dmPieces[piece_min_rta_index], peerSpeed >> 1);
                    // Assign the created piece to the pieces array.
                    peerControl.addPiece(pePiece, piece_min_rta_index, pt);
                    pePiece.setResumePriority(PRIORITY_REALTIME);
                    if (availability[piece_min_rta_index] <= globalMinOthers) {
                        nbRarestActive++;
                    }
                }
                RealTimeData rtd = (RealTimeData) pePiece.getRealTimeData();
                if (rtd == null) {
                    rtd = new RealTimeData(pePiece);
                    pePiece.setRealTimeData(rtd);
                }
                pePiece.getAndMarkBlock(pt, piece_min_rta_block);
                DiskManagerReadRequest request = pt.request(piece_min_rta_index, piece_min_rta_block * DiskManager.BLOCK_SIZE, pePiece.getBlockSize(piece_min_rta_block), true);
                if (request != null) {
                    List real_time_requests = rtd.getRequests()[piece_min_rta_block];
                    real_time_requests.add(new RealTimePeerRequest(pt, request));
                    pt.setLastPiece(piece_min_rta_index);
                    pePiece.setLastRequestedPeerSpeed(peerSpeed);
                    return (true);
                } else {
                    if (LOG_RTA)
                        rta_log_str += "{request failed}";
                    if (!pt.isLANLocal() || includeLanPeersInReqLimiting)
                        dispenser.returnUnusedChunks(1, DiskManager.BLOCK_SIZE);
                    return (false);
                }
            } else {
                if (LOG_RTA)
                    rta_log_str += "{dispenser denied}";
                return (false);
            }
        } else {
            if (LOG_RTA)
                rta_log_str += "{no piece found}";
            return (false);
        }
    } finally {
        if (LOG_RTA) {
            System.out.println(rta_log_str);
        }
    }
}
Also used : BitFlags(com.biglybt.core.peermanager.piecepicker.util.BitFlags) PEPieceImpl(com.biglybt.core.peer.impl.PEPieceImpl) PEPeerTransport(com.biglybt.core.peer.impl.PEPeerTransport) DMPieceList(com.biglybt.core.disk.impl.piecemapper.DMPieceList)

Aggregations

PEPieceImpl (com.biglybt.core.peer.impl.PEPieceImpl)3 DMPieceList (com.biglybt.core.disk.impl.piecemapper.DMPieceList)1 PEPeerTransport (com.biglybt.core.peer.impl.PEPeerTransport)1 BitFlags (com.biglybt.core.peermanager.piecepicker.util.BitFlags)1