compute static method

AliceStatsData compute(
  1. List<AliceHttpCall> callList
)

Computes all stats in a single, high-performance pass.

Implementation

static AliceStatsData compute(List<AliceHttpCall> callList) {
  int pending = 0;
  int success = 0;
  int redirection = 0;
  int error = 0;
  int bytesSent = 0;
  int bytesReceived = 0;
  int requestTimeSum = 0;
  int completedCount = 0;
  int maxRequestTime = 0;
  int minRequestTime = callList.isEmpty ? 0 : 10000000;
  int getCount = 0;
  int postCount = 0;
  int deleteCount = 0;
  int putCount = 0;
  int patchCount = 0;
  int securedCount = 0;
  int unsecuredCount = 0;
  int heavyPayloadCount = 0;

  final statusCodes = <int, int>{};
  final slowestCalls = <AliceHttpCall>[];
  final endpointMap = <String, List<AliceHttpCall>>{};

  for (final call in callList) {
    if (call.loading) {
      pending++;
    }

    final response = call.response;
    if (response != null) {
      final status = response.status;
      if (status >= 200 && status < 300) {
        success++;
      } else if (status >= 300 && status < 400) {
        redirection++;
      } else if (status >= 400 && status < 600) {
        error++;
      }

      if (status > 0) {
        statusCodes[status] = (statusCodes[status] ?? 0) + 1;
      }

      bytesReceived += response.size;
      if (response.size > 1024 * 1024) {
        heavyPayloadCount++;
      }
    }

    final request = call.request;
    if (request != null) {
      bytesSent += request.size;
    }

    if (!call.loading) {
      completedCount++;
      requestTimeSum += call.duration;
      maxRequestTime = math.max(maxRequestTime, call.duration);
      minRequestTime = math.min(minRequestTime, call.duration);
      slowestCalls.add(call);
    }

    final method = call.method.toUpperCase();
    switch (method) {
      case "GET":
        getCount++;
      case "POST":
        postCount++;
      case "DELETE":
        deleteCount++;
      case "PUT":
        putCount++;
      case "PATCH":
        patchCount++;
    }

    if (call.secure) {
      securedCount++;
    } else {
      unsecuredCount++;
    }

    // Group by method and endpoint
    final key = "$method ${call.endpoint}";
    (endpointMap[key] ??= []).add(call);
  }

  // Sort slowest calls descending
  slowestCalls.sort((a, b) => b.duration.compareTo(a.duration));

  // Build endpoint stats list
  final endpointStats = <AliceEndpointStats>[];
  for (final entry in endpointMap.entries) {
    final calls = entry.value;
    final first = calls.first;
    int epDurationSum = 0;
    int epErrorCount = 0;
    int epMinDuration = calls.first.duration;
    int epMaxDuration = 0;
    int epTotalBytes = 0;

    for (final c in calls) {
      epDurationSum += c.duration;
      epMaxDuration = math.max(epMaxDuration, c.duration);
      epMinDuration = math.min(epMinDuration, c.duration);
      if (c.error != null || ((c.response?.status ?? 0) >= 400)) {
        epErrorCount++;
      }
      if (c.response != null) {
        epTotalBytes += c.response!.size;
      }
    }

    endpointStats.add(
      AliceEndpointStats(
        method: first.method,
        endpoint: first.endpoint,
        server: first.server,
        count: calls.length,
        errorCount: epErrorCount,
        totalDuration: epDurationSum,
        minDuration: epMinDuration,
        maxDuration: epMaxDuration,
        totalBytes: epTotalBytes,
        calls: calls,
      ),
    );
  }

  // Sort endpoints by call count descending by default
  endpointStats.sort((a, b) => b.count.compareTo(a.count));

  return AliceStatsData(
    totalRequests: callList.length,
    pendingRequests: pending,
    successRequests: success,
    redirectionRequests: redirection,
    errorRequests: error,
    bytesSent: bytesSent,
    bytesReceived: bytesReceived,
    avgDuration: completedCount > 0 ? requestTimeSum ~/ completedCount : 0,
    minDuration: callList.isEmpty || completedCount == 0 ? 0 : minRequestTime,
    maxDuration: maxRequestTime,
    getCount: getCount,
    postCount: postCount,
    putCount: putCount,
    deleteCount: deleteCount,
    patchCount: patchCount,
    securedCount: securedCount,
    unsecuredCount: unsecuredCount,
    heavyPayloadCount: heavyPayloadCount,
    statusCodes: statusCodes,
    slowestCalls: slowestCalls,
    endpointStats: endpointStats,
  );
}