diff options
author | Masaya Suzuki <masayasuzuki@google.com> | 2019-03-19 20:42:10 -0700 |
---|---|---|
committer | Masaya Suzuki <masayasuzuki@google.com> | 2019-03-20 15:52:14 -0700 |
commit | 47e37b0fa4c91aa0fe3edfc298e93ddeed4c5473 (patch) | |
tree | 4ee15780ffd96c640c59df0bf615f8ef4a7499e2 /org.eclipse.jgit | |
parent | 40e74f8a1a8acdea1ce62b8fd841989d781b84bc (diff) | |
download | jgit-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')
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; |