i2psnark: Stub out support for sequential download (ticket #2234)

This commit is contained in:
zzz
2018-07-12 11:19:56 +00:00
parent b78870de54
commit d34087f4d0
2 changed files with 66 additions and 24 deletions

View File

@ -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

View File

@ -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);
} }
} }