Remove reverse deps lazily, only when the node has finished building and we discover that it no longer has certain deps.

In the common case, where a node's deps do not change in the end, this reduces lock contention and CPU.

The downside of this is that we now create a set of the previous reverse deps during each evaluation of a node. We don't store this set in order to conserve memory, so we pay for it in CPU. We will probably only construct it two or three times (most SkyFunctions don't have so many groups), so the cost shouldn't be so high, but we can try to mitigate if it shows up in profiling.

--
MOS_MIGRATED_REVID=122566267
diff --git a/src/test/java/com/google/devtools/build/skyframe/NotifyingGraph.java b/src/test/java/com/google/devtools/build/skyframe/NotifyingGraph.java
index 7e76b8f..bf3ab1b 100644
--- a/src/test/java/com/google/devtools/build/skyframe/NotifyingGraph.java
+++ b/src/test/java/com/google/devtools/build/skyframe/NotifyingGraph.java
@@ -18,6 +18,7 @@
 import com.google.common.collect.Maps;
 import com.google.common.collect.Maps.EntryTransformer;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
+import com.google.devtools.build.lib.util.GroupedList;
 
 import java.util.Map;
 import java.util.Set;
@@ -115,6 +116,7 @@
     CREATE_IF_ABSENT,
     ADD_REVERSE_DEP,
     REMOVE_REVERSE_DEP,
+    GET_TEMPORARY_DIRECT_DEPS,
     SIGNAL,
     SET_VALUE,
     MARK_DIRTY,
@@ -204,6 +206,12 @@
     }
 
     @Override
+    public GroupedList<SkyKey> getTemporaryDirectDeps() {
+      graphListener.accept(myKey, EventType.GET_TEMPORARY_DIRECT_DEPS, Order.BEFORE, null);
+      return super.getTemporaryDirectDeps();
+    }
+
+    @Override
     public boolean signalDep(Version childVersion) {
       graphListener.accept(myKey, EventType.SIGNAL, Order.BEFORE, childVersion);
       boolean result = super.signalDep(childVersion);