/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* $Rev$ $Date$ */

/**
 * Test memory allocation functions.
 */

#include <assert.h>
#include "stream.hpp"
#include "string.hpp"
#include "gc.hpp"
#include "function.hpp"
#include "perf.hpp"

namespace tuscany {

int countElements = 0;
int maxElements = 0;

class Element {
public:
    Element() : i(0) {
        countElements++;
        if (countElements > maxElements)
            maxElements = countElements;
    }

    Element(const int i) : i(i) {
        countElements++;
        if (countElements > maxElements)
            maxElements = countElements;
    }

    Element(const Element& o) : i(o.i) {
        countElements++;
        if (countElements > maxElements)
            maxElements = countElements;
    }

    ~Element() {
        countElements--;
    }

    const bool operator==(const Element& o) const {
        return o.i == i;
    }

private:
    friend ostream& operator<<(ostream& out, const Element& v);

    const int i;
    char c[20];
};

ostream& operator<<(ostream& out, const Element& v) {
    out << v.i ;
    return out;
}

const bool poolAlloc(Element** const p, const int count) {
    if (count == 0)
        return true;
    p[count - 1] = new (gc_new<Element>()) Element();
    return poolAlloc(p, count - 1);
};

bool poolFree(Element** const p, const int count) {
    if (count == 0)
        return true;
    // Do nothing to free the element, but cycle through them just
    // to get a fair comparison with the other memory alloc tests
    return poolFree(p, count - 1);
};

const bool testPoolAllocPerf() {
    const int count = 10000;
    Element** const elements = new Element*[count];
    const blambda pl = [elements, count]() -> const bool {
        const gc_scoped_pool gc;
        poolAlloc(elements, count);
        return true;
    };
    maxElements = 0;
    cout << "Memory pool alloc test " << (time(pl, 1, 1) / count) << " ms" << endl;
    assert(countElements == 0);
    assert(maxElements == count);
    return true;
}

const bool stdAlloc(Element** const p, const int count) {
    if (count == 0)
        return true;
    p[count - 1] = new Element();
    return stdAlloc(p, count - 1);
};

const bool stdFree(Element** const p, const int count) {
    if (count == 0)
        return true;
    delete p[count -1];
    return stdFree(p, count - 1);
};

const bool testStdAllocPerf() {
    const int count = 10000;
    Element** const elements = new Element*[count];
    const blambda sl = [elements, count]() -> const bool {
        stdAlloc(elements, count);
        stdFree(elements, count);
        return true;
    };
    maxElements = 0;
    cout << "Memory standard alloc test " << (time(sl, 1, 1) / count) << " ms" << endl;
    assert(countElements == 0);
    assert(maxElements == count);
    return true;
}

}

int main() {
    const tuscany::gc_scoped_pool p;
    tuscany::cout << "Testing..." << tuscany::endl;

    tuscany::testPoolAllocPerf();
    tuscany::testStdAllocPerf();

    tuscany::cout << "OK" << tuscany::endl;

    return 0;
}
