/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkRandom.h"
#include "SkTSort.h"
#include "SkString.h"

#ifdef SK_DEBUG
// Windows-debug builds (at least) don't implement tail-recursion, and we have
// a bench that triggers a worst-case behavior in SkTQSort (w/ repeated keys)
// which can overflow the stack if N is too big. So we reduce it for debug
// builds (for which we don't care about sorting performance anyways).
static const int N = 100;
#else
static const int N = 1000;
#endif

static void rand_proc(int array[], int count) {
    SkRandom rand;
    for (int i = 0; i < count; ++i) {
        array[i] = rand.nextS();
    }
}

static void randN_proc(int array[], int count) {
    SkRandom rand;
    int mod = N / 10;
    for (int i = 0; i < count; ++i) {
        array[i] = rand.nextU() % mod;
    }
}

static void forward_proc(int array[], int count) {
    for (int i = 0; i < count; ++i) {
        array[i] = i;
    }
}

static void backward_proc(int array[], int count) {
    for (int i = 0; i < count; ++i) {
        array[i] = -i;
    }
}

static void same_proc(int array[], int count) {
    for (int i = 0; i < count; ++i) {
        array[i] = count;
    }
}

typedef void (*SortProc)(int array[], int count);

enum Type {
    kRand, kRandN, kFore, kBack, kSame
};

static const struct {
    const char* fName;
    SortProc    fProc;
} gRec[] = {
    { "rand", rand_proc },
    { "rand10", randN_proc },
    { "forward", forward_proc },
    { "backward", backward_proc },
    { "repeated", same_proc },
};

static void skqsort_sort(int array[], int count) {
    SkTQSort<int>(array, array + count);
}

static void skheap_sort(int array[], int count) {
    SkTHeapSort<int>(array, count);
}

extern "C" {
    static int int_compare(const void* a, const void* b) {
        const int ai = *(const int*)a;
        const int bi = *(const int*)b;
        return ai < bi ? -1 : (ai > bi);
    }
}

static void qsort_sort(int array[], int count) {
    qsort(array, count, sizeof(int), int_compare);
}

enum SortType {
    kSKQSort, kSKHeap, kQSort
};

static const struct {
    const char* fName;
    SortProc    fProc;
} gSorts[] = {
    { "skqsort", skqsort_sort },
    { "skheap", skheap_sort },
    { "qsort", qsort_sort },
};

class SortBench : public SkBenchmark {
    SkString    fName;
    enum { MAX = 100000 };
    int         fUnsorted[MAX];
    int         fSorted[MAX];
    int         fCount;
    SortProc    fSortProc;

public:
    SortBench(void* param, Type t, int n, SortType s) : INHERITED(param) {
        if (n > MAX) {
            n = MAX;
        }
        fName.printf("sort_%s_%s", gSorts[s].fName, gRec[t].fName);
        fCount = n;
        gRec[t].fProc(fUnsorted, n);
        fSortProc = gSorts[s].fProc;
        fIsRendering = false;
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) {
        int n = SkBENCHLOOP(200);
        for (int i = 0; i < n; i++) {
            memcpy(fSorted, fUnsorted, fCount * sizeof(int));
            fSortProc(fSorted, fCount);
#ifdef SK_DEBUG
            for (int j = 1; j < fCount; ++j) {
                SkASSERT(fSorted[j - 1] <= fSorted[j]);
            }
#endif
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

static SkBenchmark* NewSkQSort(void* param, Type t) {
    return new SortBench(param, t, N, kSKQSort);
}
static SkBenchmark* NewSkHeap(void* param, Type t) {
    return new SortBench(param, t, N, kSKHeap);
}
static SkBenchmark* NewQSort(void* param, Type t) {
    return new SortBench(param, t, N, kQSort);
}

DEF_BENCH( return NewSkQSort(p, kRand); )
DEF_BENCH( return NewSkHeap(p, kRand); )
DEF_BENCH( return NewQSort(p, kRand); )

DEF_BENCH( return NewSkQSort(p, kRandN); )
DEF_BENCH( return NewSkHeap(p, kRandN); )
DEF_BENCH( return NewQSort(p, kRandN); )

DEF_BENCH( return NewSkQSort(p, kFore); )
DEF_BENCH( return NewSkHeap(p, kFore); )
DEF_BENCH( return NewQSort(p, kFore); )

DEF_BENCH( return NewSkQSort(p, kBack); )
DEF_BENCH( return NewSkHeap(p, kBack); )
DEF_BENCH( return NewQSort(p, kBack); )

DEF_BENCH( return NewSkQSort(p, kSame); )
DEF_BENCH( return NewSkHeap(p, kSame); )
DEF_BENCH( return NewQSort(p, kSame); )
