Skip to content

Commit bde0ada

Browse files
committed
Rework lookupMutationBatch and getNextMutationBatchAfterBatchId to load directly
1 parent 655e962 commit bde0ada

File tree

1 file changed

+43
-37
lines changed

1 file changed

+43
-37
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteMutationQueue.java

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static com.google.firebase.firestore.util.Assert.fail;
1919
import static com.google.firebase.firestore.util.Assert.hardAssert;
2020

21+
import android.database.sqlite.SQLiteDoneException;
2122
import android.database.sqlite.SQLiteStatement;
2223
import android.os.ParcelFileDescriptor;
2324
import com.google.firebase.Timestamp;
@@ -208,26 +209,47 @@ public MutationBatch addMutationBatch(Timestamp localWriteTime, List<Mutation> m
208209
@Nullable
209210
@Override
210211
public MutationBatch lookupMutationBatch(int batchId) {
211-
return db.query(
212-
"SELECT m.batch_id, SUBSTR(m.mutations, 1, ?) "
213-
+ "FROM mutations m "
214-
+ "WHERE uid = ? AND batch_id = ?")
215-
.binding(BLOB_MAX_INLINE_LENGTH, uid, batchId)
216-
.firstValue(row -> decodeMutationBatchRow(row.getInt(0), row.getBlob(1)));
212+
SQLiteStatement query =
213+
db.prepare("SELECT mutations FROM mutations WHERE uid = ? AND batch_id = ?");
214+
query.bindString(1, uid);
215+
query.bindLong(2, batchId);
216+
217+
return executeSimpleMutationBatchLookup(query);
217218
}
218219

219220
@Nullable
220221
@Override
221222
public MutationBatch getNextMutationBatchAfterBatchId(int batchId) {
222223
int nextBatchId = batchId + 1;
223224

224-
return db.query(
225-
"SELECT m.batch_id, SUBSTR(m.mutations, 1, ?) "
226-
+ "FROM mutations m "
227-
+ "WHERE uid = ? AND batch_id >= ? "
228-
+ "ORDER BY batch_id ASC LIMIT 1")
229-
.binding(BLOB_MAX_INLINE_LENGTH, uid, nextBatchId)
230-
.firstValue(row -> decodeMutationBatchRow(row.getInt(0), row.getBlob(1)));
225+
SQLiteStatement query =
226+
db.prepare("SELECT mutations FROM mutations "
227+
+ "WHERE uid = ? AND batch_id >= ? "
228+
+ "ORDER BY batch_id ASC LIMIT 1");
229+
query.bindString(1, uid);
230+
query.bindLong(2, nextBatchId);
231+
232+
return executeSimpleMutationBatchLookup(query);
233+
}
234+
235+
@Nullable
236+
private MutationBatch executeSimpleMutationBatchLookup(SQLiteStatement query) {
237+
ParcelFileDescriptor blobFile;
238+
try {
239+
blobFile = query.simpleQueryForBlobFileDescriptor();
240+
} catch (SQLiteDoneException e) {
241+
return null;
242+
}
243+
244+
try (ParcelFileDescriptor.AutoCloseInputStream stream =
245+
new ParcelFileDescriptor.AutoCloseInputStream(blobFile)) {
246+
return serializer.decodeMutationBatch(
247+
com.google.firebase.firestore.proto.WriteBatch.parseFrom(stream));
248+
} catch (InvalidProtocolBufferException e) {
249+
throw fail("MutationBatch failed to parse: %s", e);
250+
} catch (IOException e) {
251+
throw fail("MutationBatch failed to load: %s", e);
252+
}
231253
}
232254

233255
@Override
@@ -238,7 +260,7 @@ public List<MutationBatch> getAllMutationBatches() {
238260
+ "FROM mutations m "
239261
+ "WHERE uid = ? ORDER BY batch_id ASC")
240262
.binding(BLOB_MAX_INLINE_LENGTH, uid)
241-
.forEach(row -> result.add(decodeMutationBatchRow(row.getInt(0), row.getBlob(1))));
263+
.forEach(row -> result.add(decodeInlineMutationBatch(row.getInt(0), row.getBlob(1))));
242264
return result;
243265
}
244266

@@ -256,7 +278,7 @@ public List<MutationBatch> getAllMutationBatchesAffectingDocumentKey(DocumentKey
256278
+ "AND dm.batch_id = m.batch_id "
257279
+ "ORDER BY dm.batch_id")
258280
.binding(BLOB_MAX_INLINE_LENGTH, uid, path)
259-
.forEach(row -> result.add(decodeMutationBatchRow(row.getInt(0), row.getBlob(1))));
281+
.forEach(row -> result.add(decodeInlineMutationBatch(row.getInt(0), row.getBlob(1))));
260282
return result;
261283
}
262284

@@ -292,7 +314,7 @@ public List<MutationBatch> getAllMutationBatchesAffectingDocumentKeys(
292314
int batchId = row.getInt(0);
293315
if (!uniqueBatchIds.contains(batchId)) {
294316
uniqueBatchIds.add(batchId);
295-
result.add(decodeMutationBatchRow(batchId, row.getBlob(1)));
317+
result.add(decodeInlineMutationBatch(batchId, row.getBlob(1)));
296318
}
297319
});
298320
}
@@ -364,7 +386,7 @@ public List<MutationBatch> getAllMutationBatchesAffectingQuery(Query query) {
364386
return;
365387
}
366388

367-
result.add(decodeMutationBatchRow(batchId, row.getBlob(2)));
389+
result.add(decodeInlineMutationBatch(batchId, row.getBlob(2)));
368390
});
369391

370392
return result;
@@ -417,32 +439,16 @@ public void performConsistencyCheck() {
417439
* Decodes a mutation batch row containing a batch id and a substring of a blob. If the blob is
418440
* too large, executes another query to load the blob directly.
419441
*
420-
* @param batchId The batch ID of the row containing the blob
442+
* @param batchId The batch ID of the row containing the bytes, for fallback lookup if the value
443+
* is too large.
421444
* @param bytes The bytes represented
422-
* @return
423445
*/
424-
private MutationBatch decodeMutationBatchRow(int batchId, byte[] bytes) {
446+
private MutationBatch decodeInlineMutationBatch(int batchId, byte[] bytes) {
425447
if (bytes.length < BLOB_MAX_INLINE_LENGTH) {
426448
return decodeMutationBatch(bytes);
427449
}
428450

429-
SQLiteStatement loader =
430-
db.prepare("SELECT mutations FROM mutations WHERE uid = ? AND batch_id = ?");
431-
loader.bindString(1, uid);
432-
loader.bindLong(2, batchId);
433-
434-
ParcelFileDescriptor blobFile = loader.simpleQueryForBlobFileDescriptor();
435-
hardAssert(blobFile != null, "Blob exists so descriptor should not be null");
436-
437-
try (ParcelFileDescriptor.AutoCloseInputStream stream =
438-
new ParcelFileDescriptor.AutoCloseInputStream(blobFile)) {
439-
return serializer.decodeMutationBatch(
440-
com.google.firebase.firestore.proto.WriteBatch.parseFrom(stream));
441-
} catch (InvalidProtocolBufferException e) {
442-
throw fail("MutationBatch failed to parse: %s", e);
443-
} catch (IOException e) {
444-
throw fail("Failed to read blob for uid=%s, batch_id=%d: %s", uid, batchId, e);
445-
}
451+
return lookupMutationBatch(batchId);
446452
}
447453

448454
private MutationBatch decodeMutationBatch(byte[] bytes) {

0 commit comments

Comments
 (0)