[current results] Drop configurations and test names not seen for a week

Change-Id: I055200c9b016cbd5dcad3d53f744c79235fc39b1
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/172601
Reviewed-by: Karl Klose <karlklose@google.com>
diff --git a/current_results/bin/server.dart b/current_results/bin/server.dart
index 0869124..4d267ec 100644
--- a/current_results/bin/server.dart
+++ b/current_results/bin/server.dart
@@ -30,7 +30,10 @@
   final configurationDirectories = await bucket.configurationDirectories();
   await Pool(10).forEach(configurationDirectories,
       (configurationDirectory) async {
-    final results = await bucket.latestResults(configurationDirectory);
-    current.add(results);
+    final resultsDate = await bucket.latestResultsDate(configurationDirectory);
+    if (DateTime.now().difference(resultsDate) <= maximumAge) {
+      final results = await bucket.latestResults(configurationDirectory);
+      current.add(results);
+    }
   }).drain();
 }
diff --git a/current_results/lib/src/api_impl.dart b/current_results/lib/src/api_impl.dart
index 99241e7..3971eda 100644
--- a/current_results/lib/src/api_impl.dart
+++ b/current_results/lib/src/api_impl.dart
@@ -62,6 +62,8 @@
       response.updates
           .add(ConfigurationUpdate()..configuration = configuration);
     }
+    current.dropResultsOlderThan(maximumAge);
+    current.collectTestNames();
     return response;
   }
 }
diff --git a/current_results/lib/src/bucket.dart b/current_results/lib/src/bucket.dart
index 1543258..eb56208 100644
--- a/current_results/lib/src/bucket.dart
+++ b/current_results/lib/src/bucket.dart
@@ -27,6 +27,11 @@
       .map((entry) => entry.name)
       .toList();
 
+  Future<DateTime> latestResultsDate(String configurationDirectory) async {
+    final info = await bucket.info('${configurationDirectory}latest');
+    return info.updated;
+  }
+
   Future<List<String>> latestResults(String configurationDirectory) async {
     try {
       final revision = await bucket
diff --git a/current_results/lib/src/slice.dart b/current_results/lib/src/slice.dart
index e1baac0..c6cc1f6 100644
--- a/current_results/lib/src/slice.dart
+++ b/current_results/lib/src/slice.dart
@@ -12,6 +12,8 @@
 import 'package:current_results/src/generated/result.pb.dart' as api;
 import 'package:current_results/src/iterable.dart';
 
+const maximumAge = Duration(days: 7);
+
 int compareNames(Result a, Result b) => a.name.compareTo(b.name);
 
 /// All result names before or starting with [prefix] are "before" prefix.
@@ -43,6 +45,9 @@
   /// list sorted by test name.
   final _stored = <String, List<Result>>{};
 
+  /// The date on which the current results of a configuration were fetched
+  final _lastFetched = <String, DateTime>{};
+
   /// A sorted list of all test names seen. Names are not removed from this list.
   List<String> testNames = [];
   int _size = 0;
@@ -63,12 +68,19 @@
     final sorted = results.toList()..sort(compareNames);
     _size -= _stored[configuration]?.length ?? 0;
     _stored[configuration] = sorted;
+    _lastFetched[configuration] = DateTime.now();
     _size += sorted.length;
-    testNames = _mergeIfNeeded(testNames, sorted);
     print('latest results of $configuration: ${sorted.length} results '
         '(total: $_size)');
   }
 
+  void collectTestNames() {
+    testNames.clear();
+    for (final results in _stored.values) {
+      testNames = _mergeIfNeeded(testNames, results);
+    }
+  }
+
   static List<String> _mergeIfNeeded(List<String> names, List<Result> sorted) {
     var i = 0;
     var j = 0;
@@ -102,8 +114,6 @@
     while (j < sorted.length) {
       result.add(sorted[j++].name);
     }
-    print('Added ${result.length - names.length} new test names '
-        '(total ${result.length})');
     return result;
   }
 
@@ -214,6 +224,17 @@
     }
     return response;
   }
+
+  void dropResultsOlderThan(Duration maximumAge) {
+    final now = DateTime.now();
+    for (final configuration in _lastFetched.keys.toList()) {
+      if (now.difference(_lastFetched[configuration]) > maximumAge) {
+        _size -= _stored[configuration].length;
+        _stored.remove(configuration);
+        _lastFetched.remove(configuration);
+      }
+    }
+  }
 }
 
 class PageStart {