docs: private <T> QueryRunner<T> withPerSinkMetrics(
        final QueryRunner<T> sinkRunner,
        final QueryToolChest<T, ? extends Query<T>> queryToolChest,
        final SegmentId sinkSegmentId,
        final AtomicLong cpuTimeAccumulator
    )
    {
      // Note: reportSegmentAndCacheTime and reportSegmentTime are effectively the same here. They don't split apart
      // cache vs. non-cache due to the fact that Sinks may be partially cached and partially uncached. Making this
      // better would need to involve another accumulator like the cpuTimeAccumulator that we could share with the
      // sinkRunner.
      String sinkSegmentIdString = sinkSegmentId.toString();
      return CPUTimeMetricQueryRunner.safeBuild(
          new MetricsEmittingQueryRunner<>(
              emitter,
              queryToolChest,
              new MetricsEmittingQueryRunner<>(
                  emitter,
                  queryToolChest,
                  sinkRunner,
                  QueryMetrics::reportSegmentTime,
                  queryMetrics -> queryMetrics.segment(sinkSegmentIdString)
              ),
              QueryMetrics::reportSegmentAndCacheTime,
              queryMetrics -> queryMetrics.segment(sinkSegmentIdString)
          ).withWaitMeasuredFromNow(),
          queryToolChest,
          emitter,
          cpuTimeAccumulator,
          false
      );
    }