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>
This commit is contained in:
parent
40e74f8a1a
commit
47e37b0fa4
|
@ -127,6 +127,41 @@ public void testBuilder_AddThenSort() {
|
|||
assertSame(REF_B, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_AddThenDedupe() {
|
||||
RefList.Builder<Ref> builder = new RefList.Builder<>(1);
|
||||
builder.add(REF_B);
|
||||
builder.add(REF_A);
|
||||
builder.add(REF_A);
|
||||
builder.add(REF_B);
|
||||
builder.add(REF_c);
|
||||
|
||||
builder.sort();
|
||||
builder.dedupe((a, b) -> b);
|
||||
RefList<Ref> list = builder.toRefList();
|
||||
|
||||
assertEquals(3, list.size());
|
||||
assertSame(REF_A, list.get(0));
|
||||
assertSame(REF_B, list.get(1));
|
||||
assertSame(REF_c, list.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_AddThenDedupe_Border() {
|
||||
RefList.Builder<Ref> builder = new RefList.Builder<>(1);
|
||||
builder.sort();
|
||||
builder.dedupe((a, b) -> b);
|
||||
RefList<Ref> list = builder.toRefList();
|
||||
assertTrue(list.isEmpty());
|
||||
|
||||
builder = new RefList.Builder<>(1);
|
||||
builder.add(REF_A);
|
||||
builder.sort();
|
||||
builder.dedupe((a, b) -> b);
|
||||
list = builder.toRefList();
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_AddAll() {
|
||||
RefList.Builder<Ref> builder = new RefList.Builder<>(1);
|
||||
|
|
|
@ -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 @@ private Map<String, Ref> getAdvertisedOrDefaultRefs() throws IOException {
|
|||
// 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 @@ private Map<String, Ref> getFilteredRefs(Collection<String> refPrefixes)
|
|||
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 @@ private Map<String, Ref> getFilteredRefs(Collection<String> refPrefixes)
|
|||
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 @@ private static Map<String, Ref> mapRefs(
|
|||
names.stream()
|
||||
.map(refs::get)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toMap(Ref::getName, identity(), (a, b) -> b)));
|
||||
.collect(toRefMap((a, b) -> b)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,7 +48,10 @@
|
|||
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;
|
||||
|
||||
|
@ -332,6 +335,32 @@ public String toString() {
|
|||
return r.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -404,6 +433,16 @@ public void add(T ref) {
|
|||
list[size++] = 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>
|
||||
|
@ -444,6 +483,31 @@ public void sort() {
|
|||
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);
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
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 String toString() {
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue