Skip to content

Commit

Permalink
Dry up custom immutable Map.Entry implementations (elastic#89153)
Browse files Browse the repository at this point in the history
Follow-up to elastic#88815.
No need to have two equivalent implementations here.
  • Loading branch information
original-brownbear authored Aug 8, 2022
1 parent ac25477 commit 2429dbc
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 63 deletions.
26 changes: 4 additions & 22 deletions server/src/main/java/org/elasticsearch/cluster/DiffableUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.util.Maps;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -153,7 +154,7 @@ private static <K, T, M extends Map<K, T>> MapDiff<K, T, M> createDiff(
inserts++;
} else if (entry.getValue().equals(previousValue) == false) {
if (valueSerializer.supportsDiffableValues()) {
diffs.add(mapEntry(entry.getKey(), valueSerializer.diff(entry.getValue(), previousValue)));
diffs.add(new Maps.ImmutableEntry<>(entry.getKey(), valueSerializer.diff(entry.getValue(), previousValue)));
} else {
upserts.add(entry);
}
Expand Down Expand Up @@ -307,14 +308,14 @@ private MapDiff(
for (int i = 0; i < diffsCount; i++) {
K key = keySerializer.readKey(in);
Diff<T> diff = valueSerializer.readDiff(in, key);
diffs.add(mapEntry(key, diff));
diffs.add(new Maps.ImmutableEntry<>(key, diff));
}
int upsertsCount = in.readVInt();
upserts = upsertsCount == 0 ? List.of() : new ArrayList<>(upsertsCount);
for (int i = 0; i < upsertsCount; i++) {
K key = keySerializer.readKey(in);
T newValue = valueSerializer.read(in, key);
upserts.add(mapEntry(key, newValue));
upserts.add(new Maps.ImmutableEntry<>(key, newValue));
}
this.builderCtor = builderCtor;
}
Expand Down Expand Up @@ -402,25 +403,6 @@ public void writeTo(StreamOutput out) throws IOException {
}
}

private static <K, T> Map.Entry<K, T> mapEntry(K key, T newValue) {
return new Map.Entry<>() {
@Override
public K getKey() {
return key;
}

@Override
public T getValue() {
return newValue;
}

@Override
public T setValue(T value) {
throw new UnsupportedOperationException();
}
};
}

/**
* Provides read and write operations to serialize keys of map
* @param <K> type of key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.carrotsearch.hppc.procedures.ObjectObjectProcedure;

import org.elasticsearch.common.util.Maps;

import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
Expand Down Expand Up @@ -127,45 +129,6 @@ public Set<Map.Entry<KType, VType>> entrySet() {
return (es = entrySet) == null ? (entrySet = new EntrySet<>(map)) : es;
}

private static final class ImmutableEntry<KType, VType> implements Map.Entry<KType, VType> {
private final KType key;
private final VType value;

ImmutableEntry(KType key, VType value) {
this.key = key;
this.value = value;
}

@Override
public KType getKey() {
return key;
}

@Override
public VType getValue() {
return value;
}

@Override
public VType setValue(VType value) {
throw new UnsupportedOperationException("collection is immutable");
}

@Override
@SuppressWarnings("rawtypes")
public boolean equals(Object o) {
if (this == o) return true;
if ((o instanceof Map.Entry) == false) return false;
Map.Entry that = (Map.Entry) o;
return Objects.equals(key, that.getKey()) && Objects.equals(value, that.getValue());
}

@Override
public int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
}

private static final class ConversionIterator<KType, VType> implements Iterator<Map.Entry<KType, VType>> {

private final Iterator<ObjectObjectCursor<KType, VType>> original;
Expand All @@ -185,7 +148,7 @@ public Map.Entry<KType, VType> next() {
if (obj == null) {
return null;
}
return new ImmutableEntry<>(obj.key, obj.value);
return new Maps.ImmutableEntry<>(obj.key, obj.value);
}

@Override
Expand Down Expand Up @@ -244,7 +207,7 @@ public Spliterator<Map.Entry<KType, VType>> spliterator() {
@Override
public void forEach(Consumer<? super Map.Entry<KType, VType>> action) {
map.forEach((Consumer<? super ObjectObjectCursor<KType, VType>>) ooCursor -> {
ImmutableEntry<KType, VType> entry = new ImmutableEntry<>(ooCursor.key, ooCursor.value);
Maps.ImmutableEntry<KType, VType> entry = new Maps.ImmutableEntry<>(ooCursor.key, ooCursor.value);
action.accept(entry);
});
}
Expand Down
37 changes: 37 additions & 0 deletions server/src/main/java/org/elasticsearch/common/util/Maps.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,41 @@ public static <K, V> Map<K, V> copyOf(Map<K, V> source, Function<V, V> copyValue
}
return copy;
}

/**
* An immutable implementation of {@link Map.Entry}.
* @param key key
* @param value value
*/
public record ImmutableEntry<KType, VType> (KType key, VType value) implements Map.Entry<KType, VType> {

@Override
public KType getKey() {
return key;
}

@Override
public VType getValue() {
return value;
}

@Override
public VType setValue(VType value) {
throw new UnsupportedOperationException();
}

@Override
@SuppressWarnings("rawtypes")
public boolean equals(Object o) {
if (this == o) return true;
if ((o instanceof Map.Entry) == false) return false;
Map.Entry that = (Map.Entry) o;
return Objects.equals(key, that.getKey()) && Objects.equals(value, that.getValue());
}

@Override
public int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
}
}

0 comments on commit 2429dbc

Please sign in to comment.