Search in sources :

Example 6 with BitFlags

use of com.biglybt.core.peermanager.piecepicker.util.BitFlags in project BiglyBT by BiglySoftware.

the class PEPeerTransportProtocol method decodeBitfield.

protected void decodeBitfield(BTBitfield bitfield) {
    received_bitfield = true;
    if (is_metadata_download) {
        bitfield.destroy();
        return;
    }
    final DirectByteBuffer field = bitfield.getBitfield();
    final byte[] dataf = new byte[(nbPieces + 7) / 8];
    if (field.remaining(DirectByteBuffer.SS_PEER) < dataf.length) {
        final String error = toString() + " has sent invalid Bitfield: too short [" + field.remaining(DirectByteBuffer.SS_PEER) + "<" + dataf.length + "]";
        Debug.out(error);
        if (Logger.isEnabled())
            Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, error));
        bitfield.destroy();
        return;
    }
    field.get(DirectByteBuffer.SS_PEER, dataf);
    try {
        closing_mon.enter();
        if (closing)
            bitfield.destroy();
        else {
            final BitFlags tempHavePieces;
            if (peerHavePieces == null) {
                tempHavePieces = new BitFlags(nbPieces);
            } else {
                tempHavePieces = peerHavePieces;
                removeAvailability();
            }
            for (int i = 0; i < nbPieces; i++) {
                final int index = i / 8;
                final int bit = 7 - (i % 8);
                final byte bData = dataf[index];
                final byte b = (byte) (bData >> bit);
                if ((b & 0x01) == 1) {
                    tempHavePieces.set(i);
                    manager.updateSuperSeedPiece(this, i);
                }
            }
            bitfield.destroy();
            peerHavePieces = tempHavePieces;
            addAvailability();
            checkSeed();
            checkInterested();
            checkFast(tempHavePieces);
        }
    } finally {
        closing_mon.exit();
    }
}
Also used : BitFlags(com.biglybt.core.peermanager.piecepicker.util.BitFlags)

Example 7 with BitFlags

use of com.biglybt.core.peermanager.piecepicker.util.BitFlags in project BiglyBT by BiglySoftware.

the class PercentHaveWeNeedItem method refresh.

@Override
public void refresh(TableCell cell) {
    PEPeer peer = (PEPeer) cell.getDataSource();
    int value = -1;
    if (peer != null) {
        PEPeerManager pm = peer.getManager();
        if (pm != null) {
            if (!pm.isSeeding()) {
                if (peer.isSeed()) {
                    value = 1000 - pm.getDiskManager().getPercentDoneExcludingDND();
                } else {
                    BitFlags bf = peer.getAvailable();
                    if (bf != null) {
                        boolean[] peer_has = bf.flags;
                        if (peer_has != null) {
                            int we_have = 0;
                            int we_need = 0;
                            int they_have_we_need = 0;
                            DiskManagerPiece[] dm_pieces = pm.getDiskManager().getPieces();
                            for (int i = 0; i < dm_pieces.length; i++) {
                                DiskManagerPiece piece = dm_pieces[i];
                                if (piece.isNeeded()) {
                                    if (piece.isDone()) {
                                        we_have++;
                                    } else {
                                        we_need++;
                                        if (peer_has[i]) {
                                            they_have_we_need++;
                                        }
                                    }
                                }
                            }
                            if (we_need > 0) {
                                value = (1000 * they_have_we_need) / (we_have + we_need);
                            }
                        }
                    }
                }
            }
        }
    }
    if (!cell.setSortValue(value) && cell.isValid()) {
        return;
    }
    cell.setText(value < 0 ? "" : DisplayFormatters.formatPercentFromThousands(value));
}
Also used : BitFlags(com.biglybt.core.peermanager.piecepicker.util.BitFlags) PEPeer(com.biglybt.core.peer.PEPeer) PEPeerManager(com.biglybt.core.peer.PEPeerManager) DiskManagerPiece(com.biglybt.core.disk.DiskManagerPiece)

Example 8 with BitFlags

use of com.biglybt.core.peermanager.piecepicker.util.BitFlags in project BiglyBT by BiglySoftware.

the class PeerInfoView method refreshInfoCanvas.

/**
 * Constructs and image representing the download state of _all_
 * the pieces in the torrent.  Particularily slow when there's lots of pieces,
 * and also wasteful since only a fraction of them ever get painted at
 * any given time.
 *
 * TODO: Construct image for visible area only or something
 */
private void refreshInfoCanvas() {
    refreshInfoCanvasQueued = false;
    if (peerInfoComposite == null || peerInfoComposite.isDisposed() || !peerInfoComposite.isVisible()) {
        return;
    }
    peerInfoCanvas.layout(true);
    Rectangle bounds = peerInfoCanvas.getClientArea();
    if (bounds.width <= 0 || bounds.height <= 0)
        return;
    if (img != null && !img.isDisposed()) {
        img.dispose();
        img = null;
    }
    if (peer == null || peer.getPeerState() != PEPeer.TRANSFERING) {
        GC gc = new GC(peerInfoCanvas);
        gc.fillRectangle(bounds);
        gc.dispose();
        return;
    }
    PEPeerManager pm = peer.getManager();
    DiskManager dm = pm == null ? null : pm.getDiskManager();
    BitFlags peerHavePieces = peer.getAvailable();
    if (dm == null || peerHavePieces == null) {
        GC gc = new GC(peerInfoCanvas);
        gc.fillRectangle(bounds);
        gc.dispose();
        return;
    }
    int numPieces = dm.getNbPieces();
    if (numPieces > MAX_PIECES_TO_SHOW) {
        numPieces = MAX_PIECES_TO_SHOW;
    }
    DiskManagerPiece[] dm_pieces = dm.getPieces();
    int iNumCols = bounds.width / BLOCK_SIZE;
    int iNeededHeight = (((numPieces - 1) / iNumCols) + 1) * BLOCK_SIZE;
    if (sc.getMinHeight() != iNeededHeight) {
        sc.setMinHeight(iNeededHeight);
        sc.layout(true, true);
        bounds = peerInfoCanvas.getClientArea();
    }
    img = new Image(peerInfoCanvas.getDisplay(), bounds.width, iNeededHeight);
    GC gcImg = new GC(img);
    try {
        // use advanced capabilities for faster drawText
        gcImg.setAdvanced(true);
        gcImg.setBackground(peerInfoCanvas.getBackground());
        gcImg.fillRectangle(0, 0, bounds.width, iNeededHeight);
        int[] availability = pm.getAvailability();
        int iNextDLPieceID = -1;
        int iDLPieceID = -1;
        int[] ourRequestedPieces = peer.getOutgoingRequestedPieceNumbers();
        if (ourRequestedPieces != null) {
            if (!peer.isChokingMe()) {
                if (ourRequestedPieces.length > 0) {
                    iDLPieceID = ourRequestedPieces[0];
                    if (ourRequestedPieces.length > 1)
                        iNextDLPieceID = ourRequestedPieces[1];
                }
            } else {
                if (ourRequestedPieces.length > 0)
                    iNextDLPieceID = ourRequestedPieces[0];
            }
        // if (iNextDLPieceID == -1) {
        // iNextDLPieceID = peer.getNextPieceNumberGuess();
        // }
        }
        int[] peerRequestedPieces = peer.getIncomingRequestedPieceNumbers();
        if (peerRequestedPieces == null)
            peerRequestedPieces = new int[0];
        int peerNextRequestedPiece = -1;
        if (peerRequestedPieces.length > 0)
            peerNextRequestedPiece = peerRequestedPieces[0];
        Arrays.sort(peerRequestedPieces);
        int iRow = 0;
        int iCol = 0;
        for (int i = 0; i < numPieces; i++) {
            int colorIndex;
            boolean done = (dm_pieces == null) ? false : dm_pieces[i].isDone();
            int iXPos = iCol * BLOCK_SIZE;
            int iYPos = iRow * BLOCK_SIZE;
            if (done) {
                if (peerHavePieces.flags[i])
                    colorIndex = BLOCKCOLOR_AVAIL_HAVE;
                else
                    colorIndex = BLOCKCOLOR_NOAVAIL_HAVE;
                gcImg.setBackground(blockColors[colorIndex]);
                gcImg.fillRectangle(iXPos, iYPos, BLOCK_FILLSIZE, BLOCK_FILLSIZE);
            } else {
                // !done
                boolean partiallyDone = (dm_pieces == null) ? false : dm_pieces[i].getNbWritten() > 0;
                int x = iXPos;
                int width = BLOCK_FILLSIZE;
                if (partiallyDone) {
                    if (peerHavePieces.flags[i])
                        colorIndex = BLOCKCOLOR_AVAIL_HAVE;
                    else
                        colorIndex = BLOCKCOLOR_NOAVAIL_HAVE;
                    gcImg.setBackground(blockColors[colorIndex]);
                    // partiallyDone false when dm_pieces null
                    @SuppressWarnings("null") int iNewWidth = (int) (((float) dm_pieces[i].getNbWritten() / dm_pieces[i].getNbBlocks()) * width);
                    if (iNewWidth >= width)
                        iNewWidth = width - 1;
                    else if (iNewWidth <= 0)
                        iNewWidth = 1;
                    gcImg.fillRectangle(x, iYPos, iNewWidth, BLOCK_FILLSIZE);
                    width -= iNewWidth;
                    x += iNewWidth;
                }
                if (peerHavePieces.flags[i])
                    colorIndex = BLOCKCOLOR_AVAIL_NOHAVE;
                else
                    colorIndex = BLOCKCOLOR_NOAVAIL_NOHAVE;
                gcImg.setBackground(blockColors[colorIndex]);
                gcImg.fillRectangle(x, iYPos, width, BLOCK_FILLSIZE);
            }
            // Down Arrow inside box for "dowloading" piece
            if (i == iDLPieceID) {
                gcImg.setBackground(blockColors[BLOCKCOLOR_TRANSFER]);
                gcImg.fillPolygon(new int[] { iXPos, iYPos, iXPos + BLOCK_FILLSIZE, iYPos, iXPos + (BLOCK_FILLSIZE / 2), iYPos + BLOCK_FILLSIZE });
            }
            // Small Down Arrow inside box for next download piece
            if (i == iNextDLPieceID) {
                gcImg.setBackground(blockColors[BLOCKCOLOR_NEXT]);
                gcImg.fillPolygon(new int[] { iXPos + 2, iYPos + 2, iXPos + BLOCK_FILLSIZE - 1, iYPos + 2, iXPos + (BLOCK_FILLSIZE / 2), iYPos + BLOCK_FILLSIZE - 1 });
            }
            // Up Arrow in uploading piece
            if (i == peerNextRequestedPiece) {
                gcImg.setBackground(blockColors[BLOCKCOLOR_TRANSFER]);
                gcImg.fillPolygon(new int[] { iXPos, iYPos + BLOCK_FILLSIZE, iXPos + BLOCK_FILLSIZE, iYPos + BLOCK_FILLSIZE, iXPos + (BLOCK_FILLSIZE / 2), iYPos });
            } else if (Arrays.binarySearch(peerRequestedPieces, i) >= 0) {
                // Small Up Arrow each upload request
                gcImg.setBackground(blockColors[BLOCKCOLOR_NEXT]);
                gcImg.fillPolygon(new int[] { iXPos + 1, iYPos + BLOCK_FILLSIZE - 2, iXPos + BLOCK_FILLSIZE - 2, iYPos + BLOCK_FILLSIZE - 2, iXPos + (BLOCK_FILLSIZE / 2), iYPos + 2 });
            }
            if (availability != null && availability[i] < 10) {
                gcImg.setFont(font);
                String sNumber = String.valueOf(availability[i]);
                Point size = gcImg.stringExtent(sNumber);
                int x = iXPos + (BLOCK_FILLSIZE / 2) - (size.x / 2);
                int y = iYPos + (BLOCK_FILLSIZE / 2) - (size.y / 2);
                gcImg.setForeground(blockColors[BLOCKCOLOR_AVAILCOUNT]);
                gcImg.drawText(sNumber, x, y, true);
            }
            iCol++;
            if (iCol >= iNumCols) {
                iCol = 0;
                iRow++;
            }
        }
    } catch (Exception e) {
        Logger.log(new LogEvent(LogIDs.GUI, "drawing piece map", e));
    } finally {
        gcImg.dispose();
    }
    peerInfoCanvas.redraw();
}
Also used : BitFlags(com.biglybt.core.peermanager.piecepicker.util.BitFlags) LogEvent(com.biglybt.core.logging.LogEvent) DiskManager(com.biglybt.core.disk.DiskManager) PEPeerManager(com.biglybt.core.peer.PEPeerManager) DiskManagerPiece(com.biglybt.core.disk.DiskManagerPiece)

Example 9 with BitFlags

use of com.biglybt.core.peermanager.piecepicker.util.BitFlags in project BiglyBT by BiglySoftware.

the class RemotePieceDistributionView method refresh.

@Override
public void refresh() {
    if (pem == null)
        return;
    if (peer instanceof PEPeerTransportProtocol) {
        PEPeerTransportProtocol pet = (PEPeerTransportProtocol) peer;
        BitFlags avl = pet.getAvailable();
        if (avl == null)
            hasPieces = null;
        else
            hasPieces = avl.flags;
    } else {
        if (peer.isSeed()) {
            hasPieces = new boolean[pem.getPieces().length];
            Arrays.fill(hasPieces, true);
        } else
            hasPieces = null;
    }
    super.refresh();
}
Also used : PEPeerTransportProtocol(com.biglybt.core.peer.impl.transport.PEPeerTransportProtocol) BitFlags(com.biglybt.core.peermanager.piecepicker.util.BitFlags)

Example 10 with BitFlags

use of com.biglybt.core.peermanager.piecepicker.util.BitFlags 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

BitFlags (com.biglybt.core.peermanager.piecepicker.util.BitFlags)16 PEPeer (com.biglybt.core.peer.PEPeer)4 LogEvent (com.biglybt.core.logging.LogEvent)3 PEPeerTransport (com.biglybt.core.peer.impl.PEPeerTransport)3 DiskManagerPiece (com.biglybt.core.disk.DiskManagerPiece)2 DMPieceList (com.biglybt.core.disk.impl.piecemapper.DMPieceList)2 PEPeerManager (com.biglybt.core.peer.PEPeerManager)2 DiskManager (com.biglybt.core.disk.DiskManager)1 NetworkAdminASN (com.biglybt.core.networkmanager.admin.NetworkAdminASN)1 NetworkAdminASNListener (com.biglybt.core.networkmanager.admin.NetworkAdminASNListener)1 NetworkAdminException (com.biglybt.core.networkmanager.admin.NetworkAdminException)1 PEPeerListener (com.biglybt.core.peer.PEPeerListener)1 PEPieceImpl (com.biglybt.core.peer.impl.PEPieceImpl)1 PEPeerTransportProtocol (com.biglybt.core.peer.impl.transport.PEPeerTransportProtocol)1 AERunnable (com.biglybt.core.util.AERunnable)1 BloomFilter (com.biglybt.core.util.bloom.BloomFilter)1 Graphic (com.biglybt.pif.ui.Graphic)1 UISWTGraphic (com.biglybt.ui.swt.pif.UISWTGraphic)1 UISWTGraphicImpl (com.biglybt.ui.swt.pifimpl.UISWTGraphicImpl)1 TableCellSWT (com.biglybt.ui.swt.views.table.TableCellSWT)1