Skip to content

Support deleteAllIndexes in PersistentCacheIndexManager #5162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ public void testAutoIndexCreationSetSuccessfully() {

results = waitFor(collection.whereEqualTo("match", true).get());
assertEquals(1, results.size());

assertDoesNotThrow(() -> db.getPersistentCacheIndexManager().deleteAllIndexes());
assertEquals(1, results.size());
}

@Test
Expand All @@ -161,6 +164,9 @@ public void testAutoIndexCreationSetSuccessfullyUsingDefault() {

results = waitFor(collection.whereEqualTo("match", true).get());
assertEquals(1, results.size());

assertDoesNotThrow(() -> db.getPersistentCacheIndexManager().deleteAllIndexes());
assertEquals(1, results.size());
}

@Test
Expand All @@ -175,5 +181,9 @@ public void testAutoIndexCreationAfterFailsTermination() {
expectError(
() -> db.getPersistentCacheIndexManager().disableIndexAutoCreation(),
"The client has already been terminated");

expectError(
() -> db.getPersistentCacheIndexManager().deleteAllIndexes(),
"The client has already been terminated");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,12 @@ public void enableIndexAutoCreation() {
public void disableIndexAutoCreation() {
client.setIndexAutoCreationEnabled(false);
}

/**
* Removes all persistent cache indexes. Please note this function will also deletes indexes
* generated by {@link FirebaseFirestore#setIndexConfiguration(String)}, which is deprecated.
*/
public void deleteAllIndexes() {
client.deleteAllFieldIndexes();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,11 @@ public void setIndexAutoCreationEnabled(boolean enabled) {
asyncQueue.enqueueAndForget(() -> localStore.setIndexAutoCreationEnabled(enabled));
}

public void deleteAllFieldIndexes() {
verifyNotTerminated();
asyncQueue.enqueueAndForget(() -> localStore.deleteAllFieldIndexes());
}

public void removeSnapshotsInSyncListener(EventListener<Void> listener) {
// Checks for shutdown but does not raise error, allowing remove after shutdown to be a no-op.
if (isTerminated()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ enum IndexType {
/** Removes the given field index and deletes all index values. */
void deleteFieldIndex(FieldIndex index);

/** Removes all field indexes and deletes all index values. */
void deleteAllFieldIndexes();

/** Creates a full matched field index which serves the given target. */
void createTargetIndexes(Target target);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,10 @@ public void configureFieldIndexes(List<FieldIndex> newFieldIndexes) {
});
}

public void deleteAllFieldIndexes() {
persistence.runTransaction("Delete All Indexes", () -> indexManager.deleteAllFieldIndexes());
}

public void setIndexAutoCreationEnabled(boolean enabled) {
queryEngine.setIndexAutoCreationEnabled(enabled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public void deleteFieldIndex(FieldIndex index) {
// Field indices are not supported with memory persistence.
}

@Override
public void deleteAllFieldIndexes() {
// Field indices are not supported with memory persistence.
}

@Override
public void createTargetIndexes(Target target) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,16 @@ public void deleteFieldIndex(FieldIndex index) {
}
}

@Override
public void deleteAllFieldIndexes() {
db.execute("DELETE FROM index_configuration");
db.execute("DELETE FROM index_entries");
db.execute("DELETE FROM index_state");

nextIndexToUpdate.clear();
memoizedIndexes.clear();
}

@Override
public void createTargetIndexes(Target target) {
hardAssert(started, "IndexManager not started");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ protected void setRelativeIndexReadCostPerDocument(double newCost) {
queryEngine.setRelativeIndexReadCostPerDocument(newCost);
}

protected void deleteAllIndexes() {
localStore.deleteAllFieldIndexes();
}

private void releaseTarget(int targetId) {
localStore.releaseTarget(targetId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,68 @@ public void testDisableIndexAutoCreationWorks() {
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2);
}

@Test
public void testDeleteAllIndexesWorksWithIndexAutoCreation() {
Query query = query("coll").filter(filter("value", "==", "match"));
int targetId = allocateQuery(query);

setIndexAutoCreationEnabled(true);
setMinCollectionSizeToAutoCreateIndex(0);
setRelativeIndexReadCostPerDocument(2);

applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("value", "match")), targetId));
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("value", Double.NaN)), targetId));
applyRemoteEvent(addedRemoteEvent(doc("coll/c", 10, map("value", null)), targetId));
applyRemoteEvent(addedRemoteEvent(doc("coll/d", 10, map("value", "mismatch")), targetId));
applyRemoteEvent(addedRemoteEvent(doc("coll/e", 10, map("value", "match")), targetId));

// First time query is running without indexes.
// Based on current heuristic, collection document counts (5) > 2 * resultSize (2).
// Full matched index should be created.
executeQuery(query);
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2);
assertQueryReturned("coll/a", "coll/e");

setIndexAutoCreationEnabled(false);

backfillIndexes();

executeQuery(query);
assertRemoteDocumentsRead(/* byKey= */ 2, /* byCollection= */ 0);
assertQueryReturned("coll/a", "coll/e");

deleteAllIndexes();

executeQuery(query);
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2);
assertQueryReturned("coll/a", "coll/e");
}

@Test
public void testDeleteAllIndexesWorksWithManualAddedIndexes() {
FieldIndex index =
fieldIndex(
"coll", 0, FieldIndex.INITIAL_STATE, "matches", FieldIndex.Segment.Kind.ASCENDING);
configureFieldIndexes(singletonList(index));

Query query = query("coll").filter(filter("matches", "==", true));
int targetId = allocateQuery(query);

applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId));

backfillIndexes();

executeQuery(query);
assertRemoteDocumentsRead(/* byKey= */ 1, /* byCollection= */ 0);
assertQueryReturned("coll/a");

deleteAllIndexes();

executeQuery(query);
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 1);
assertQueryReturned("coll/a");
}

@Test
public void testIndexAutoCreationWorksWithMutation() {
Query query =
Expand Down