add option for sequential download

This commit is contained in:
Zlatin Balevsky
2019-10-03 20:45:22 +01:00
parent e09c456a13
commit 91d771944b
7 changed files with 34 additions and 13 deletions

View File

@@ -74,7 +74,7 @@ public class DownloadManager {
destinations.addAll(e.sources) destinations.addAll(e.sources)
destinations.remove(me.destination) destinations.remove(me.destination)
Pieces pieces = getPieces(infohash, size, pieceSize) Pieces pieces = getPieces(infohash, size, pieceSize, e.sequential)
def downloader = new Downloader(eventBus, this, me, e.target, size, def downloader = new Downloader(eventBus, this, me, e.target, size,
infohash, pieceSize, connector, destinations, infohash, pieceSize, connector, destinations,
@@ -123,7 +123,11 @@ public class DownloadManager {
infoHash = new InfoHash(root) infoHash = new InfoHash(root)
} }
Pieces pieces = getPieces(infoHash, (long)json.length, json.pieceSizePow2) boolean sequential = false
if (json.sequential != null)
sequential = json.sequential
Pieces pieces = getPieces(infoHash, (long)json.length, json.pieceSizePow2, sequential)
def downloader = new Downloader(eventBus, this, me, file, (long)json.length, def downloader = new Downloader(eventBus, this, me, file, (long)json.length,
infoHash, json.pieceSizePow2, connector, destinations, incompletes, pieces) infoHash, json.pieceSizePow2, connector, destinations, incompletes, pieces)
@@ -137,12 +141,12 @@ public class DownloadManager {
} }
} }
private Pieces getPieces(InfoHash infoHash, long length, int pieceSizePow2) { private Pieces getPieces(InfoHash infoHash, long length, int pieceSizePow2, boolean sequential) {
int pieceSize = 0x1 << pieceSizePow2 int pieceSize = 0x1 << pieceSizePow2
int nPieces = (int)(length / pieceSize) int nPieces = (int)(length / pieceSize)
if (length % pieceSize != 0) if (length % pieceSize != 0)
nPieces++ nPieces++
Mesh mesh = meshManager.getOrCreate(infoHash, nPieces) Mesh mesh = meshManager.getOrCreate(infoHash, nPieces, sequential)
mesh.pieces mesh.pieces
} }
@@ -188,6 +192,9 @@ public class DownloadManager {
json.hashRoot = Base64.encode(infoHash.getRoot()) json.hashRoot = Base64.encode(infoHash.getRoot())
json.paused = downloader.paused json.paused = downloader.paused
json.sequential = downloader.pieces.ratio == 0f
writer.println(JsonOutput.toJson(json)) writer.println(JsonOutput.toJson(json))
} }
} }

View File

@@ -30,7 +30,7 @@ class Pieces {
} }
// if fuller than ratio just do sequential // if fuller than ratio just do sequential
if ( (1.0f * claimedCardinality) / nPieces > ratio) { if ( (1.0f * claimedCardinality) / nPieces >= ratio) {
int rv = claimed.nextClearBit(0) int rv = claimed.nextClearBit(0)
claimed.set(rv) claimed.set(rv)
return [rv, partials.getOrDefault(rv, 0), 0] return [rv, partials.getOrDefault(rv, 0), 0]
@@ -59,7 +59,8 @@ class Pieces {
return [rv, partials.getOrDefault(rv, 0), 1] return [rv, partials.getOrDefault(rv, 0), 1]
} }
List<Integer> toList = availableCopy.toList() List<Integer> toList = availableCopy.toList()
Collections.shuffle(toList) if (ratio > 0f)
Collections.shuffle(toList)
int rv = toList[0] int rv = toList[0]
claimed.set(rv) claimed.set(rv)
[rv, partials.getOrDefault(rv, 0), 0] [rv, partials.getOrDefault(rv, 0), 0]

View File

@@ -10,4 +10,5 @@ class UIDownloadEvent extends Event {
UIResultEvent[] result UIResultEvent[] result
Set<Destination> sources Set<Destination> sources
File target File target
boolean sequential
} }

View File

@@ -33,11 +33,12 @@ class MeshManager {
meshes.get(infoHash) meshes.get(infoHash)
} }
Mesh getOrCreate(InfoHash infoHash, int nPieces) { Mesh getOrCreate(InfoHash infoHash, int nPieces, boolean sequential) {
synchronized(meshes) { synchronized(meshes) {
if (meshes.containsKey(infoHash)) if (meshes.containsKey(infoHash))
return meshes.get(infoHash) return meshes.get(infoHash)
Pieces pieces = new Pieces(nPieces, settings.downloadSequentialRatio) float ratio = sequential ? 0f : settings.downloadSequentialRatio
Pieces pieces = new Pieces(nPieces, ratio)
if (fileManager.rootToFiles.containsKey(infoHash)) { if (fileManager.rootToFiles.containsKey(infoHash)) {
for (int i = 0; i < nPieces; i++) for (int i = 0; i < nPieces; i++)
pieces.markDownloaded(i) pieces.markDownloaded(i)

View File

@@ -92,7 +92,7 @@ public class UploadManager {
pieceSize = downloader.pieceSizePow2 pieceSize = downloader.pieceSizePow2
} else { } else {
SharedFile sharedFile = sharedFiles.iterator().next(); SharedFile sharedFile = sharedFiles.iterator().next();
mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces) mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces, false)
file = sharedFile.file file = sharedFile.file
pieceSize = sharedFile.pieceSize pieceSize = sharedFile.pieceSize
} }
@@ -217,7 +217,7 @@ public class UploadManager {
pieceSize = downloader.pieceSizePow2 pieceSize = downloader.pieceSizePow2
} else { } else {
SharedFile sharedFile = sharedFiles.iterator().next(); SharedFile sharedFile = sharedFiles.iterator().next();
mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces) mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces, false)
file = sharedFile.file file = sharedFile.file
pieceSize = sharedFile.pieceSize pieceSize = sharedFile.pieceSize
} }

View File

@@ -46,7 +46,8 @@ class SearchTabController {
def resultsBucket = model.hashBucket[result.infohash] def resultsBucket = model.hashBucket[result.infohash]
def sources = model.sourcesBucket[result.infohash] def sources = model.sourcesBucket[result.infohash]
core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, sources: sources, target : file)) core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, sources: sources,
target : file, sequential : view.sequentialDownloadCheckbox.model.isSelected()))
mvcGroup.parentGroup.view.showDownloadsWindow.call() mvcGroup.parentGroup.view.showDownloadsWindow.call()
} }

View File

@@ -43,11 +43,13 @@ class SearchTabView {
def lastSendersSortEvent def lastSendersSortEvent
def resultsTable def resultsTable
def lastSortEvent def lastSortEvent
def sequentialDownloadCheckbox
void initUI() { void initUI() {
builder.with { builder.with {
def resultsTable def resultsTable
def sendersTable def sendersTable
def sequentialDownloadCheckbox
def pane = panel { def pane = panel {
gridLayout(rows :1, cols : 1) gridLayout(rows :1, cols : 1)
splitPane(orientation: JSplitPane.VERTICAL_SPLIT, continuousLayout : true, dividerLocation: 300 ) { splitPane(orientation: JSplitPane.VERTICAL_SPLIT, continuousLayout : true, dividerLocation: 300 ) {
@@ -83,7 +85,14 @@ class SearchTabView {
} }
} }
panel(constraints : BorderLayout.SOUTH) { panel(constraints : BorderLayout.SOUTH) {
button(text : "Download", enabled : bind {model.downloadActionEnabled}, downloadAction) borderLayout()
panel(constraints: BorderLayout.CENTER) {
button(text : "Download", enabled : bind {model.downloadActionEnabled}, downloadAction)
}
panel(constraints: BorderLayout.EAST) {
sequentialDownloadCheckbox = checkBox(selected : false)
label(text : "Download sequentially")
}
} }
} }
} }
@@ -95,6 +104,7 @@ class SearchTabView {
this.resultsTable = resultsTable this.resultsTable = resultsTable
this.sendersTable = sendersTable this.sendersTable = sendersTable
this.sequentialDownloadCheckbox = sequentialDownloadCheckbox
def selectionModel = resultsTable.getSelectionModel() def selectionModel = resultsTable.getSelectionModel()
selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)