This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-fury.git
The following commit(s) were added to refs/heads/main by this push:
new a87b9025 refactor(java): Remove Guava's Collection usages (#1611)
a87b9025 is described below
commit a87b90252dfb84f8bc48924fcf7f6d2e6a8da6fa
Author: Nikita Ivchenko <[email protected]>
AuthorDate: Wed May 8 17:21:57 2024 +0300
refactor(java): Remove Guava's Collection usages (#1611)
## What does this PR do?
Remove Guava's Collection usages
## Related issues
<!--
Is there any related issue? Please attach here.
- #xxxx0
- #xxxx1
- #xxxx2
-->
#1113
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/incubator-fury/issues/new/choose)
describing the need to do so and update the document if necessary.
-->
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
Lazy map become slightly more lazy =)
<!--
When the PR has an impact on performance (if you don't know whether the
PR will have an impact on performance, you can submit the PR first, and
if it will have impact on performance, the code reviewer will explain
it), be sure to attach a benchmark data here.
-->
---
.../fury/builder/BaseObjectCodecBuilder.java | 15 +-
.../apache/fury/builder/ObjectCodecBuilder.java | 75 ++++---
.../org/apache/fury/codegen/CodegenContext.java | 4 +-
.../java/org/apache/fury/collection/LazyMap.java | 217 +++++++++++++++++++--
.../collection/ChildContainerSerializers.java | 7 +-
5 files changed, 261 insertions(+), 57 deletions(-)
diff --git
a/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
b/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
index 5cce3228..34bb51ba 100644
---
a/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
+++
b/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
@@ -48,7 +48,6 @@ import static org.apache.fury.type.TypeUtils.isBoxed;
import static org.apache.fury.type.TypeUtils.isPrimitive;
import static org.apache.fury.util.Preconditions.checkArgument;
-import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -450,11 +449,7 @@ public abstract class BaseObjectCodecBuilder extends
CodecBuilder {
buffer,
inputObject));
return invokeGenerated(
- ctx,
- ImmutableSet.of(buffer, inputObject),
- writeClassAndObject,
- "writeClassAndObject",
- false);
+ ctx, ofHashSet(buffer, inputObject), writeClassAndObject,
"writeClassAndObject", false);
}
/**
@@ -666,7 +661,7 @@ public abstract class BaseObjectCodecBuilder extends
CodecBuilder {
serializer =
invokeGenerated(
ctx,
- ImmutableSet.of(buffer, collection),
+ ofHashSet(buffer, collection),
writeClassAction,
"writeCollectionClassInfo",
false);
@@ -685,7 +680,7 @@ public abstract class BaseObjectCodecBuilder extends
CodecBuilder {
actions.add(write);
if (generateNewMethod) {
return invokeGenerated(
- ctx, ImmutableSet.of(buffer, collection, serializer), actions,
"writeCollection", false);
+ ctx, ofHashSet(buffer, collection, serializer), actions,
"writeCollection", false);
}
return actions;
}
@@ -970,7 +965,7 @@ public abstract class BaseObjectCodecBuilder extends
CodecBuilder {
// Spit this into a separate method to avoid method too big to inline.
serializer =
invokeGenerated(
- ctx, ImmutableSet.of(buffer, map), writeClassAction,
"writeMapClassInfo", false);
+ ctx, ofHashSet(buffer, map), writeClassAction,
"writeMapClassInfo", false);
}
} else if
(!AbstractMapSerializer.class.isAssignableFrom(serializer.type().getRawType()))
{
serializer = new Cast(serializer,
TypeRef.of(AbstractMapSerializer.class), "mapSerializer");
@@ -981,7 +976,7 @@ public abstract class BaseObjectCodecBuilder extends
CodecBuilder {
jitWriteMap(buffer, map, serializer, typeRef),
new Invoke(serializer, "write", buffer, map));
if (generateNewMethod) {
- return invokeGenerated(ctx, ImmutableSet.of(buffer, map), write,
"writeMap", false);
+ return invokeGenerated(ctx, ofHashSet(buffer, map), write, "writeMap",
false);
}
return write;
}
diff --git
a/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java
b/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java
index 2e2df420..d1d8bc57 100644
---
a/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java
+++
b/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java
@@ -22,6 +22,7 @@ package org.apache.fury.builder;
import static org.apache.fury.codegen.Code.LiteralValue.FalseLiteral;
import static org.apache.fury.codegen.Expression.Invoke.inlineInvoke;
import static org.apache.fury.codegen.ExpressionUtils.add;
+import static org.apache.fury.collection.Collections.ofHashSet;
import static org.apache.fury.type.TypeUtils.OBJECT_ARRAY_TYPE;
import static org.apache.fury.type.TypeUtils.OBJECT_TYPE;
import static org.apache.fury.type.TypeUtils.PRIMITIVE_BYTE_ARRAY_TYPE;
@@ -32,8 +33,6 @@ import static org.apache.fury.type.TypeUtils.getRawType;
import static org.apache.fury.type.TypeUtils.getSizeOfPrimitiveType;
import static org.apache.fury.type.TypeUtils.isPrimitive;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -162,17 +161,12 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
}
expressions.addAll(serializePrimitives(bean, buffer,
objectCodecOptimizer.primitiveGroups));
int numGroups = getNumGroups(objectCodecOptimizer);
- for (List<Descriptor> group :
- Iterables.concat(
- objectCodecOptimizer.boxedWriteGroups,
- objectCodecOptimizer.finalWriteGroups,
- objectCodecOptimizer.otherWriteGroups)) {
- if (group.isEmpty()) {
- continue;
- }
- boolean inline = group.size() == 1 && numGroups < 10;
- expressions.add(serializeGroup(group, bean, buffer, inline));
- }
+ addGroupExpressions(
+ objectCodecOptimizer.boxedWriteGroups, numGroups, expressions, bean,
buffer);
+ addGroupExpressions(
+ objectCodecOptimizer.finalWriteGroups, numGroups, expressions, bean,
buffer);
+ addGroupExpressions(
+ objectCodecOptimizer.otherWriteGroups, numGroups, expressions, bean,
buffer);
for (Descriptor descriptor :
objectCodecOptimizer.descriptorGrouper.getCollectionDescriptors()) {
expressions.add(serializeGroup(Collections.singletonList(descriptor),
bean, buffer, false));
@@ -183,6 +177,21 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
return expressions;
}
+ private void addGroupExpressions(
+ List<List<Descriptor>> writeGroup,
+ int numGroups,
+ ListExpression expressions,
+ Expression bean,
+ Reference buffer) {
+ for (List<Descriptor> group : writeGroup) {
+ if (group.isEmpty()) {
+ continue;
+ }
+ boolean inline = group.size() == 1 && numGroups < 10;
+ expressions.add(serializeGroup(group, bean, buffer, inline));
+ }
+ }
+
private int getNumGroups(ObjectCodecOptimizer objectCodecOptimizer) {
return objectCodecOptimizer.boxedWriteGroups.size()
+ objectCodecOptimizer.finalWriteGroups.size()
@@ -291,7 +300,7 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
} else {
expressions.add(
objectCodecOptimizer.invokeGenerated(
- ImmutableSet.of(bean, base, writerAddr), groupExpressions,
"writeFields"));
+ ofHashSet(bean, base, writerAddr), groupExpressions,
"writeFields"));
}
}
Expression increaseWriterIndex =
@@ -397,7 +406,7 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
} else {
expressions.add(
objectCodecOptimizer.invokeGenerated(
- ImmutableSet.of(bean, buffer, base), groupExpressions,
"writeFields"));
+ ofHashSet(bean, buffer, base), groupExpressions,
"writeFields"));
}
}
return expressions;
@@ -445,17 +454,12 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
}
expressions.addAll(deserializePrimitives(bean, buffer,
objectCodecOptimizer.primitiveGroups));
int numGroups = getNumGroups(objectCodecOptimizer);
- for (List<Descriptor> group :
- Iterables.concat(
- objectCodecOptimizer.boxedReadGroups,
- objectCodecOptimizer.finalReadGroups,
- objectCodecOptimizer.otherReadGroups)) {
- if (group.isEmpty()) {
- continue;
- }
- boolean inline = group.size() == 1 && numGroups < 10;
- expressions.add(deserializeGroup(group, bean, buffer, inline));
- }
+ deserializeReadGroup(
+ objectCodecOptimizer.boxedReadGroups, numGroups, expressions, bean,
buffer);
+ deserializeReadGroup(
+ objectCodecOptimizer.finalReadGroups, numGroups, expressions, bean,
buffer);
+ deserializeReadGroup(
+ objectCodecOptimizer.otherReadGroups, numGroups, expressions, bean,
buffer);
for (Descriptor d :
objectCodecOptimizer.descriptorGrouper.getCollectionDescriptors()) {
expressions.add(deserializeGroup(Collections.singletonList(d), bean,
buffer, false));
}
@@ -481,6 +485,21 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
return expressions;
}
+ private void deserializeReadGroup(
+ List<List<Descriptor>> readGroups,
+ int numGroups,
+ ListExpression expressions,
+ Expression bean,
+ Reference buffer) {
+ for (List<Descriptor> group : readGroups) {
+ if (group.isEmpty()) {
+ continue;
+ }
+ boolean inline = group.size() == 1 && numGroups < 10;
+ expressions.add(deserializeGroup(group, bean, buffer, inline));
+ }
+ }
+
protected Expression buildComponentsArray() {
return new StaticInvoke(
Platform.class, "copyObjectArray", OBJECT_ARRAY_TYPE,
recordComponentDefaultValues);
@@ -653,7 +672,7 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
} else {
expressions.add(
objectCodecOptimizer.invokeGenerated(
- ImmutableSet.of(bean, heapBuffer, readerAddr),
groupExpressions, "readFields"));
+ ofHashSet(bean, heapBuffer, readerAddr), groupExpressions,
"readFields"));
}
}
Expression increaseReaderIndex =
@@ -742,7 +761,7 @@ public class ObjectCodecBuilder extends
BaseObjectCodecBuilder {
} else {
expressions.add(
objectCodecOptimizer.invokeGenerated(
- ImmutableSet.of(bean, buffer, heapBuffer), groupExpressions,
"readFields"));
+ ofHashSet(bean, buffer, heapBuffer), groupExpressions,
"readFields"));
}
}
return expressions;
diff --git
a/java/fury-core/src/main/java/org/apache/fury/codegen/CodegenContext.java
b/java/fury-core/src/main/java/org/apache/fury/codegen/CodegenContext.java
index d60fb6a7..624e55e9 100644
--- a/java/fury-core/src/main/java/org/apache/fury/codegen/CodegenContext.java
+++ b/java/fury-core/src/main/java/org/apache/fury/codegen/CodegenContext.java
@@ -19,13 +19,13 @@
package org.apache.fury.codegen;
+import static java.util.Collections.unmodifiableSet;
import static org.apache.fury.codegen.Code.ExprCode;
import static org.apache.fury.codegen.CodeGenerator.alignIndent;
import static org.apache.fury.codegen.CodeGenerator.indent;
import static org.apache.fury.type.TypeUtils.getArrayType;
import static org.apache.fury.type.TypeUtils.getRawType;
-import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -114,7 +114,7 @@ public class CodegenContext {
"true",
"false",
"null"));
- JAVA_RESERVED_WORDS = ImmutableSet.copyOf(JAVA_RESERVED_WORDS);
+ JAVA_RESERVED_WORDS = unmodifiableSet(JAVA_RESERVED_WORDS);
}
private static Map<String, Map<String, Boolean>> nameConflicts = new
ConcurrentHashMap<>();
diff --git
a/java/fury-core/src/main/java/org/apache/fury/collection/LazyMap.java
b/java/fury-core/src/main/java/org/apache/fury/collection/LazyMap.java
index 972f4eb5..36147727 100644
--- a/java/fury-core/src/main/java/org/apache/fury/collection/LazyMap.java
+++ b/java/fury-core/src/main/java/org/apache/fury/collection/LazyMap.java
@@ -19,17 +19,22 @@
package org.apache.fury.collection;
-import com.google.common.collect.ForwardingMap;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
import org.apache.fury.util.Preconditions;
/** A map which populate lazily until the first map query happens to reduce
map#put cost. */
-public class LazyMap<K, V> extends ForwardingMap<K, V> {
- private List<Entry<K, V>> entries;
+public class LazyMap<K, V> implements Map<K, V> {
+ private List<Entry<? extends K, ? extends V>> entries;
+ private Map<K, V> map;
public LazyMap() {
entries = new ArrayList<>();
@@ -39,19 +44,16 @@ public class LazyMap<K, V> extends ForwardingMap<K, V> {
entries = new ArrayList<>(size);
}
- public LazyMap(List<Entry<K, V>> entries) {
+ public LazyMap(List<Entry<? extends K, ? extends V>> entries) {
this.entries = entries;
}
- private Map<K, V> map;
-
- @Override
public Map<K, V> delegate() {
Map<K, V> m = this.map;
if (m == null) {
- List<Entry<K, V>> e = this.entries;
+ List<Entry<? extends K, ? extends V>> e = this.entries;
m = new HashMap<>(e.size());
- for (Entry<K, V> entry : e) {
+ for (Entry<? extends K, ? extends V> entry : e) {
m.put(entry.getKey(), entry.getValue());
}
this.map = m;
@@ -59,6 +61,11 @@ public class LazyMap<K, V> extends ForwardingMap<K, V> {
return m;
}
+ public void setEntries(List<Entry<? extends K, ? extends V>> entries) {
+ Preconditions.checkArgument(map == null);
+ this.entries = entries;
+ }
+
@Override
public V put(K key, V value) {
Map<K, V> m = map;
@@ -71,13 +78,195 @@ public class LazyMap<K, V> extends ForwardingMap<K, V> {
}
}
- public void setEntries(List<Entry<K, V>> entries) {
- Preconditions.checkArgument(map == null);
- this.entries = entries;
+ @Override
+ public V getOrDefault(Object key, V defaultValue) {
+ return delegate().getOrDefault(key, defaultValue);
+ }
+
+ @Override
+ public void forEach(BiConsumer<? super K, ? super V> action) {
+ Map<K, V> m = map;
+ if (m == null) {
+ for (Entry<? extends K, ? extends V> entry : entries) {
+ action.accept(entry.getKey(), entry.getValue());
+ }
+ } else {
+ m.forEach(action);
+ }
+ }
+
+ @Override
+ public void replaceAll(BiFunction<? super K, ? super V, ? extends V>
function) {
+ delegate().replaceAll(function);
+ }
+
+ @Override
+ public V putIfAbsent(K key, V value) {
+ return delegate().putIfAbsent(key, value);
+ }
+
+ @Override
+ public boolean remove(Object key, Object value) {
+ return delegate().remove(key, value);
+ }
+
+ @Override
+ public V remove(Object key) {
+ return delegate().remove(key);
+ }
+
+ @Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ return delegate().replace(key, oldValue, newValue);
+ }
+
+ @Override
+ public V replace(K key, V value) {
+ return delegate().replace(key, value);
+ }
+
+ @Override
+ public V computeIfAbsent(K key, Function<? super K, ? extends V>
mappingFunction) {
+ return delegate().computeIfAbsent(key, mappingFunction);
+ }
+
+ @Override
+ public V computeIfPresent(
+ K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+ return delegate().computeIfPresent(key, remappingFunction);
+ }
+
+ @Override
+ public V compute(K key, BiFunction<? super K, ? super V, ? extends V>
remappingFunction) {
+ return delegate().compute(key, remappingFunction);
+ }
+
+ @Override
+ public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V>
remappingFunction) {
+ return delegate().merge(key, value, remappingFunction);
+ }
+
+ @Override
+ public int size() {
+ Map<K, V> m = map;
+ return m == null ? entries.size() : m.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ Map<K, V> m = map;
+ return m == null ? entries.isEmpty() : m.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return delegate().containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return delegate().containsValue(value);
+ }
+
+ @Override
+ public V get(Object key) {
+ return delegate().get(key);
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+ Map<K, V> map = this.map;
+ if (map == null) {
+ // avoid map put cost when deserialization this map.
+ entries.addAll(m.entrySet());
+ } else {
+ map.putAll(m);
+ }
+ }
+
+ @Override
+ public void clear() {
+ Map<K, V> m = map;
+ if (m == null) {
+ entries.clear();
+ } else {
+ m.clear();
+ }
}
+ @Override
+ public Set<K> keySet() {
+ return delegate().keySet();
+ }
+
+ @Override
+ public Collection<V> values() {
+ return delegate().values();
+ }
+
+ @Override
+ public Set<Entry<K, V>> entrySet() {
+ return delegate().entrySet();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ Map<K, V> m = map;
+ if (m != null) {
+ return m.equals(obj);
+ }
+
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof Map)) {
+ return false;
+ }
+ Map<?, ?> map = (Map<?, ?>) obj;
+ List<Entry<? extends K, ? extends V>> entries = this.entries;
+ if (map.size() != entries.size()) {
+ return false;
+ }
+
+ try {
+ for (Entry<? extends K, ? extends V> e : entries) {
+ K key = e.getKey();
+ V value = e.getValue();
+ if (value == null) {
+ if (!(map.get(key) == null && map.containsKey(key))) {
+ return false;
+ }
+ } else {
+ if (!value.equals(map.get(key))) {
+ return false;
+ }
+ }
+ }
+ } catch (ClassCastException | NullPointerException unused) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ Map<K, V> m = map;
+ if (m != null) {
+ return m.hashCode();
+ }
+
+ int h = 0;
+ for (Entry<? extends K, ? extends V> entry : entries) {
+ h += entry.hashCode();
+ }
+ return h;
+ }
+
+ @Override
public String toString() {
- Iterator<Entry<K, V>> i = entries.iterator();
+ Iterator<Entry<? extends K, ? extends V>> i = entries.iterator();
if (!i.hasNext()) {
return "{}";
}
@@ -85,7 +274,7 @@ public class LazyMap<K, V> extends ForwardingMap<K, V> {
StringBuilder sb = new StringBuilder();
sb.append('{');
for (; ; ) {
- Entry<K, V> e = i.next();
+ Entry<? extends K, ? extends V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
diff --git
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ChildContainerSerializers.java
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ChildContainerSerializers.java
index 23187e93..fdb8c18f 100644
---
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ChildContainerSerializers.java
+++
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ChildContainerSerializers.java
@@ -19,7 +19,8 @@
package org.apache.fury.serializer.collection;
-import com.google.common.collect.ImmutableSet;
+import static org.apache.fury.collection.Collections.ofHashSet;
+
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
@@ -122,7 +123,7 @@ public class ChildContainerSerializers {
public static class ChildCollectionSerializer<T extends Collection>
extends CollectionSerializer<T> {
public static Set<Class<?>> superClasses =
- ImmutableSet.of(
+ ofHashSet(
ArrayList.class, LinkedList.class, ArrayDeque.class, Vector.class,
HashSet.class
// PriorityQueue/TreeSet/ConcurrentSkipListSet need comparator as
constructor argument
);
@@ -172,7 +173,7 @@ public class ChildContainerSerializers {
*/
public static class ChildMapSerializer<T extends Map> extends
MapSerializer<T> {
public static Set<Class<?>> superClasses =
- ImmutableSet.of(
+ ofHashSet(
HashMap.class, LinkedHashMap.class, ConcurrentHashMap.class
// TreeMap/ConcurrentSkipListMap need comparator as constructor
argument
);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]