Optimize the 'path_owners_entries' cache eviction

The OWNERS file can be present either under the `refs/meta/config` or
`refs/heads/*` ref. Ignore evictions to All-Users project and to other
(gerrit technical refs).

Bug: Issue 16830
Change-Id: I2c2d4a6ec3950f7890ae1d8e372f71bffcc7796b
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java
index 07be702..c2ec085 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java
@@ -15,11 +15,13 @@
 package com.googlesource.gerrit.owners.common;
 
 import com.google.common.cache.RemovalNotification;
+import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.server.cache.CacheModule;
 import com.google.gerrit.server.cache.CacheRemovalListener;
+import com.google.gerrit.server.config.AllUsersName;
 import com.google.inject.Inject;
 import com.google.inject.Module;
 import com.google.inject.Singleton;
@@ -103,15 +105,25 @@
   @Singleton
   class OwnersRefUpdateListener implements GitReferenceUpdatedListener {
     private final PathOwnersEntriesCache cache;
+    private final String allUsersName;
 
     @Inject
-    OwnersRefUpdateListener(PathOwnersEntriesCache cache) {
+    OwnersRefUpdateListener(PathOwnersEntriesCache cache, AllUsersName allUsersName) {
       this.cache = cache;
+      this.allUsersName = allUsersName.get();
     }
 
     @Override
     public void onGitReferenceUpdated(Event event) {
-      cache.invalidate(event.getProjectName(), event.getRefName());
+      if (supportedEvent(allUsersName, event)) {
+        cache.invalidate(event.getProjectName(), event.getRefName());
+      }
+    }
+
+    static boolean supportedEvent(String allUsersName, Event event) {
+      String refName = event.getRefName();
+      return !allUsersName.equals(event.getProjectName())
+          && (refName.equals(RefNames.REFS_CONFIG) || !RefNames.isGerritRef(refName));
     }
   }
 
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/OwnersRefUpdateListenerTest.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/OwnersRefUpdateListenerTest.java
new file mode 100644
index 0000000..fa20c79
--- /dev/null
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/OwnersRefUpdateListenerTest.java
@@ -0,0 +1,72 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.owners.common;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
+import com.google.gerrit.server.config.AllProjectsNameProvider;
+import com.google.gerrit.server.config.AllUsersNameProvider;
+import com.googlesource.gerrit.owners.common.PathOwnersEntriesCache.OwnersRefUpdateListener;
+import java.util.Arrays;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class OwnersRefUpdateListenerTest {
+  @Parameterized.Parameters
+  public static Collection<Object[]> events() {
+    return Arrays.asList(
+        new Object[][] {
+          {mockEvent(ALL_USERS_NAME, null), false},
+          {mockEvent(AllProjectsNameProvider.DEFAULT, RefNames.REFS_CHANGES), false},
+          {mockEvent(AllProjectsNameProvider.DEFAULT, RefNames.REFS_SEQUENCES), false},
+          {mockEvent(AllProjectsNameProvider.DEFAULT, RefNames.REFS_CONFIG), true},
+          {mockEvent("foo", RefNames.fullName("bar")), true},
+          {mockEvent("foo", RefNames.REFS_CONFIG), true}
+        });
+  }
+
+  private static String ALL_USERS_NAME = AllUsersNameProvider.DEFAULT;
+
+  private final GitReferenceUpdatedListener.Event input;
+  private final boolean expected;
+
+  public OwnersRefUpdateListenerTest(GitReferenceUpdatedListener.Event input, boolean expected) {
+    this.input = input;
+    this.expected = expected;
+  }
+
+  @Test
+  public void shouldParseLabelDefinition() {
+    // when
+    boolean result = OwnersRefUpdateListener.supportedEvent(ALL_USERS_NAME, input);
+
+    // then
+    assertThat(result).isEqualTo(expected);
+  }
+
+  private static GitReferenceUpdatedListener.Event mockEvent(String project, String ref) {
+    GitReferenceUpdatedListener.Event eventMock = mock(GitReferenceUpdatedListener.Event.class);
+    when(eventMock.getProjectName()).thenReturn(project);
+    when(eventMock.getRefName()).thenReturn(ref);
+    return eventMock;
+  }
+}