Search in sources :

Example 1 with DMPieceMap

use of com.biglybt.core.disk.impl.piecemapper.DMPieceMap in project BiglyBT by BiglySoftware.

the class PiecePickerImpl method computeBasePriorities.

/**
 * This computes the base priority for all pieces that need requesting if there's
 * been any availability change or user priority setting changes since the last
 * call, which will be most of the time since availability changes so dynamicaly
 * It will change startPriorities[] (unless there was nothing to do)
 */
private void computeBasePriorities() {
    final long now = SystemTime.getCurrentTime();
    if (now < lastProviderRecalcTime || now - lastProviderRecalcTime > 1000) {
        lastProviderRecalcTime = now;
        priorityRTAexists = computeProviderPriorities();
    }
    if (!priorityRTAexists) {
        if (startPriorities != null && ((now > timeLastPriorities && now < timeLastPriorities + TIME_MIN_PRIORITIES) || (priorityParamChange >= paramPriorityChange && priorityFileChange >= filePriorityChange && priorityAvailChange >= availabilityChange))) {
            // *somehow* nothing changed, so nothing to do
            return;
        }
    }
    // store the latest change indicators before we start making dependent calculations so that a
    // further change while computing stuff doesn't get lost
    timeLastPriorities = now;
    priorityParamChange = paramPriorityChange;
    priorityFileChange = filePriorityChange;
    priorityAvailChange = availabilityChange;
    boolean foundPieceToDownload = false;
    final int[] newPriorities = new int[nbPieces];
    // locals are a tiny bit faster
    final boolean firstPiecePriorityL = firstPiecePriority;
    final boolean completionPriorityL = completionPriority;
    final DMPieceMap pieceMap = diskManager.getPieceMap();
    CopyOnWriteSet<Integer> forced = forced_pieces;
    try {
        final boolean rarestOverride = calcRarestAllowed() < 1;
        // calculate all base (starting) priorities for all pieces needing requesting
        final int nbConnects = peerControl.getNbPeers() + peerControl.getNbSeeds();
        for (int i = 0; i < nbPieces; i++) {
            final DiskManagerPiece dmPiece = dmPieces[i];
            if (dmPiece.isDone()) {
                if (forced != null && forced.contains(i)) {
                    if (forced.remove(i) && forced.size() == 0) {
                        synchronized (this) {
                            if (forced_pieces != null && forced_pieces.size() == 0) {
                                forced_pieces = null;
                            }
                        }
                    }
                }
                // nothing to do for pieces not needing requesting
                continue;
            }
            int startPriority = Integer.MIN_VALUE;
            final DMPieceList pieceList = pieceMap.getPieceList(dmPiece.getPieceNumber());
            final int pieceListSize = pieceList.size();
            for (int j = 0; j < pieceListSize; j++) {
                final DiskManagerFileInfoImpl fileInfo = pieceList.get(j).getFile();
                final long downloaded = fileInfo.getDownloaded();
                final long length = fileInfo.getLength();
                if (length > 0 && downloaded < length && !fileInfo.isSkipped()) {
                    int priority = 0;
                    // user option "prioritize first and last piece"
                    // TODO: should prioritize ~10% from edges of file
                    boolean hasFirstLastPriority = false;
                    if (firstPiecePriorityL && fileInfo.getNbPieces() > FIRST_PIECE_MIN_NB) {
                        if (i == fileInfo.getFirstPieceNumber() || i == fileInfo.getLastPieceNumber()) {
                            hasFirstLastPriority = true;
                        }
                    }
                    // if the file is high-priority
                    // startPriority +=(1000 *fileInfo.getPriority()) /255;
                    int file_priority = fileInfo.getPriority();
                    int max = Math.max(file_priority, max_file_priority);
                    int min = Math.min(file_priority, min_file_priority);
                    int range = max - min;
                    if (range > 0) {
                        int relative_file_priority = file_priority - min;
                        priority += PRIORITY_W_FILE_BASE;
                        int adjustment;
                        if (hasFirstLastPriority) {
                            // one less than the next higher priority file
                            adjustment = ((PRIORITY_W_FILE_RANGE * (relative_file_priority + 1)) / range) - 1;
                        } else {
                            adjustment = (PRIORITY_W_FILE_RANGE * relative_file_priority) / range;
                        }
                        priority += adjustment;
                    } else {
                        if (hasFirstLastPriority) {
                            priority += PRIORITY_W_FIRSTLAST;
                        }
                    }
                    if (completionPriorityL) {
                        final long percent = (1000 * downloaded) / length;
                        if (percent >= 900) {
                            priority += (PRIORITY_W_COMPLETION * downloaded) / diskManager.getTotalLength();
                        }
                    }
                    if (priority > startPriority) {
                        startPriority = priority;
                    }
                }
            }
            if (startPriority >= 0) {
                dmPiece.setNeeded();
                foundPieceToDownload = true;
                final int avail = availability[i];
                // nbconnects is async calculate so may be wrong - make sure we don't decrease pri by accident
                if (avail > 0 && nbConnects > avail) {
                    // boost priority for rarity
                    startPriority += nbConnects - avail;
                    // Boost priority even a little more if it's a globally rarest piece
                    if (!rarestOverride && avail <= globalMinOthers)
                        startPriority += nbConnects / avail;
                }
                if (provider_piece_rtas != null) {
                    if (provider_piece_rtas[i] > 0) {
                        startPriority = PRIORITY_REALTIME;
                    }
                } else if (provider_piece_priorities != null) {
                    startPriority += provider_piece_priorities[i];
                } else if (forced != null && forced.contains(i)) {
                    startPriority = PRIORITY_FORCED;
                }
            } else {
                dmPiece.clearNeeded();
            }
            newPriorities[i] = startPriority;
        }
    } catch (Throwable e) {
        Debug.printStackTrace(e);
    }
    if (sequentialDownload != 0 && !priorityRTAexists) {
        int seq_pri = PRIORITY_SEQUENTIAL_START;
        boolean do_file_priorities = min_file_priority != max_file_priority;
        int file_priority_start = nbPieces * 10;
        int loop_start;
        int loop_end;
        int loop_dir;
        if (sequentialDownload > 0) {
            loop_start = nbPieces;
            loop_end = sequentialDownload - 1;
            loop_dir = -1;
        } else {
            loop_start = -1;
            loop_end = -(sequentialDownload + 1);
            loop_dir = +1;
        }
        int loop_pos = loop_start;
        do {
            loop_pos += loop_dir;
            int priority = newPriorities[loop_pos];
            if (priority == Integer.MIN_VALUE) {
                continue;
            }
            if (priority != PRIORITY_FORCED) {
                if (do_file_priorities) {
                    final DiskManagerPiece dmPiece = dmPieces[loop_pos];
                    int highest = Integer.MIN_VALUE;
                    final DMPieceList pieceList = pieceMap.getPieceList(dmPiece.getPieceNumber());
                    final int pieceListSize = pieceList.size();
                    for (int j = 0; j < pieceListSize; j++) {
                        final DiskManagerFileInfoImpl fileInfo = pieceList.get(j).getFile();
                        final long downloaded = fileInfo.getDownloaded();
                        final long length = fileInfo.getLength();
                        if (length > 0 && downloaded < length && !fileInfo.isSkipped()) {
                            highest = Math.max(highest, fileInfo.getPriority());
                        }
                    }
                    if (highest == Integer.MIN_VALUE) {
                        newPriorities[loop_pos] = seq_pri;
                    } else {
                        int rel = highest - min_file_priority;
                        newPriorities[loop_pos] = file_priority_start + nbPieces * rel + seq_pri;
                    }
                } else {
                    newPriorities[loop_pos] = seq_pri;
                }
            }
            seq_pri += 10;
        } while (loop_pos != loop_end);
    }
    if (foundPieceToDownload != hasNeededUndonePiece) {
        hasNeededUndonePiece = foundPieceToDownload;
        neededUndonePieceChange++;
    }
    startPriorities = newPriorities;
}
Also used : DMPieceMap(com.biglybt.core.disk.impl.piecemapper.DMPieceMap) DiskManagerFileInfoImpl(com.biglybt.core.disk.impl.DiskManagerFileInfoImpl) DMPieceList(com.biglybt.core.disk.impl.piecemapper.DMPieceList)

Aggregations

DiskManagerFileInfoImpl (com.biglybt.core.disk.impl.DiskManagerFileInfoImpl)1 DMPieceList (com.biglybt.core.disk.impl.piecemapper.DMPieceList)1 DMPieceMap (com.biglybt.core.disk.impl.piecemapper.DMPieceMap)1