gerrit: a bad implementation of parallel object finding
This commit is contained in:
parent
23dd318e67
commit
1d7704d247
|
@ -47,6 +47,8 @@ in
|
||||||
|
|
||||||
./gerrit-cl-431977-bump-sshd.patch
|
./gerrit-cl-431977-bump-sshd.patch
|
||||||
./gerrit-cl-431977-part-2-bump-bouncycastle.patch
|
./gerrit-cl-431977-part-2-bump-bouncycastle.patch
|
||||||
|
|
||||||
|
./jgit-parallel-object-counting.patch
|
||||||
];
|
];
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
62
gerrit/jgit-parallel-object-counting.patch
Normal file
62
gerrit/jgit-parallel-object-counting.patch
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
diff --git a/modules/jgit/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java b/modules/jgit/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
|
||||||
|
index 01f514b93..c9888657a 100644
|
||||||
|
--- a/modules/jgit/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
|
||||||
|
+++ b/modules/jgit/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
+import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.zip.DataFormatException;
|
||||||
|
import java.util.zip.Inflater;
|
||||||
|
|
||||||
|
@@ -166,10 +167,49 @@ public LocalObjectToPack newObjectToPack(AnyObjectId objectId, int type) {
|
||||||
|
return new LocalObjectToPack(objectId, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Above this number of objects, perform this counting in parallel. */
|
||||||
|
+ private static final int OBJECTS_TO_MULTITHREAD = 10_000;
|
||||||
|
+
|
||||||
|
@Override
|
||||||
|
public void selectObjectRepresentation(PackWriter packer,
|
||||||
|
ProgressMonitor monitor, Iterable<ObjectToPack> objects)
|
||||||
|
throws IOException, MissingObjectException {
|
||||||
|
+ if (objects instanceof Collection<ObjectToPack>) {
|
||||||
|
+ // If it isn't a collection, we can't tell how many objects there are.
|
||||||
|
+ Collection<ObjectToPack> sizedObjects = (Collection<ObjectToPack>)objects;
|
||||||
|
+ if (sizedObjects.size() >= OBJECTS_TO_MULTITHREAD) {
|
||||||
|
+ // Where we're going, we don't need single-threaded.
|
||||||
|
+ AtomicInteger counter = new AtomicInteger();
|
||||||
|
+ try {
|
||||||
|
+ sizedObjects.parallelStream()
|
||||||
|
+ .forEach(otp -> {
|
||||||
|
+ try {
|
||||||
|
+ // TODO: maybe creating a new WindowCursor each time is expensive?
|
||||||
|
+ db.selectObjectRepresentation(packer, otp, new WindowCursor(db));
|
||||||
|
+ } catch (IOException e) {
|
||||||
|
+ throw new RuntimeException(e);
|
||||||
|
+ }
|
||||||
|
+ if (counter.incrementAndGet() >= OBJECTS_TO_MULTITHREAD) {
|
||||||
|
+ int rem = counter.getAndSet(0);
|
||||||
|
+ if (rem >= OBJECTS_TO_MULTITHREAD) {
|
||||||
|
+ synchronized (monitor) {
|
||||||
|
+ monitor.update(rem);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ counter.addAndGet(rem);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ monitor.update(counter.get());
|
||||||
|
+ } catch (RuntimeException e) {
|
||||||
|
+ if (e.getCause() != null && e.getCause() instanceof IOException) throw (IOException)e.getCause();
|
||||||
|
+ throw e;
|
||||||
|
+ }
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Otherwise, single-threaded mode.
|
||||||
|
for (ObjectToPack otp : objects) {
|
||||||
|
db.selectObjectRepresentation(packer, otp, this);
|
||||||
|
monitor.update(1);
|
Loading…
Reference in a new issue