Skip to content

Commit

Permalink
更新调度器
Browse files Browse the repository at this point in the history
  • Loading branch information
weikaiyun committed Dec 2, 2020
1 parent f06a959 commit 5361b67
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 11 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
import com.android.build.api.transform.TransformInput;
import com.android.build.api.transform.TransformOutputProvider;
import com.android.build.gradle.internal.pipeline.TransformManager;
import com.android.ide.common.internal.WaitableExecutor;
import com.quinn.hunter.transform.asm.BaseWeaver;
import com.quinn.hunter.transform.asm.ClassLoaderHelper;
import com.quinn.hunter.transform.concurrent.Schedulers;
import com.quinn.hunter.transform.concurrent.Worker;

import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
Expand Down Expand Up @@ -42,15 +43,15 @@ public class HunterTransform extends Transform {
SCOPES.add(QualifiedContent.Scope.EXTERNAL_LIBRARIES);
}

private Project project;
private final Project project;
protected BaseWeaver bytecodeWeaver;
private WaitableExecutor waitableExecutor;
private final Worker worker;
private boolean emptyRun = false;

public HunterTransform(Project project){
this.project = project;
this.logger = project.getLogger();
this.waitableExecutor = WaitableExecutor.useGlobalSharedThreadPool();
this.worker = Schedulers.IO();
}

@Override
Expand Down Expand Up @@ -171,13 +172,13 @@ public void transform(Context context,

}

waitableExecutor.waitForTasksWithQuickFail(true);
worker.await();
long costTime = System.currentTimeMillis() - startTime;
logger.warn((getName() + " costed " + costTime + "ms"));
}

private void transformSingleFile(final File inputFile, final File outputFile, final String srcBaseDir) {
waitableExecutor.execute(() -> {
worker.submit(() -> {
bytecodeWeaver.weaveSingleClassToFile(inputFile, outputFile, srcBaseDir);
return null;
});
Expand All @@ -192,7 +193,7 @@ private void transformDir(final File inputDir, final File outputDir) throws IOEx
final String outputDirPath = outputDir.getAbsolutePath();
if (inputDir.isDirectory()) {
for (final File file : com.android.utils.FileUtils.getAllFiles(inputDir)) {
waitableExecutor.execute(() -> {
worker.submit(() -> {
String filePath = file.getAbsolutePath();
File outputFile = new File(filePath.replace(inputDirPath, outputDirPath));
bytecodeWeaver.weaveSingleClassToFile(file, outputFile, inputDirPath);
Expand All @@ -203,7 +204,7 @@ private void transformDir(final File inputDir, final File outputDir) throws IOEx
}

private void transformJar(final File srcJar, final File destJar, Status status) {
waitableExecutor.execute(() -> {
worker.submit(() -> {
if(emptyRun) {
FileUtils.copyFile(srcJar, destJar);
return null;
Expand All @@ -214,7 +215,7 @@ private void transformJar(final File srcJar, final File destJar, Status status)
}

private void cleanDexBuilderFolder(File dest) {
waitableExecutor.execute(() -> {
worker.submit(() -> {
try {
String dexBuilderDir = replaceLastPart(dest.getAbsolutePath(), getName(), "dexBuilder");
//intermediates/transforms/dexBuilder/debug
Expand All @@ -233,7 +234,7 @@ private void cleanDexBuilderFolder(File dest) {
private String replaceLastPart(String originString, String replacement, String toreplace) {
int start = originString.lastIndexOf(replacement);
StringBuilder builder = new StringBuilder();
builder.append(originString.substring(0, start));
builder.append(originString, 0, start);
builder.append(toreplace);
builder.append(originString.substring(start + replacement.length()));
return builder.toString();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.quinn.hunter.transform.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Schedulers {
private static final int cpuCount = Runtime.getRuntime().availableProcessors();
private final static ExecutorService IO = new ThreadPoolExecutor(0, cpuCount * 3,
30L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());

private static final ExecutorService COMPUTATION = Executors.newWorkStealingPool(cpuCount);

public static Worker IO() {
return new Worker(IO);
}

public static Worker COMPUTATION() {
return new Worker(COMPUTATION);
}

public static ForkJoinPool FORKJOINPOOL() {
return (ForkJoinPool) COMPUTATION;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.quinn.hunter.transform.concurrent;

import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.function.Consumer;

public class Worker {
protected final LinkedList<Future<?>> futures = new LinkedList<Future<?>>() {
@Override
public synchronized boolean add(Future<?> future) {
return super.add(future);
}

@Override
public synchronized Future<?> pollFirst() {
return super.pollFirst();
}
};
protected ExecutorService executor;

Worker(ExecutorService executor) {
this.executor = executor;
}

public void execute(Runnable runnable) {
futures.add(executor.submit(runnable));
}

public <T> Future<T> submit(Callable<T> callable) {
Future<T> future = executor.submit(callable);
futures.add(future);
return future;
}

public void await() throws IOException {
Future<?> future;
while ((future = futures.pollFirst()) != null) {
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
if (e.getCause() instanceof IOException) {
throw (IOException) e.getCause();
} else if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
} else if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
throw new RuntimeException(e.getCause());
}
}
}

public <I> void submitAndAwait(Collection<I> is, Consumer<I> consumer) throws IOException {
is.stream().map(f -> (Runnable) () -> consumer.accept(f)).forEach(this::execute);
await();
}
}

0 comments on commit 5361b67

Please sign in to comment.