/*
 * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
 *
 * License: GNU GPL, version 2 or later.
 *   See the COPYING file in the top-level directory.
 */
#include "qemu/osdep.h"
#include "qemu/processor.h"
#include "qemu/atomic.h"
#include "qemu/qht.h"
#include "qemu/rcu.h"
#include "exec/tb-hash-xx.h"

struct thread_stats {
    size_t rd;
    size_t not_rd;
    size_t in;
    size_t not_in;
    size_t rm;
    size_t not_rm;
    size_t rz;
    size_t not_rz;
};

struct thread_info {
    void (*func)(struct thread_info *);
    struct thread_stats stats;
    uint64_t r;
    bool write_op; /* writes alternate between insertions and removals */
    bool resize_down;
} QEMU_ALIGNED(64); /* avoid false sharing among threads */

static struct qht ht;
static QemuThread *rw_threads;

#define DEFAULT_RANGE (4096)
#define DEFAULT_QHT_N_ELEMS DEFAULT_RANGE

static unsigned int duration = 1;
static unsigned int n_rw_threads = 1;
static unsigned long lookup_range = DEFAULT_RANGE;
static unsigned long update_range = DEFAULT_RANGE;
static size_t init_range = DEFAULT_RANGE;
static size_t init_size = DEFAULT_RANGE;
static size_t n_ready_threads;
static long populate_offset;
static long *keys;

static size_t resize_min;
static size_t resize_max;
static struct thread_info *rz_info;
static unsigned long resize_delay = 1000;
static double resize_rate; /* 0.0 to 1.0 */
static unsigned int n_rz_threads = 1;
static QemuThread *rz_threads;
static bool precompute_hash;

static double update_rate; /* 0.0 to 1.0 */
static uint64_t update_threshold;
static uint64_t resize_threshold;

static size_t qht_n_elems = DEFAULT_QHT_N_ELEMS;
static int qht_mode;

static bool test_start;
static bool test_stop;

static struct thread_info *rw_info;

static const char commands_string[] =
    " -d = duration, in seconds\n"
    " -n = number of threads\n"
    "\n"
    " -o = offset at which keys start\n"
    "\n"
    " -g = set -s,-k,-K,-l,-r to the same value\n"
    " -s = initial size hint\n"
    " -k = initial number of keys\n"
    " -K = initial range of keys (will be rounded up to pow2)\n"
    " -l = lookup range of keys (will be rounded up to pow2)\n"
    " -r = update range of keys (will be rounded up to pow2)\n"
    "\n"
    " -u = update rate (0.0 to 100.0), 50/50 split of insertions/removals\n"
    "\n"
    " -R = enable auto-resize\n"
    " -S = resize rate (0.0 to 100.0)\n"
    " -D = delay (in us) between potential resizes\n"
    " -N = number of resize threads";

static void usage_complete(int argc, char *argv[])
{
    fprintf(stderr, "Usage: %s [options]\n", argv[0]);
    fprintf(stderr, "options:\n%s\n", commands_string);
    exit(-1);
}

static bool is_equal(const void *ap, const void *bp)
{
    const long *a = ap;
    const long *b = bp;

    return *a == *b;
}

static uint32_t h(unsigned long v)
{
    return tb_hash_func7(v, 0, 0, 0, 0);
}

static uint32_t hval(unsigned long v)
{
    return v;
}

static uint32_t (*hfunc)(unsigned long v) = h;

/*
 * From: https://en.wikipedia.org/wiki/Xorshift
 * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
 * guaranteed to be >= INT_MAX).
 */
static uint64_t xorshift64star(uint64_t x)
{
    x ^= x >> 12; /* a */
    x ^= x << 25; /* b */
    x ^= x >> 27; /* c */
    return x * UINT64_C(2685821657736338717);
}

static void do_rz(struct thread_info *info)
{
    struct thread_stats *stats = &info->stats;

    if (info->r < resize_threshold) {
        size_t size = info->resize_down ? resize_min : resize_max;
        bool resized;

        resized = qht_resize(&ht, size);
        info->resize_down = !info->resize_down;

        if (resized) {
            stats->rz++;
        } else {
            stats->not_rz++;
        }
    }
    g_usleep(resize_delay);
}

static void do_rw(struct thread_info *info)
{
    struct thread_stats *stats = &info->stats;
    uint32_t hash;
    long *p;

    if (info->r >= update_threshold) {
        bool read;

        p = &keys[info->r & (lookup_range - 1)];
        hash = hfunc(*p);
        read = qht_lookup(&ht, p, hash);
        if (read) {
            stats->rd++;
        } else {
            stats->not_rd++;
        }
    } else {
        p = &keys[info->r & (update_range - 1)];
        hash = hfunc(*p);
        if (info->write_op) {
            bool written = false;

            if (qht_lookup(&ht, p, hash) == NULL) {
                written = qht_insert(&ht, p, hash, NULL);
            }
            if (written) {
                stats->in++;
            } else {
                stats->not_in++;
            }
        } else {
            bool removed = false;

            if (qht_lookup(&ht, p, hash)) {
                removed = qht_remove(&ht, p, hash);
            }
            if (removed) {
                stats->rm++;
            } else {
                stats->not_rm++;
            }
        }
        info->write_op = !info->write_op;
    }
}

static void *thread_func(void *p)
{
    struct thread_info *info = p;

    rcu_register_thread();

    atomic_inc(&n_ready_threads);
    while (!atomic_read(&test_start)) {
        cpu_relax();
    }

    rcu_read_lock();
    while (!atomic_read(&test_stop)) {
        info->r = xorshift64star(info->r);
        info->func(info);
    }
    rcu_read_unlock();

    rcu_unregister_thread();
    return NULL;
}

/* sets everything except info->func */
static void prepare_thread_info(struct thread_info *info, int i)
{
    /* seed for the RNG; each thread should have a different one */
    info->r = (i + 1) ^ time(NULL);
    /* the first update will be a write */
    info->write_op = true;
    /* the first resize will be down */
    info->resize_down = true;

    memset(&info->stats, 0, sizeof(info->stats));
}

static void
th_create_n(QemuThread **threads, struct thread_info **infos, const char *name,
            void (*func)(struct thread_info *), int offset, int n)
{
    struct thread_info *info;
    QemuThread *th;
    int i;

    th = g_malloc(sizeof(*th) * n);
    *threads = th;

    info = qemu_memalign(64, sizeof(*info) * n);
    *infos = info;

    for (i = 0; i < n; i++) {
        prepare_thread_info(&info[i], offset + i);
        info[i].func = func;
        qemu_thread_create(&th[i], name, thread_func, &info[i],
                           QEMU_THREAD_JOINABLE);
    }
}

static void create_threads(void)
{
    th_create_n(&rw_threads, &rw_info, "rw", do_rw, 0, n_rw_threads);
    th_create_n(&rz_threads, &rz_info, "rz", do_rz, n_rw_threads, n_rz_threads);
}

static void pr_params(void)
{
    printf("Parameters:\n");
    printf(" duration:          %d s\n", duration);
    printf(" # of threads:      %u\n", n_rw_threads);
    printf(" initial # of keys: %zu\n", init_size);
    printf(" initial size hint: %zu\n", qht_n_elems);
    printf(" auto-resize:       %s\n",
           qht_mode & QHT_MODE_AUTO_RESIZE ? "on" : "off");
    if (resize_rate) {
        printf(" resize_rate:       %f%%\n", resize_rate * 100.0);
        printf(" resize range:      %zu-%zu\n", resize_min, resize_max);
        printf(" # resize threads   %u\n", n_rz_threads);
    }
    printf(" update rate:       %f%%\n", update_rate * 100.0);
    printf(" offset:            %ld\n", populate_offset);
    printf(" initial key range: %zu\n", init_range);
    printf(" lookup range:      %lu\n", lookup_range);
    printf(" update range:      %lu\n", update_range);
}

static void do_threshold(double rate, uint64_t *threshold)
{
    if (rate == 1.0) {
        *threshold = UINT64_MAX;
    } else {
        *threshold = rate * UINT64_MAX;
    }
}

static void htable_init(void)
{
    unsigned long n = MAX(init_range, update_range);
    uint64_t r = time(NULL);
    size_t retries = 0;
    size_t i;

    /* avoid allocating memory later by allocating all the keys now */
    keys = g_malloc(sizeof(*keys) * n);
    for (i = 0; i < n; i++) {
        long val = populate_offset + i;

        keys[i] = precompute_hash ? h(val) : hval(val);
    }

    /* some sanity checks */
    g_assert_cmpuint(lookup_range, <=, n);

    /* compute thresholds */
    do_threshold(update_rate, &update_threshold);
    do_threshold(resize_rate, &resize_threshold);

    if (resize_rate) {
        resize_min = n / 2;
        resize_max = n;
        assert(resize_min < resize_max);
    } else {
        n_rz_threads = 0;
    }

    /* initialize the hash table */
    qht_init(&ht, is_equal, qht_n_elems, qht_mode);
    assert(init_size <= init_range);

    pr_params();

    fprintf(stderr, "Initialization: populating %zu items...", init_size);
    for (i = 0; i < init_size; i++) {
        for (;;) {
            uint32_t hash;
            long *p;

            r = xorshift64star(r);
            p = &keys[r & (init_range - 1)];
            hash = hfunc(*p);
            if (qht_insert(&ht, p, hash, NULL)) {
                break;
            }
            retries++;
        }
    }
    fprintf(stderr, " populated after %zu retries\n", retries);
}

static void add_stats(struct thread_stats *s, struct thread_info *info, int n)
{
    int i;

    for (i = 0; i < n; i++) {
        struct thread_stats *stats = &info[i].stats;

        s->rd += stats->rd;
        s->not_rd += stats->not_rd;

        s->in += stats->in;
        s->not_in += stats->not_in;

        s->rm += stats->rm;
        s->not_rm += stats->not_rm;

        s->rz += stats->rz;
        s->not_rz += stats->not_rz;
    }
}

static void pr_stats(void)
{
    struct thread_stats s = {};
    double tx;

    add_stats(&s, rw_info, n_rw_threads);
    add_stats(&s, rz_info, n_rz_threads);

    printf("Results:\n");

    if (resize_rate) {
        printf(" Resizes:           %zu (%.2f%% of %zu)\n",
               s.rz, (double)s.rz / (s.rz + s.not_rz) * 100, s.rz + s.not_rz);
    }

    printf(" Read:              %.2f M (%.2f%% of %.2fM)\n",
           (double)s.rd / 1e6,
           (double)s.rd / (s.rd + s.not_rd) * 100,
           (double)(s.rd + s.not_rd) / 1e6);
    printf(" Inserted:          %.2f M (%.2f%% of %.2fM)\n",
           (double)s.in / 1e6,
           (double)s.in / (s.in + s.not_in) * 100,
           (double)(s.in + s.not_in) / 1e6);
    printf(" Removed:           %.2f M (%.2f%% of %.2fM)\n",
           (double)s.rm / 1e6,
           (double)s.rm / (s.rm + s.not_rm) * 100,
           (double)(s.rm + s.not_rm) / 1e6);

    tx = (s.rd + s.not_rd + s.in + s.not_in + s.rm + s.not_rm) / 1e6 / duration;
    printf(" Throughput:        %.2f MT/s\n", tx);
    printf(" Throughput/thread: %.2f MT/s/thread\n", tx / n_rw_threads);
}

static void run_test(void)
{
    unsigned int remaining;
    int i;

    while (atomic_read(&n_ready_threads) != n_rw_threads + n_rz_threads) {
        cpu_relax();
    }
    atomic_set(&test_start, true);
    do {
        remaining = sleep(duration);
    } while (remaining);
    atomic_set(&test_stop, true);

    for (i = 0; i < n_rw_threads; i++) {
        qemu_thread_join(&rw_threads[i]);
    }
    for (i = 0; i < n_rz_threads; i++) {
        qemu_thread_join(&rz_threads[i]);
    }
}

static void parse_args(int argc, char *argv[])
{
    int c;

    for (;;) {
        c = getopt(argc, argv, "d:D:g:k:K:l:hn:N:o:pr:Rs:S:u:");
        if (c < 0) {
            break;
        }
        switch (c) {
        case 'd':
            duration = atoi(optarg);
            break;
        case 'D':
            resize_delay = atol(optarg);
            break;
        case 'g':
            init_range = pow2ceil(atol(optarg));
            lookup_range = pow2ceil(atol(optarg));
            update_range = pow2ceil(atol(optarg));
            qht_n_elems = atol(optarg);
            init_size = atol(optarg);
            break;
        case 'h':
            usage_complete(argc, argv);
            exit(0);
        case 'k':
            init_size = atol(optarg);
            break;
        case 'K':
            init_range = pow2ceil(atol(optarg));
            break;
        case 'l':
            lookup_range = pow2ceil(atol(optarg));
            break;
        case 'n':
            n_rw_threads = atoi(optarg);
            break;
        case 'N':
            n_rz_threads = atoi(optarg);
            break;
        case 'o':
            populate_offset = atol(optarg);
            break;
        case 'p':
            precompute_hash = true;
            hfunc = hval;
            break;
        case 'r':
            update_range = pow2ceil(atol(optarg));
            break;
        case 'R':
            qht_mode |= QHT_MODE_AUTO_RESIZE;
            break;
        case 's':
            qht_n_elems = atol(optarg);
            break;
        case 'S':
            resize_rate = atof(optarg) / 100.0;
            if (resize_rate > 1.0) {
                resize_rate = 1.0;
            }
            break;
        case 'u':
            update_rate = atof(optarg) / 100.0;
            if (update_rate > 1.0) {
                update_rate = 1.0;
            }
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    parse_args(argc, argv);
    htable_init();
    create_threads();
    run_test();
    pr_stats();
    return 0;
}
