use of com.biglybt.core.disk.DiskManager in project BiglyBT by BiglySoftware.
the class DiskManagerRandomReadController method executeRequest.
private void executeRequest() {
DiskManagerRandomReadRequestImpl request;
synchronized (requests) {
if (requests.isEmpty()) {
return;
}
request = requests.remove(0);
}
if (request.isCancelled()) {
return;
}
DiskManagerFileInfoListener info_listener = null;
com.biglybt.core.disk.DiskManagerFileInfo core_file = request.getFile().getCore();
DownloadManager core_download = core_file.getDownloadManager();
int prev_hint_piece = -1;
int curr_hint_piece = -1;
try {
if (core_download.getTorrent() == null) {
throw (new DownloadException("Torrent invalid"));
}
if (core_download.isDestroyed()) {
Debug.out("Download has been removed");
throw (new DownloadException("Download has been removed"));
}
TOTorrentFile tf = core_file.getTorrentFile();
TOTorrent torrent = tf.getTorrent();
TOTorrentFile[] tfs = torrent.getFiles();
long core_file_start_byte = 0;
for (int i = 0; i < core_file.getIndex(); i++) {
core_file_start_byte += tfs[i].getLength();
}
long download_byte_start = core_file_start_byte + request.getOffset();
long download_byte_end = download_byte_start + request.getLength();
int piece_size = (int) tf.getTorrent().getPieceLength();
if (core_file.getDownloaded() != core_file.getLength()) {
if (core_file.isSkipped()) {
core_file.setSkipped(false);
}
boolean force_start = download.isForceStart();
if (!force_start) {
download.setForceStart(true);
set_force_start = true;
final AESemaphore running_sem = new AESemaphore("rs");
DownloadListener dl_listener = new DownloadListener() {
@Override
public void stateChanged(Download download, int old_state, int new_state) {
if (new_state == Download.ST_DOWNLOADING || new_state == Download.ST_SEEDING) {
running_sem.release();
}
}
@Override
public void positionChanged(Download download, int oldPosition, int newPosition) {
}
};
download.addListener(dl_listener);
try {
if (download.getState() != Download.ST_DOWNLOADING && download.getState() != Download.ST_SEEDING) {
if (!running_sem.reserve(10 * 1000)) {
throw (new DownloadException("timeout waiting for download to start"));
}
}
} finally {
download.removeListener(dl_listener);
}
}
}
boolean is_reverse = request.isReverse();
final AESemaphore wait_sem = new AESemaphore("rr:waiter");
info_listener = new DiskManagerFileInfoListener() {
@Override
public void dataWritten(long offset, long length) {
wait_sem.release();
}
@Override
public void dataChecked(long offset, long length) {
}
};
long start_time = SystemTime.getMonotonousTime();
boolean has_started = false;
core_file.addListener(info_listener);
while (download_byte_start < download_byte_end) {
if (request.isCancelled()) {
throw (new Exception("request cancelled"));
}
// System.out.println( "Request current: " + download_byte_start + " -> " + download_byte_end );
long now = SystemTime.getMonotonousTime();
int piece_start = (int) (download_byte_start / piece_size);
int piece_start_offset = (int) (download_byte_start % piece_size);
int piece_end = (int) ((download_byte_end - 1) / piece_size);
int piece_end_offset = (int) ((download_byte_end - 1) % piece_size) + 1;
// System.out.println( " piece details: " + piece_start + "/" + piece_start_offset + " -> " + piece_end + "/" + piece_end_offset );
DiskManagerPiece[] pieces = null;
DiskManager disk_manager = core_download.getDiskManager();
if (disk_manager != null) {
pieces = disk_manager.getPieces();
}
long avail_start;
long avail_end;
if (pieces == null) {
if (core_file.getDownloaded() == core_file.getLength()) {
avail_start = download_byte_start;
avail_end = download_byte_end;
} else {
if (now - start_time < 10000 && !has_started) {
wait_sem.reserve(250);
continue;
}
throw (new Exception("download stopped"));
}
} else {
has_started = true;
if (is_reverse) {
long min_done = download_byte_end;
for (int i = piece_end; i >= piece_start; i--) {
int p_start = i == piece_start ? piece_start_offset : 0;
int p_end = i == piece_end ? piece_end_offset : piece_size;
DiskManagerPiece piece = pieces[i];
boolean[] done = piece.getWritten();
if (done == null) {
if (piece.isDone()) {
min_done = i * (long) piece_size;
continue;
} else {
break;
}
}
int block_size = piece.getBlockSize(0);
int first_block = p_start / block_size;
int last_block = (p_end - 1) / block_size;
for (int j = last_block; j >= first_block; j--) {
if (done[j]) {
min_done = i * (long) piece_size + j * block_size;
} else {
break;
}
}
}
avail_start = Math.max(download_byte_start, min_done);
avail_end = download_byte_end;
} else {
long max_done = download_byte_start;
for (int i = piece_start; i <= piece_end; i++) {
int p_start = i == piece_start ? piece_start_offset : 0;
int p_end = i == piece_end ? piece_end_offset : piece_size;
DiskManagerPiece piece = pieces[i];
boolean[] done = piece.getWritten();
if (done == null) {
if (piece.isDone()) {
max_done = (i + 1) * (long) piece_size;
continue;
} else {
break;
}
}
int block_size = piece.getBlockSize(0);
int first_block = p_start / block_size;
int last_block = (p_end - 1) / block_size;
for (int j = first_block; j <= last_block; j++) {
if (done[j]) {
max_done = i * (long) piece_size + (j + 1) * block_size;
} else {
break;
}
}
}
avail_start = download_byte_start;
avail_end = Math.min(download_byte_end, max_done);
}
}
// System.out.println( " avail: " + avail_start + " -> " + avail_end );
int max_chunk = 128 * 1024;
if (avail_end > avail_start) {
long length = avail_end - avail_start;
if (length > max_chunk) {
if (is_reverse) {
avail_start = avail_end - max_chunk;
} else {
avail_end = avail_start + max_chunk;
}
}
// System.out.println( "got data: " + avail_start + " -> " + avail_end );
long read_offset = avail_start - core_file_start_byte;
int read_length = (int) (avail_end - avail_start);
DirectByteBuffer buffer = core_file.read(read_offset, read_length);
request.dataAvailable(buffer, read_offset, read_length);
if (is_reverse) {
download_byte_end = avail_start;
} else {
download_byte_start = avail_end;
}
continue;
}
PEPeerManager pm = core_download.getPeerManager();
if (pm == null) {
if (now - start_time < 10000 && !has_started) {
wait_sem.reserve(250);
continue;
}
throw (new Exception("download stopped"));
} else {
has_started = true;
}
PiecePicker picker = pm.getPiecePicker();
picker.setReverseBlockOrder(is_reverse);
int hint_piece;
int hint_offset;
int hint_length;
if (piece_start == piece_end) {
hint_piece = piece_start;
hint_offset = piece_start_offset;
hint_length = piece_end_offset - piece_start_offset;
} else {
if (is_reverse) {
hint_piece = piece_end;
hint_offset = 0;
hint_length = piece_end_offset;
} else {
hint_piece = piece_start;
hint_offset = piece_start_offset;
hint_length = piece_size - piece_start_offset;
}
}
if (curr_hint_piece == -1) {
int[] existing = picker.getGlobalRequestHint();
if (existing != null) {
curr_hint_piece = existing[0];
}
}
// System.out.println( "hint: " + hint_piece + "/" + hint_offset + "/" + hint_length + ": curr=" + curr_hint_piece + ", prev=" + prev_hint_piece );
picker.setGlobalRequestHint(hint_piece, hint_offset, hint_length);
if (hint_piece != curr_hint_piece) {
prev_hint_piece = curr_hint_piece;
curr_hint_piece = hint_piece;
}
if (prev_hint_piece != -1) {
clearHint(pm, prev_hint_piece);
}
wait_sem.reserve(250);
}
} catch (Throwable e) {
request.failed(e);
} finally {
PEPeerManager pm = core_download.getPeerManager();
if (pm != null) {
PiecePicker picker = pm.getPiecePicker();
if (picker != null) {
picker.setReverseBlockOrder(false);
picker.setGlobalRequestHint(-1, 0, 0);
if (curr_hint_piece != -1) {
clearHint(pm, curr_hint_piece);
}
}
}
if (info_listener != null) {
core_file.removeListener(info_listener);
}
}
}
use of com.biglybt.core.disk.DiskManager in project BiglyBT by BiglySoftware.
the class GeneralView method refresh.
public void refresh() {
if (gFile == null || gFile.isDisposed() || manager == null)
return;
loopFactor++;
if ((loopFactor % graphicsUpdate) == 0) {
updateAvailability();
availabilityImage.redraw();
updatePiecesInfo(false);
piecesImage.redraw();
}
DiskManager dm = manager.getDiskManager();
String remaining;
String eta = DisplayFormatters.formatETA(manager.getStats().getSmoothedETA());
if (dm != null) {
long rem = dm.getRemainingExcludingDND();
String data_rem = DisplayFormatters.formatByteCountToKiBEtc(rem);
if (rem > 0) {
remaining = eta + (eta.length() == 0 ? "" : " ") + data_rem;
} else {
if (eta.length() == 0) {
remaining = data_rem;
} else {
remaining = eta;
}
}
} else {
// only got eta value, just use that
remaining = eta;
}
setTime(manager.getStats().getElapsedTime(), remaining);
TRTrackerScraperResponse hd = manager.getTrackerScrapeResponse();
String seeds_str = manager.getNbSeeds() + " " + MessageText.getString("GeneralView.label.connected");
String peers_str = manager.getNbPeers() + " " + MessageText.getString("GeneralView.label.connected");
String completed;
if (hd != null && hd.isValid()) {
seeds_str += " ( " + hd.getSeeds() + " " + MessageText.getString("GeneralView.label.in_swarm") + " )";
peers_str += " ( " + hd.getPeers() + " " + MessageText.getString("GeneralView.label.in_swarm") + " )";
completed = hd.getCompleted() > -1 ? Integer.toString(hd.getCompleted()) : "?";
} else {
completed = "?";
}
String _shareRatio = "";
int sr = manager.getStats().getShareRatio();
if (sr == -1)
_shareRatio = Constants.INFINITY_STRING;
if (sr > 0) {
String partial = "" + sr % 1000;
while (partial.length() < 3) partial = "0" + partial;
_shareRatio = (sr / 1000) + "." + partial;
}
DownloadManagerStats stats = manager.getStats();
String swarm_speed = DisplayFormatters.formatByteCountToKiBEtcPerSec(stats.getTotalAverage()) + " ( " + DisplayFormatters.formatByteCountToKiBEtcPerSec(stats.getTotalAveragePerPeer()) + " " + MessageText.getString("GeneralView.label.averagespeed") + " )";
String swarm_completion = "";
String distributedCopies = "0.000";
String piecesDoneAndSum = "" + manager.getNbPieces();
PEPeerManager pm = manager.getPeerManager();
if (pm != null) {
int comp = pm.getAverageCompletionInThousandNotation();
if (comp >= 0) {
swarm_completion = DisplayFormatters.formatPercentFromThousands(comp);
}
piecesDoneAndSum = pm.getPiecePicker().getNbPiecesDone() + "/" + piecesDoneAndSum;
distributedCopies = new DecimalFormat("0.000").format(pm.getPiecePicker().getMinAvailability() - pm.getNbSeeds() - (pm.isSeeding() && stats.getDownloadCompleted(false) == 1000 ? 1 : 0));
}
int kInB = DisplayFormatters.getKinB();
setStats(DisplayFormatters.formatDownloaded(stats), DisplayFormatters.formatByteCountToKiBEtc(stats.getTotalDataBytesSent()), DisplayFormatters.formatByteCountToKiBEtcPerSec(stats.getDataReceiveRate()), DisplayFormatters.formatByteCountToKiBEtcPerSec(stats.getDataSendRate()), swarm_speed, "" + manager.getStats().getDownloadRateLimitBytesPerSecond() / kInB, "" + (manager.getStats().getUploadRateLimitBytesPerSecond() / kInB), seeds_str, peers_str, completed, DisplayFormatters.formatHashFails(manager), _shareRatio, swarm_completion, distributedCopies);
TOTorrent torrent = manager.getTorrent();
String creation_date = DisplayFormatters.formatDate(manager.getTorrentCreationDate() * 1000);
byte[] created_by = torrent == null ? null : torrent.getCreatedBy();
if (created_by != null) {
try {
creation_date = MessageText.getString("GeneralView.torrent_created_on_and_by", new String[] { creation_date, new String(created_by, Constants.DEFAULT_ENCODING) });
} catch (java.io.UnsupportedEncodingException e) {
/* forget it */
}
}
setInfos(manager.getDisplayName(), DisplayFormatters.formatByteCountToKiBEtc(manager.getSize()), DisplayFormatters.formatDownloadStatus(manager), manager.getState() == DownloadManager.STATE_ERROR, manager.getSaveLocation().toString(), TorrentUtils.nicePrintTorrentHash(torrent), piecesDoneAndSum, manager.getPieceLength(), manager.getTorrentComment(), creation_date, manager.getDownloadState().getUserComment(), MessageText.getString("GeneralView." + (torrent != null && torrent.getPrivate() ? "yes" : "no")));
// the initial layout fails.
if (loopFactor == 2) {
getComposite().layout(true);
}
}
use of com.biglybt.core.disk.DiskManager in project BiglyBT by BiglySoftware.
the class DownloadManagerImpl method downloadEnded.
/**
* Is called when a download is finished.
* Activates alerts for the user.
*
* @param never_downloaded true indicates that we never actually downloaded
* anything in this session, but we determined that
* the download is complete (usually via
* startDownload())
*
* @author Rene Leonhardt
*/
protected void downloadEnded(boolean never_downloaded) {
if (!never_downloaded) {
if (!COConfigurationManager.getBooleanParameter("StartStopManager_bRetainForceStartWhenComplete")) {
if (isForceStart()) {
setForceStart(false);
}
}
setAssumedComplete(true);
informDownloadEnded();
}
TRTrackerAnnouncer tc = tracker_client;
if (tc != null) {
DiskManager dm = getDiskManager();
if (dm != null && dm.getRemaining() == 0 && !COConfigurationManager.getBooleanParameter("peercontrol.hide.piece")) {
tc.complete(never_downloaded);
}
}
}
use of com.biglybt.core.disk.DiskManager in project BiglyBT by BiglySoftware.
the class DownloadManagerImpl method saveDownload.
@Override
public void saveDownload() {
DiskManager disk_manager = controller.getDiskManager();
if (disk_manager != null) {
disk_manager.saveState();
}
download_manager_state.save();
}
use of com.biglybt.core.disk.DiskManager in project BiglyBT by BiglySoftware.
the class DownloadManagerImpl method destroy.
@Override
public void destroy(boolean is_duplicate) {
destroyed = true;
if (is_duplicate) {
// minimal tear-down
controller.destroy();
} else {
try {
// Data files don't exist, so we just don't do anything.
if (!getSaveLocation().exists()) {
return;
}
DiskManager dm = this.getDiskManager();
if (dm != null) {
dm.downloadRemoved();
return;
}
SaveLocationChange move_details;
move_details = DownloadManagerMoveHandler.onRemoval(this);
if (move_details == null) {
return;
}
boolean can_move_torrent = move_details.hasTorrentChange();
try {
if (move_details.hasDownloadChange()) {
this.moveDataFiles(move_details.download_location, move_details.download_name);
}
} catch (Exception e) {
can_move_torrent = false;
Logger.log(new LogAlert(this, true, "Problem moving files to removed download directory", e));
}
// This code will silently fail if the torrent file doesn't exist.
if (can_move_torrent) {
try {
this.moveTorrentFile(move_details.torrent_location, move_details.torrent_name);
} catch (Exception e) {
Logger.log(new LogAlert(this, true, "Problem moving torrent to removed download directory", e));
}
}
} finally {
clearFileLinks();
controller.destroy();
}
}
}
Aggregations