use of com.google.firebase.firestore.model.mutation.Mutation 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());
}
});
}
use of com.google.firebase.firestore.model.mutation.Mutation in project firebase-android-sdk by firebase.
the class MutationQueueTestCase method testAllMutationBatchesAffectingDocumentKeys.
@Test
public void testAllMutationBatchesAffectingDocumentKeys() {
List<Mutation> mutations = asList(setMutation("fob/bar", map("a", 1)), setMutation("foo/bar", map("a", 1)), patchMutation("foo/bar", map("b", 1)), setMutation("foo/bar/suffix/key", map("a", 1)), setMutation("foo/baz", map("a", 1)), setMutation("food/bar", map("a", 1)));
// Store all the mutations.
List<MutationBatch> batches = new ArrayList<>();
persistence.runTransaction("New mutation batch", () -> {
for (Mutation mutation : mutations) {
batches.add(mutationQueue.addMutationBatch(Timestamp.now(), Collections.emptyList(), asList(mutation)));
}
});
ImmutableSortedSet<DocumentKey> keys = DocumentKey.emptyKeySet().insert(key("foo/bar")).insert(key("foo/baz"));
List<MutationBatch> expected = asList(batches.get(1), batches.get(2), batches.get(4));
List<MutationBatch> matches = mutationQueue.getAllMutationBatchesAffectingDocumentKeys(keys);
assertEquals(expected, matches);
}
use of com.google.firebase.firestore.model.mutation.Mutation in project firebase-android-sdk by firebase.
the class MutationQueueTestCase method testAllMutationBatchesAffectingQuery.
@Test
public void testAllMutationBatchesAffectingQuery() {
List<Mutation> mutations = asList(setMutation("fob/bar", map("a", 1)), setMutation("foo/bar", map("a", 1)), patchMutation("foo/bar", map("b", 1)), setMutation("foo/bar/suffix/key", map("a", 1)), setMutation("foo/baz", map("a", 1)), setMutation("food/bar", map("a", 1)));
// Store all the mutations.
List<MutationBatch> batches = new ArrayList<>();
persistence.runTransaction("New mutation batch", () -> {
for (Mutation mutation : mutations) {
batches.add(mutationQueue.addMutationBatch(Timestamp.now(), Collections.emptyList(), asList(mutation)));
}
});
List<MutationBatch> expected = asList(batches.get(1), batches.get(2), batches.get(4));
Query query = Query.atPath(path("foo"));
List<MutationBatch> matches = mutationQueue.getAllMutationBatchesAffectingQuery(query);
assertEquals(expected, matches);
}
use of com.google.firebase.firestore.model.mutation.Mutation in project firebase-android-sdk by firebase.
the class Datastore method commit.
public Task<List<MutationResult>> commit(List<Mutation> mutations) {
CommitRequest.Builder builder = CommitRequest.newBuilder();
builder.setDatabase(serializer.databaseName());
for (Mutation mutation : mutations) {
builder.addWrites(serializer.encodeMutation(mutation));
}
return channel.runRpc(FirestoreGrpc.getCommitMethod(), builder.build()).continueWith(workerQueue.getExecutor(), task -> {
if (!task.isSuccessful()) {
if (task.getException() instanceof FirebaseFirestoreException && ((FirebaseFirestoreException) task.getException()).getCode() == FirebaseFirestoreException.Code.UNAUTHENTICATED) {
channel.invalidateToken();
}
throw task.getException();
}
CommitResponse response = task.getResult();
SnapshotVersion commitVersion = serializer.decodeVersion(response.getCommitTime());
int count = response.getWriteResultsCount();
ArrayList<MutationResult> results = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
com.google.firestore.v1.WriteResult result = response.getWriteResults(i);
results.add(serializer.decodeMutationResult(result, commitVersion));
}
return results;
});
}
use of com.google.firebase.firestore.model.mutation.Mutation in project firebase-android-sdk by firebase.
the class SQLiteDocumentOverlayCache method saveOverlays.
@Override
public void saveOverlays(int largestBatchId, Map<DocumentKey, Mutation> overlays) {
for (Map.Entry<DocumentKey, Mutation> entry : overlays.entrySet()) {
DocumentKey key = entry.getKey();
Mutation overlay = checkNotNull(entry.getValue(), "null value for key: %s", key);
saveOverlay(largestBatchId, key, overlay);
}
}
Aggregations