<commit_before>/*
//# /Users/arnold/Documents/prg/clang/bin/clang++ -U__STRICT_ANSI__ -std=c++14 -I/Users/arnold/Documents/prg/libraries/boost_1_56_0/ -I/Developer/SDKs/MacOSX10.6.sdk/usr/include -Wall -O2 -L/Users/arnold/Documents/prg/libraries/boost_1_56_0/stage/lib  -o mandel mandel.cpp -lboost_system -lboost_filesystem -lboost_iostreams -L/Users/arnold/Documents/prg/libraries/libpng-1.6.21/.libs
# -lpng16 -I/Users/arnold/Documents/prg/libraries/libpng-1.6.21
 g++ -std=c++14 join.cpp -o join -O2 -s -Wall
 */
#include <iostream>
#include <vector>
#include <string>
#include <fstream>

 class Row
 {
 public:
 	explicit Row(const std::vector<std::string>& v) : values_(v)
 	{}
 	~Row() 				= default;
 	Row(const Row&) 	= default;
 	Row(Row&& r) : values_(std::move(r.values_)) {}
 	Row& operator=(const Row&) = delete;

 	std::vector<std::string>::size_type size() const { return values_.size(); }
 	const std::string& operator[](std::vector<std::string>::size_type i) const { return values_[i]; }
 private:
 	const std::vector<std::string> values_;
 };

 class Table
 {
 public:
 	Table(const std::string& name);
 	~Table();
 	unsigned size() const { return rows_.size(); }
 	const Row& operator[](unsigned i) const { return rows_[i]; }
 	void
 private:
 	std::vector<Row> rows_;
 	std::string name_;
 	std::map<std::string, unsigned> schema_;
 };

int main(int argc, char const *argv[])
{
	int ret = 0;
	std::vector<std::string> params(argv, argv + argc);
	std::vector<std::string> file;
	try {
		std::ifstream in(params[1]);
		std::string buffer;
		std::cerr << "Reading " << params[1];
		unsigned lines = 0;
		while (in.good())
		{
			std::getline(in, buffer);
			file.push_back(buffer);
			++lines;
		}
		std::cerr << "OK (" << lines << " lines read)" << std::endl;
	}
	catch(const std::exception& e) {
		std::cerr << e.what() << '\n';
	}
	return ret;
}
<commit_msg>20160429<commit_after>/*
//# /Users/arnold/Documents/prg/clang/bin/clang++ -U__STRICT_ANSI__ -std=c++14 -I/Users/arnold/Documents/prg/libraries/boost_1_56_0/ -I/Developer/SDKs/MacOSX10.6.sdk/usr/include -Wall -O2 -L/Users/arnold/Documents/prg/libraries/boost_1_56_0/stage/lib  -o join join.cpp -lboost_system -lboost_filesystem -lboost_iostreams -L/Users/arnold/Documents/prg/libraries/libpng-1.6.21/.libs
# -lpng16 -I/Users/arnold/Documents/prg/libraries/libpng-1.6.21
# g++ -std=c++14 join.cpp -o join -O2 -s -Wall
 */
#include <iostream>
#include <vector>
#include <string>
#include <fstream>

 class Row
 {
 public:
 	explicit Row(const std::vector<std::string>& v) : values_(v)
 	{}
 	~Row() 				= default;
 	Row(const Row&) 	= default;
 	Row(Row&& r) : values_(std::move(r.values_)) {}
 	Row& operator=(const Row&) = delete;

 	std::vector<std::string>::size_type size() const { return values_.size(); }
 	const std::string& operator[](std::vector<std::string>::size_type i) const { return values_[i]; }
 private:
 	const std::vector<std::string> values_;
 };

 class Table
 {
 public:
 	Table(const std::string& name);
 	~Table();
 	unsigned size() const { return rows_.size(); }
 	const Row& operator[](unsigned i) const { return rows_[i]; }
 	void
 private:
 	std::vector<Row> rows_;
 	std::string name_;
 	std::map<std::string, unsigned> schema_;
 };

int main(int argc, char const *argv[])
{
	int ret = 0;
	std::vector<std::string> params(argv, argv + argc);
	std::vector<std::string> file;
	try {
		std::ifstream in(params[1]);
		std::string buffer;
		std::cerr << "Reading " << params[1];
		unsigned lines = 0;
		while (in.good())
		{
			std::getline(in, buffer);
			file.push_back(buffer);
			++lines;
		}
		std::cerr << "OK (" << lines << " lines read)" << std::endl;
	}
	catch(const std::exception& e) {
		std::cerr << e.what() << '\n';
	}
	return ret;
}
<|endoftext|>


<commit_before>#ifndef _ctoolhu_std_ext_included_
#define _ctoolhu_std_ext_included_

#include <algorithm>

namespace std_ext {

	template <class Container, class Predicate>
	bool all_of(const Container &c, const Predicate &p)
	{
		return std::all_of(std::cbegin(c), std::cend(c), p);
	}

	template <class Container, class Predicate>
	bool any_of(const Container &c, const Predicate &p)
	{
		return std::any_of(std::cbegin(c), std::cend(c), p);
	}

	template <class Container, class Predicate>
	auto erase_if(Container &c, const Predicate &p)
		-> decltype(c.erase(remove_if(c, p), std::end(c)))
	{
		return c.erase(remove_if(c, p), std::end(c));
	}

	template <class Container, class Value>
	auto find(Container &c, const Value &v)
		-> decltype(std::find(std::begin(c), std::end(c), v))
	{
		return std::find(std::begin(c), std::end(c), v);
	}

	template <class Container, class Predicate>
	auto find_if(Container &c, const Predicate &p)
		-> decltype(std::find_if(std::begin(c), std::end(c), p))
	{
		return std::find_if(std::begin(c), std::end(c), p);
	}

	template <class Container, class Predicate>
	auto remove_if(Container &c, const Predicate &p)
		-> decltype(std::remove_if(std::begin(c), std::end(c), p))
	{
		return std::remove_if(std::begin(c), std::end(c), p);
	}

	template <class Container>
	void sort(Container &c)
	{
		std::sort(std::begin(c), std::end(c));
	}

	template <class Container, class Comparator>
	void sort(Container &c, const Comparator &comp)
	{
		std::sort(std::begin(c), std::end(c), comp);
	}
}

#endif //file guard
<commit_msg>added 'contains' function for containers with 'find' member<commit_after>#ifndef _ctoolhu_std_ext_included_
#define _ctoolhu_std_ext_included_

#include <algorithm>

namespace std_ext {

	template <class Container, class Predicate>
	bool all_of(const Container &c, const Predicate &p)
	{
		return std::all_of(std::cbegin(c), std::cend(c), p);
	}

	template <class Container, class Predicate>
	bool any_of(const Container &c, const Predicate &p)
	{
		return std::any_of(std::cbegin(c), std::cend(c), p);
	}

	template <class LookupContainer>
	bool contains(const LookupContainer &c, const typename LookupContainer::value_type &v)
	{
		return c.find(v) != c.end();
	}

	template <class Container, class Predicate>
	auto erase_if(Container &c, const Predicate &p)
		-> decltype(c.erase(remove_if(c, p), std::end(c)))
	{
		return c.erase(remove_if(c, p), std::end(c));
	}

	template <class Container>
	auto find(Container &c, const typename Container::value_type &v)
		-> decltype(std::find(std::begin(c), std::end(c), v))
	{
		return std::find(std::begin(c), std::end(c), v);
	}

	template <class Container, class Predicate>
	auto find_if(Container &c, const Predicate &p)
		-> decltype(std::find_if(std::begin(c), std::end(c), p))
	{
		return std::find_if(std::begin(c), std::end(c), p);
	}

	template <class Container, class Predicate>
	auto remove_if(Container &c, const Predicate &p)
		-> decltype(std::remove_if(std::begin(c), std::end(c), p))
	{
		return std::remove_if(std::begin(c), std::end(c), p);
	}

	template <class Container>
	void sort(Container &c)
	{
		std::sort(std::begin(c), std::end(c));
	}

	template <class Container, class Comparator>
	void sort(Container &c, const Comparator &comp)
	{
		std::sort(std::begin(c), std::end(c), comp);
	}
}

#endif //file guard
<|endoftext|>


<commit_before>#include "localsocket.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "sys/uio.h"
#include <sys/un.h>
#include <unistd.h>

#include <cassert>
#include <climits>
#include <cstdlib>
#include <cstring>

// HACK, put this somewhere else (get the value from original d-bus? or is it infinite?)
static const int maxFds = 12;

using namespace std;

LocalSocket::LocalSocket(int fd)
   : m_fd(fd)
{}

LocalSocket::LocalSocket(const string &socketFilePath)
   : m_fd(-1)
{
    const int fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        return;
    }
    // don't let forks inherit the file descriptor - that can cause confusion...
    fcntl(fd, F_SETFD, FD_CLOEXEC);

    struct sockaddr_un addr;
    addr.sun_family = PF_UNIX;
    bool ok = socketFilePath.length() < sizeof(addr.sun_path);
    if (ok) {
        memcpy(addr.sun_path, socketFilePath.c_str(), socketFilePath.length());
    }

    ok = ok && (connect(fd, (struct sockaddr *)&addr, sizeof(sa_family_t) + socketFilePath.length()) == 0);

    if (ok) {
        m_fd = fd;
    } else {
        ::close(fd);
    }
}

LocalSocket::~LocalSocket()
{
    close();
}

void LocalSocket::close()
{
    setEventDispatcher(0);
    if (m_fd >= 0) {
        ::close(m_fd);
    }
    m_fd = -1;
}

int LocalSocket::write(array a)
{
    if (m_fd < 0) {
        return 0; // TODO -1?
    }

    // sendmsg  boilerplate
    struct msghdr send_msg; // C convention makes them stand out (too many similar variables...)
    struct iovec iov;

    send_msg.msg_name = 0;
    send_msg.msg_namelen = 0;
    send_msg.msg_flags = 0;
    send_msg.msg_iov = &iov;
    send_msg.msg_iovlen = 1;

    iov.iov_base = a.begin;
    iov.iov_len = a.length;

    // we can only send a fixed number of fds anyway due to the non-flexible size of the control message
    // receive buffer, so we set an arbitrary limit.
    const int numFds = 0; // TODO - how many should we get? do we need to know?
    assert(numFds <= maxFds);

    char cmsgBuf[CMSG_SPACE(sizeof(int) * maxFds)];

    if (numFds) {
        // fill in a control message
        send_msg.msg_control = cmsgBuf;
        send_msg.msg_controllen = CMSG_SPACE(sizeof(int) * numFds);

        struct cmsghdr *c_msg = CMSG_FIRSTHDR(&send_msg);
        c_msg->cmsg_len = CMSG_LEN(sizeof(int) * numFds);
        c_msg->cmsg_level = SOL_SOCKET;
        c_msg->cmsg_type = SCM_RIGHTS;

        // set the control data to pass - this is why we don't use the simpler write()
        for (int i = 0; i < numFds; i++) {
            // TODO
            // reinterpret_cast<int *>(CMSG_DATA(c_msg))[i] = message.m_fileDescriptors[i];
        }
    } else {
        // no file descriptor to send, no control message
        send_msg.msg_control = 0;
        send_msg.msg_controllen = 0;
    }

    while (iov.iov_len > 0) {
        int nbytes = sendmsg(m_fd, &send_msg, 0);
        if (nbytes < 0) {
            if (errno == EINTR) {
                continue;
            } else {
                close();
                return false;
            }
        }

        iov.iov_base = static_cast<char *>(iov.iov_base) + nbytes;
        iov.iov_len -= nbytes;
        // sendmsg() should always send the number of bytes asked for or block, so...
        if (nbytes != 0) {
            assert(iov.iov_len == 0);
        }
    }

    return a.length - iov.iov_len; // "- iov.iov_len" is for later, TODO revisit
}

int LocalSocket::availableBytesForReading()
{
    int available = 0;
    if (ioctl(m_fd, FIONREAD, &available) < 0) {
        available = 0;
    }
    return available;
}

array LocalSocket::read(byte *buffer, int maxSize)
{
    array ret;
    if (maxSize <= 0) {
        return ret;
    }

    // recvmsg-with-control-message boilerplate
    struct msghdr recv_msg;
    char cmsgBuf[CMSG_SPACE(sizeof(int) * maxFds)];
    memset(cmsgBuf, 0, sizeof(cmsgBuf));

    recv_msg.msg_control = cmsgBuf;
    recv_msg.msg_controllen = sizeof(cmsgBuf);
    recv_msg.msg_name = 0;
    recv_msg.msg_namelen = 0;
    recv_msg.msg_flags = 0;

    struct iovec iov;
    recv_msg.msg_iov = &iov;
    recv_msg.msg_iovlen = 1;

    // end boilerplate

    ret.begin = buffer;
    ret.length = 0;
    iov.iov_base = ret.begin;
    iov.iov_len = maxSize;
    while (iov.iov_len > 0) {
        int nbytes =  recvmsg(m_fd, &recv_msg, 0);
        if (nbytes < 0 && errno != EINTR) {
            close();
            return ret;
        }
        ret.length += nbytes;
        iov.iov_base = static_cast<char *>(iov.iov_base) + nbytes;
        iov.iov_len -= nbytes;
        // recvmsg() should always return the number of bytes asked for or block, so...
        if (nbytes != 0) {
            assert(iov.iov_len == 0);
        }
    }

    // done reading "regular data", now read any file descriptors passed via control messages

    struct cmsghdr *c_msg = CMSG_FIRSTHDR(&recv_msg);
    if (c_msg && c_msg->cmsg_level == SOL_SOCKET && c_msg->cmsg_type == SCM_RIGHTS) {
        const int len = c_msg->cmsg_len / sizeof(int);
        int *data = reinterpret_cast<int *>(CMSG_DATA(c_msg));
        for (int i = 0; i < len; i++) {
            // TODO
            // message.appendFileDescriptor(data[i]);
        }
    }

    return ret;
}

bool LocalSocket::isOpen()
{
    return m_fd != -1;
}

int LocalSocket::fileDescriptor() const
{
    return m_fd;
}

void LocalSocket::notifyRead()
{
    if (availableBytesForReading()) {
        IConnection::notifyRead();
    } else {
        // This should really only happen in error cases! ### TODO test?
        close();
    }
}
<commit_msg>Remove an incorrect assertion.<commit_after>#include "localsocket.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "sys/uio.h"
#include <sys/un.h>
#include <unistd.h>

#include <cassert>
#include <climits>
#include <cstdlib>
#include <cstring>

// HACK, put this somewhere else (get the value from original d-bus? or is it infinite?)
static const int maxFds = 12;

using namespace std;

LocalSocket::LocalSocket(int fd)
   : m_fd(fd)
{}

LocalSocket::LocalSocket(const string &socketFilePath)
   : m_fd(-1)
{
    const int fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        return;
    }
    // don't let forks inherit the file descriptor - that can cause confusion...
    fcntl(fd, F_SETFD, FD_CLOEXEC);

    struct sockaddr_un addr;
    addr.sun_family = PF_UNIX;
    bool ok = socketFilePath.length() < sizeof(addr.sun_path);
    if (ok) {
        memcpy(addr.sun_path, socketFilePath.c_str(), socketFilePath.length());
    }

    ok = ok && (connect(fd, (struct sockaddr *)&addr, sizeof(sa_family_t) + socketFilePath.length()) == 0);

    if (ok) {
        m_fd = fd;
    } else {
        ::close(fd);
    }
}

LocalSocket::~LocalSocket()
{
    close();
}

void LocalSocket::close()
{
    setEventDispatcher(0);
    if (m_fd >= 0) {
        ::close(m_fd);
    }
    m_fd = -1;
}

int LocalSocket::write(array a)
{
    if (m_fd < 0) {
        return 0; // TODO -1?
    }

    // sendmsg  boilerplate
    struct msghdr send_msg; // C convention makes them stand out (too many similar variables...)
    struct iovec iov;

    send_msg.msg_name = 0;
    send_msg.msg_namelen = 0;
    send_msg.msg_flags = 0;
    send_msg.msg_iov = &iov;
    send_msg.msg_iovlen = 1;

    iov.iov_base = a.begin;
    iov.iov_len = a.length;

    // we can only send a fixed number of fds anyway due to the non-flexible size of the control message
    // receive buffer, so we set an arbitrary limit.
    const int numFds = 0; // TODO - how many should we get? do we need to know?
    assert(numFds <= maxFds);

    char cmsgBuf[CMSG_SPACE(sizeof(int) * maxFds)];

    if (numFds) {
        // fill in a control message
        send_msg.msg_control = cmsgBuf;
        send_msg.msg_controllen = CMSG_SPACE(sizeof(int) * numFds);

        struct cmsghdr *c_msg = CMSG_FIRSTHDR(&send_msg);
        c_msg->cmsg_len = CMSG_LEN(sizeof(int) * numFds);
        c_msg->cmsg_level = SOL_SOCKET;
        c_msg->cmsg_type = SCM_RIGHTS;

        // set the control data to pass - this is why we don't use the simpler write()
        for (int i = 0; i < numFds; i++) {
            // TODO
            // reinterpret_cast<int *>(CMSG_DATA(c_msg))[i] = message.m_fileDescriptors[i];
        }
    } else {
        // no file descriptor to send, no control message
        send_msg.msg_control = 0;
        send_msg.msg_controllen = 0;
    }

    while (iov.iov_len > 0) {
        int nbytes = sendmsg(m_fd, &send_msg, 0);
        if (nbytes < 0) {
            if (errno == EINTR) {
                continue;
            } else {
                close();
                return false;
            }
        }

        iov.iov_base = static_cast<char *>(iov.iov_base) + nbytes;
        iov.iov_len -= nbytes;
        // sendmsg() should always send the number of bytes asked for or block, so...
        if (nbytes != 0) {
            assert(iov.iov_len == 0);
        }
    }

    return a.length - iov.iov_len; // "- iov.iov_len" is for later, TODO revisit
}

int LocalSocket::availableBytesForReading()
{
    int available = 0;
    if (ioctl(m_fd, FIONREAD, &available) < 0) {
        available = 0;
    }
    return available;
}

array LocalSocket::read(byte *buffer, int maxSize)
{
    array ret;
    if (maxSize <= 0) {
        return ret;
    }

    // recvmsg-with-control-message boilerplate
    struct msghdr recv_msg;
    char cmsgBuf[CMSG_SPACE(sizeof(int) * maxFds)];
    memset(cmsgBuf, 0, sizeof(cmsgBuf));

    recv_msg.msg_control = cmsgBuf;
    recv_msg.msg_controllen = sizeof(cmsgBuf);
    recv_msg.msg_name = 0;
    recv_msg.msg_namelen = 0;
    recv_msg.msg_flags = 0;

    struct iovec iov;
    recv_msg.msg_iov = &iov;
    recv_msg.msg_iovlen = 1;

    // end boilerplate

    ret.begin = buffer;
    ret.length = 0;
    iov.iov_base = ret.begin;
    iov.iov_len = maxSize;
    while (iov.iov_len > 0) {
        int nbytes =  recvmsg(m_fd, &recv_msg, 0);
        if (nbytes < 0 && errno != EINTR) {
            close();
            return ret;
        }
        ret.length += nbytes;
        iov.iov_base = static_cast<char *>(iov.iov_base) + nbytes;
        iov.iov_len -= nbytes;
    }

    // done reading "regular data", now read any file descriptors passed via control messages

    struct cmsghdr *c_msg = CMSG_FIRSTHDR(&recv_msg);
    if (c_msg && c_msg->cmsg_level == SOL_SOCKET && c_msg->cmsg_type == SCM_RIGHTS) {
        const int len = c_msg->cmsg_len / sizeof(int);
        int *data = reinterpret_cast<int *>(CMSG_DATA(c_msg));
        for (int i = 0; i < len; i++) {
            // TODO
            // message.appendFileDescriptor(data[i]);
        }
    }

    return ret;
}

bool LocalSocket::isOpen()
{
    return m_fd != -1;
}

int LocalSocket::fileDescriptor() const
{
    return m_fd;
}

void LocalSocket::notifyRead()
{
    if (availableBytesForReading()) {
        IConnection::notifyRead();
    } else {
        // This should really only happen in error cases! ### TODO test?
        close();
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <memory>
#include <set>
#include <vector>
#include <functional>
#include <thread>
#include <atomic>
#include <chrono>
#include "CompileConfig.h"
#include "utils/Noncopyable.hpp"
#include "core/UpdateCallback.hpp"
#include "core/Timer.hpp"
#include "graphics/Renderer.hpp"
#include "audio/Audio.hpp"
#include "files/FileSystem.hpp"
#include "events/EventDispatcher.hpp"
#include "scene/SceneManager.hpp"
#include "core/Cache.hpp"
#include "localization/Localization.hpp"
#include "network/Network.hpp"
#include "utils/INI.hpp"

void ouzelMain(const std::vector<std::string>& args);

namespace ouzel
{
    class Window;

    class Engine: public Noncopyable
    {
    public:
        Engine();
        virtual ~Engine();

        bool init();

        const std::vector<std::string>& getArgs() { return args; }

        FileSystem* getFileSystem() { return fileSystem.get(); }
        EventDispatcher* getEventDispatcher() { return &eventDispatcher; }
        Timer* getTimer() { return &timer; }
        Cache* getCache() { return &cache; }
        Window* getWindow() const { return window.get(); }
        graphics::Renderer* getRenderer() const { return renderer.get(); }
        audio::Audio* getAudio() const { return audio.get(); }
        scene::SceneManager* getSceneManager() { return &sceneManager; }
        input::Input* getInput() const { return input.get(); }
        Localization* getLocalization() { return &localization; }
        network::Network* getNetwork() { return &network; }

        const INI& getDefaultSettings() const { return defaultSettings; }
        const INI& getUserSettings() const { return userSettings; }

        virtual int run();
        void start();
        void pause();
        void resume();
        void exit();

        bool isPaused() const { return paused; }
        bool isActive() const { return active; }

        void scheduleUpdate(UpdateCallback* callback);
        void unscheduleUpdate(UpdateCallback* callback);

        void update();

        virtual void executeOnMainThread(const std::function<void(void)>& func) = 0;

        virtual bool openURL(const std::string& url);

        virtual void setScreenSaverEnabled(bool newScreenSaverEnabled);
        bool isScreenSaverEnabled() const { return screenSaverEnabled; }

    protected:
        virtual void main();

        std::unique_ptr<FileSystem> fileSystem;
        EventDispatcher eventDispatcher;
        Timer timer;
        std::unique_ptr<Window> window;
        std::unique_ptr<graphics::Renderer> renderer;
        std::unique_ptr<audio::Audio> audio;
        std::unique_ptr<input::Input> input;
        Localization localization;
        Cache cache;
        scene::SceneManager sceneManager;
        network::Network network;

        INI defaultSettings;
        INI userSettings;

        std::chrono::steady_clock::time_point previousUpdateTime;

        std::vector<UpdateCallback*> updateCallbacks;
        std::set<UpdateCallback*> updateCallbackAddSet;
        std::set<UpdateCallback*> updateCallbackDeleteSet;

#if OUZEL_MULTITHREADED
        std::thread updateThread;
        std::mutex updateMutex;
        std::condition_variable updateCondition;
#endif

        std::atomic<bool> paused;
        std::atomic<bool> active;

        // from application
        std::atomic<bool> screenSaverEnabled;
        std::vector<std::string> args;
        // from application
    };

    extern Engine* sharedEngine;
}
<commit_msg>Change order of Engine's attributes<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <memory>
#include <set>
#include <vector>
#include <functional>
#include <thread>
#include <atomic>
#include <chrono>
#include "CompileConfig.h"
#include "utils/Noncopyable.hpp"
#include "core/UpdateCallback.hpp"
#include "core/Timer.hpp"
#include "graphics/Renderer.hpp"
#include "audio/Audio.hpp"
#include "files/FileSystem.hpp"
#include "events/EventDispatcher.hpp"
#include "scene/SceneManager.hpp"
#include "core/Cache.hpp"
#include "localization/Localization.hpp"
#include "network/Network.hpp"
#include "utils/INI.hpp"

void ouzelMain(const std::vector<std::string>& args);

namespace ouzel
{
    class Window;

    class Engine: public Noncopyable
    {
    public:
        Engine();
        virtual ~Engine();

        bool init();

        const std::vector<std::string>& getArgs() { return args; }

        FileSystem* getFileSystem() { return fileSystem.get(); }
        EventDispatcher* getEventDispatcher() { return &eventDispatcher; }
        Timer* getTimer() { return &timer; }
        Cache* getCache() { return &cache; }
        Window* getWindow() const { return window.get(); }
        graphics::Renderer* getRenderer() const { return renderer.get(); }
        audio::Audio* getAudio() const { return audio.get(); }
        scene::SceneManager* getSceneManager() { return &sceneManager; }
        input::Input* getInput() const { return input.get(); }
        Localization* getLocalization() { return &localization; }
        network::Network* getNetwork() { return &network; }

        const INI& getDefaultSettings() const { return defaultSettings; }
        const INI& getUserSettings() const { return userSettings; }

        virtual int run();
        void start();
        void pause();
        void resume();
        void exit();

        bool isPaused() const { return paused; }
        bool isActive() const { return active; }

        void scheduleUpdate(UpdateCallback* callback);
        void unscheduleUpdate(UpdateCallback* callback);

        void update();

        virtual void executeOnMainThread(const std::function<void(void)>& func) = 0;

        virtual bool openURL(const std::string& url);

        virtual void setScreenSaverEnabled(bool newScreenSaverEnabled);
        bool isScreenSaverEnabled() const { return screenSaverEnabled; }

    protected:
        virtual void main();

        std::unique_ptr<FileSystem> fileSystem;
        EventDispatcher eventDispatcher;
        Timer timer;
        std::unique_ptr<Window> window;
        std::unique_ptr<graphics::Renderer> renderer;
        std::unique_ptr<audio::Audio> audio;
        std::unique_ptr<input::Input> input;
        Localization localization;
        Cache cache;
        scene::SceneManager sceneManager;
        network::Network network;

        INI defaultSettings;
        INI userSettings;

        std::chrono::steady_clock::time_point previousUpdateTime;

        std::vector<UpdateCallback*> updateCallbacks;
        std::set<UpdateCallback*> updateCallbackAddSet;
        std::set<UpdateCallback*> updateCallbackDeleteSet;

#if OUZEL_MULTITHREADED
        std::thread updateThread;
        std::mutex updateMutex;
        std::condition_variable updateCondition;
#endif

        std::atomic<bool> active;
        std::atomic<bool> paused;

        // from application
        std::atomic<bool> screenSaverEnabled;
        std::vector<std::string> args;
        // from application
    };

    extern Engine* sharedEngine;
}
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "PField.h"
#include "PFieldSet.h"
#ifndef NULL
#define NULL 0
#endif

PFieldSet::PFieldSet(int numfields)
	: _array(new PField *[numfields]), _size(numfields)
{
	for (int n = 0; n < numfields; ++n)
		_array[n] = NULL;
}

PFieldSet::~PFieldSet()
{
	for (int n = 0; n < _size; ++n)
		_array[n]->unref();
	delete [] _array;
}

void
PFieldSet::load(PField *pf, int index)
{
	if (_array[index] != pf) {
		RefCounted::unref(_array[index]);
		_array[index] = pf;
		pf->ref();
	}
}

PField &
PFieldSet::operator[](int index) const
{
	return *_array[index];
}

<commit_msg>Fixed destructor to allow destroy of partially-filled set.<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "PField.h"
#include "PFieldSet.h"
#ifndef NULL
#define NULL 0
#endif

PFieldSet::PFieldSet(int numfields)
	: _array(new PField *[numfields]), _size(numfields)
{
	for (int n = 0; n < numfields; ++n)
		_array[n] = NULL;
}

PFieldSet::~PFieldSet()
{
	for (int n = 0; n < _size; ++n)
		RefCounted::unref(_array[n]);
	delete [] _array;
}

void
PFieldSet::load(PField *pf, int index)
{
	if (_array[index] != pf) {
		RefCounted::unref(_array[index]);
		_array[index] = pf;
		pf->ref();
	}
}

PField &
PFieldSet::operator[](int index) const
{
	return *_array[index];
}

<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// Licensed 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.                                           //
// ======================================================================== //

#include "tasking/taskscheduler.h"
#include "tasking/taskscheduler_new.h"

#include "math/math.h"
#include "kernels/algorithms/sort.h"
#include <tbb/tbb.h>

namespace embree
{
  std::fstream fs;

  struct reduce_benchmark
  {
    reduce_benchmark()
      : N(0), array(NULL) {}

    size_t N;
    double* array;
    double threadReductions[1024];

    TASK_FUNCTION_(reduce_benchmark,reduce);

    void reduce(size_t threadIndex, size_t threadCount)
    {
      const size_t begin = (threadIndex+0)*N/threadCount;
      const size_t end   = (threadIndex+1)*N/threadCount;
      double c = 0;
      for (size_t i=begin; i<end; i++) c += sin(array[i]);
      threadReductions[threadIndex] = c;
    }

    void init(size_t N)
    {
      this->N = N;
      array = new double[N];

      for (size_t i=0; i<N; i++)
        array[i] = drand48();

    }

    double reduce_sequential(size_t N)
    {
      double sum = 0.0;
      for (size_t i=0; i<N; i++)
        sum += sin(array[i]);
      return sum;
    }

    double run_sequential (size_t N)
    {
      double t0 = getSeconds();
      double c0 = 0;
      for (size_t i=0; i<N; i++) c0 += sin(array[i]);
      volatile double result = c0;
      double t1 = getSeconds();

      /*double sum = reduce_sequential(N);
      if (abs(sum-c0) > 1E-5) {
        std::cerr << "internal error: " << sum << " != " << c0 << std::endl;
        exit(1);
        }*/
      return t1-t0;
    }

    double run_locksteptaskscheduler(size_t N)
    {
      double t0 = getSeconds();
      this->N = N;
      LockStepTaskScheduler* scheduler = LockStepTaskScheduler::instance();
      scheduler->dispatchTask( task_reduce, this, 0, scheduler->getNumThreads() );

      double c = 0;
      for (size_t i=0; i<scheduler->getNumThreads(); i++)
        c += threadReductions[i];
      volatile double result = c;
      double t1 = getSeconds();

      /*double sum = reduce_sequential(N);
      if (abs(sum-c) > 1E-5) {
        std::cerr << "internal error: " << sum << " != " << c << std::endl;
        exit(1);
        }*/
      return t1-t0;
    }

    double run_tbb(size_t N)
    {
      double t0 = getSeconds();
      double c2 = 0;
      //LockStepTaskScheduler::execute_tbb([&] () {
      c2 = tbb::parallel_reduce(tbb::blocked_range<size_t>(0,N,1024), 0.0,
                                [&](const tbb::blocked_range<size_t>& r, double value) -> double {
                                  double c = value;
                                  for (size_t i=r.begin(); i<r.end(); i++) c += sin(array[i]);
                                  return c;
                                },
                                std::plus<double>());
      //});
      volatile double result = c2;
      double t1 = getSeconds();

      /*double sum = reduce_sequential(N);
      if (abs(sum-c2) > 1E-5) {
        std::cerr << "internal error: " << sum << " != " << c2 << std::endl;
        exit(1);
        }*/
      return t1-t0;
    }

    const char* name;
  };

  template<typename Closure>
  void benchmark(size_t N0, size_t N1, const char* name, const Closure& closure)
  {
    fs << "# " << name << std::endl;
    fs << "# N dt_min dt_avg dt_max M/s(min) M/s(avg) M/s(max)" << std::endl;
    for (size_t N = N0; N < N1; N *= 1.5)
    {
      double t_min = pos_inf;
      double t_avg = 0.0f;
      double t_max = neg_inf;
      for (size_t i=0; i<10; i++)
      {
        double dt = closure(N);
        t_min = min(t_min,dt);
        if (i != 0) t_avg = t_avg + dt;
        t_max = max(t_max,dt);
      }
      t_avg /= 9.0;
      fs << N << " "
                << 1000.0f*t_min << " " << 1000.0f*t_avg << " " << 1000.0f*t_max << " "
                << 1E-6*N/t_max << " " << 1E-6*N/t_avg << " " << 1E-6*N/t_min << std::endl;
    }
  }

  reduce_benchmark reduce;

  size_t fib(size_t i)
  {
    if (i == 0)
      return 0;
    else if (i == 1)
      return 1;
    else {
      return fib(i-1) + fib(i-2);
    }
  }

  /* regression testing */
  struct task_scheduler_regression_test //: public RegressionTest
  {
    task_scheduler_regression_test(const char* name) : name(name) {
      //registerRegressionTest(this);
    }

    bool operator() (size_t N)
    {
      bool passed = true;
      printf("%s::%s ... ",TOSTRING(isa),name);
      fflush(stdout);

      /* create task scheduler */
      TaskSchedulerNew* scheduler = new TaskSchedulerNew;

      struct Fib
      {
        size_t& r;
        size_t i;

        __forceinline Fib (size_t& r, size_t i) : r(r), i(i) {}

        void operator() (size_t, size_t) const
        {
          if (i == 0)
            r = 0;
          else if (i == 1)
            r = 1;
          else {
            size_t r0; const Fib fib0(r0, i-1);
            size_t r1; const Fib fib1(r1, i-2);
            TaskSchedulerNew::spawn(fib0);
            TaskSchedulerNew::spawn(fib1);
            TaskSchedulerNew::wait();
            r = r0+r1;
          }
        }
      };

      /* parallel calculation of sum of fibonacci number */
      size_t r0 = fib(N);
      double t0 = getSeconds();
      size_t r1; Fib pfib(r1,N);
      scheduler->spawn_root(pfib);
      double t1 = getSeconds();
      printf("fib(%zu) = %zu, parallel_fib(%zu) = %zu\n",N,r0,N,r1);
      passed = r0 == r1;

      /* output if test passed or not */
      if (passed) printf("[passed]\n");
      else        printf("[failed]\n");

      delete scheduler;
      return passed;
    }

    const char* name;
  };

  void main()
  {
#if 1
    task_scheduler_regression_test task_scheduler_regression("task_scheduler_regression_test");
    task_scheduler_regression(1000);
#else

    const size_t N = 100*1024*1024;
    const size_t N_seq = 10*1024*1024;

    /* parallel reduction */
    reduce.init(N);

    fs.open ("benchmark_reduce_sequential.csv", std::fstream::out);
    benchmark(1000,N_seq,"reduce_sequential",[] (size_t N) -> double { return reduce.run_sequential(N); });
    fs.close();

    fs.open ("benchmark_reduce_lockstep.csv", std::fstream::out);
    TaskScheduler::create();
    execute_closure([&] () -> double { benchmark(1000,N,"reduce_lockstep",[] (size_t N) -> double { return reduce.run_locksteptaskscheduler(N); }); return 0.0; });
    TaskScheduler::destroy();
    fs.close();

    {
      fs.open ("benchmark_reduce_tbb.csv", std::fstream::out);
      tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads());
      benchmark(1000,N,"reduce_tbb",[] (size_t N) -> double { return reduce.run_tbb(N); });
      fs.close();
    }

    /* parallel sort */
    int* src = new int[N];
    int* array = new int[N];
    int* temp = new int[N];
    for (size_t i=0; i<N; i++) src[i] = random<int>();
    for (size_t i=0; i<N; i++) array[i] = i;
    for (size_t i=0; i<N; i++) temp[i] = i;

    fs.open ("benchmark_sort_sequential.csv", std::fstream::out);
    benchmark(1000,N_seq,"sort_sequential",[&] (size_t N) -> double
    {
      for (size_t i=0; i<N; i++) array[i] = src[i];
      double t0 = getSeconds();
      std::sort(array,array+N);
      double t1 = getSeconds();
      //for (size_t i=1; i<N; i++) if (array[i] < array[i-1]) { std::cerr << "internal error" << std::endl;  exit(1); }
      return t1-t0;
    });
    fs.close();

    {
      fs.open ("benchmark_sort_tbb.csv", std::fstream::out);
      tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads());
      benchmark(1000,N,"sort_tbb",[&] (size_t N) -> double
      {
        for (size_t i=0; i<N; i++) array[i] = src[i];
        double t0 = getSeconds();
        tbb::parallel_sort(array,array+N);
        double t1 = getSeconds();
        //for (size_t i=1; i<N; i++) if (array[i] < array[i-1]) { std::cerr << "internal error" << std::endl;  exit(1); }
        return t1-t0;
      });
      fs.close();
    }

    fs.open ("benchmark_sort_lockstep.csv", std::fstream::out);
    TaskScheduler::create();
    execute_closure([&] () -> double
    {
      benchmark(1000,N,"sort_lockstep",[&] (size_t N) -> double
      {
        for (size_t i=0; i<N; i++) array[i] = src[i];
        double t0 = getSeconds();
        radix_sort_u32(array,temp,N);
        double t1 = getSeconds();
        //for (size_t i=1; i<N; i++) if (array[i] < array[i-1]) { std::cerr << "internal error" << std::endl;  exit(1); }
        return t1-t0;
      });
      return 0.0;
    });
    TaskScheduler::destroy();
    fs.close();
#endif
  }
}

int main() {
  embree::main();
  return 0;
}

<commit_msg>bugfix to fibonacci calculation on benchmark_tasking<commit_after>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// Licensed 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.                                           //
// ======================================================================== //

#include "tasking/taskscheduler.h"
#include "tasking/taskscheduler_new.h"

#include "math/math.h"
#include "kernels/algorithms/sort.h"
#include <tbb/tbb.h>

namespace embree
{
  std::fstream fs;

  struct reduce_benchmark
  {
    reduce_benchmark()
      : N(0), array(NULL) {}

    size_t N;
    double* array;
    double threadReductions[1024];

    TASK_FUNCTION_(reduce_benchmark,reduce);

    void reduce(size_t threadIndex, size_t threadCount)
    {
      const size_t begin = (threadIndex+0)*N/threadCount;
      const size_t end   = (threadIndex+1)*N/threadCount;
      double c = 0;
      for (size_t i=begin; i<end; i++) c += sin(array[i]);
      threadReductions[threadIndex] = c;
    }

    void init(size_t N)
    {
      this->N = N;
      array = new double[N];

      for (size_t i=0; i<N; i++)
        array[i] = drand48();

    }

    double reduce_sequential(size_t N)
    {
      double sum = 0.0;
      for (size_t i=0; i<N; i++)
        sum += sin(array[i]);
      return sum;
    }

    double run_sequential (size_t N)
    {
      double t0 = getSeconds();
      double c0 = 0;
      for (size_t i=0; i<N; i++) c0 += sin(array[i]);
      volatile double result = c0;
      double t1 = getSeconds();

      /*double sum = reduce_sequential(N);
      if (abs(sum-c0) > 1E-5) {
        std::cerr << "internal error: " << sum << " != " << c0 << std::endl;
        exit(1);
        }*/
      return t1-t0;
    }

    double run_locksteptaskscheduler(size_t N)
    {
      double t0 = getSeconds();
      this->N = N;
      LockStepTaskScheduler* scheduler = LockStepTaskScheduler::instance();
      scheduler->dispatchTask( task_reduce, this, 0, scheduler->getNumThreads() );

      double c = 0;
      for (size_t i=0; i<scheduler->getNumThreads(); i++)
        c += threadReductions[i];
      volatile double result = c;
      double t1 = getSeconds();

      /*double sum = reduce_sequential(N);
      if (abs(sum-c) > 1E-5) {
        std::cerr << "internal error: " << sum << " != " << c << std::endl;
        exit(1);
        }*/
      return t1-t0;
    }

    double run_tbb(size_t N)
    {
      double t0 = getSeconds();
      double c2 = 0;
      //LockStepTaskScheduler::execute_tbb([&] () {
      c2 = tbb::parallel_reduce(tbb::blocked_range<size_t>(0,N,1024), 0.0,
                                [&](const tbb::blocked_range<size_t>& r, double value) -> double {
                                  double c = value;
                                  for (size_t i=r.begin(); i<r.end(); i++) c += sin(array[i]);
                                  return c;
                                },
                                std::plus<double>());
      //});
      volatile double result = c2;
      double t1 = getSeconds();

      /*double sum = reduce_sequential(N);
      if (abs(sum-c2) > 1E-5) {
        std::cerr << "internal error: " << sum << " != " << c2 << std::endl;
        exit(1);
        }*/
      return t1-t0;
    }

    const char* name;
  };

  template<typename Closure>
  void benchmark(size_t N0, size_t N1, const char* name, const Closure& closure)
  {
    fs << "# " << name << std::endl;
    fs << "# N dt_min dt_avg dt_max M/s(min) M/s(avg) M/s(max)" << std::endl;
    for (size_t N = N0; N < N1; N *= 1.5)
    {
      double t_min = pos_inf;
      double t_avg = 0.0f;
      double t_max = neg_inf;
      for (size_t i=0; i<10; i++)
      {
        double dt = closure(N);
        t_min = min(t_min,dt);
        if (i != 0) t_avg = t_avg + dt;
        t_max = max(t_max,dt);
      }
      t_avg /= 9.0;
      fs << N << " "
                << 1000.0f*t_min << " " << 1000.0f*t_avg << " " << 1000.0f*t_max << " "
                << 1E-6*N/t_max << " " << 1E-6*N/t_avg << " " << 1E-6*N/t_min << std::endl;
    }
  }

  reduce_benchmark reduce;

  size_t fib(size_t i)
  {
    if (i == 0)
      return 0;
    else if (i == 1)
      return 1;
    else {
      return fib(i-1) + fib(i-2);
    }
  }

  /* regression testing */
  struct task_scheduler_regression_test //: public RegressionTest
  {
    task_scheduler_regression_test(const char* name) : name(name) {
      //registerRegressionTest(this);
    }

    bool operator() (size_t N)
    {
      bool passed = true;
      printf("%s::%s ... \n",TOSTRING(isa),name);
      fflush(stdout);

      /* create task scheduler */
      TaskSchedulerNew* scheduler = new TaskSchedulerNew;

      struct Fib
      {
        size_t& r;
        size_t i;

        __forceinline Fib (size_t& r, size_t i) : r(r), i(i) {}

        void operator() (size_t, size_t) const
        {
          if (i == 0)
            r = 0;
          else if (i == 1)
            r = 1;
          else {
            size_t r0; const Fib fib0(r0, i-1);
            size_t r1; const Fib fib1(r1, i-2);
            TaskSchedulerNew::spawn(fib0);
            TaskSchedulerNew::spawn(fib1);
            TaskSchedulerNew::wait();
            r = r0+r1;
          }
        }
      };

      /* parallel calculation of sum of fibonacci number */
      double t0 = getSeconds();
      size_t r0 = fib(N);
      double t1 = getSeconds();
      size_t r1; Fib pfib(r1,N);
      scheduler->spawn_root(pfib);
      double t2 = getSeconds();
      printf("  sequential_fib(%zu) = %zu, %3.2fms\n",N,r0,1000.0f*(t1-t0));
      printf("  parallel_fib  (%zu) = %zu, %3.2fms\n",N,r1,1000.0f*(t2-t1));
      passed = r0 == r1;

      /* output if test passed or not */
      if (passed) printf("[passed]\n");
      else        printf("[failed]\n");

      delete scheduler;
      return passed;
    }

    const char* name;
  };

  void main()
  {
#if 1
    task_scheduler_regression_test task_scheduler_regression("task_scheduler_regression_test");
    task_scheduler_regression(40);
#else

    const size_t N = 100*1024*1024;
    const size_t N_seq = 10*1024*1024;

    /* parallel reduction */
    reduce.init(N);

    fs.open ("benchmark_reduce_sequential.csv", std::fstream::out);
    benchmark(1000,N_seq,"reduce_sequential",[] (size_t N) -> double { return reduce.run_sequential(N); });
    fs.close();

    fs.open ("benchmark_reduce_lockstep.csv", std::fstream::out);
    TaskScheduler::create();
    execute_closure([&] () -> double { benchmark(1000,N,"reduce_lockstep",[] (size_t N) -> double { return reduce.run_locksteptaskscheduler(N); }); return 0.0; });
    TaskScheduler::destroy();
    fs.close();

    {
      fs.open ("benchmark_reduce_tbb.csv", std::fstream::out);
      tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads());
      benchmark(1000,N,"reduce_tbb",[] (size_t N) -> double { return reduce.run_tbb(N); });
      fs.close();
    }

    /* parallel sort */
    int* src = new int[N];
    int* array = new int[N];
    int* temp = new int[N];
    for (size_t i=0; i<N; i++) src[i] = random<int>();
    for (size_t i=0; i<N; i++) array[i] = i;
    for (size_t i=0; i<N; i++) temp[i] = i;

    fs.open ("benchmark_sort_sequential.csv", std::fstream::out);
    benchmark(1000,N_seq,"sort_sequential",[&] (size_t N) -> double
    {
      for (size_t i=0; i<N; i++) array[i] = src[i];
      double t0 = getSeconds();
      std::sort(array,array+N);
      double t1 = getSeconds();
      //for (size_t i=1; i<N; i++) if (array[i] < array[i-1]) { std::cerr << "internal error" << std::endl;  exit(1); }
      return t1-t0;
    });
    fs.close();

    {
      fs.open ("benchmark_sort_tbb.csv", std::fstream::out);
      tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads());
      benchmark(1000,N,"sort_tbb",[&] (size_t N) -> double
      {
        for (size_t i=0; i<N; i++) array[i] = src[i];
        double t0 = getSeconds();
        tbb::parallel_sort(array,array+N);
        double t1 = getSeconds();
        //for (size_t i=1; i<N; i++) if (array[i] < array[i-1]) { std::cerr << "internal error" << std::endl;  exit(1); }
        return t1-t0;
      });
      fs.close();
    }

    fs.open ("benchmark_sort_lockstep.csv", std::fstream::out);
    TaskScheduler::create();
    execute_closure([&] () -> double
    {
      benchmark(1000,N,"sort_lockstep",[&] (size_t N) -> double
      {
        for (size_t i=0; i<N; i++) array[i] = src[i];
        double t0 = getSeconds();
        radix_sort_u32(array,temp,N);
        double t1 = getSeconds();
        //for (size_t i=1; i<N; i++) if (array[i] < array[i-1]) { std::cerr << "internal error" << std::endl;  exit(1); }
        return t1-t0;
      });
      return 0.0;
    });
    TaskScheduler::destroy();
    fs.close();
#endif
  }
}

int main() {
  embree::main();
  return 0;
}

<|endoftext|>


<commit_before>//  arithmetic.cpp : bitset-based arithmetic tests
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include "stdafx.h"
#include <sstream>
#include "../../bitset/bitset_helpers.hpp"

using namespace std;

void BasicArithmeticTests() {
	const size_t nbits = 33;

	cout << "Bitset arithmetic tests" << endl;

	std::bitset<nbits> a, b, sum;
	bool carry = 0;
	a = flip_sign_bit(convert_to_bitset<nbits,uint64_t>(uint64_t(0x55555555)));
	b = convert_to_bitset<nbits,uint64_t>(uint64_t(0x5));

	carry = add_signed_magnitude(a, b, sum);

	cout << "a   = " << a << endl;
	cout << "b   = " << to_binary(b) << endl;
	cout << "sum = " << to_binary(sum) << " carry = " << carry << endl;

	cout << "1's complement of a = " << to_binary(ones_complement(a)) << endl;
	cout << "1's complement of b = " << to_binary(ones_complement(b)) << endl;

	std::bitset<9> c;
	c = convert_to_bitset<9,int8_t>(int8_t(-128));
	cout << "c                = " << to_binary(c) << endl;
	c = twos_complement(c);
	cout << "2's Complement   = " << to_binary(c) << endl;

	std::bitset<9> d;
	d = convert_to_bitset<9,int64_t>(int64_t(int8_t(-128)));
	cout << "d                = " << to_binary(d) << endl;
	d = twos_complement(d);
	cout << "2's complement   = " << to_binary(d) << endl;
}

template<size_t nbits>
void add_fractions(int f1_scale, std::bitset<nbits> f1, int f2_scale, std::bitset<nbits> f2, int& sum_scale, std::bitset<nbits>& sum) {
	// fraction operations that are part of adding posits

	cout << "f1 scale " << f1_scale << " value " << to_hex(f1) << endl;
	cout << "f2 scale " << f2_scale << " value " << to_hex(f2) << endl;

	// scale the smaller number to the bigger number by right shifting the difference
	// fractions are right extended, and the hidden bit becomes the msb
	f1.set(nbits - 1);
	f2.set(nbits - 1);
	int diff = f1_scale - f2_scale;
	cout << "scale difference is " << diff << endl;

	if (diff < 0) {
		f1 >>= -diff;	// denormalize
	}
	else {
		f2 >>= diff;	// denormalize
	}
	cout << "f1  : " << f1 << endl;
	cout << "f2  : " << f2 << endl;

	bool carry = add_unsigned(f1, f2, sum);
	cout << "sum : " << sum << " carry : " << (carry ? 1 : 0) << endl;

	sum_scale = (f1_scale > f2_scale ? f1_scale : f2_scale);
	sum_scale = f1_scale + (carry ? 1 : 0);
	sum >>= (carry ? 1 : 0);
}

bool AddFractionsTest()
{
	bool bValid = true;

	const size_t posit_nbits = 16;
	const size_t fraction_nbits = posit_nbits - 2;
	int f1_scale = 5;
	std::bitset<fraction_nbits> f1 = convert_to_bitset<fraction_nbits,uint64_t>(uint64_t(0x1fff));
	int f2_scale = 3;
	std::bitset<fraction_nbits> f2 = convert_to_bitset<fraction_nbits,uint64_t>(uint64_t(0xf));
	int sum_scale = 0;
	std::bitset<fraction_nbits> sum;
	add_fractions<fraction_nbits>(f1_scale, f1, f2_scale, f2, sum_scale, sum);
	cout << "sum : " << sum << " sum_scale : " << sum_scale << endl;

	return bValid;
}

bool IncrementRightAdjustedBitset()
{
	bool bValid = true;
	const size_t size = 5;
	std::bitset<size> r1, ref;
	bool carry;

	for (int i = 0; i < size; i++) {
		r1.reset();
		r1.set(size - 1 - i, true);
		carry = false;
		cout << "carry " << (carry ? "1" : "0") << " r1 " << r1 << " <-- input" << endl;
		carry = increment_unsigned(r1, i);
		cout << "carry " << (carry ? "1" : "0") << " r1 " << r1 << " <-- result" << endl;
	}

	return bValid;
}

int main()
try
{
	BasicArithmeticTests();

	IncrementRightAdjustedBitset();

	return 0;
}
catch (char* msg) {
	cerr << msg << endl;
	return 1;
}
<commit_msg>Reorganizing bitset operators<commit_after>//  arithmetic.cpp : bitset-based arithmetic tests
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include "stdafx.h"
#include <sstream>
#include "../../bitset/bitset_helpers.hpp"

using namespace std;

void BinaryConversions() {
	const size_t nbits = 33;
		std::bitset<nbits> a, b, sum;
	bool carry = 0;

	cout << "Binary conversions" << endl;

	a = flip_sign_bit(convert_to_bitset<nbits,uint64_t>(uint64_t(0x55555555)));
	b = convert_to_bitset<nbits,uint64_t>(uint64_t(0x5));

	carry = add_signed_magnitude(a, b, sum);

	cout << "a   = " << a << endl;
	cout << "b   = " << to_binary(b) << endl;
	cout << "sum = " << to_binary(sum) << " carry = " << carry << endl;

	cout << "1's complement of a = " << to_binary(ones_complement(a)) << endl;
	cout << "1's complement of b = " << to_binary(ones_complement(b)) << endl;

	std::bitset<9> c;
	c = convert_to_bitset<9,int8_t>(int8_t(-128));
	cout << "c                = " << to_binary(c) << endl;
	c = twos_complement(c);
	cout << "2's Complement   = " << to_binary(c) << endl;

	std::bitset<9> d;
	d = convert_to_bitset<9,int64_t>(int64_t(int8_t(-128)));
	cout << "d                = " << to_binary(d) << endl;
	d = twos_complement(d);
	cout << "2's complement   = " << to_binary(d) << endl;
	cout << endl;
}

template<size_t nbits>
void add_fractions(int f1_scale, std::bitset<nbits> f1, int f2_scale, std::bitset<nbits> f2, int& sum_scale, std::bitset<nbits>& sum) {
	// fraction operations that are part of adding posits
	cout << "add fractions" << endl;
	cout << "f1 scale " << f1_scale << " value " << to_hex(f1) << endl;
	cout << "f2 scale " << f2_scale << " value " << to_hex(f2) << endl;

	// scale the smaller number to the bigger number by right shifting the difference
	// fractions are right extended, and the hidden bit becomes the msb
	f1.set(nbits - 1);
	f2.set(nbits - 1);
	int diff = f1_scale - f2_scale;
	cout << "scale difference is " << diff << endl;

	if (diff < 0) {
		f1 >>= -diff;	// denormalize
	}
	else {
		f2 >>= diff;	// denormalize
	}
	cout << "f1  : " << f1 << endl;
	cout << "f2  : " << f2 << endl;

	bool carry = add_unsigned(f1, f2, sum);
	cout << "sum : " << sum << " carry : " << (carry ? 1 : 0) << endl;

	sum_scale = (f1_scale > f2_scale ? f1_scale : f2_scale);
	sum_scale = f1_scale + (carry ? 1 : 0);
	sum >>= (carry ? 1 : 0);
}

bool FractionManipulation()
{
	bool bValid = true;
	const size_t posit_nbits = 16;
	const size_t fraction_nbits = posit_nbits - 2;
	int f1_scale = 5;

	cout << "Fraction manipulation" << endl;
	std::bitset<fraction_nbits> f1 = convert_to_bitset<fraction_nbits,uint64_t>(uint64_t(0x1fff));
	int f2_scale = 3;
	std::bitset<fraction_nbits> f2 = convert_to_bitset<fraction_nbits,uint64_t>(uint64_t(0xf));
	int sum_scale = 0;
	std::bitset<fraction_nbits> sum;
	add_fractions<fraction_nbits>(f1_scale, f1, f2_scale, f2, sum_scale, sum);
	cout << "sum : " << sum << " sum_scale : " << sum_scale << endl;
	cout << endl;
	return bValid;
}

bool IncrementRightAdjustedBitset()
{
	bool bValid = true;
	const size_t size = 5;
	std::bitset<size> r1, ref;
	bool carry;

	cout << "Increments" << endl;
	for (int i = 0; i < size; i++) {
		r1.reset();
		r1.set(size - 1 - i, true);
		carry = false;
		cout << "carry " << (carry ? "1" : "0") << " r1 " << r1 << " <-- input" << endl;
		carry = increment_unsigned(r1, i);
		cout << "carry " << (carry ? "1" : "0") << " r1 " << r1 << " <-- result" << endl;
	}
	cout << endl;
	return bValid;
}

int main()
try
{

	cout << "Arithmetic experiments on bitsets" << endl;

	BinaryConversions();

	IncrementRightAdjustedBitset();

	FractionManipulation();

	return 0;
}
catch (char* msg) {
	cerr << msg << endl;
	return 1;
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// cache_test.cpp
//
// Identification: tests/common/cache_test.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "harness.h"

#include "backend/common/cache.h"
#include "backend/common/logger.h"
#include "backend/planner/mock_plan.h"

#include "backend/bridge/dml/mapper/mapper.h"

#include <unordered_set>

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Cache Test
//===--------------------------------------------------------------------===//

class CacheTest : public PelotonTest {};

#define CACHE_SIZE 5

static void fill(
    std::vector<std::shared_ptr<const planner::AbstractPlan> > &vec, int n) {
  for (int i = 0; i < n; i++) {
    std::shared_ptr<const planner::AbstractPlan> plan(
        new MockPlan(), bridge::PlanTransformer::CleanPlan);
    vec.push_back(std::move(plan));
  }
}

/**
 * Test basic functionality
 *
 */
TEST_F(CacheTest, Basic) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  EXPECT_EQ(0, cache.size());
  EXPECT_EQ(true, cache.empty());
}

/**
 *  Test find operation
 *
 */
TEST_F(CacheTest, Find) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  EXPECT_EQ(cache.end(), cache.find(1));
}

/**
 * Test insert operation
 *
 */
TEST_F(CacheTest, Insert) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE);

  cache.insert(std::make_pair(0, plans[0]));

  auto cache_it = cache.find(0);

  EXPECT_EQ((*cache_it).get(), plans[0].get());

  for (int i = 1; i < CACHE_SIZE; i++)
    cache.insert(std::make_pair(i, plans[i]));

  EXPECT_EQ(CACHE_SIZE, cache.size());
  EXPECT_EQ(false, cache.empty());
}

/**
 * Test insert operation with default threshold
 *
 */
TEST_F(CacheTest, InsertThreshold) {
  // Default insert threshold is 3, i.e. it will not be inserted
  // until 3 attempts are detected.
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE);

  // For the first two attempts, the plan will not be inserted
  for (int i = 0; i < 2; ++i) {
    cache.insert(std::make_pair(0, plans[0]));
    auto cache_it = cache.find(0);
    EXPECT_EQ(cache.end(), cache_it);
  }

  // For the third attempt, insertion should succeed.
  cache.insert(std::make_pair(0, plans[0]));
  auto cache_it = cache.find(0);
  EXPECT_EQ((*cache_it).get(), plans[0].get());

  // For existent key in the cache, the value should be immediately replaced
  cache.insert(std::make_pair(0, plans[1]));
  EXPECT_EQ((*cache_it).get(), plans[1].get());
}

/**
 * Test iterator function
 */
TEST_F(CacheTest, Iterator) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE);
  std::unordered_set<const planner::AbstractPlan *> set;

  for (int i = 0; i < CACHE_SIZE; i++)
    cache.insert(std::make_pair(i, plans[i]));

  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());
  for (int i = 0; i < CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

/**
 * Test eviction
 *
 * Try to insert 2 times of the capacity of the cache
 * The cache should keep the most recent half
 */
TEST_F(CacheTest, EvictionByInsert) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE * 2);
  std::unordered_set<const planner::AbstractPlan *> set;

  for (int i = 0; i < 2 * CACHE_SIZE; i++)
    cache.insert(std::make_pair(i, plans[i]));

  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());
  for (int i = 0; i < CACHE_SIZE; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (int i = CACHE_SIZE; i < 2 * CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

/**
 * Test eviction
 *
 * Try to insert 2 times of the capacity of the cache
 * The cache should keep the most recent half
 */
TEST_F(CacheTest, EvictionWithAccessing) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE * 2);
  std::unordered_set<const planner::AbstractPlan *> set;

  int i = 0;
  /* insert 0,1,2,3,4,5,6,7
   *
   * The cache should keep 3,4,5,6,7
   * */
  for (; i < CACHE_SIZE * 1.5; i++) cache.insert(std::make_pair(i, plans[i]));
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  int diff = CACHE_SIZE / 2;

  /* read 4, 3
   * */
  for (int idx = CACHE_SIZE - 1; idx > CACHE_SIZE - diff - 1; idx--) {
    auto it = cache.find(idx);
    EXPECT_NE(it, cache.end());
    EXPECT_EQ((*it).get(), plans[idx].get());
  }

  /* Insert 8, 9 */
  for (; i < CACHE_SIZE * 2; i++) cache.insert(std::make_pair(i, plans[i]));

  set.clear();
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  i = 0;
  for (; i < CACHE_SIZE - diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE + diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE * 2; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }

  i = 0;
  for (; i < CACHE_SIZE; i++) {
    cache.insert(std::make_pair(i, plans[i]));
  }

  set.clear();
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, cache.size());
  EXPECT_EQ(false, cache.empty());

  i = 0;
  for (; i < CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

/**
 * Test eviction
 *
 * Try to insert 2 times of the capacity of the cache
 * The cache should keep the most recent half
 */
TEST_F(CacheTest, Updating) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE * 2);

  std::unordered_set<const planner::AbstractPlan *> set;

  /* insert 0,1,2,3,4,5,6,7
   *
   * The cache should keep 3,4,5,6,7
   * */
  int i = 0;
  for (; i < CACHE_SIZE * 1.5; i++) cache.insert(std::make_pair(i, plans[i]));

  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  int diff = CACHE_SIZE / 2;

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans2;
  fill(plans2, diff);
  /* update 4, 3
   * */
  for (int idx = CACHE_SIZE - 1, j = 0; idx > CACHE_SIZE - diff - 1;
       idx--, j++) {
    cache.insert(std::make_pair(idx, plans2[j]));
  }

  for (; i < CACHE_SIZE * 2; i++) cache.insert(std::make_pair(i, plans[i]));

  set.clear();
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  i = 0;
  for (; i < CACHE_SIZE - diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (int j = 0; i < CACHE_SIZE; i++, j++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
    EXPECT_NE(set.end(), set.find(plans2[j].get()));
  }

  for (; i < CACHE_SIZE + diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE * 2; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

}  // End test namespace
}  // End peloton namespace
<commit_msg>fix memory leak in unit test<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// cache_test.cpp
//
// Identification: tests/common/cache_test.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "harness.h"

#include "backend/common/cache.h"
#include "backend/common/logger.h"
#include "backend/planner/mock_plan.h"

#include "backend/bridge/dml/mapper/mapper.h"

#include <unordered_set>

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Cache Test
//===--------------------------------------------------------------------===//

class CacheTest : public PelotonTest {};

#define CACHE_SIZE 5

static void fill(
    std::vector<std::shared_ptr<const planner::AbstractPlan> > &vec, int n) {
  for (int i = 0; i < n; i++) {
    std::shared_ptr<const planner::AbstractPlan> plan(new MockPlan());
    vec.push_back(std::move(plan));
  }
}

/**
 * Test basic functionality
 *
 */
TEST_F(CacheTest, Basic) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  EXPECT_EQ(0, cache.size());
  EXPECT_EQ(true, cache.empty());
}

/**
 *  Test find operation
 *
 */
TEST_F(CacheTest, Find) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  EXPECT_EQ(cache.end(), cache.find(1));
}

/**
 * Test insert operation
 *
 */
TEST_F(CacheTest, Insert) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE);

  cache.insert(std::make_pair(0, plans[0]));

  auto cache_it = cache.find(0);

  EXPECT_EQ((*cache_it).get(), plans[0].get());

  for (int i = 1; i < CACHE_SIZE; i++)
    cache.insert(std::make_pair(i, plans[i]));

  EXPECT_EQ(CACHE_SIZE, cache.size());
  EXPECT_EQ(false, cache.empty());
}

/**
 * Test insert operation with default threshold
 *
 */
TEST_F(CacheTest, InsertThreshold) {
  // Default insert threshold is 3, i.e. it will not be inserted
  // until 3 attempts are detected.
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE);

  // For the first two attempts, the plan will not be inserted
  for (int i = 0; i < 2; ++i) {
    cache.insert(std::make_pair(0, plans[0]));
    auto cache_it = cache.find(0);
    EXPECT_EQ(cache.end(), cache_it);
  }

  // For the third attempt, insertion should succeed.
  cache.insert(std::make_pair(0, plans[0]));
  auto cache_it = cache.find(0);
  EXPECT_EQ((*cache_it).get(), plans[0].get());

  // For existent key in the cache, the value should be immediately replaced
  cache.insert(std::make_pair(0, plans[1]));
  EXPECT_EQ((*cache_it).get(), plans[1].get());
}

/**
 * Test iterator function
 */
TEST_F(CacheTest, Iterator) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE);
  std::unordered_set<const planner::AbstractPlan *> set;

  for (int i = 0; i < CACHE_SIZE; i++)
    cache.insert(std::make_pair(i, plans[i]));

  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());
  for (int i = 0; i < CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

/**
 * Test eviction
 *
 * Try to insert 2 times of the capacity of the cache
 * The cache should keep the most recent half
 */
TEST_F(CacheTest, EvictionByInsert) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE * 2);
  std::unordered_set<const planner::AbstractPlan *> set;

  for (int i = 0; i < 2 * CACHE_SIZE; i++)
    cache.insert(std::make_pair(i, plans[i]));

  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());
  for (int i = 0; i < CACHE_SIZE; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (int i = CACHE_SIZE; i < 2 * CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

/**
 * Test eviction
 *
 * Try to insert 2 times of the capacity of the cache
 * The cache should keep the most recent half
 */
TEST_F(CacheTest, EvictionWithAccessing) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE * 2);
  std::unordered_set<const planner::AbstractPlan *> set;

  int i = 0;
  /* insert 0,1,2,3,4,5,6,7
   *
   * The cache should keep 3,4,5,6,7
   * */
  for (; i < CACHE_SIZE * 1.5; i++) cache.insert(std::make_pair(i, plans[i]));
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  int diff = CACHE_SIZE / 2;

  /* read 4, 3
   * */
  for (int idx = CACHE_SIZE - 1; idx > CACHE_SIZE - diff - 1; idx--) {
    auto it = cache.find(idx);
    EXPECT_NE(it, cache.end());
    EXPECT_EQ((*it).get(), plans[idx].get());
  }

  /* Insert 8, 9 */
  for (; i < CACHE_SIZE * 2; i++) cache.insert(std::make_pair(i, plans[i]));

  set.clear();
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  i = 0;
  for (; i < CACHE_SIZE - diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE + diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE * 2; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }

  i = 0;
  for (; i < CACHE_SIZE; i++) {
    cache.insert(std::make_pair(i, plans[i]));
  }

  set.clear();
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, cache.size());
  EXPECT_EQ(false, cache.empty());

  i = 0;
  for (; i < CACHE_SIZE; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

/**
 * Test eviction
 *
 * Try to insert 2 times of the capacity of the cache
 * The cache should keep the most recent half
 */
TEST_F(CacheTest, Updating) {
  Cache<uint32_t, const planner::AbstractPlan> cache(
      CACHE_SIZE, bridge::PlanTransformer::CleanPlan, 1);

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans;
  fill(plans, CACHE_SIZE * 2);

  std::unordered_set<const planner::AbstractPlan *> set;

  /* insert 0,1,2,3,4,5,6,7
   *
   * The cache should keep 3,4,5,6,7
   * */
  int i = 0;
  for (; i < CACHE_SIZE * 1.5; i++) cache.insert(std::make_pair(i, plans[i]));

  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  int diff = CACHE_SIZE / 2;

  std::vector<std::shared_ptr<const planner::AbstractPlan> > plans2;
  fill(plans2, diff);
  /* update 4, 3
   * */
  for (int idx = CACHE_SIZE - 1, j = 0; idx > CACHE_SIZE - diff - 1;
       idx--, j++) {
    cache.insert(std::make_pair(idx, plans2[j]));
  }

  for (; i < CACHE_SIZE * 2; i++) cache.insert(std::make_pair(i, plans[i]));

  set.clear();
  for (auto plan : cache) {
    set.insert(plan.get());
  }

  EXPECT_EQ(CACHE_SIZE, set.size());
  EXPECT_EQ(false, cache.empty());

  i = 0;
  for (; i < CACHE_SIZE - diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (int j = 0; i < CACHE_SIZE; i++, j++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
    EXPECT_NE(set.end(), set.find(plans2[j].get()));
  }

  for (; i < CACHE_SIZE + diff; i++) {
    EXPECT_EQ(set.end(), set.find(plans[i].get()));
  }

  for (; i < CACHE_SIZE * 2; i++) {
    EXPECT_NE(set.end(), set.find(plans[i].get()));
  }
}

}  // End test namespace
}  // End peloton namespace
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.3  2000/02/06 07:47:58  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  1999/12/18 00:21:23  roddey
 * Fixed a small reported memory leak
 *
 * Revision 1.1.1.1  1999/11/09 01:07:47  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:02  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef SAXEXCEPTION_HPP
#define SAXEXCEPTION_HPP

#include <util/XMLString.hpp>
#include <util/XMLUni.hpp>

/**
  * Encapsulate a general SAX error or warning.
  *
  *
This class can contain basic error or warning information from
  * either the XML SAX parser or the application: a parser writer or
  * application writer can subclass it to provide additional
  * functionality.  SAX handlers may throw this exception or
  * any exception subclassed from it.

  *
  *
If the application needs to pass through other types of
  * exceptions, it must wrap those exceptions in a SAXException
  * or an exception derived from a SAXException.

  *
  *
If the parser or application needs to include information
  * about a specific location in an XML document, it should use the
  * SAXParseException subclass.

  *
  * $Log$
  * Revision 1.3  2000/02/06 07:47:58  rahulj
  * Year 2K copyright swat.
  *
  * Revision 1.2  1999/12/18 00:21:23  roddey
  * Fixed a small reported memory leak
  *
  * Revision 1.1.1.1  1999/11/09 01:07:47  twl
  * Initial checkin
  *
  * Revision 1.2  1999/11/08 20:45:02  rahul
  * Swat for adding in Product name and CVS comment log variable.
  *
  * @see SAXParseException#SAXParseException
  */
class SAX_EXPORT SAXException
{
public:
    /** @name Constructors and Destructor */
    //@{
    /** Default constructor
     */
    SAXException() :

        fMsg(XMLString::replicate(XMLUni::fgZeroLenString))
    {
    }

  /**
    * Create a new SAXException.
    *
    * @param msg The error or warning message.
    */
    SAXException(const XMLCh* const msg) :

        fMsg(XMLString::replicate(msg))
    {
    }

    SAXException(const char* const msg) :

        fMsg(XMLString::transcode(msg))
    {
    }

    SAXException(const SAXException& toCopy) :

        fMsg(XMLString::replicate(toCopy.fMsg))
    {
    }

    /** Destructor */
    virtual ~SAXException()
    {
        delete [] fMsg;
    }

    //@}

    /** @name Public Operators */
    SAXException& operator=(const SAXException& toCopy)
    {
        if (this == &toCopy)
            return *this;

        delete [] fMsg;
        fMsg = XMLString::replicate(toCopy.fMsg);
        return *this;
    }

    /** @name Getter Methods */
    const XMLCh* getMessage() const
    {
        return fMsg;
    }

private :
    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fMsg
    //      This is the text of the error that is being thrown.
    // -----------------------------------------------------------------------
    XMLCh*  fMsg;
};

#endif
<commit_msg>Inserted documentation for new APIs<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.4  2000/02/09 19:15:17  abagchi
 * Inserted documentation for new APIs
 *
 * Revision 1.3  2000/02/06 07:47:58  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  1999/12/18 00:21:23  roddey
 * Fixed a small reported memory leak
 *
 * Revision 1.1.1.1  1999/11/09 01:07:47  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:02  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef SAXEXCEPTION_HPP
#define SAXEXCEPTION_HPP

#include <util/XMLString.hpp>
#include <util/XMLUni.hpp>

/**
  * Encapsulate a general SAX error or warning.
  *
  *
This class can contain basic error or warning information from
  * either the XML SAX parser or the application: a parser writer or
  * application writer can subclass it to provide additional
  * functionality.  SAX handlers may throw this exception or
  * any exception subclassed from it.

  *
  *
If the application needs to pass through other types of
  * exceptions, it must wrap those exceptions in a SAXException
  * or an exception derived from a SAXException.

  *
  *
If the parser or application needs to include information
  * about a specific location in an XML document, it should use the
  * SAXParseException subclass.

  *
  * @see SAXParseException#SAXParseException
  */
class SAX_EXPORT SAXException
{
public:
    /** @name Constructors and Destructor */
    //@{
    /** Default constructor
     */
    SAXException() :

        fMsg(XMLString::replicate(XMLUni::fgZeroLenString))
    {
    }

  /**
    * Create a new SAXException.
    *
    * @param msg The error or warning message.
    */
    SAXException(const XMLCh* const msg) :

        fMsg(XMLString::replicate(msg))
    {
    }

  /**
    * Create a new SAXException.
    *
    * @param msg The error or warning message.
    */
    SAXException(const char* const msg) :

        fMsg(XMLString::transcode(msg))
    {
    }

  /**
    * Copy constructor
    *
    * @param toCopy The exception to be copy constructed
    */
    SAXException(const SAXException& toCopy) :

        fMsg(XMLString::replicate(toCopy.fMsg))
    {
    }

    /** Destructor */
    virtual ~SAXException()
    {
        delete [] fMsg;
    }

    //@}

    /** @name Public Operators */
    //@{
    /**
      * Assignment operator
      *
      * @param toCopy The object to be copied
      */
    SAXException& operator=(const SAXException& toCopy)
    {
        if (this == &toCopy)
            return *this;

        delete [] fMsg;
        fMsg = XMLString::replicate(toCopy.fMsg);
        return *this;
    }
    //@}

    /** @name Getter Methods */
    //@{
    /**
      * Get the contents of the message
      *
      */
    const XMLCh* getMessage() const
    {
        return fMsg;
    }
    //@}

private :
    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fMsg
    //      This is the text of the error that is being thrown.
    // -----------------------------------------------------------------------
    XMLCh*  fMsg;
};

#endif
<|endoftext|>


<commit_before><commit_msg>linux: spoof UA string when using Yahoo mail<commit_after><|endoftext|>


<commit_before>#include "kfold.h"
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <iostream>
using std::vector;
using std::cout;
using std::endl;
/**
Class to generate the vectors from a dataset for kfold cross validation.
data is the whole dataset
numGenes is the number of rows
classSizes is a vector containing the 2 classSizes
k is the number of folds
**/
kfold::kfold( vector<double> & data, int numGenes, vector<int> & classSizes, int k){
    this->nGenes = numGenes;
    this->orig_data = &data;
    this->class1size = classSizes[0];
    this->class2size = classSizes[1];
    this->k = k;
    this->it = 0;
    this->samp_vector = generateSampleVector();
    this->next_fold = 0;
    this->generated_data = NULL;
    this->generated_test = NULL;
    this->curr_class = -1;
    this->curr_classSizes = classSizes;
}

kfold::~kfold(){
    delete generated_data;
    delete generated_test;
    orig_data = NULL;
}
/**
Generates a vector containing [0,...,n-1] that has been shuffled.
**/
vector<int> kfold::generateSampleVector(){

    srand(time(NULL));
    if (k > class1size + class2size){
        k = class1size + class2size;
        //k is bigger than our sample size, so lets do loocv
    }
    vector<int> samples(class1size+class2size);
    for(int i = 0;i<class1size+class2size;i++){
        samples[i] = i;
    }
    for(int i=class1size+class2size-1;i>0;i--){//fisher-yates shuffle
        int j = rand() % i;
        int temp = samples[i];
        samples[i] = samples[j];
        samples[j] = temp;
    }

    if (checkFoldsGood(samples)){
        return samples;
    } else {
        //all our pigeons are in the same hole.
        //shuffle shuffle
        return generateSampleVector();
    }

}
/**
Checks that we will not have a training set without any samples for a class.

**/
bool kfold::checkFoldsGood( vector<int> & sample){
    int fsize = getFoldSize();

    bool good = true;

    if (class1size > fsize && class2size > fsize) return good;//shortcircuit pigeon
    int class1counter=0;
    int class2counter=0;
    for(unsigned int i = 0; i < sample.size();i++ ){
        //the only way for this to happen is if all of one class ends up in a
        //fold
        if (i%fsize == 0){//new fold
           class1counter = 0;
           class2counter = 0;
        }
        //size of class[1||2] in this fold
        if(sample.at(i) < class1size){//class1sample
            class1counter++;
        } else {//class2sample
            class2counter++;
        }
        if ((class1counter == class1size)
            || (class2counter == class2size)){
            //Oh noes!!!!All our eggs are in one basket.
            good = false;
            break;
        }
     }
     return good;
}
/**
Returns a vector that contains the training set for the next set of learners
Returns null if there are no more training sets to be generated.

NOTE: on each call to this function the previous training set is deleted!!
You will need to copy the vector if you want to keep it.
**/
vector<double> * kfold::getNextTrainingSet(){
    next_fold = next_fold + getFoldSize();
    curr_classSizes[0] = 0;
    curr_classSizes[1] = 0;

    if (next_fold > (int)samp_vector.size()) next_fold = (int)samp_vector.size();
    if ((int)samp_vector.size() == it) return NULL;

    delete generated_data;
    generated_data = new vector<double>();
    for(int base_i = 0; base_i<class1size+class2size;base_i++){
        if(trainingData(base_i) ){
            curr_classSizes[base_i >= class1size]++;
            for(int j=0; j<nGenes;j++){
                generated_data->push_back(orig_data->at(base_i*nGenes + j));
            }
        }

    }
    return generated_data;
}
/**
Returns the current test vector.
Returns null if their are no more test vectors for the current training set

NOTE: on each call to this function the previous test vector is deleted!!
You will need to copy the vector if you want to keep it.
**/
vector<double> * kfold::getNextTestVector(){
    delete generated_test;
    if(it == next_fold){
        curr_class = -1;
        generated_test = NULL;
        return NULL;
    }
    generated_test = new vector<double>();
    int next_sample = samp_vector[it];
    if (next_sample < class1size){
        curr_class = 0;
    } else {
        curr_class = 1;
    }
    int col = nGenes*next_sample;

    for(int i = 0; i<nGenes; i++){
        generated_test->push_back(orig_data->at(col + i));
    }
    it++;
   return generated_test;
}
vector<int> kfold::getClassSizes(){
    return curr_classSizes;
}

int kfold::getTestVectorClass(){
    return curr_class;
}
/**
Given a sample number
return true if sample is in training set
return false is sample is to be used for crossvalidation
**/
bool kfold::trainingData(int sample){
    for(int i=it; i < next_fold;i++){
        if(samp_vector[i] == sample){
            return false;
        }
    }
    return true;
}
int kfold::getFoldSize(){
    int ksize = (class1size+class2size)/k;
    if((class1size+class2size)%k > 0){
        ksize++;
    }
    return ksize;
}
void printVect(vector<double> a, int rows){
    for(unsigned int i=0;i<a.size();i++){
        if (i%rows == 0){cout << endl;}
        cout << a.at(i) << " ";
    }
    cout << endl;
}
/**
int main(){

    vector<double> data;
    vector<int> cs;

    int c1=5;
    int c2 = 5;
    int nGenes = 10;
    float base = 0.0;
    for (int i=0; i<c1;i++){
        for(int j=0;j<nGenes;j++){
                base = 0.0;
            data.push_back(i*nGenes + j + base);
        }

    }
    for (int i=c1; i<c1+c2;i++){
        for(int j=0;j<nGenes;j++){
                base = 0.5;
            data.push_back(i*nGenes + j + base);
        }

    }
    cs.push_back(c1);
    cs.push_back(c2);
    kfold k(data,nGenes, cs, 3);
    vector<double> * ts;
    vector<double> * ls;
    ts = k.getNextTrainingSet();
    int counter = 0;
    while(ts != NULL){
    counter++;
    cout <<endl<< "ts" << endl;
        printVect((*ts), nGenes);
        ls = k.getNextTestVector();
        while(ls != NULL){
            cout <<  endl<< "ls" << endl;
            printVect((*ls), nGenes);
            cout << "class=" << k.getTestVectorClass()<<endl;
            cout << "cs1=" <<k.getClassSizes()[0];
            cout << "cs2=" <<k.getClassSizes()[1];
            k.getTestVectorClass();
            ls = k.getNextTestVector();
        }
        ts = k.getNextTrainingSet();
    }

    cout << "times ran = " << counter << endl;
}**/
<commit_msg>dumb mistake in random shuffle, no way for a sample to stay where it was.<commit_after>#include "kfold.h"
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <iostream>
using std::vector;
using std::cout;
using std::endl;
/**
Class to generate the vectors from a dataset for kfold cross validation.
data is the whole dataset
numGenes is the number of rows
classSizes is a vector containing the 2 classSizes
k is the number of folds
**/
kfold::kfold( vector<double> & data, int numGenes, vector<int> & classSizes, int k){
    this->nGenes = numGenes;
    this->orig_data = &data;
    this->class1size = classSizes[0];
    this->class2size = classSizes[1];
    this->k = k;
    this->it = 0;
    this->samp_vector = generateSampleVector();
    this->next_fold = 0;
    this->generated_data = NULL;
    this->generated_test = NULL;
    this->curr_class = -1;
    this->curr_classSizes = classSizes;
}

kfold::~kfold(){
    delete generated_data;
    delete generated_test;
    orig_data = NULL;
}
/**
Generates a vector containing [0,...,n-1] that has been shuffled.
**/
vector<int> kfold::generateSampleVector(){

    srand(time(NULL));
    if (k > class1size + class2size){
        k = class1size + class2size;
        //k is bigger than our sample size, so lets do loocv
    }
    vector<int> samples(class1size+class2size);
    for(int i = 0;i<class1size+class2size;i++){
        samples[i] = i;
    }
    for(int i=class1size+class2size-1;i>0;i--){//fisher-yates shuffle
        int j = rand() % (i+1);
        int temp = samples[i];
        samples[i] = samples[j];
        samples[j] = temp;
    }

    if (checkFoldsGood(samples)){
        return samples;
    } else {
        //all our pigeons are in the same hole.
        //shuffle shuffle
        return generateSampleVector();
    }

}
/**
Checks that we will not have a training set without any samples for a class.

**/
bool kfold::checkFoldsGood( vector<int> & sample){
    int fsize = getFoldSize();

    bool good = true;

    if (class1size > fsize && class2size > fsize) return good;//shortcircuit pigeon
    int class1counter=0;
    int class2counter=0;
    for(unsigned int i = 0; i < sample.size();i++ ){
        //the only way for this to happen is if all of one class ends up in a
        //fold
        if (i%fsize == 0){//new fold
           class1counter = 0;
           class2counter = 0;
        }
        //size of class[1||2] in this fold
        if(sample.at(i) < class1size){//class1sample
            class1counter++;
        } else {//class2sample
            class2counter++;
        }
        if ((class1counter == class1size)
            || (class2counter == class2size)){
            //Oh noes!!!!All our eggs are in one basket.
            good = false;
            break;
        }
     }
     return good;
}
/**
Returns a vector that contains the training set for the next set of learners
Returns null if there are no more training sets to be generated.

NOTE: on each call to this function the previous training set is deleted!!
You will need to copy the vector if you want to keep it.
**/
vector<double> * kfold::getNextTrainingSet(){
    next_fold = next_fold + getFoldSize();
    curr_classSizes[0] = 0;
    curr_classSizes[1] = 0;

    if (next_fold > (int)samp_vector.size()) next_fold = (int)samp_vector.size();
    if ((int)samp_vector.size() == it) return NULL;

    delete generated_data;
    generated_data = new vector<double>();
    for(int base_i = 0; base_i<class1size+class2size;base_i++){
        if(trainingData(base_i) ){
            curr_classSizes[base_i >= class1size]++;
            for(int j=0; j<nGenes;j++){
                generated_data->push_back(orig_data->at(base_i*nGenes + j));
            }
        }

    }
    return generated_data;
}
/**
Returns the current test vector.
Returns null if their are no more test vectors for the current training set

NOTE: on each call to this function the previous test vector is deleted!!
You will need to copy the vector if you want to keep it.
**/
vector<double> * kfold::getNextTestVector(){
    delete generated_test;
    if(it == next_fold){
        curr_class = -1;
        generated_test = NULL;
        return NULL;
    }
    generated_test = new vector<double>();
    int next_sample = samp_vector[it];
    if (next_sample < class1size){
        curr_class = 0;
    } else {
        curr_class = 1;
    }
    int col = nGenes*next_sample;

    for(int i = 0; i<nGenes; i++){
        generated_test->push_back(orig_data->at(col + i));
    }
    it++;
   return generated_test;
}
vector<int> kfold::getClassSizes(){
    return curr_classSizes;
}

int kfold::getTestVectorClass(){
    return curr_class;
}
/**
Given a sample number
return true if sample is in training set
return false is sample is to be used for crossvalidation
**/
bool kfold::trainingData(int sample){
    for(int i=it; i < next_fold;i++){
        if(samp_vector[i] == sample){
            return false;
        }
    }
    return true;
}
int kfold::getFoldSize(){
    int ksize = (class1size+class2size)/k;
    if((class1size+class2size)%k > 0){
        ksize++;
    }
    return ksize;
}
void printVect(vector<double> a, int rows){
    for(unsigned int i=0;i<a.size();i++){
        if (i%rows == 0){cout << endl;}
        cout << a.at(i) << " ";
    }
    cout << endl;
}
/**
int main(){

    vector<double> data;
    vector<int> cs;

    int c1=5;
    int c2 = 5;
    int nGenes = 10;
    float base = 0.0;
    for (int i=0; i<c1;i++){
        for(int j=0;j<nGenes;j++){
                base = 0.0;
            data.push_back(i*nGenes + j + base);
        }

    }
    for (int i=c1; i<c1+c2;i++){
        for(int j=0;j<nGenes;j++){
                base = 0.5;
            data.push_back(i*nGenes + j + base);
        }

    }
    cs.push_back(c1);
    cs.push_back(c2);
    kfold k(data,nGenes, cs, 3);
    vector<double> * ts;
    vector<double> * ls;
    ts = k.getNextTrainingSet();
    int counter = 0;
    while(ts != NULL){
    counter++;
    cout <<endl<< "ts" << endl;
        printVect((*ts), nGenes);
        ls = k.getNextTestVector();
        while(ls != NULL){
            cout <<  endl<< "ls" << endl;
            printVect((*ls), nGenes);
            cout << "class=" << k.getTestVectorClass()<<endl;
            cout << "cs1=" <<k.getClassSizes()[0];
            cout << "cs2=" <<k.getClassSizes()[1];
            k.getTestVectorClass();
            ls = k.getNextTestVector();
        }
        ts = k.getNextTrainingSet();
    }

    cout << "times ran = " << counter << endl;
}**/
<|endoftext|>