summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorMasaya Suzuki <masayasuzuki@google.com>2019-03-19 20:42:10 -0700
committerMasaya Suzuki <masayasuzuki@google.com>2019-03-20 15:52:14 -0700
commit47e37b0fa4c91aa0fe3edfc298e93ddeed4c5473 (patch)
tree4ee15780ffd96c640c59df0bf615f8ef4a7499e2 /org.eclipse.jgit
parent40e74f8a1a8acdea1ce62b8fd841989d781b84bc (diff)
downloadjgit-47e37b0fa4c91aa0fe3edfc298e93ddeed4c5473.tar.gz
jgit-47e37b0fa4c91aa0fe3edfc298e93ddeed4c5473.zip
Use RefMap instead of HashMap
HashMap<String, Ref> has a memory overhead for refs. Use RefMap. Change-Id: I3fb4616135dacf687cc3bc2b473effc66ccef5e6 Signed-off-by: Masaya Suzuki <masayasuzuki@google.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java11
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java64
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java18
3 files changed, 87 insertions, 6 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index fe3e8141f4..dce06d3059 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -44,8 +44,7 @@
package org.eclipse.jgit.transport;
import static java.util.Collections.unmodifiableMap;
-import static java.util.function.Function.identity;
-import static java.util.stream.Collectors.toMap;
+import static org.eclipse.jgit.util.RefMap.toRefMap;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REF_IN_WANT;
import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_FETCH;
@@ -817,7 +816,7 @@ public class UploadPack {
// Fall back to all refs.
setAdvertisedRefs(
db.getRefDatabase().getRefs().stream()
- .collect(toMap(Ref::getName, identity())));
+ .collect(toRefMap((a, b) -> b)));
}
return refs;
}
@@ -836,7 +835,7 @@ public class UploadPack {
String[] prefixes = refPrefixes.toArray(new String[0]);
Map<String, Ref> rs =
db.getRefDatabase().getRefsByPrefix(prefixes).stream()
- .collect(toMap(Ref::getName, identity(), (a, b) -> b));
+ .collect(toRefMap((a, b) -> b));
if (refFilter != RefFilter.DEFAULT) {
return refFilter.filter(rs);
}
@@ -848,7 +847,7 @@ public class UploadPack {
return refs.values().stream()
.filter(ref -> refPrefixes.stream()
.anyMatch(ref.getName()::startsWith))
- .collect(toMap(Ref::getName, identity()));
+ .collect(toRefMap((a, b) -> b));
}
/**
@@ -871,7 +870,7 @@ public class UploadPack {
names.stream()
.map(refs::get)
.filter(Objects::nonNull)
- .collect(toMap(Ref::getName, identity(), (a, b) -> b)));
+ .collect(toRefMap((a, b) -> b)));
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
index 639c353621..60dead51b2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
@@ -48,7 +48,10 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.function.BinaryOperator;
+import java.util.stream.Collector;
+import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefComparator;
@@ -333,6 +336,32 @@ public class RefList<T extends Ref> implements Iterable<Ref> {
}
/**
+ * Create a {@link Collector} for {@link Ref}.
+ *
+ * @param mergeFunction
+ * if specified the result will be sorted and deduped.
+ * @return {@link Collector} for {@link Ref}
+ * @since 5.4
+ */
+ public static <T extends Ref> Collector<T, ?, RefList<T>> toRefList(
+ @Nullable BinaryOperator<T> mergeFunction) {
+ return Collector.of(
+ () -> new Builder<>(),
+ Builder<T>::add, (b1, b2) -> {
+ Builder<T> b = new Builder<>();
+ b.addAll(b1);
+ b.addAll(b2);
+ return b;
+ }, (b) -> {
+ if (mergeFunction != null) {
+ b.sort();
+ b.dedupe(mergeFunction);
+ }
+ return b.toRefList();
+ });
+ }
+
+ /**
* Builder to facilitate fast construction of an immutable RefList.
*
* @param <T>
@@ -405,6 +434,16 @@ public class RefList<T extends Ref> implements Iterable<Ref> {
}
/**
+ * Add all items from another builder.
+ *
+ * @param other
+ * @since 5.4
+ */
+ public void addAll(Builder other) {
+ addAll(other.list, 0, other.size);
+ }
+
+ /**
* Add all items from a source array.
* <p>
* References must be added in sort order, or the array must be sorted
@@ -444,6 +483,31 @@ public class RefList<T extends Ref> implements Iterable<Ref> {
Arrays.sort(list, 0, size, RefComparator.INSTANCE);
}
+ /**
+ * Dedupe the refs in place. Must be called after {@link #sort}.
+ *
+ * @param mergeFunction
+ */
+ @SuppressWarnings("unchecked")
+ void dedupe(BinaryOperator<T> mergeFunction) {
+ if (size == 0) {
+ return;
+ }
+ int lastElement = 0;
+ for (int i = 1; i < size; i++) {
+ if (RefComparator.INSTANCE.compare(list[lastElement],
+ list[i]) == 0) {
+ list[lastElement] = mergeFunction
+ .apply((T) list[lastElement], (T) list[i]);
+ } else {
+ list[lastElement + 1] = list[i];
+ lastElement++;
+ }
+ }
+ size = lastElement + 1;
+ Arrays.fill(list, size, list.length, null);
+ }
+
/** @return an unmodifiable list using this collection's backing array. */
public RefList<T> toRefList() {
return new RefList<>(list, size);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
index a3f9730f13..d7a4c2535a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
@@ -49,6 +49,9 @@ import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.function.BinaryOperator;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
@@ -285,6 +288,21 @@ public class RefMap extends AbstractMap<String, Ref> {
return r.toString();
}
+ /**
+ * Create a {@link Collector} for {@link Ref}.
+ *
+ * @param mergeFunction
+ * @return {@link Collector} for {@link Ref}
+ * @since 5.4
+ */
+ public static Collector<Ref, ?, RefMap> toRefMap(
+ BinaryOperator<Ref> mergeFunction) {
+ return Collectors.collectingAndThen(RefList.toRefList(mergeFunction),
+ (refs) -> new RefMap("", //$NON-NLS-1$
+ refs, RefList.emptyList(),
+ RefList.emptyList()));
+ }
+
private String toRefName(String name) {
if (0 < prefix.length())
name = prefix + name;