Search in sources :

Example 76 with MutableDocument

use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.

the class LruGarbageCollectorTestCase method testCacheTooSmall.

@Test
public void testCacheTooSmall() {
    // Default LRU Params are ok for this test.
    persistence.runTransaction("Fill cache", () -> {
        // Simulate a bunch of ack'd mutations
        for (int i = 0; i < 50; i++) {
            MutableDocument doc = cacheADocumentInTransaction();
            markDocumentEligibleForGcInTransaction(doc.getKey());
        }
    });
    // Make sure we're under the target size
    long cacheSize = garbageCollector.getByteSize();
    assertTrue(cacheSize < lruParams.minBytesThreshold);
    LruGarbageCollector.Results results = persistence.runTransaction("GC", () -> garbageCollector.collect(new SparseArray<>()));
    assertFalse(results.hasRun());
}
Also used : SparseArray(android.util.SparseArray) MutableDocument(com.google.firebase.firestore.model.MutableDocument) Test(org.junit.Test)

Example 77 with MutableDocument

use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.

the class LruGarbageCollectorTestCase method testRemoveOrphanedDocuments.

@Test
public void testRemoveOrphanedDocuments() {
    // Track documents we expect to be retained so we can verify post-GC.
    // This will contain documents associated with targets that survive GC, as well
    // as any documents with pending mutations.
    Set<DocumentKey> expectedRetained = new HashSet<>();
    // we add two mutations later, for now track them in an array.
    List<Mutation> mutations = new ArrayList<>();
    persistence.runTransaction("add a target and add two documents to it", () -> {
        // Add two documents to first target, queue a mutation on the second document
        TargetData targetData = addNextQueryInTransaction();
        MutableDocument doc1 = cacheADocumentInTransaction();
        addDocumentToTarget(doc1.getKey(), targetData.getTargetId());
        expectedRetained.add(doc1.getKey());
        MutableDocument doc2 = cacheADocumentInTransaction();
        addDocumentToTarget(doc2.getKey(), targetData.getTargetId());
        expectedRetained.add(doc2.getKey());
        mutations.add(mutation(doc2.getKey()));
    });
    // Add a second query and register a third document on it
    persistence.runTransaction("second query", () -> {
        TargetData targetData = addNextQueryInTransaction();
        MutableDocument doc3 = cacheADocumentInTransaction();
        addDocumentToTarget(doc3.getKey(), targetData.getTargetId());
        expectedRetained.add(doc3.getKey());
    });
    // cache another document and prepare a mutation on it.
    persistence.runTransaction("queue a mutation", () -> {
        MutableDocument doc4 = cacheADocumentInTransaction();
        mutations.add(mutation(doc4.getKey()));
        expectedRetained.add(doc4.getKey());
    });
    // Insert the mutations. These operations don't have a sequence number, they just
    // serve to keep the mutated documents from being GC'd while the mutations are outstanding.
    persistence.runTransaction("actually register the mutations", () -> {
        Timestamp writeTime = Timestamp.now();
        mutationQueue.addMutationBatch(writeTime, Collections.emptyList(), mutations);
    });
    // Mark 5 documents eligible for GC. This simulates documents that were mutated then ack'd.
    // Since they were ack'd, they are no longer in a mutation queue, and there is nothing keeping
    // them alive.
    Set<DocumentKey> toBeRemoved = new HashSet<>();
    persistence.runTransaction("add orphaned docs (previously mutated, then ack'd)", () -> {
        for (int i = 0; i < 5; i++) {
            MutableDocument doc = cacheADocumentInTransaction();
            toBeRemoved.add(doc.getKey());
            markDocumentEligibleForGcInTransaction(doc.getKey());
        }
    });
    // We expect only the orphaned documents, those not in a mutation or a target, to be removed.
    // use a large sequence number to remove as much as possible
    int removed = garbageCollector.removeOrphanedDocuments(1000);
    assertEquals(toBeRemoved.size(), removed);
    persistence.runTransaction("verify", () -> {
        for (DocumentKey key : toBeRemoved) {
            assertFalse(documentCache.get(key).isValidDocument());
            assertFalse(targetCache.containsKey(key));
        }
        for (DocumentKey key : expectedRetained) {
            assertTrue(documentCache.get(key).isValidDocument());
        }
    });
}
Also used : DocumentKey(com.google.firebase.firestore.model.DocumentKey) ArrayList(java.util.ArrayList) MutableDocument(com.google.firebase.firestore.model.MutableDocument) Mutation(com.google.firebase.firestore.model.mutation.Mutation) SetMutation(com.google.firebase.firestore.model.mutation.SetMutation) Timestamp(com.google.firebase.Timestamp) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 78 with MutableDocument

use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.

the class LruGarbageCollectorTestCase method testGCRan.

@Test
public void testGCRan() {
    // Set a low byte threshold so we can guarantee that GC will run.
    LruGarbageCollector.Params params = LruGarbageCollector.Params.WithCacheSizeBytes(100);
    // Switch to persistence using our new params.
    persistence.shutdown();
    newTestResources(params);
    // Add 100 targets and 10 documents to each
    for (int i = 0; i < 100; i++) {
        // Use separate transactions so that each target and associated documents get their own
        // sequence number.
        persistence.runTransaction("Add a target and some documents", () -> {
            TargetData targetData = addNextQueryInTransaction();
            for (int j = 0; j < 10; j++) {
                MutableDocument doc = cacheADocumentInTransaction();
                addDocumentToTarget(doc.getKey(), targetData.getTargetId());
            }
        });
    }
    // Mark nothing as live, so everything is eligible.
    LruGarbageCollector.Results results = persistence.runTransaction("GC", () -> garbageCollector.collect(new SparseArray<>()));
    // By default, we collect 10% of the sequence numbers. Since we added 100 targets,
    // that should be 10 targets with 10 documents each, for a total of 100 documents.
    assertTrue(results.hasRun());
    assertEquals(10, results.getTargetsRemoved());
    assertEquals(100, results.getDocumentsRemoved());
}
Also used : SparseArray(android.util.SparseArray) MutableDocument(com.google.firebase.firestore.model.MutableDocument) Test(org.junit.Test)

Example 79 with MutableDocument

use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.

the class LruGarbageCollectorTestCase method testRemoveOrphanedDocumentsWithLargeNumberOfDocuments.

@Test
public void testRemoveOrphanedDocumentsWithLargeNumberOfDocuments() {
    int orphanedDocumentCount = SQLiteLruReferenceDelegate.REMOVE_ORPHANED_DOCUMENTS_BATCH_SIZE * 2 + 1;
    persistence.runTransaction("add orphaned docs", () -> {
        for (int i = 0; i < orphanedDocumentCount; i++) {
            MutableDocument doc = cacheADocumentInTransaction();
            markDocumentEligibleForGcInTransaction(doc.getKey());
        }
    });
    int removed = garbageCollector.removeOrphanedDocuments(1000);
    assertEquals(orphanedDocumentCount, removed);
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) Test(org.junit.Test)

Example 80 with MutableDocument

use of com.google.firebase.firestore.model.MutableDocument in project firebase-android-sdk by firebase.

the class RemoteDocumentCacheTestCase method testGetAllFromSinceReadTimeAndNanoseconds.

@Test
public void testGetAllFromSinceReadTimeAndNanoseconds() {
    add(doc("b/old", 1, DOC_DATA), version(1, 1));
    add(doc("b/current", 1, DOC_DATA), version(1, 2));
    add(doc("b/new", 1, DOC_DATA), version(1, 3));
    ResourcePath collection = path("b");
    Map<DocumentKey, MutableDocument> results = remoteDocumentCache.getAll(collection, IndexOffset.createSuccessor(version(1, 2), -1));
    assertThat(results.values()).containsExactly(doc("b/new", 1, DOC_DATA));
}
Also used : ResourcePath(com.google.firebase.firestore.model.ResourcePath) DocumentKey(com.google.firebase.firestore.model.DocumentKey) MutableDocument(com.google.firebase.firestore.model.MutableDocument) Test(org.junit.Test)

Aggregations

MutableDocument (com.google.firebase.firestore.model.MutableDocument)166 Test (org.junit.Test)125 DocumentKey (com.google.firebase.firestore.model.DocumentKey)43 Mutation.calculateOverlayMutation (com.google.firebase.firestore.model.mutation.Mutation.calculateOverlayMutation)30 TestUtil.deleteMutation (com.google.firebase.firestore.testutil.TestUtil.deleteMutation)30 TestUtil.mergeMutation (com.google.firebase.firestore.testutil.TestUtil.mergeMutation)30 TestUtil.patchMutation (com.google.firebase.firestore.testutil.TestUtil.patchMutation)30 TestUtil.setMutation (com.google.firebase.firestore.testutil.TestUtil.setMutation)30 HashMap (java.util.HashMap)22 TestUtil.wrapObject (com.google.firebase.firestore.testutil.TestUtil.wrapObject)18 ArrayList (java.util.ArrayList)18 TargetData (com.google.firebase.firestore.local.TargetData)15 WatchTargetChange (com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)14 DocumentChange (com.google.firebase.firestore.remote.WatchChange.DocumentChange)13 ResourcePath (com.google.firebase.firestore.model.ResourcePath)12 Query (com.google.firebase.firestore.core.Query)10 Map (java.util.Map)10 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)8 Document (com.google.firebase.firestore.model.Document)7 Timestamp (com.google.firebase.Timestamp)6