use of com.google.firebase.firestore.model.Document in project firebase-android-sdk by firebase.
the class LocalDocumentsView method getNextDocuments.
/**
* Given a collection group, returns the next documents that follow the provided offset, along
* with an updated batch ID.
*
* <p>The documents returned by this method are ordered by remote version from the provided
* offset. If there are no more remote documents after the provided offset, documents with
* mutations in order of batch id from the offset are returned. Since all documents in a batch are
* returned together, the total number of documents returned can exceed {@code count}.
*
* @param collectionGroup The collection group for the documents.
* @param offset The offset to index into.
* @param count The number of documents to return
* @return A LocalDocumentsResult with the documents that follow the provided offset and the last
* processed batch id.
*/
LocalDocumentsResult getNextDocuments(String collectionGroup, IndexOffset offset, int count) {
Map<DocumentKey, MutableDocument> docs = remoteDocumentCache.getAll(collectionGroup, offset, count);
Map<DocumentKey, Overlay> overlays = count - docs.size() > 0 ? documentOverlayCache.getOverlays(collectionGroup, offset.getLargestBatchId(), count - docs.size()) : Collections.emptyMap();
int largestBatchId = FieldIndex.INITIAL_LARGEST_BATCH_ID;
for (Overlay overlay : overlays.values()) {
if (!docs.containsKey(overlay.getKey())) {
docs.put(overlay.getKey(), getBaseDocument(overlay.getKey(), overlay));
}
// The callsite will use the largest batch ID together with the latest read time to create
// a new index offset. Since we only process batch IDs if all remote documents have been read,
// no overlay will increase the overall read time. This is why we only need to special case
// the batch id.
largestBatchId = Math.max(largestBatchId, overlay.getLargestBatchId());
}
populateOverlays(overlays, docs.keySet());
ImmutableSortedMap<DocumentKey, Document> localDocs = computeViews(docs, overlays, Collections.emptySet());
return new LocalDocumentsResult(largestBatchId, localDocs);
}
use of com.google.firebase.firestore.model.Document in project firebase-android-sdk by firebase.
the class LocalStore method writeLocally.
/**
* Accepts locally generated Mutations and commits them to storage.
*/
public LocalDocumentsResult writeLocally(List<Mutation> mutations) {
Timestamp localWriteTime = Timestamp.now();
// TODO: Call queryEngine.handleDocumentChange() appropriately.
Set<DocumentKey> keys = new HashSet<>();
for (Mutation mutation : mutations) {
keys.add(mutation.getKey());
}
return persistence.runTransaction("Locally write mutations", () -> {
// Load and apply all existing mutations. This lets us compute the current base state for
// all non-idempotent transforms before applying any additional user-provided writes.
ImmutableSortedMap<DocumentKey, Document> documents = localDocuments.getDocuments(keys);
// For non-idempotent mutations (such as `FieldValue.increment()`), we record the base
// state in a separate patch mutation. This is later used to guarantee consistent values
// and prevents flicker even if the backend sends us an update that already includes our
// transform.
List<Mutation> baseMutations = new ArrayList<>();
for (Mutation mutation : mutations) {
ObjectValue baseValue = mutation.extractTransformBaseValue(documents.get(mutation.getKey()));
if (baseValue != null) {
// NOTE: The base state should only be applied if there's some existing
// document to override, so use a Precondition of exists=true
baseMutations.add(new PatchMutation(mutation.getKey(), baseValue, baseValue.getFieldMask(), Precondition.exists(true)));
}
}
MutationBatch batch = mutationQueue.addMutationBatch(localWriteTime, baseMutations, mutations);
Map<DocumentKey, Mutation> overlays = batch.applyToLocalDocumentSet(documents);
documentOverlayCache.saveOverlays(batch.getBatchId(), overlays);
return new LocalDocumentsResult(batch.getBatchId(), documents);
});
}
use of com.google.firebase.firestore.model.Document in project firebase-android-sdk by firebase.
the class MemoryRemoteDocumentCache method removeAll.
@Override
public void removeAll(Collection<DocumentKey> keys) {
hardAssert(indexManager != null, "setIndexManager() not called");
ImmutableSortedMap<DocumentKey, Document> deletedDocs = emptyDocumentMap();
for (DocumentKey key : keys) {
docs = docs.remove(key);
deletedDocs = deletedDocs.insert(key, MutableDocument.newNoDocument(key, SnapshotVersion.NONE));
}
indexManager.updateIndexEntries(deletedDocs);
}
use of com.google.firebase.firestore.model.Document in project firebase-android-sdk by firebase.
the class MemoryRemoteDocumentCache method getAll.
@Override
public Map<DocumentKey, MutableDocument> getAll(ResourcePath collection, IndexOffset offset) {
Map<DocumentKey, MutableDocument> result = new HashMap<>();
// Documents are ordered by key, so we can use a prefix scan to narrow down the documents
// we need to match the query against.
DocumentKey prefix = DocumentKey.fromPath(collection.append(""));
Iterator<Map.Entry<DocumentKey, Document>> iterator = docs.iteratorFrom(prefix);
while (iterator.hasNext()) {
Map.Entry<DocumentKey, Document> entry = iterator.next();
Document doc = entry.getValue();
DocumentKey key = entry.getKey();
if (!collection.isPrefixOf(key.getPath())) {
// We are now scanning the next collection. Abort.
break;
}
if (key.getPath().length() > collection.length() + 1) {
// Exclude entries from subcollections.
continue;
}
if (IndexOffset.fromDocument(doc).compareTo(offset) <= 0) {
// The document sorts before the offset.
continue;
}
result.put(doc.getKey(), doc.mutableCopy());
}
return result;
}
use of com.google.firebase.firestore.model.Document in project firebase-android-sdk by firebase.
the class LocalDocumentsView method getDocumentsMatchingCollectionGroupQuery.
private ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingCollectionGroupQuery(Query query, IndexOffset offset) {
hardAssert(query.getPath().isEmpty(), "Currently we only support collection group queries at the root.");
String collectionId = query.getCollectionGroup();
ImmutableSortedMap<DocumentKey, Document> results = emptyDocumentMap();
List<ResourcePath> parents = indexManager.getCollectionParents(collectionId);
// aggregate the results.
for (ResourcePath parent : parents) {
Query collectionQuery = query.asCollectionQueryAtPath(parent.append(collectionId));
ImmutableSortedMap<DocumentKey, Document> collectionResults = getDocumentsMatchingCollectionQuery(collectionQuery, offset);
for (Map.Entry<DocumentKey, Document> docEntry : collectionResults) {
results = results.insert(docEntry.getKey(), docEntry.getValue());
}
}
return results;
}
Aggregations