#include <benchmark/benchmark.h>

#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <vector>
#include <tuple>

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

using namespace std;
static const size_t pageSize = PAGE_SIZE;
static size_t fsize = 1024 * (1ull << 20);
static size_t pagesTotal = fsize / pageSize;

class Fd {
    int m_fd = -1;
public:
    int get() { return m_fd; }
    void set(int fd) { m_fd = fd; }
    Fd() {}
    explicit Fd(int fd) : m_fd{fd} {}
    ~Fd() {
        if (m_fd >= 0)
            close(m_fd);
    }
};

int dummy = 0;

void fillPageJunk(void *ptr)
{
    uint64_t seed = (unsigned long long)rand() | ((unsigned long long)rand() << 32);
    uint64_t *target = (uint64_t*)ptr;
    for (int i = 0; i < pageSize / sizeof(uint64_t); i++) {
        *target = seed ^ (uint64_t)(uintptr_t)target;
        seed = (seed << 1) | ((seed >> 63) & 1);
        target++;
    }
}

class FileMap {
    string m_name;
    size_t m_size;
    void *m_ptr = nullptr;
    Fd m_fileFd;
public:
    enum Hint {
       FILE_MAP_HINT_NONE,
       FILE_MAP_HINT_RAND,
       FILE_MAP_HINT_LINEAR,
    };
    FileMap(const string &name, size_t size, Hint hint = FILE_MAP_HINT_NONE) : m_name{name}, m_size{size} {
        int fd = open(name.c_str(), O_CREAT | O_RDWR, S_IRWXU);
        if (fd < 0) {
            cout << "Error: open failed for " << name << ": " << strerror(errno) << endl;
            exit(1);
        }
        m_fileFd.set(fd);
        fallocate(m_fileFd.get(), 0, 0, size);
        unlink(name.c_str());
        m_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fileFd.get(), 0);
        if ((int)(uintptr_t)m_ptr == -1) {
            cout << "Error: mmap failed: " << (int)(uintptr_t)m_ptr << ": " << strerror(errno) << endl;
            exit(1);
        }
        switch (hint) {
        case FILE_MAP_HINT_NONE: break;
        case FILE_MAP_HINT_RAND:
            madvise(m_ptr, m_size, MADV_RANDOM);
            break;
        case FILE_MAP_HINT_LINEAR:
            madvise(m_ptr, m_size, MADV_SEQUENTIAL);
            break;
        }
        for (int i = 0; i < m_size / pageSize; i++) {
            uint8_t *targetPtr = (uint8_t*)m_ptr + 4096ull * i;
            fillPageJunk(targetPtr);
        }
    }
    void benchRandomRead(unsigned int targetPage) {
        uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * targetPage;
        dummy += *targetPtr;
    }
    void benchRandomWrite(unsigned int targetPage) {
        uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * targetPage;
        *targetPtr = dummy;
    }
    void benchLinearRead(unsigned int j) {
        uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * j;
        dummy += *targetPtr;
    }
    void benchLinearWrite(unsigned int j) {
        uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * j;
        *targetPtr = dummy;
    }
    void dropCache() {
        int ret1 = msync(m_ptr, m_size, MS_SYNC | MS_INVALIDATE);
        madvise(m_ptr, m_size, MADV_DONTNEED);
        (void)ret1;
    }
    ~FileMap() {
        if (m_ptr)
            munmap(m_ptr, m_size);
    }

};

static void benchRandomRead(benchmark::State& state) {
    FileMap file{"/data/local/tmp/mmap_test", fsize};
    while (state.KeepRunning()) {
        unsigned int targetPage = rand() % pagesTotal;
        file.benchRandomRead(targetPage);
    }
    state.SetBytesProcessed(state.iterations() * pageSize);
}
BENCHMARK(benchRandomRead);

static void benchRandomWrite(benchmark::State& state) {
    FileMap file{"/data/local/tmp/mmap_test", fsize};
    while (state.KeepRunning()) {
        unsigned int targetPage = rand() % pagesTotal;
        file.benchRandomWrite(targetPage);
    }
    state.SetBytesProcessed(state.iterations() * pageSize);
}
BENCHMARK(benchRandomWrite);

static void benchLinearRead(benchmark::State& state) {
   FileMap file{"/data/local/tmp/mmap_test", fsize};
   unsigned int j = 0;
   while (state.KeepRunning()) {
       file.benchLinearRead(j);
       j = (j + 1) % pagesTotal;
   }
   state.SetBytesProcessed(state.iterations() * pageSize);
}
BENCHMARK(benchLinearRead);

static void benchLinearWrite(benchmark::State& state) {
   FileMap file{"/data/local/tmp/mmap_test", fsize};
   unsigned int j = 0;
   while (state.KeepRunning()) {
       file.benchLinearWrite(j);
       j = (j + 1) % pagesTotal;
   }
   state.SetBytesProcessed(state.iterations() * pageSize);
}
BENCHMARK(benchLinearWrite);

BENCHMARK_MAIN();
