/*
 * 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 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 inline uint32_t h(unsigned long v)
{
    return tb_hash_func7(v, 0, 0, 0, 0);
}

/*
 * 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 = h(*p);
        read = qht_lookup(&ht, p, hash);
        if (read) {
            stats->rd++;
        } else {
            stats->not_rd++;
        }
    } else {
        p = &keys[info->r & (update_range - 1)];
        hash = h(*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++) {
        keys[i] = populate_offset + i;
    }

    /* 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 = h(*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:r: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 '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;
}
