Skip to content

Commit f62d94f

Browse files
committed
TestingHooks.java: use CopyOnWriteArrayList and AtomicReference to manage the registered ExistenceFilterMismatchListener objects
1 parent db3e7c3 commit f62d94f

File tree

1 file changed

+21
-17
lines changed
  • firebase-firestore/src/main/java/com/google/firebase/firestore/remote

1 file changed

+21
-17
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/remote/TestingHooks.java

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import com.google.auto.value.AutoValue;
2323
import com.google.firebase.firestore.ListenerRegistration;
2424
import com.google.firebase.firestore.util.Executors;
25-
import java.util.HashMap;
26-
import java.util.Map;
25+
import java.util.concurrent.CopyOnWriteArrayList;
26+
import java.util.concurrent.atomic.AtomicReference;
2727

2828
/**
2929
* Manages "testing hooks", hooks into the internals of the SDK to verify internal state and events
@@ -36,8 +36,10 @@ final class TestingHooks {
3636

3737
private static final TestingHooks instance = new TestingHooks();
3838

39-
private final Map<Object, ExistenceFilterMismatchListener> existenceFilterMismatchListeners =
40-
new HashMap<>();
39+
// Use CopyOnWriteArrayList to store the listeners so that we don't need to worry about
40+
// synchronizing adds, removes, and traversals.
41+
private final CopyOnWriteArrayList<AtomicReference<ExistenceFilterMismatchListener>>
42+
existenceFilterMismatchListeners = new CopyOnWriteArrayList<>();
4143

4244
private TestingHooks() {}
4345

@@ -48,16 +50,21 @@ static TestingHooks getInstance() {
4850
}
4951

5052
/**
51-
* Notifies all registered {@link ExistenceFilterMismatchListener}` listeners registered via
52-
* {@link #addExistenceFilterMismatchListener}.
53+
* Asynchronously notifies all registered {@link ExistenceFilterMismatchListener}` listeners
54+
* registered via {@link #addExistenceFilterMismatchListener}.
5355
*
5456
* @param info Information about the existence filter mismatch to deliver to the listeners.
5557
*/
5658
void notifyOnExistenceFilterMismatch(@NonNull ExistenceFilterMismatchInfo info) {
57-
synchronized (existenceFilterMismatchListeners) {
58-
for (ExistenceFilterMismatchListener listener : existenceFilterMismatchListeners.values()) {
59-
Executors.BACKGROUND_EXECUTOR.execute(() -> listener.onExistenceFilterMismatch(info));
60-
}
59+
for (AtomicReference<ExistenceFilterMismatchListener> listenerRef :
60+
existenceFilterMismatchListeners) {
61+
Executors.BACKGROUND_EXECUTOR.execute(
62+
() -> {
63+
ExistenceFilterMismatchListener listener = listenerRef.get();
64+
if (listener != null) {
65+
listener.onExistenceFilterMismatch(info);
66+
}
67+
});
6168
}
6269
}
6370

@@ -83,15 +90,12 @@ ListenerRegistration addExistenceFilterMismatchListener(
8390
@NonNull ExistenceFilterMismatchListener listener) {
8491
checkNotNull(listener, "a null listener is not allowed");
8592

86-
Object listenerId = new Object();
87-
synchronized (existenceFilterMismatchListeners) {
88-
existenceFilterMismatchListeners.put(listenerId, listener);
89-
}
93+
AtomicReference<ExistenceFilterMismatchListener> listenerRef = new AtomicReference<>(listener);
94+
existenceFilterMismatchListeners.add(listenerRef);
9095

9196
return () -> {
92-
synchronized (existenceFilterMismatchListeners) {
93-
existenceFilterMismatchListeners.remove(listenerId);
94-
}
97+
listenerRef.set(null);
98+
existenceFilterMismatchListeners.remove(listenerRef);
9599
};
96100
}
97101

0 commit comments

Comments
 (0)