update method

  1. @override
Future<void> update(
  1. List<MetricPoint> points,
  2. DateTime commitTime,
  3. String taskName
)
override

Insert new data points or modify old ones with matching id.

Implementation

@override
Future<void> update(
    List<MetricPoint> points, DateTime commitTime, String taskName) async {
  // 1st, create a map based on git repo, git revision, and point id. Git repo
  // and git revision are the top level components of the Skia perf GCS object
  // name.
  final Map<String, Map<String?, Map<String, SkiaPerfPoint>>> pointMap =
      <String, Map<String, Map<String, SkiaPerfPoint>>>{};
  for (final SkiaPerfPoint p
      in points.map((MetricPoint x) => SkiaPerfPoint.fromPoint(x))) {
    pointMap[p.githubRepo] ??= <String, Map<String, SkiaPerfPoint>>{};
    pointMap[p.githubRepo]![p.gitHash] ??= <String, SkiaPerfPoint>{};
    pointMap[p.githubRepo]![p.gitHash]![p.id] = p;
  }

  // All created locks must be released before returning
  final List<Future<void>> lockFutures = <Future<void>>[];

  // 2nd, read existing points from the gcs object and update with new ones.
  for (final String repo in pointMap.keys) {
    for (final String? revision in pointMap[repo]!.keys) {
      final String objectName = await SkiaPerfGcsAdaptor.computeObjectName(
          repo, revision, commitTime, taskName);
      final Map<String, SkiaPerfPoint>? newPoints = pointMap[repo]![revision];
      // Too many bots writing the metrics of a git revision into a single json
      // file will cause high contention on the lock. We use multiple
      // json files according to task names. Skia perf read all json files in
      // the directory so one can use arbitrary names for those sharded json
      // file names.
      lockFutures.add(
        _lock!.protectedRun('$objectName.lock', () async {
          final List<SkiaPerfPoint> oldPoints =
              await _gcs.readPoints(objectName);
          for (final SkiaPerfPoint p in oldPoints) {
            if (newPoints![p.id] == null) {
              newPoints[p.id] = p;
            }
          }
          await _gcs.writePoints(objectName, newPoints!.values.toList());
        }),
      );
    }
  }
  await Future.wait(lockFutures);
}