21
21
import androidx .annotation .VisibleForTesting ;
22
22
import com .google .android .gms .tasks .Task ;
23
23
import com .google .android .gms .tasks .TaskCompletionSource ;
24
+ import com .google .common .collect .ImmutableMap ;
25
+ import com .google .common .collect .ImmutableSet ;
24
26
import com .google .firebase .database .collection .ImmutableSortedMap ;
25
27
import com .google .firebase .database .collection .ImmutableSortedSet ;
26
28
import com .google .firebase .firestore .FirebaseFirestoreException ;
55
57
import com .google .firebase .firestore .util .Util ;
56
58
import io .grpc .Status ;
57
59
import java .io .IOException ;
58
- import java .util .ArrayDeque ;
59
60
import java .util .ArrayList ;
60
61
import java .util .Collections ;
61
62
import java .util .HashMap ;
63
+ import java .util .LinkedHashSet ;
62
64
import java .util .List ;
63
65
import java .util .Map ;
64
- import java .util .Queue ;
65
66
import java .util .Set ;
66
67
67
68
/**
@@ -130,7 +131,7 @@ interface SyncEngineCallback {
130
131
* The keys of documents that are in limbo for which we haven't yet started a limbo resolution
131
132
* query.
132
133
*/
133
- private final Queue <DocumentKey > enqueuedLimboResolutions ;
134
+ private final LinkedHashSet <DocumentKey > enqueuedLimboResolutions ;
134
135
135
136
/** Keeps track of the target ID for each document that is in limbo with an active target. */
136
137
private final Map <DocumentKey , Integer > activeLimboTargetsByKey ;
@@ -169,7 +170,7 @@ public SyncEngine(
169
170
queryViewsByQuery = new HashMap <>();
170
171
queriesByTarget = new HashMap <>();
171
172
172
- enqueuedLimboResolutions = new ArrayDeque <>();
173
+ enqueuedLimboResolutions = new LinkedHashSet <>();
173
174
activeLimboTargetsByKey = new HashMap <>();
174
175
activeLimboResolutionsByTarget = new HashMap <>();
175
176
limboDocumentRefs = new ReferenceSet ();
@@ -321,8 +322,6 @@ public void handleRemoteEvent(RemoteEvent event) {
321
322
TargetChange targetChange = entry .getValue ();
322
323
LimboResolution limboResolution = activeLimboResolutionsByTarget .get (targetId );
323
324
if (limboResolution != null ) {
324
- Logger .warn ("zzyzx" , "handleRemoteEvent() limboResolution.key=" + limboResolution .key + " targetChange.getAddedDocuments().size()=" + targetChange .getAddedDocuments ().size () + " targetChange.getModifiedDocuments().size()=" + targetChange .getModifiedDocuments ().size () + " targetChange.getRemovedDocuments().size()=" + targetChange .getRemovedDocuments ().size ());
325
-
326
325
// Since this is a limbo resolution lookup, it's for a single document and it could be
327
326
// added, modified, or removed, but not a combination.
328
327
hardAssert (
@@ -398,7 +397,6 @@ public void handleRejectedListen(int targetId, Status error) {
398
397
LimboResolution limboResolution = activeLimboResolutionsByTarget .get (targetId );
399
398
DocumentKey limboKey = limboResolution != null ? limboResolution .key : null ;
400
399
if (limboKey != null ) {
401
- Logger .warn ("zzyzx" , "handleRejectedListen() limboKey=" + limboKey + " targetId=" + targetId );
402
400
// Since this query failed, we won't want to manually unlisten to it.
403
401
// So go ahead and remove it from bookkeeping.
404
402
activeLimboTargetsByKey .remove (limboKey );
@@ -605,26 +603,11 @@ private void removeAndCleanupTarget(int targetId, Status status) {
605
603
}
606
604
}
607
605
608
- private String describeKeyInActiveLimboTargetsByKey (DocumentKey key ) {
609
- ArrayList <String > list = new ArrayList <>();
610
- for (DocumentKey currentKey : activeLimboTargetsByKey .keySet ()) {
611
- list .add (currentKey .toString ());
612
- }
613
- Collections .sort (list );
614
- return "activeLimboTargetsByKey.containsKey(key)="
615
- + activeLimboTargetsByKey .containsKey (key )
616
- + " (by string: "
617
- + list .contains (key .toString ())
618
- + ") activeLimboTargetsByKey="
619
- + list ;
620
- }
621
-
622
606
private void removeLimboTarget (DocumentKey key ) {
607
+ enqueuedLimboResolutions .remove (key );
623
608
// It's possible that the target already got removed because the query failed. In that case,
624
609
// the key won't exist in `limboTargetsByKey`. Only do the cleanup if we still have the target.
625
610
Integer targetId = activeLimboTargetsByKey .get (key );
626
- Logger .warn ("zzyzx" , "removeLimboTarget() start; key=" + key + " targetId=" + targetId + " " + describeKeyInActiveLimboTargetsByKey (key ));
627
- enqueuedLimboResolutions .remove (key );
628
611
if (targetId != null ) {
629
612
remoteStore .stopListening (targetId );
630
613
activeLimboTargetsByKey .remove (key );
@@ -675,12 +658,10 @@ private void updateTrackedLimboDocuments(List<LimboDocumentChange> limboChanges,
675
658
for (LimboDocumentChange limboChange : limboChanges ) {
676
659
switch (limboChange .getType ()) {
677
660
case ADDED :
678
- Logger .warn ("zzyzx" , "updateTrackedLimboDocuments() ADDED " + limboChange .getKey ());
679
661
limboDocumentRefs .addReference (limboChange .getKey (), targetId );
680
662
trackLimboChange (limboChange );
681
663
break ;
682
664
case REMOVED :
683
- Logger .warn ("zzyzx" , "updateTrackedLimboDocuments() REMOVED " + limboChange .getKey ());
684
665
Logger .debug (TAG , "Document no longer in limbo: %s" , limboChange .getKey ());
685
666
DocumentKey limboDocKey = limboChange .getKey ();
686
667
limboDocumentRefs .removeReference (limboDocKey , targetId );
@@ -697,8 +678,7 @@ private void updateTrackedLimboDocuments(List<LimboDocumentChange> limboChanges,
697
678
698
679
private void trackLimboChange (LimboDocumentChange change ) {
699
680
DocumentKey key = change .getKey ();
700
- Logger .warn ("zzyzx" , "trackLimboChange() for " + key + ": activeLimboTargetsByKey.get(key)==" + activeLimboTargetsByKey .get (key ));
701
- if (!activeLimboTargetsByKey .containsKey (key )) {
681
+ if (!activeLimboTargetsByKey .containsKey (key ) && !enqueuedLimboResolutions .contains (key )) {
702
682
Logger .debug (TAG , "New document in limbo: %s" , key );
703
683
enqueuedLimboResolutions .add (key );
704
684
pumpEnqueuedLimboResolutions ();
@@ -714,12 +694,11 @@ private void trackLimboChange(LimboDocumentChange change) {
714
694
* https://github.com/firebase/firebase-js-sdk/issues/2683.
715
695
*/
716
696
private void pumpEnqueuedLimboResolutions () {
717
- Logger .warn ("zzyzx" , "pumpEnqueuedLimboResolutions() start; enqueuedLimboResolutions.size()=" + enqueuedLimboResolutions .size () + " activeLimboTargetsByKey.size()=" + activeLimboTargetsByKey .size ());
718
697
while (!enqueuedLimboResolutions .isEmpty ()
719
698
&& activeLimboTargetsByKey .size () < maxConcurrentLimboResolutions ) {
720
- DocumentKey key = enqueuedLimboResolutions .remove ();
699
+ DocumentKey key = enqueuedLimboResolutions .iterator ().next ();
700
+ enqueuedLimboResolutions .remove (key );
721
701
int limboTargetId = targetIdGenerator .nextId ();
722
- Logger .warn ("zzyzx" , "pumpEnqueuedLimboResolutions() starting listen for " + key + " (limboTargetId=" + limboTargetId + ")" );
723
702
activeLimboResolutionsByTarget .put (limboTargetId , new LimboResolution (key ));
724
703
activeLimboTargetsByKey .put (key , limboTargetId );
725
704
remoteStore .listen (
@@ -729,19 +708,18 @@ private void pumpEnqueuedLimboResolutions() {
729
708
ListenSequence .INVALID ,
730
709
QueryPurpose .LIMBO_RESOLUTION ));
731
710
}
732
- Logger .warn ("zzyzx" , "pumpEnqueuedLimboResolutions() done; enqueuedLimboResolutions.size()=" + enqueuedLimboResolutions .size () + " activeLimboTargetsByKey.size()=" + activeLimboTargetsByKey .size ());
733
711
}
734
712
735
713
@ VisibleForTesting
736
- public Map <DocumentKey , Integer > getActiveLimboDocumentResolutions () {
714
+ public ImmutableMap <DocumentKey , Integer > getActiveLimboDocumentResolutions () {
737
715
// Make a defensive copy as the Map continues to be modified.
738
- return new HashMap <> (activeLimboTargetsByKey );
716
+ return ImmutableMap . copyOf (activeLimboTargetsByKey );
739
717
}
740
718
741
719
@ VisibleForTesting
742
- public Queue <DocumentKey > getEnqueuedLimboDocumentResolutions () {
743
- // Make a defensive copy as the Queue continues to be modified.
744
- return new ArrayDeque <> (enqueuedLimboResolutions );
720
+ public ImmutableSet <DocumentKey > getEnqueuedLimboDocumentResolutions () {
721
+ // Make a defensive copy as the LinkedHashMap continues to be modified.
722
+ return ImmutableSet . copyOf (enqueuedLimboResolutions );
745
723
}
746
724
747
725
public void handleCredentialChange (User user ) {
0 commit comments