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;
}
Aggregations