Multithreaded asset downloading, should be a lot quicker (#175)
* Multithreaded asset downloading, should be a lot quicker * Force the string width * Limit threads to max 10 and min 1 * Use ConcurrentLinkedDequedev/0.11
parent
daf922d928
commit
46b616af0f
|
@ -28,7 +28,12 @@ import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import org.gradle.api.GradleException;
|
import org.gradle.api.GradleException;
|
||||||
|
@ -76,8 +81,11 @@ public class MinecraftAssetsProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressLogger progressLogger = ProgressLogger.getProgressFactory(project, MinecraftAssetsProvider.class.getName());
|
project.getLogger().lifecycle(":downloading assets...");
|
||||||
progressLogger.start("Downloading assets...", "assets");
|
|
||||||
|
Deque<ProgressLogger> loggers = new ConcurrentLinkedDeque<>();
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(Math.min(10, Math.max(Runtime.getRuntime().availableProcessors() / 2, 1)));
|
||||||
|
|
||||||
AssetIndex index;
|
AssetIndex index;
|
||||||
|
|
||||||
try (FileReader fileReader = new FileReader(assetsInfo)) {
|
try (FileReader fileReader = new FileReader(assetsInfo)) {
|
||||||
|
@ -85,9 +93,6 @@ public class MinecraftAssetsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, AssetObject> parent = index.getFileMap();
|
Map<String, AssetObject> parent = index.getFileMap();
|
||||||
final int totalSize = parent.size();
|
|
||||||
int position = 0;
|
|
||||||
project.getLogger().lifecycle(":downloading assets...");
|
|
||||||
|
|
||||||
for (Map.Entry<String, AssetObject> entry : parent.entrySet()) {
|
for (Map.Entry<String, AssetObject> entry : parent.entrySet()) {
|
||||||
AssetObject object = entry.getValue();
|
AssetObject object = entry.getValue();
|
||||||
|
@ -103,9 +108,16 @@ public class MinecraftAssetsProvider {
|
||||||
throw new GradleException("Asset " + entry.getKey() + " not found at " + file.getAbsolutePath());
|
throw new GradleException("Asset " + entry.getKey() + " not found at " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
project.getLogger().debug(":downloading asset " + entry.getKey());
|
executor.execute(() -> {
|
||||||
DownloadUtil.downloadIfChanged(new URL(Constants.RESOURCES_BASE + sha1.substring(0, 2) + "/" + sha1), file, project.getLogger(), true);
|
ProgressLogger progressLogger;
|
||||||
}
|
|
||||||
|
if (loggers.isEmpty()) {
|
||||||
|
//Create a new logger if we need one
|
||||||
|
progressLogger = ProgressLogger.getProgressFactory(project, MinecraftAssetsProvider.class.getName());
|
||||||
|
progressLogger.start("Downloading assets...", "assets");
|
||||||
|
} else {
|
||||||
|
// use a free logger if we can
|
||||||
|
progressLogger = loggers.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
String assetName = entry.getKey();
|
String assetName = entry.getKey();
|
||||||
|
@ -115,10 +127,33 @@ public class MinecraftAssetsProvider {
|
||||||
assetName = assetName.substring(end);
|
assetName = assetName.substring(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
progressLogger.progress(assetName + " - " + position + "/" + totalSize + " (" + (int) ((position / (double) totalSize) * 100) + "%) assets downloaded");
|
project.getLogger().debug(":downloading asset " + assetName);
|
||||||
position++;
|
progressLogger.progress(String.format("%-30.30s", assetName) + " - " + sha1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DownloadUtil.downloadIfChanged(new URL(Constants.RESOURCES_BASE + sha1.substring(0, 2) + "/" + sha1), file, project.getLogger(), true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to download: " + assetName, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
progressLogger.completed();
|
//Give this logger back
|
||||||
|
loggers.add(progressLogger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wait for the assets to all download
|
||||||
|
executor.shutdown();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (executor.awaitTermination(2, TimeUnit.HOURS)) {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
loggers.forEach(ProgressLogger::completed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue