Skip to content

Commit 0e40391

Browse files
author
Brian Chen
authored
add update time to FieldIndex (#2984)
1 parent e445aca commit 0e40391

File tree

5 files changed

+93
-22
lines changed

5 files changed

+93
-22
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,9 @@ public Index encodeFieldIndex(FieldIndex fieldIndex) {
311311
return index.build();
312312
}
313313

314-
public FieldIndex decodeFieldIndex(String collection_group, int indexId, Index index) {
315-
FieldIndex fieldIndex = new FieldIndex(collection_group, indexId);
314+
public FieldIndex decodeFieldIndex(
315+
String collectionGroup, int indexId, Index index, int updateSeconds, int updateNanos) {
316+
FieldIndex fieldIndex = new FieldIndex(collectionGroup, indexId);
316317
for (Index.IndexField field : index.getFieldsList()) {
317318
fieldIndex =
318319
fieldIndex.withAddedField(
@@ -321,7 +322,8 @@ public FieldIndex decodeFieldIndex(String collection_group, int indexId, Index i
321322
? FieldIndex.Segment.Kind.CONTAINS
322323
: FieldIndex.Segment.Kind.ORDERED);
323324
}
324-
325+
fieldIndex =
326+
fieldIndex.withVersion(new SnapshotVersion(new Timestamp(updateSeconds, updateNanos)));
325327
return fieldIndex;
326328
}
327329
}

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

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,27 +103,36 @@ public void addFieldIndex(FieldIndex index) {
103103
+ "index_id, "
104104
+ "collection_group, "
105105
+ "index_proto, "
106-
+ "active) VALUES(?, ?, ?, ?)",
106+
+ "active, "
107+
+ "update_time_seconds, "
108+
+ "update_time_nanos) VALUES(?, ?, ?, ?, ?, ?)",
107109
currentMax + 1,
108-
index.getCollectionId(),
110+
index.getCollectionGroup(),
109111
encodeFieldIndex(index),
110-
true);
112+
true,
113+
index.getVersion().getTimestamp().getSeconds(),
114+
index.getVersion().getTimestamp().getNanoseconds());
111115
}
112116

113117
@Override
114118
public void addIndexEntries(Document document) {
115119
DocumentKey documentKey = document.getKey();
116120
String collectionGroup = documentKey.getCollectionGroup();
117121
db.query(
118-
"SELECT index_id, index_proto FROM index_configuration WHERE collection_group = ? AND active = 1")
122+
"SELECT index_id, index_proto, update_time_seconds, update_time_nanos "
123+
+ "FROM index_configuration WHERE collection_group = ? AND active = 1")
119124
.binding(collectionGroup)
120125
.forEach(
121126
row -> {
122127
try {
123128
int indexId = row.getInt(0);
124129
FieldIndex fieldIndex =
125130
serializer.decodeFieldIndex(
126-
collectionGroup, row.getInt(0), Index.parseFrom(row.getBlob(1)));
131+
collectionGroup,
132+
row.getInt(0),
133+
Index.parseFrom(row.getBlob(1)),
134+
row.getInt(2),
135+
row.getInt(3));
127136

128137
List<Value> values = extractFieldValue(document, fieldIndex);
129138
if (values == null) return;
@@ -250,14 +259,18 @@ public Set<DocumentKey> getDocumentsMatchingTarget(Target target) {
250259
List<FieldIndex> activeIndices = new ArrayList<>();
251260

252261
db.query(
253-
"SELECT index_id, index_proto FROM index_configuration WHERE collection_group = ? AND active = 1")
262+
"SELECT index_id, index_proto, update_time_seconds, update_time_nanos FROM index_configuration WHERE collection_group = ? AND active = 1")
254263
.binding(collectionGroup)
255264
.forEach(
256265
row -> {
257266
try {
258267
FieldIndex fieldIndex =
259268
serializer.decodeFieldIndex(
260-
collectionGroup, row.getInt(0), Index.parseFrom(row.getBlob(1)));
269+
collectionGroup,
270+
row.getInt(0),
271+
Index.parseFrom(row.getBlob(1)),
272+
row.getInt(2),
273+
row.getInt(3));
261274
boolean matches = targetIndexMatcher.servedByIndex(fieldIndex);
262275
if (matches) {
263276
activeIndices.add(fieldIndex);
@@ -370,4 +383,28 @@ private boolean isMultiValueFilter(Target target, FieldPath fieldPath) {
370383
private byte[] encodeFieldIndex(FieldIndex fieldIndex) {
371384
return serializer.encodeFieldIndex(fieldIndex).toByteArray();
372385
}
386+
387+
// TODO(indexing): Add support for fetching last N updated entries.
388+
public List<FieldIndex> getFieldIndexes() {
389+
List<FieldIndex> allIndexes = new ArrayList<>();
390+
db.query(
391+
"SELECT index_id, collection_group, index_proto, update_time_seconds, update_time_nanos FROM index_configuration "
392+
+ "WHERE active = 1")
393+
.forEach(
394+
row -> {
395+
try {
396+
allIndexes.add(
397+
serializer.decodeFieldIndex(
398+
row.getString(1),
399+
row.getInt(0),
400+
Index.parseFrom(row.getBlob(2)),
401+
row.getInt(3),
402+
row.getInt(4)));
403+
} catch (InvalidProtocolBufferException e) {
404+
throw fail("Failed to decode index: " + e);
405+
}
406+
});
407+
408+
return allIndexes;
409+
}
373410
}

firebase-firestore/src/main/java/com/google/firebase/firestore/model/FieldIndex.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,32 @@ public String toString() {
5656
}
5757
}
5858

59-
private final String collectionId;
59+
private final String collectionGroup;
6060
private final int indexId;
6161
private final List<Segment> segments;
62+
private final SnapshotVersion version;
6263

63-
public FieldIndex(String collectionId, int indexId) {
64-
this.collectionId = collectionId;
64+
public FieldIndex(String collectionGroup, int indexId) {
65+
this.collectionGroup = collectionGroup;
6566
this.segments = new ArrayList<>();
6667
this.indexId = indexId;
68+
this.version = SnapshotVersion.NONE;
6769
}
6870

6971
public FieldIndex(String collectionId) {
7072
this(collectionId, -1);
7173
}
7274

73-
FieldIndex(String collectionId, int indexId, List<Segment> segments) {
74-
this.collectionId = collectionId;
75+
FieldIndex(String collectionGroup, int indexId, List<Segment> segments, SnapshotVersion version) {
76+
this.collectionGroup = collectionGroup;
7577
this.segments = segments;
7678
this.indexId = indexId;
79+
this.version = version;
7780
}
7881

7982
/** The collection ID this index applies to. */
80-
public String getCollectionId() {
81-
return collectionId;
83+
public String getCollectionGroup() {
84+
return collectionGroup;
8285
}
8386

8487
/**
@@ -97,6 +100,10 @@ public int segmentCount() {
97100
return segments.size();
98101
}
99102

103+
public SnapshotVersion getVersion() {
104+
return version;
105+
}
106+
100107
@NonNull
101108
@Override
102109
public Iterator<Segment> iterator() {
@@ -107,7 +114,12 @@ public Iterator<Segment> iterator() {
107114
public FieldIndex withAddedField(FieldPath fieldPath, Segment.Kind kind) {
108115
List<Segment> newSegments = new ArrayList<>(segments);
109116
newSegments.add(new AutoValue_FieldIndex_Segment(fieldPath, kind));
110-
return new FieldIndex(collectionId, indexId, newSegments);
117+
return new FieldIndex(collectionGroup, indexId, newSegments, version);
118+
}
119+
120+
/** Returns a new field index with the updated version. */
121+
public FieldIndex withVersion(SnapshotVersion version) {
122+
return new FieldIndex(collectionGroup, indexId, segments, version);
111123
}
112124

113125
@Override
@@ -118,18 +130,22 @@ public boolean equals(Object o) {
118130
FieldIndex fieldIndex = (FieldIndex) o;
119131

120132
if (!segments.equals(fieldIndex.segments)) return false;
121-
return collectionId.equals(fieldIndex.collectionId);
133+
if (!version.equals(fieldIndex.version)) return false;
134+
return collectionGroup.equals(fieldIndex.collectionGroup);
122135
}
123136

124137
@Override
125138
public int hashCode() {
126-
int result = collectionId.hashCode();
139+
int result = collectionGroup.hashCode();
127140
result = 31 * result + segments.hashCode();
141+
result = 31 * result + version.hashCode();
128142
return result;
129143
}
130144

131145
@Override
132146
public String toString() {
133-
return String.format("FieldIndex{collectionId='%s', segments=%s}", collectionId, segments);
147+
return String.format(
148+
"FieldIndex{collectionGroup='%s', segments=%s, version=%s}",
149+
collectionGroup, segments, version);
134150
}
135151
}

firebase-firestore/src/main/java/com/google/firebase/firestore/model/TargetIndexMatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public TargetIndexMatcher(Target target) {
116116
* @throws AssertionError if the index is for a different collection
117117
*/
118118
public boolean servedByIndex(FieldIndex index) {
119-
hardAssert(index.getCollectionId().equals(collectionId), "Collection IDs do not match");
119+
hardAssert(index.getCollectionGroup().equals(collectionId), "Collection IDs do not match");
120120
for (int i = 0; i < index.segmentCount(); ++i) {
121121
if (!canUseSegment(index.getSegment(i))) {
122122
return false;

firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteIndexManagerTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424
import static com.google.firebase.firestore.testutil.TestUtil.orderBy;
2525
import static com.google.firebase.firestore.testutil.TestUtil.path;
2626
import static com.google.firebase.firestore.testutil.TestUtil.query;
27+
import static org.junit.Assert.assertEquals;
2728
import static org.junit.Assert.assertNull;
2829

30+
import com.google.firebase.Timestamp;
2931
import com.google.firebase.firestore.core.Query;
3032
import com.google.firebase.firestore.model.DocumentKey;
3133
import com.google.firebase.firestore.model.FieldIndex;
3234
import com.google.firebase.firestore.model.MutableDocument;
35+
import com.google.firebase.firestore.model.SnapshotVersion;
3336
import java.util.Arrays;
3437
import java.util.List;
3538
import java.util.Map;
@@ -265,6 +268,19 @@ public void testCollectionGroup() {
265268
verifyResults(query, "coll1/doc1", "coll2/doc2/coll1/doc1");
266269
}
267270

271+
@Test
272+
public void testUpdateTime() {
273+
indexManager.addFieldIndex(
274+
new FieldIndex("coll1")
275+
.withAddedField(field("value"), FieldIndex.Segment.Kind.ORDERED)
276+
.withVersion(new SnapshotVersion(new Timestamp(10, 20))));
277+
278+
List<FieldIndex> indexes = ((SQLiteIndexManager) indexManager).getFieldIndexes();
279+
assertEquals(indexes.size(), 1);
280+
FieldIndex index = indexes.get(0);
281+
assertEquals(index.getVersion(), new SnapshotVersion(new Timestamp(10, 20)));
282+
}
283+
268284
private void addDoc(String key, Map<String, Object> data) {
269285
MutableDocument doc = doc(key, 1, data);
270286
indexManager.addIndexEntries(doc);

0 commit comments

Comments
 (0)