2025-09-03 11:48:45 +01:00
|
|
|
package moe.nekojimi.friendcloud;
|
|
|
|
|
|
|
|
import moe.nekojimi.friendcloud.objects.NetworkFile;
|
2025-09-17 12:16:15 +01:00
|
|
|
import moe.nekojimi.friendcloud.tasks.FileDownloadTask;
|
2025-09-03 11:48:45 +01:00
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
|
|
|
|
public class DownloadManager
|
|
|
|
{
|
|
|
|
private static DownloadManager instance = null;
|
|
|
|
public static DownloadManager getInstance()
|
|
|
|
{
|
|
|
|
if(instance == null)
|
|
|
|
instance = new DownloadManager();
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
private DownloadManager()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public Map<FileDownloadTask, CompletableFuture<Void>> activeDownloads = new HashMap<>();
|
|
|
|
|
|
|
|
public CompletableFuture<?> downloadPieces(NetworkFile file, SortedSet<Integer> pieces)
|
|
|
|
{
|
|
|
|
cullCompletedDownloads();
|
|
|
|
|
|
|
|
Set<CompletableFuture<Void>> tasksToWaitFor = new HashSet<>();
|
|
|
|
SortedSet<Integer> inactivePieces = new TreeSet<>(pieces);
|
|
|
|
for (Map.Entry<FileDownloadTask, CompletableFuture<Void>> e : activeDownloads.entrySet())
|
|
|
|
{
|
|
|
|
if (!Collections.disjoint(inactivePieces, e.getKey().getMissingPieceIndices()))
|
|
|
|
{
|
|
|
|
inactivePieces.removeAll(e.getKey().getMissingPieceIndices());
|
|
|
|
tasksToWaitFor.add(e.getValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!inactivePieces.isEmpty())
|
|
|
|
{
|
|
|
|
FileDownloadTask downloadTask = new FileDownloadTask(file, Main.getInstance().getConnectionManager(), pieces);
|
|
|
|
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(downloadTask,Main.getInstance().getExecutor());
|
|
|
|
activeDownloads.put(downloadTask,completableFuture);
|
|
|
|
return completableFuture;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CompletableFuture.allOf(tasksToWaitFor.toArray(new CompletableFuture[0]));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void cullCompletedDownloads()
|
|
|
|
{
|
|
|
|
Set<FileDownloadTask> toRemove = new HashSet<>();
|
|
|
|
for (Map.Entry<FileDownloadTask, CompletableFuture<Void>> e : activeDownloads.entrySet())
|
|
|
|
{
|
|
|
|
if (e.getValue().isDone())
|
|
|
|
toRemove.add(e.getKey());
|
|
|
|
}
|
|
|
|
for (FileDownloadTask t: toRemove)
|
|
|
|
activeDownloads.remove(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Map<FileDownloadTask, CompletableFuture<Void>> getActiveDownloads()
|
|
|
|
{
|
|
|
|
return Collections.unmodifiableMap(activeDownloads);
|
|
|
|
}
|
|
|
|
}
|