forked from I2P_Developers/i2p.i2p
i2psnark: Stub out support for sequential download (ticket #2234)
This commit is contained in:
@ -105,6 +105,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
private static final String PROP_META_UPLOADED = "uploaded";
|
private static final String PROP_META_UPLOADED = "uploaded";
|
||||||
private static final String PROP_META_ADDED = "added";
|
private static final String PROP_META_ADDED = "added";
|
||||||
private static final String PROP_META_COMPLETED = "completed";
|
private static final String PROP_META_COMPLETED = "completed";
|
||||||
|
private static final String PROP_META_INORDER = "inOrder";
|
||||||
private static final String PROP_META_MAGNET = "magnet";
|
private static final String PROP_META_MAGNET = "magnet";
|
||||||
private static final String PROP_META_MAGNET_DN = "magnet_dn";
|
private static final String PROP_META_MAGNET_DN = "magnet_dn";
|
||||||
private static final String PROP_META_MAGNET_TR = "magnet_tr";
|
private static final String PROP_META_MAGNET_TR = "magnet_tr";
|
||||||
@ -1759,7 +1760,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
addMessage(_t("Torrent with this info hash is already running: {0}", snark.getBaseName()));
|
addMessage(_t("Torrent with this info hash is already running: {0}", snark.getBaseName()));
|
||||||
return false;
|
return false;
|
||||||
} else if (bitfield != null) {
|
} else if (bitfield != null) {
|
||||||
saveTorrentStatus(metainfo, bitfield, null, baseFile, true, 0, true); // no file priorities
|
saveTorrentStatus(metainfo, bitfield, null, false, baseFile, true, 0, true); // no file priorities
|
||||||
}
|
}
|
||||||
// so addTorrent won't recheck
|
// so addTorrent won't recheck
|
||||||
if (filename == null) {
|
if (filename == null) {
|
||||||
@ -1898,19 +1899,21 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
return;
|
return;
|
||||||
Properties config = getConfig(snark);
|
Properties config = getConfig(snark);
|
||||||
String pri = config.getProperty(PROP_META_PRIORITY);
|
String pri = config.getProperty(PROP_META_PRIORITY);
|
||||||
if (pri == null)
|
if (pri != null) {
|
||||||
return;
|
int filecount = metainfo.getFiles().size();
|
||||||
int filecount = metainfo.getFiles().size();
|
int[] rv = new int[filecount];
|
||||||
int[] rv = new int[filecount];
|
String[] arr = DataHelper.split(pri, ",");
|
||||||
String[] arr = DataHelper.split(pri, ",");
|
for (int i = 0; i < filecount && i < arr.length; i++) {
|
||||||
for (int i = 0; i < filecount && i < arr.length; i++) {
|
if (arr[i].length() > 0) {
|
||||||
if (arr[i].length() > 0) {
|
try {
|
||||||
try {
|
rv[i] = Integer.parseInt(arr[i]);
|
||||||
rv[i] = Integer.parseInt(arr[i]);
|
} catch (Throwable t) {}
|
||||||
} catch (Throwable t) {}
|
}
|
||||||
}
|
}
|
||||||
|
storage.setFilePriorities(rv);
|
||||||
}
|
}
|
||||||
storage.setFilePriorities(rv);
|
boolean inOrder = Boolean.parseBoolean(config.getProperty(PROP_META_INORDER));
|
||||||
|
storage.setInOrder(inOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2017,7 +2020,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
Storage storage = snark.getStorage();
|
Storage storage = snark.getStorage();
|
||||||
if (meta == null || storage == null)
|
if (meta == null || storage == null)
|
||||||
return;
|
return;
|
||||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), storage.getInOrder(),
|
||||||
storage.getBase(), storage.getPreserveFileNames(),
|
storage.getBase(), storage.getPreserveFileNames(),
|
||||||
snark.getUploaded(), snark.isStopped(), comments);
|
snark.getUploaded(), snark.isStopped(), comments);
|
||||||
}
|
}
|
||||||
@ -2034,24 +2037,24 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
* @param priorities may be null
|
* @param priorities may be null
|
||||||
* @param base may be null
|
* @param base may be null
|
||||||
*/
|
*/
|
||||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
|
||||||
File base, boolean preserveNames, long uploaded, boolean stopped) {
|
File base, boolean preserveNames, long uploaded, boolean stopped) {
|
||||||
saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, null);
|
saveTorrentStatus(metainfo, bitfield, priorities, inOrder, base, preserveNames, uploaded, stopped, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param comments null for no change
|
* @param comments null for no change
|
||||||
* @since 0.9.31
|
* @since 0.9.31
|
||||||
*/
|
*/
|
||||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
|
||||||
File base, boolean preserveNames, long uploaded, boolean stopped,
|
File base, boolean preserveNames, long uploaded, boolean stopped,
|
||||||
Boolean comments) {
|
Boolean comments) {
|
||||||
synchronized (_configLock) {
|
synchronized (_configLock) {
|
||||||
locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, comments);
|
locked_saveTorrentStatus(metainfo, bitfield, priorities, inOrder, base, preserveNames, uploaded, stopped, comments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
|
||||||
File base, boolean preserveNames, long uploaded, boolean stopped,
|
File base, boolean preserveNames, long uploaded, boolean stopped,
|
||||||
Boolean comments) {
|
Boolean comments) {
|
||||||
byte[] ih = metainfo.getInfoHash();
|
byte[] ih = metainfo.getInfoHash();
|
||||||
@ -2077,6 +2080,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
config.setProperty(PROP_META_UPLOADED, Long.toString(uploaded));
|
config.setProperty(PROP_META_UPLOADED, Long.toString(uploaded));
|
||||||
boolean running = !stopped;
|
boolean running = !stopped;
|
||||||
config.setProperty(PROP_META_RUNNING, Boolean.toString(running));
|
config.setProperty(PROP_META_RUNNING, Boolean.toString(running));
|
||||||
|
config.setProperty(PROP_META_INORDER, Boolean.toString(inOrder));
|
||||||
if (base != null)
|
if (base != null)
|
||||||
config.setProperty(PROP_META_BASE, base.getAbsolutePath());
|
config.setProperty(PROP_META_BASE, base.getAbsolutePath());
|
||||||
if (comments != null)
|
if (comments != null)
|
||||||
@ -2095,7 +2099,9 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
// generate string like -5,,4,3,,,,,,-2 where no number is zero.
|
// generate string like -5,,4,3,,,,,,-2 where no number is zero.
|
||||||
StringBuilder buf = new StringBuilder(2 * priorities.length);
|
StringBuilder buf = new StringBuilder(2 * priorities.length);
|
||||||
for (int i = 0; i < priorities.length; i++) {
|
for (int i = 0; i < priorities.length; i++) {
|
||||||
if (priorities[i] != 0)
|
// only output if !inOrder || !skipped so the string isn't too long
|
||||||
|
if (priorities[i] != 0 &&
|
||||||
|
(!inOrder || priorities[i] < 0))
|
||||||
buf.append(Integer.toString(priorities[i]));
|
buf.append(Integer.toString(priorities[i]));
|
||||||
if (i != priorities.length - 1)
|
if (i != priorities.length - 1)
|
||||||
buf.append(',');
|
buf.append(',');
|
||||||
@ -2443,7 +2449,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
MetaInfo meta = snark.getMetaInfo();
|
MetaInfo meta = snark.getMetaInfo();
|
||||||
Storage storage = snark.getStorage();
|
Storage storage = snark.getStorage();
|
||||||
if (meta != null && storage != null)
|
if (meta != null && storage != null)
|
||||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), storage.getInOrder(),
|
||||||
storage.getBase(), storage.getPreserveFileNames(), snark.getUploaded(),
|
storage.getBase(), storage.getPreserveFileNames(), snark.getUploaded(),
|
||||||
snark.isStopped());
|
snark.isStopped());
|
||||||
}
|
}
|
||||||
@ -2467,7 +2473,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
snark.stopTorrent();
|
snark.stopTorrent();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
saveTorrentStatus(meta, storage.getBitField(), null,
|
saveTorrentStatus(meta, storage.getBitField(), null, false,
|
||||||
storage.getBase(), storage.getPreserveFileNames(), 0,
|
storage.getBase(), storage.getPreserveFileNames(), 0,
|
||||||
snark.isStopped());
|
snark.isStopped());
|
||||||
// temp for addMessage() in case canonical throws
|
// temp for addMessage() in case canonical throws
|
||||||
|
@ -72,6 +72,7 @@ public class Storage implements Closeable
|
|||||||
private final boolean _preserveFileNames;
|
private final boolean _preserveFileNames;
|
||||||
private boolean changed;
|
private boolean changed;
|
||||||
private volatile boolean _isChecking;
|
private volatile boolean _isChecking;
|
||||||
|
private boolean _inOrder;
|
||||||
private final AtomicInteger _allocateCount = new AtomicInteger();
|
private final AtomicInteger _allocateCount = new AtomicInteger();
|
||||||
private final AtomicInteger _checkProgress = new AtomicInteger();
|
private final AtomicInteger _checkProgress = new AtomicInteger();
|
||||||
|
|
||||||
@ -82,6 +83,8 @@ public class Storage implements Closeable
|
|||||||
/** The maximum number of pieces in a torrent. */
|
/** The maximum number of pieces in a torrent. */
|
||||||
public static final int MAX_PIECES = 32*1024;
|
public static final int MAX_PIECES = 32*1024;
|
||||||
public static final long MAX_TOTAL_SIZE = MAX_PIECE_SIZE * (long) MAX_PIECES;
|
public static final long MAX_TOTAL_SIZE = MAX_PIECE_SIZE * (long) MAX_PIECES;
|
||||||
|
public static final int PRIORITY_SKIP = -9;
|
||||||
|
public static final int PRIORITY_NORMAL = 0;
|
||||||
|
|
||||||
private static final Map<String, String> _filterNameCache = new ConcurrentHashMap<String, String>();
|
private static final Map<String, String> _filterNameCache = new ConcurrentHashMap<String, String>();
|
||||||
|
|
||||||
@ -145,7 +148,7 @@ public class Storage implements Closeable
|
|||||||
_torrentFiles = getFiles(baseFile);
|
_torrentFiles = getFiles(baseFile);
|
||||||
|
|
||||||
long total = 0;
|
long total = 0;
|
||||||
ArrayList<Long> lengthsList = new ArrayList<Long>();
|
ArrayList<Long> lengthsList = new ArrayList<Long>(_torrentFiles.size());
|
||||||
for (TorrentFile tf : _torrentFiles)
|
for (TorrentFile tf : _torrentFiles)
|
||||||
{
|
{
|
||||||
long length = tf.length;
|
long length = tf.length;
|
||||||
@ -178,7 +181,7 @@ public class Storage implements Closeable
|
|||||||
bitfield = new BitField(pieces);
|
bitfield = new BitField(pieces);
|
||||||
needed = 0;
|
needed = 0;
|
||||||
|
|
||||||
List<List<String>> files = new ArrayList<List<String>>();
|
List<List<String>> files = new ArrayList<List<String>>(_torrentFiles.size());
|
||||||
for (TorrentFile tf : _torrentFiles)
|
for (TorrentFile tf : _torrentFiles)
|
||||||
{
|
{
|
||||||
List<String> file = new ArrayList<String>();
|
List<String> file = new ArrayList<String>();
|
||||||
@ -494,6 +497,38 @@ public class Storage implements Closeable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return as last set, default false
|
||||||
|
* @since 0.9.36
|
||||||
|
*/
|
||||||
|
public boolean getInOrder() {
|
||||||
|
return _inOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call AFTER setFilePriorites() so we know what's skipped
|
||||||
|
* @param yes enable or not
|
||||||
|
* @since 0.9.36
|
||||||
|
*/
|
||||||
|
public void setInOrder(boolean yes) {
|
||||||
|
if (yes == _inOrder)
|
||||||
|
return;
|
||||||
|
_inOrder = yes;
|
||||||
|
if (complete() || metainfo.getFiles() == null)
|
||||||
|
return;
|
||||||
|
if (yes) {
|
||||||
|
int sz = _torrentFiles.size();
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
_torrentFiles.get(i).priority = sz - i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (TorrentFile tf : _torrentFiles) {
|
||||||
|
if (tf.priority > PRIORITY_NORMAL)
|
||||||
|
tf.priority = PRIORITY_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call setPriority() for all changed files first,
|
* Call setPriority() for all changed files first,
|
||||||
* then call this.
|
* then call this.
|
||||||
@ -513,6 +548,7 @@ public class Storage implements Closeable
|
|||||||
for (int i = 0; i < rv.length; i++) {
|
for (int i = 0; i < rv.length; i++) {
|
||||||
pcEnd += piece_size;
|
pcEnd += piece_size;
|
||||||
int pri = _torrentFiles.get(file).priority;
|
int pri = _torrentFiles.get(file).priority;
|
||||||
|
// TODO if (_inOrder) ...
|
||||||
while (fileEnd <= pcEnd && file < _torrentFiles.size() - 1) {
|
while (fileEnd <= pcEnd && file < _torrentFiles.size() - 1) {
|
||||||
file++;
|
file++;
|
||||||
TorrentFile tf = _torrentFiles.get(file);
|
TorrentFile tf = _torrentFiles.get(file);
|
||||||
@ -544,7 +580,7 @@ public class Storage implements Closeable
|
|||||||
long rv = 0;
|
long rv = 0;
|
||||||
final int end = pri.length - 1;
|
final int end = pri.length - 1;
|
||||||
for (int i = 0; i <= end; i++) {
|
for (int i = 0; i <= end; i++) {
|
||||||
if (pri[i] <= -9 && !bitfield.get(i)) {
|
if (pri[i] <= PRIORITY_SKIP && !bitfield.get(i)) {
|
||||||
rv += (i != end) ? piece_size : metainfo.getPieceLength(i);
|
rv += (i != end) ? piece_size : metainfo.getPieceLength(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user