diff third_party/wrk/src/stats.c @ 178:94705b5986b3

[ThirdParty] Added WRK and luajit for load testing.
author MrJuneJune <me@mrjunejune.com>
date Thu, 22 Jan 2026 20:10:30 -0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/third_party/wrk/src/stats.c	Thu Jan 22 20:10:30 2026 -0800
@@ -0,0 +1,107 @@
+// Copyright (C) 2012 - Will Glozer.  All rights reserved.
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "stats.h"
+#include "zmalloc.h"
+
+stats *stats_alloc(uint64_t max) {
+    uint64_t limit = max + 1;
+    stats *s = zcalloc(sizeof(stats) + sizeof(uint64_t) * limit);
+    s->limit = limit;
+    s->min   = UINT64_MAX;
+    return s;
+}
+
+void stats_free(stats *stats) {
+    zfree(stats);
+}
+
+int stats_record(stats *stats, uint64_t n) {
+    if (n >= stats->limit) return 0;
+    __sync_fetch_and_add(&stats->data[n], 1);
+    __sync_fetch_and_add(&stats->count, 1);
+    uint64_t min = stats->min;
+    uint64_t max = stats->max;
+    while (n < min) min = __sync_val_compare_and_swap(&stats->min, min, n);
+    while (n > max) max = __sync_val_compare_and_swap(&stats->max, max, n);
+    return 1;
+}
+
+void stats_correct(stats *stats, int64_t expected) {
+    for (uint64_t n = expected * 2; n <= stats->max; n++) {
+        uint64_t count = stats->data[n];
+        int64_t m = (int64_t) n - expected;
+        while (count && m > expected) {
+            stats->data[m] += count;
+            stats->count += count;
+            m -= expected;
+        }
+    }
+}
+
+long double stats_mean(stats *stats) {
+    if (stats->count == 0) return 0.0;
+
+    uint64_t sum = 0;
+    for (uint64_t i = stats->min; i <= stats->max; i++) {
+        sum += stats->data[i] * i;
+    }
+    return sum / (long double) stats->count;
+}
+
+long double stats_stdev(stats *stats, long double mean) {
+    long double sum = 0.0;
+    if (stats->count < 2) return 0.0;
+    for (uint64_t i = stats->min; i <= stats->max; i++) {
+        if (stats->data[i]) {
+            sum += powl(i - mean, 2) * stats->data[i];
+        }
+    }
+    return sqrtl(sum / (stats->count - 1));
+}
+
+long double stats_within_stdev(stats *stats, long double mean, long double stdev, uint64_t n) {
+    long double upper = mean + (stdev * n);
+    long double lower = mean - (stdev * n);
+    uint64_t sum = 0;
+
+    for (uint64_t i = stats->min; i <= stats->max; i++) {
+        if (i >= lower && i <= upper) {
+            sum += stats->data[i];
+        }
+    }
+
+    return (sum / (long double) stats->count) * 100;
+}
+
+uint64_t stats_percentile(stats *stats, long double p) {
+    uint64_t rank = round((p / 100.0) * stats->count + 0.5);
+    uint64_t total = 0;
+    for (uint64_t i = stats->min; i <= stats->max; i++) {
+        total += stats->data[i];
+        if (total >= rank) return i;
+    }
+    return 0;
+}
+
+uint64_t stats_popcount(stats *stats) {
+    uint64_t count = 0;
+    for (uint64_t i = stats->min; i <= stats->max; i++) {
+        if (stats->data[i]) count++;
+    }
+    return count;
+}
+
+uint64_t stats_value_at(stats *stats, uint64_t index, uint64_t *count) {
+    *count = 0;
+    for (uint64_t i = stats->min; i <= stats->max; i++) {
+        if (stats->data[i] && (*count)++ == index) {
+            *count = stats->data[i];
+            return i;
+        }
+    }
+    return 0;
+}