<commit_before>/* -*- C++ -*-; c-basic-offset: 4; indent-tabs-mode: nil */
/*
 * Framework stress test standalone
 *
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
#include <unistd.h>
#include <csignal>

#include <string>
#include <vector>
#include <iostream>

#include <boost/program_options.hpp>

#include <modelgbp/dmtree/Root.hpp>
#include <modelgbp/metadata/metadata.hpp>
#include <opflex/test/MockOpflexServer.h>
#include <opflex/ofcore/OFFramework.h>
#include <opflex/ofcore/OFConstants.h>

#include <opflexagent/logging.h>
#include <opflexagent/cmd.h>
#include "Policies.h"

using std::string;
using std::make_pair;
using std::shared_ptr;
namespace po = boost::program_options;
using opflex::test::MockOpflexServer;
using opflex::ofcore::OFConstants;
using namespace opflexagent;

volatile bool running = true;
volatile int gotconfig = 0;

/**
 * Listener for changes related to plaform config.
 */
class ConfigListener : public opflex::modb::ObjectListener {
public:
    ConfigListener() {}
    virtual ~ConfigListener() {}

    virtual void objectUpdated(opflex::modb::class_id_t class_id,
                               const opflex::modb::URI& uri) {
        LOG(INFO);
        gotconfig += 1;
    }
};
ConfigListener configListener;

void sighandler(int sig) {
    running = false;
    LOG(INFO) << "Got " << strsignal(sig) << " signal";
}

#define SERVER_ROLES \
        (OFConstants::POLICY_REPOSITORY |     \
         OFConstants::ENDPOINT_REGISTRY |     \
         OFConstants::OBSERVER)
#define LOCALHOST "127.0.0.1"

int main(int argc, char** argv) {
    signal(SIGPIPE, SIG_IGN);
    // Parse command line options
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Print this help message")
        ("log", po::value<string>()->default_value(""),
         "Log to the specified file (default standard out)")
        ("level", po::value<string>()->default_value("info"),
         "Use the specified log level (default info)")
        ("policy,p", po::value<string>()->default_value(""),
         "Read the specified policy file to seed the MODB")
        ;

    std::string log_file;
    std::string level_str;
    std::string policy_file;

    po::variables_map vm;
    try {
        po::store(po::command_line_parser(argc, argv).
                  options(desc).run(), vm);
        po::notify(vm);

        if (vm.count("help")) {
            std::cout << "Usage: " << argv[0] << " [options]\n";
            std::cout << desc;
            return 0;
        }
        log_file = vm["log"].as<string>();
        level_str = vm["level"].as<string>();
        policy_file = vm["policy"].as<string>();

    } catch (po::unknown_option e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    initLogging(level_str, false /*syslog*/, log_file, "framework-stress");

    try {
        MockOpflexServer::peer_vec_t peer_vec;
        peer_vec.push_back(make_pair(SERVER_ROLES, LOCALHOST":8009"));
        MockOpflexServer server(8009, SERVER_ROLES, peer_vec,
                                modelgbp::getMetadata());

        if (policy_file != "") {
            server.readPolicy(policy_file);
        }

        server.start();

        signal(SIGINT | SIGTERM, sighandler);
        while (running) {
            gotconfig = 0;

            opflex::ofcore::OFFramework framework;
            framework.setModel(modelgbp::getMetadata());
            framework.setOpflexIdentity("test", "test");
            framework.start();
            framework.addPeer(LOCALHOST, 8009);

            modelgbp::platform::Config::
                registerListener(framework, &configListener);
            modelgbp::gbp::EpGroup::
                registerListener(framework, &configListener);

            shared_ptr<modelgbp::epdr::L2Discovered> l2d;
            {
                opflex::modb::Mutator mutator(framework, "init");
                shared_ptr<modelgbp::dmtree::Root> root =
                    modelgbp::dmtree::Root::createRootElement(framework);
                root->addPolicyUniverse();
                root->addRelatorUniverse();
                root->addEprL2Universe();
                root->addEprL3Universe();
                l2d = root->addEpdrL2Discovered();
                root->addEpdrL3Discovered();
                root->addGbpeVMUniverse();
                root->addObserverEpStatUniverse();

                root->addDomainConfig()
                    ->addDomainConfigToConfigRSrc()
                    ->setTargetConfig("openstack");

                mutator.commit();
            }
            {
                opflex::modb::Mutator mutator(framework, "policyelement");
                l2d->addEpdrLocalL2Ep("1")
                    ->addEpdrEndPointToGroupRSrc()
                    ->setTargetEpGroup(opflex::modb::URIBuilder()
                                       .addElement("PolicyUniverse")
                                       .addElement("PolicySpace")
                                       .addElement("test")
                                       .addElement("GbpEpGroup")
                                       .addElement("group1").build());
                l2d->addEpdrLocalL2Ep("2")
                    ->addEpdrEndPointToGroupRSrc()
                    ->setTargetEpGroup(opflex::modb::URIBuilder()
                                       .addElement("PolicyUniverse")
                                       .addElement("PolicySpace")
                                       .addElement("test")
                                       .addElement("GbpEpGroup")
                                       .addElement("group2").build());
                l2d->addEpdrLocalL2Ep("3")
                    ->addEpdrEndPointToGroupRSrc()
                    ->setTargetEpGroup(opflex::modb::URIBuilder()
                                       .addElement("PolicyUniverse")
                                       .addElement("PolicySpace")
                                       .addElement("test")
                                       .addElement("GbpEpGroup")
                                       .addElement("group3").build());
                mutator.commit();
            }

            int c = 0;
            while (gotconfig < 2 && c < 500) {
                c += 1;
                usleep(1000);
            }
            framework.prettyPrintMODB(opflexagent::Logger(INFO, __FILE__,
                                                          __LINE__,
                                                          __FUNCTION__)
                                      .stream() << "\n",
                                      true, false, true);
            if (gotconfig < 2)
                LOG(ERROR) << "Didn't happen!";
            framework.stop();
        }

        server.stop();
    } catch (const std::exception& e) {
        LOG(ERROR) << "Fatal error: " << e.what();
        return 2;
    } catch (...) {
        LOG(ERROR) << "Unknown fatal error";
        return 3;
    }
}
<commit_msg>Fix compilation error in integration test<commit_after>/* -*- C++ -*-; c-basic-offset: 4; indent-tabs-mode: nil */
/*
 * Framework stress test standalone
 *
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
#include <unistd.h>
#include <csignal>

#include <string>
#include <vector>
#include <iostream>

#include <boost/program_options.hpp>

#include <modelgbp/dmtree/Root.hpp>
#include <modelgbp/metadata/metadata.hpp>
#include <opflex/test/MockOpflexServer.h>
#include <opflex/ofcore/OFFramework.h>
#include <opflex/ofcore/OFConstants.h>

#include <opflexagent/logging.h>
#include <opflexagent/cmd.h>
#include "Policies.h"

using std::string;
using std::make_pair;
using std::shared_ptr;
namespace po = boost::program_options;
using opflex::test::MockOpflexServer;
using opflex::ofcore::OFConstants;
using namespace opflexagent;

volatile bool running = true;
volatile int gotconfig = 0;

/**
 * Listener for changes related to plaform config.
 */
class ConfigListener : public opflex::modb::ObjectListener {
public:
    ConfigListener() {}
    virtual ~ConfigListener() {}

    virtual void objectUpdated(opflex::modb::class_id_t class_id,
                               const opflex::modb::URI& uri) {
        LOG(INFO);
        gotconfig += 1;
    }
};
ConfigListener configListener;

void sighandler(int sig) {
    running = false;
    LOG(INFO) << "Got " << strsignal(sig) << " signal";
}

#define SERVER_ROLES \
        (OFConstants::POLICY_REPOSITORY |     \
         OFConstants::ENDPOINT_REGISTRY |     \
         OFConstants::OBSERVER)
#define LOCALHOST "127.0.0.1"

int main(int argc, char** argv) {
    signal(SIGPIPE, SIG_IGN);
    // Parse command line options
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Print this help message")
        ("log", po::value<string>()->default_value(""),
         "Log to the specified file (default standard out)")
        ("level", po::value<string>()->default_value("info"),
         "Use the specified log level (default info)")
        ("policy,p", po::value<string>()->default_value(""),
         "Read the specified policy file to seed the MODB")
        ;

    std::string log_file;
    std::string level_str;
    std::string policy_file;

    po::variables_map vm;
    try {
        po::store(po::command_line_parser(argc, argv).
                  options(desc).run(), vm);
        po::notify(vm);

        if (vm.count("help")) {
            std::cout << "Usage: " << argv[0] << " [options]\n";
            std::cout << desc;
            return 0;
        }
        log_file = vm["log"].as<string>();
        level_str = vm["level"].as<string>();
        policy_file = vm["policy"].as<string>();

    } catch (const po::unknown_option& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    initLogging(level_str, false /*syslog*/, log_file, "framework-stress");

    try {
        MockOpflexServer::peer_vec_t peer_vec;
        peer_vec.push_back(make_pair(SERVER_ROLES, LOCALHOST":8009"));
        MockOpflexServer server(8009, SERVER_ROLES, peer_vec, std::vector<std::string>(),
                                modelgbp::getMetadata());

        if (policy_file != "") {
            server.readPolicy(policy_file);
        }

        server.start();

        signal(SIGINT | SIGTERM, sighandler);
        while (running) {
            gotconfig = 0;

            opflex::ofcore::OFFramework framework;
            framework.setModel(modelgbp::getMetadata());
            framework.setOpflexIdentity("test", "test");
            framework.start();
            framework.addPeer(LOCALHOST, 8009);

            modelgbp::platform::Config::
                registerListener(framework, &configListener);
            modelgbp::gbp::EpGroup::
                registerListener(framework, &configListener);

            shared_ptr<modelgbp::epdr::L2Discovered> l2d;
            {
                opflex::modb::Mutator mutator(framework, "init");
                shared_ptr<modelgbp::dmtree::Root> root =
                    modelgbp::dmtree::Root::createRootElement(framework);
                root->addPolicyUniverse();
                root->addRelatorUniverse();
                root->addEprL2Universe();
                root->addEprL3Universe();
                l2d = root->addEpdrL2Discovered();
                root->addEpdrL3Discovered();
                root->addGbpeVMUniverse();
                root->addObserverEpStatUniverse();

                root->addDomainConfig()
                    ->addDomainConfigToConfigRSrc()
                    ->setTargetConfig("openstack");

                mutator.commit();
            }
            {
                opflex::modb::Mutator mutator(framework, "policyelement");
                l2d->addEpdrLocalL2Ep("1")
                    ->addEpdrEndPointToGroupRSrc()
                    ->setTargetEpGroup(opflex::modb::URIBuilder()
                                       .addElement("PolicyUniverse")
                                       .addElement("PolicySpace")
                                       .addElement("test")
                                       .addElement("GbpEpGroup")
                                       .addElement("group1").build());
                l2d->addEpdrLocalL2Ep("2")
                    ->addEpdrEndPointToGroupRSrc()
                    ->setTargetEpGroup(opflex::modb::URIBuilder()
                                       .addElement("PolicyUniverse")
                                       .addElement("PolicySpace")
                                       .addElement("test")
                                       .addElement("GbpEpGroup")
                                       .addElement("group2").build());
                l2d->addEpdrLocalL2Ep("3")
                    ->addEpdrEndPointToGroupRSrc()
                    ->setTargetEpGroup(opflex::modb::URIBuilder()
                                       .addElement("PolicyUniverse")
                                       .addElement("PolicySpace")
                                       .addElement("test")
                                       .addElement("GbpEpGroup")
                                       .addElement("group3").build());
                mutator.commit();
            }

            int c = 0;
            while (gotconfig < 2 && c < 500) {
                c += 1;
                usleep(1000);
            }
            framework.prettyPrintMODB(opflexagent::Logger(INFO, __FILE__,
                                                          __LINE__,
                                                          __FUNCTION__)
                                      .stream() << "\n",
                                      true, false, true);
            if (gotconfig < 2)
                LOG(ERROR) << "Didn't happen!";
            framework.stop();
        }

        server.stop();
    } catch (const std::exception& e) {
        LOG(ERROR) << "Fatal error: " << e.what();
        return 2;
    } catch (...) {
        LOG(ERROR) << "Unknown fatal error";
        return 3;
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tblnumfm.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:14:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PRECOMPILED
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#ifndef _SVX_SVXIDS_HRC //autogen
#include <svx/svxids.hrc>
#endif
#ifndef _SVX_NUMFMT_HXX //autogen
#include <svx/numfmt.hxx>
#endif

#include "swtypes.hxx"

#include "chrdlg.hrc"
#include "tblnumfm.hxx"

SwNumFmtDlg::SwNumFmtDlg(Window* pParent, SfxItemSet& rSet) :

    SfxSingleTabDialog(pParent, rSet, 0)

{
//    SetText(SW_RESSTR(STR_NUMFMT));

    // TabPage erzeugen
    SvxNumberFormatTabPage* pPage = (SvxNumberFormatTabPage*) SvxNumberFormatTabPage::Create(this, rSet);
    const SfxPoolItem& rInfoItem = pPage->GetItemSet().Get(SID_ATTR_NUMBERFORMAT_INFO);
    pPage->SetNumberFormatList((const SvxNumberInfoItem&)rInfoItem );

    SetTabPage(pPage);
}

SwNumFmtDlg::~SwNumFmtDlg()
{
}

/*************************************************************************

      Source Code Control System - Update

      $Log: not supported by cvs2svn $
      Revision 1.5  2000/09/18 16:05:15  willem.vandorp
      OpenOffice header added.

      Revision 1.4  1998/02/25 11:39:14  TJ
      include

      Rev 1.3   25 Feb 1998 12:39:14   TJ
   include

      Rev 1.2   21 Nov 1997 12:24:36   MA
   includes

      Rev 1.1   03 Nov 1997 13:10:22   MA
   precomp entfernt

      Rev 1.0   14 Feb 1997 18:05:02   OM
   Initial revision.

*************************************************************************/

<commit_msg>remove temp variable<commit_after>/*************************************************************************
 *
 *  $RCSfile: tblnumfm.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: jp $ $Date: 2001-03-12 17:51:14 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PRECOMPILED
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _SVX_NUMFMT_HXX
#include <svx/numfmt.hxx>
#endif
#ifndef _SWTYPES_HXX
#include <swtypes.hxx>
#endif
#ifndef _TBLNUMFM_HXX
#include <tblnumfm.hxx>
#endif

#ifndef _CHRDLG_HRC
#include <chrdlg.hrc>
#endif

SwNumFmtDlg::SwNumFmtDlg(Window* pParent, SfxItemSet& rSet)
    : SfxSingleTabDialog( pParent, rSet, 0 )
{
//    SetText(SW_RESSTR(STR_NUMFMT));

    // TabPage erzeugen
    SvxNumberFormatTabPage* pPage = (SvxNumberFormatTabPage*)
                                SvxNumberFormatTabPage::Create( this, rSet );
    pPage->SetNumberFormatList( (const SvxNumberInfoItem&)pPage->
                            GetItemSet().Get( SID_ATTR_NUMBERFORMAT_INFO ) );
    SetTabPage( pPage );
}

SwNumFmtDlg::~SwNumFmtDlg()
{
}

/*************************************************************************

      Source Code Control System - Update

      $Log: not supported by cvs2svn $
      Revision 1.1.1.1  2000/09/18 17:14:32  hr
      initial import

      Revision 1.5  2000/09/18 16:05:15  willem.vandorp
      OpenOffice header added.

      Revision 1.4  1998/02/25 11:39:14  TJ
      include

      Rev 1.3   25 Feb 1998 12:39:14   TJ
   include

      Rev 1.2   21 Nov 1997 12:24:36   MA
   includes

      Rev 1.1   03 Nov 1997 13:10:22   MA
   precomp entfernt

      Rev 1.0   14 Feb 1997 18:05:02   OM
   Initial revision.

*************************************************************************/

<|endoftext|>


<commit_before>/**
 * \file Library.cpp
 * \author Matt Hammerly
 */

#include <string>
#include <iostream>
#include "Library.h"

/**
 * \brief Default constructor
 *
 * Todo: sanitize the db credentials I guess lol
 */
CLibrary::CLibrary()
{
    char connectionString[512];
    snprintf(connectionString, 512, "dbname=%s host=%s user=%s password=%s",
             DBNAME, DBHOST, DBUSER, DBPW);

    mConnection = PQconnectdb(connectionString);

    if (PQstatus(mConnection) == CONNECTION_BAD)
    {
        std::cout << "Failed to connect to the database" << std::endl;
        exit(0);
    }
}

/**
 * \brief Destructor
 *
 * Will close the database connection before exiting
 */
CLibrary::~CLibrary()
{
    PQfinish(mConnection);
}

/**
 * \brief Create the database tables for this application
 *
 * \returns -1 if something goes wrong
 *
 * Todo: Write database schema in this comment
 *       `create trigger IF NOT EXISTS` or similar
 */
int CLibrary::PrepareDatabase()
{
    PGresult *res;
    res = PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks (\
                id SERIAL NOT NULL PRIMARY KEY,\
                filepath TEXT NOT NULL,\
                date_added TIMESTAMPTZ NOT NULL DEFAULT NOW()\
          )");
    PQclear(res);

    res = PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                title TEXT NOT NULL,\
                length INTEGER NOT NULL DEFAULT 0\
          )");
    PQclear(res);

    res = PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks_playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                track_id INTEGER NOT NULL,\
                playlist_id INTEGER NOT NULL,\
                position FLOAT NOT NULL\
          )");
    PQclear(res);

    // Create a function to adjust the length of a playlist
    res = PQexec(mConnection,
            "CREATE OR REPLACE FUNCTION tracks_playlists_insert_func() RETURNS TRIGGER\
            LANGUAGE plpgsql\
            AS $tracks_playlists_insert_func$\
            DECLARE\
                pid INTEGER;\
            BEGIN\
                pid=0;\
                IF (TG_OP = 'INSERT') THEN pid = NEW.playlist_id;\
                ELSIF (TG_OP = 'DELETE') THEN pid = OLD.playlist_id;\
                END IF;\
                WITH Sub AS (SELECT COUNT(id) AS c FROM tracks_playlists WHERE playlist_id = pid)\
                    UPDATE playlists AS Main SET length = Sub.c FROM Sub WHERE Main.id = pid AND 1=1;\
                RETURN NULL;\
            END;\
            $tracks_playlists_insert_func$;");
    PQclear(res);

    // Create a trigger to adjust the length of a playlist on each insert or delete
    res = PQexec(mConnection,
            "CREATE TRIGGER tracks_playlists_insert_trg\
            AFTER INSERT OR DELETE ON tracks_playlists\
            FOR EACH ROW EXECUTE PROCEDURE tracks_playlists_insert_func();");
    PQclear(res);

    // Create a default playlist for all songs to be added to
    res = PQexec(mConnection, "INSERT INTO playlists (title) VALUES ('library')");
    PQclear(res);

    return 0;
}

/**
 * \brief Destroy all database objects used in this application
 *
 * \returns -1 if something goes wrong? I don't know what or why, frankly.
 */
int CLibrary::DestroyDatabase()
{
    PGresult *res;
    res = PQexec(mConnection, "DROP TRIGGER IF EXISTS tracks_playlists_insert_trg ON tracks_playlists;");
    PQclear(res);

    res = PQexec(mConnection, "DROP FUNCTION IF EXISTS tracks_playlists_insert_func() CASCADE;");
    PQclear(res);

    res = PQexec(mConnection, "DROP TABLE IF EXISTS tracks;");
    PQclear(res);

    res = PQexec(mConnection, "DROP TABLE IF EXISTS playlists;");
    PQclear(res);

    res = PQexec(mConnection, "DROP TABLE IF EXISTS tracks_playlists;");
    PQclear(res);

    return 0;
}

/**
 * \brief Exposes the database connection status
 * \returns PostgreSQL connection status object
 *
 * Just in case.
 */
ConnStatusType CLibrary::GetStatus()
{
    return PQstatus(mConnection);
}

/**
 * \brief Returns a pointer to the connection object
 *
 * It makes tests easier. Might make this protected and
 * require a testing subclass to use this later, whatever.
 */
PGconn* CLibrary::GetConnection()
{
    return mConnection;
}

/**
 * \brief Add a track to the database
 * \param filepath The filepath of the file to be added
 * \returns The ID of the new track (as a string)
 *
 * This method also adds the track to the all-library playlist created on database setup
 */
std::string CLibrary::AddTrack(std::string filepath)
{
    std::string query = "INSERT INTO tracks (filepath) VALUES (";

    // Safety first
    char *escaped_filepath = PQescapeLiteral(mConnection, filepath.c_str(), filepath.length());
    query.append(escaped_filepath);
    PQfreemem(escaped_filepath);

    query.append(") RETURNING id");

    PGresult *res = PQexec(mConnection, query.c_str());
    char *id = PQgetvalue(res, 0, 0);

    // Create an std::string to return so we can appropriately free the PGresult
    std::string std_id(id);
    PQclear(res);

    // Add this track to the all-library playlist created on database setup
    std::string query2 = "INSERT INTO tracks_playlists (track_id, playlist_id, position) SELECT " + std_id + ", 1, COALESCE(MAX(position), 0) + 1 FROM tracks_playlists RETURNING id";
    res = PQexec(mConnection, query2.c_str());
    PQclear(res);

    return std_id;
}

/**
 * \brief Add a playlist to the database
 * \param title The title of the playlist to be added
 * \returns The ID of the new playlist (as a string)
 */
std::string CLibrary::AddPlaylist(std::string title)
{
    std::string query = "INSERT INTO playlists (title) VALUES (";

    // Safety first
    char *escaped_title = PQescapeLiteral(mConnection, title.c_str(), title.length());
    query.append(escaped_title);
    PQfreemem(escaped_title);

    query.append(") RETURNING id");

    PGresult *res = PQexec(mConnection, query.c_str());
    char *id = PQgetvalue(res, 0, 0);

    // Create an std::string to return so we can appropriately free the PGresult
    std::string std_id(id);
    PQclear(res);

    return std_id;
}

/**
 * \brief Removes a track from the database, and all records of the track's playlist membership
 * \param id ID of the track to be deleted
 * \returns ID of the deleted track
 */
std::string CLibrary::RemoveTrack(std::string id)
{
    std::string query = "DELETE FROM tracks WHERE id=";

    char escaped_id[30];
    PQescapeStringConn(mConnection, escaped_id, id.c_str(), 30, 0);
    query.append(escaped_id);
    query.append("; DELETE FROM tracks_playlists WHERE track_id=");
    query.append(escaped_id);

    PGresult *res = PQexec(mConnection, query.c_str());
    PQclear(res);

    return id;
}

/**
 * \brief Removes a playlist from the database, and all records of membership in the playlist
 * \param id ID of the playlist to be deleted
 * \returns ID of the deleted playlist
 */
std::string CLibrary::RemovePlaylist(std::string id)
{
    std::string query = "DELETE FROM playlists WHERE id=";

    char escaped_id[30];
    PQescapeStringConn(mConnection, escaped_id, id.c_str(), 30, 0);
    query.append(escaped_id);
    query.append("; DELETE FROM tracks_playlists WHERE playlist_id=");
    query.append(escaped_id);

    PGresult *res = PQexec(mConnection, query.c_str());
    PQclear(res);

    return id;
}
<commit_msg>when a track is deleted, all playlists it was in must be renormalized<commit_after>/**
 * \file Library.cpp
 * \author Matt Hammerly
 */

#include <string>
#include <iostream>
#include "Library.h"

/**
 * \brief Default constructor
 *
 * Todo: sanitize the db credentials I guess lol
 */
CLibrary::CLibrary()
{
    char connectionString[512];
    snprintf(connectionString, 512, "dbname=%s host=%s user=%s password=%s",
             DBNAME, DBHOST, DBUSER, DBPW);

    mConnection = PQconnectdb(connectionString);

    if (PQstatus(mConnection) == CONNECTION_BAD)
    {
        std::cout << "Failed to connect to the database" << std::endl;
        exit(0);
    }
}

/**
 * \brief Destructor
 *
 * Will close the database connection before exiting
 */
CLibrary::~CLibrary()
{
    PQfinish(mConnection);
}

/**
 * \brief Create the database tables for this application
 *
 * \returns -1 if something goes wrong
 *
 * Todo: Write database schema in this comment
 *       `create trigger IF NOT EXISTS` or similar
 */
int CLibrary::PrepareDatabase()
{
    PGresult *res;
    res = PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks (\
                id SERIAL NOT NULL PRIMARY KEY,\
                filepath TEXT NOT NULL,\
                date_added TIMESTAMPTZ NOT NULL DEFAULT NOW()\
          )");
    PQclear(res);

    res = PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                title TEXT NOT NULL,\
                length INTEGER NOT NULL DEFAULT 0\
          )");
    PQclear(res);

    res = PQexec(mConnection,
            "CREATE TABLE IF NOT EXISTS tracks_playlists (\
                id SERIAL NOT NULL PRIMARY KEY,\
                track_id INTEGER NOT NULL,\
                playlist_id INTEGER NOT NULL,\
                position FLOAT NOT NULL\
          )");
    PQclear(res);

    // Create a function to adjust the length of a playlist
    res = PQexec(mConnection,
            "CREATE OR REPLACE FUNCTION tracks_playlists_insert_func() RETURNS TRIGGER\
            LANGUAGE plpgsql\
            AS $tracks_playlists_insert_func$\
            DECLARE\
                pid INTEGER;\
            BEGIN\
                pid=0;\
                IF (TG_OP = 'INSERT') THEN pid = NEW.playlist_id;\
                ELSIF (TG_OP = 'DELETE') THEN pid = OLD.playlist_id;\
                END IF;\
                WITH Sub AS (SELECT COUNT(id) AS c FROM tracks_playlists WHERE playlist_id = pid)\
                    UPDATE playlists AS Main SET length = Sub.c FROM Sub WHERE Main.id = pid AND 1=1;\
                RETURN NULL;\
            END;\
            $tracks_playlists_insert_func$;");
    PQclear(res);

    // Create a trigger to adjust the length of a playlist on each insert or delete
    res = PQexec(mConnection,
            "CREATE TRIGGER tracks_playlists_insert_trg\
            AFTER INSERT OR DELETE ON tracks_playlists\
            FOR EACH ROW EXECUTE PROCEDURE tracks_playlists_insert_func();");
    PQclear(res);

    // Create a default playlist for all songs to be added to
    res = PQexec(mConnection, "INSERT INTO playlists (title) VALUES ('library')");
    PQclear(res);

    return 0;
}

/**
 * \brief Destroy all database objects used in this application
 *
 * \returns -1 if something goes wrong? I don't know what or why, frankly.
 */
int CLibrary::DestroyDatabase()
{
    PGresult *res;
    res = PQexec(mConnection, "DROP TRIGGER IF EXISTS tracks_playlists_insert_trg ON tracks_playlists;");
    PQclear(res);

    res = PQexec(mConnection, "DROP FUNCTION IF EXISTS tracks_playlists_insert_func() CASCADE;");
    PQclear(res);

    res = PQexec(mConnection, "DROP TABLE IF EXISTS tracks;");
    PQclear(res);

    res = PQexec(mConnection, "DROP TABLE IF EXISTS playlists;");
    PQclear(res);

    res = PQexec(mConnection, "DROP TABLE IF EXISTS tracks_playlists;");
    PQclear(res);

    return 0;
}

/**
 * \brief Exposes the database connection status
 * \returns PostgreSQL connection status object
 *
 * Just in case.
 */
ConnStatusType CLibrary::GetStatus()
{
    return PQstatus(mConnection);
}

/**
 * \brief Returns a pointer to the connection object
 *
 * It makes tests easier. Might make this protected and
 * require a testing subclass to use this later, whatever.
 */
PGconn* CLibrary::GetConnection()
{
    return mConnection;
}

/**
 * \brief Add a track to the database
 * \param filepath The filepath of the file to be added
 * \returns The ID of the new track (as a string)
 *
 * This method also adds the track to the all-library playlist created on database setup
 */
std::string CLibrary::AddTrack(std::string filepath)
{
    std::string query = "INSERT INTO tracks (filepath) VALUES (";

    // Safety first
    char *escaped_filepath = PQescapeLiteral(mConnection, filepath.c_str(), filepath.length());
    query.append(escaped_filepath);
    PQfreemem(escaped_filepath);

    query.append(") RETURNING id");

    PGresult *res = PQexec(mConnection, query.c_str());
    char *id = PQgetvalue(res, 0, 0);

    // Create an std::string to return so we can appropriately free the PGresult
    std::string std_id(id);
    PQclear(res);

    // Add this track to the all-library playlist created on database setup
    std::string query2 = "INSERT INTO tracks_playlists (track_id, playlist_id, position) SELECT " + std_id + ", 1, COALESCE(MAX(position), 0) + 1 FROM tracks_playlists RETURNING id";
    res = PQexec(mConnection, query2.c_str());
    PQclear(res);

    return std_id;
}

/**
 * \brief Add a playlist to the database
 * \param title The title of the playlist to be added
 * \returns The ID of the new playlist (as a string)
 */
std::string CLibrary::AddPlaylist(std::string title)
{
    std::string query = "INSERT INTO playlists (title) VALUES (";

    // Safety first
    char *escaped_title = PQescapeLiteral(mConnection, title.c_str(), title.length());
    query.append(escaped_title);
    PQfreemem(escaped_title);

    query.append(") RETURNING id");

    PGresult *res = PQexec(mConnection, query.c_str());
    char *id = PQgetvalue(res, 0, 0);

    // Create an std::string to return so we can appropriately free the PGresult
    std::string std_id(id);
    PQclear(res);

    return std_id;
}

/**
 * \brief Removes a track from the database, and all records of the track's playlist membership
 * \param id ID of the track to be deleted
 * \returns ID of the deleted track
 */
std::string CLibrary::RemoveTrack(std::string id)
{
    std::string query = "DELETE FROM tracks WHERE id=";

    char escaped_id[30];
    PQescapeStringConn(mConnection, escaped_id, id.c_str(), 30, 0);
    query.append(escaped_id);
    query.append("; DELETE FROM tracks_playlists WHERE track_id=");
    query.append(escaped_id);

    PGresult *res = PQexec(mConnection, query.c_str());
    PQclear(res);

    // We need to now normalize every playlist
    // Ideally we'll only normalize those playlists the track was actually in
    // but I'll do that some other day
    res = PQexec(mConnection, "SELECT id FROM playlists");
    int n = PQntuples(res);
    for (int i = 0; i < n; ++i)
    {
        char *id = PQgetvalue(res, i, 0);

        std::string normalize_query = "WITH Sub AS (SELECT id, row_number() OVER (ORDER BY position) FROM tracks_playlists WHERE playlist_id=";
        normalize_query.append(id);
        normalize_query.append(") UPDATE tracks_playlists AS Main SET position = Sub.row_number FROM Sub WHERE Main.id = Sub.id");

        PQclear(PQexec(mConnection, normalize_query.c_str()));
    }

    return id;
}

/**
 * \brief Removes a playlist from the database, and all records of membership in the playlist
 * \param id ID of the playlist to be deleted
 * \returns ID of the deleted playlist
 */
std::string CLibrary::RemovePlaylist(std::string id)
{
    std::string query = "DELETE FROM playlists WHERE id=";

    char escaped_id[30];
    PQescapeStringConn(mConnection, escaped_id, id.c_str(), 30, 0);
    query.append(escaped_id);
    query.append("; DELETE FROM tracks_playlists WHERE playlist_id=");
    query.append(escaped_id);

    PGresult *res = PQexec(mConnection, query.c_str());
    PQclear(res);

    return id;
}
<|endoftext|>


<commit_before>#include "MIMEType.hh"

#include <string>
#include <unordered_map>

using namespace std;

static const unordered_map<string, string> mime_type_for_file_extension({
  {"aif", "audio/aiff"},
  {"aifc", "audio/aiff"},
  {"aiff", "audio/aiff"},
  {"ani", "application/x-navi-animation"},
  {"asf", "video/x-ms-asf"},
  {"asm", "text/x-asm"},
  {"asp", "text/asp"},
  {"asx", "video/x-ms-asf"},
  {"au", "audio/basic"},
  {"avi", "video/avi"},
  {"bm", "image/bmp"},
  {"bmp", "image/bmp"},
  {"dib", "image/bmp"},
  {"bz", "application/x-bzip"},
  {"bz2", "application/x-bzip2"},
  {"c", "text/x-c"},
  {"c", "text/x-c"},
  {"cc", "text/x-c"},
  {"class", "application/java"},
  {"conf", "text/plain"},
  {"cpp", "text/x-c"},
  {"crt", "application/pkix-cert"},
  {"csh", "text/x-script.csh"},
  {"css", "text/css"},
  {"cxx", "text/x-c"},
  {"doc", "application/msword"},
  {"dv", "video/x-dv"},
  {"dvi", "application/x-dvi"},
  {"eps", "application/postscript"},
  {"f", "text/x-fortran"},
  {"f77", "text/x-fortran"},
  {"f90", "text/x-fortran"},
  {"gif", "image/gif"},
  {"gitignore", "text/plain"},
  {"gz", "application/x-gzip"},
  {"gzip", "multipart/x-gzip"},
  {"h", "text/x-c"},
  {"hh", "text/x-c"},
  {"hqx", "application/binhex"},
  {"htm", "text/html"},
  {"html", "text/html"},
  {"htmls", "text/html"},
  {"it", "audio/it"},
  {"jav", "text/x-java-source"},
  {"java", "text/x-java-source"},
  {"jfif", "image/jpeg"},
  {"jpe", "image/jpeg"},
  {"jpeg", "image/jpeg"},
  {"jpg", "image/jpeg"},
  {"js", "text/javascript"},
  {"ksh", "text/x-script.ksh"},
  {"latex", "application/x-latex"},
  {"log", "text/plain"},
  {"m", "text/plain"},
  {"m1v", "video/mpeg"},
  {"m2a", "audio/mpeg"},
  {"m2v", "video/mpeg"},
  {"man", "application/x-troff-man"},
  {"mid", "audio/midi"},
  {"midi", "audio/midi"},
  {"mod", "audio/mod"},
  {"moov", "video/quicktime"},
  {"mov", "video/quicktime"},
  {"mp2", "video/mpeg"},
  {"mp3", "audio/mpeg3"},
  {"mpe", "video/mpeg"},
  {"mpeg", "video/mpeg"},
  {"mpg", "video/mpeg"},
  {"p", "text/pascal"},
  {"p10", "application/pkcs10"},
  {"p12", "application/pkcs-12"},
  {"p7a", "application/x-pkcs7-signature"},
  {"p7c", "application/x-pkcs7-mime"},
  {"p7m", "application/x-pkcs7-mime"},
  {"p7r", "application/x-pkcs7-certreqresp"},
  {"p7s", "application/pkcs7-signature"},
  {"pas", "text/x-pascal"},
  {"pbm", "image/x-portable-bitmap"},
  {"pct", "image/x-pict"},
  {"pcx", "image/x-pcx"},
  {"pdf", "application/pdf"},
  {"pgm", "image/x-portable-greymap"},
  {"pic", "image/pict"},
  {"pict", "image/pict"},
  {"pkg", "application/x-newton-compatible-pkg"},
  {"pl", "text/x-script.perl"},
  {"png", "image/png"},
  {"pnm", "image/x-portable-anymap"},
  {"ppm", "image/x-portable-pixmap"},
  {"ppt", "application/x-mspowerpoint"},
  {"ps", "application/postscript"},
  {"py", "text/x-script.python"},
  {"pyc", "application/x-bytecode.python"},
  {"qt", "video/quicktime"},
  {"ra", "audio/x-realaudio"},
  {"ram", "audio/x-realaudio"},
  {"rm", "audio/x-pn-realaudio"},
  {"rtf", "application/rtf"},
  {"s", "text/x-asm"},
  {"s3m", "audio/s3m"},
  {"sea", "application/sea"},
  {"sh", "text/x-script.sh"},
  {"shtml", "text/html"},
  {"snd", "audio/basic"},
  {"swf", "application/x-shockwave-flash"},
  {"t", "application/x-troff"},
  {"tar", "application/x-tar"},
  {"tcl", "text/x-script.tcl"},
  {"tcsh", "text/x-script.tcsh"},
  {"tex", "application/x-tex"},
  {"text", "text/plain"},
  {"tgz", "application/x-compressed"},
  {"tif", "image/tiff"},
  {"tiff", "image/tiff"},
  {"tr", "application/x-troff"},
  {"tsv", "text/tab-separated-values"},
  {"txt", "text/plain"},
  {"wav", "audio/wav"},
  {"xm", "audio/xm"},
  {"xml", "text/xml"},
  {"z", "application/x-compressed"},
  {"zip", "application/x-compressed"},
  {"zsh", "text/x-script.zsh"},
});

static const unordered_map<string, string> mime_type_for_basename({
  {"LICENSE", "text/plain"},
  {"Makefile", "text/plain"},
  {"README", "text/plain"},
});

const char* mime_type_for_filename(const string& filename) {
  size_t extension_pos = filename.rfind('.');
  if (extension_pos != string::npos) {
    try {
      string extension = filename.substr(extension_pos + 1);
      return mime_type_for_file_extension.at(extension).c_str();
    } catch (const out_of_range& e) { }
  }

  // some common (usually text) files don't have extensions
  try {
    return mime_type_for_basename.at(filename).c_str();
  } catch (const out_of_range& e) { }

  return "application/octet-stream";
}
<commit_msg>add some mime types<commit_after>#include "MIMEType.hh"

#include <string>
#include <unordered_map>

using namespace std;

static const unordered_map<string, string> mime_type_for_file_extension({
  {"aif", "audio/aiff"},
  {"aifc", "audio/aiff"},
  {"aiff", "audio/aiff"},
  {"ani", "application/x-navi-animation"},
  {"asf", "video/x-ms-asf"},
  {"asm", "text/x-asm"},
  {"asp", "text/asp"},
  {"asx", "video/x-ms-asf"},
  {"au", "audio/basic"},
  {"avi", "video/avi"},
  {"bm", "image/bmp"},
  {"bmp", "image/bmp"},
  {"dib", "image/bmp"},
  {"bz", "application/x-bzip"},
  {"bz2", "application/x-bzip2"},
  {"c", "text/x-c"},
  {"cc", "text/x-c"},
  {"class", "application/java"},
  {"conf", "text/plain"},
  {"cpp", "text/x-c"},
  {"crt", "application/pkix-cert"},
  {"csh", "text/x-script.csh"},
  {"css", "text/css"},
  {"cxx", "text/x-c"},
  {"doc", "application/msword"},
  {"dv", "video/x-dv"},
  {"dvi", "application/x-dvi"},
  {"eps", "application/postscript"},
  {"f", "text/x-fortran"},
  {"f77", "text/x-fortran"},
  {"f90", "text/x-fortran"},
  {"gif", "image/gif"},
  {"gitignore", "text/plain"},
  {"gz", "application/x-gzip"},
  {"gzip", "multipart/x-gzip"},
  {"h", "text/x-c"},
  {"hh", "text/x-c"},
  {"hpp", "text/x-c"},
  {"hqx", "application/binhex"},
  {"htm", "text/html"},
  {"html", "text/html"},
  {"htmls", "text/html"},
  {"hxx", "text/x-c"},
  {"ico", "image/x-icon"},
  {"it", "audio/it"},
  {"jav", "text/x-java-source"},
  {"java", "text/x-java-source"},
  {"jfif", "image/jpeg"},
  {"jpe", "image/jpeg"},
  {"jpeg", "image/jpeg"},
  {"jpg", "image/jpeg"},
  {"js", "text/javascript"},
  {"json", "application/json"},
  {"ksh", "text/x-script.ksh"},
  {"latex", "application/x-latex"},
  {"log", "text/plain"},
  {"m", "text/plain"},
  {"m1v", "video/mpeg"},
  {"m2a", "audio/mpeg"},
  {"m2v", "video/mpeg"},
  {"man", "application/x-troff-man"},
  {"mid", "audio/midi"},
  {"midi", "audio/midi"},
  {"mod", "audio/mod"},
  {"moov", "video/quicktime"},
  {"mov", "video/quicktime"},
  {"mp2", "video/mpeg"},
  {"mp3", "audio/mpeg3"},
  {"mpe", "video/mpeg"},
  {"mpeg", "video/mpeg"},
  {"mpg", "video/mpeg"},
  {"p", "text/pascal"},
  {"p10", "application/pkcs10"},
  {"p12", "application/pkcs-12"},
  {"p7a", "application/x-pkcs7-signature"},
  {"p7c", "application/x-pkcs7-mime"},
  {"p7m", "application/x-pkcs7-mime"},
  {"p7r", "application/x-pkcs7-certreqresp"},
  {"p7s", "application/pkcs7-signature"},
  {"pas", "text/x-pascal"},
  {"pbm", "image/x-portable-bitmap"},
  {"pct", "image/x-pict"},
  {"pcx", "image/x-pcx"},
  {"pdf", "application/pdf"},
  {"pgm", "image/x-portable-greymap"},
  {"php", "text/x-php"},
  {"php5", "text/x-php"},
  {"phps", "text/x-php"},
  {"pic", "image/pict"},
  {"pict", "image/pict"},
  {"pkg", "application/x-newton-compatible-pkg"},
  {"pl", "text/x-script.perl"},
  {"png", "image/png"},
  {"pnm", "image/x-portable-anymap"},
  {"ppm", "image/x-portable-pixmap"},
  {"ppt", "application/x-mspowerpoint"},
  {"ps", "application/postscript"},
  {"py", "text/x-script.python"},
  {"pyc", "application/x-bytecode.python"},
  {"pyo", "application/x-bytecode.python"},
  {"qt", "video/quicktime"},
  {"ra", "audio/x-realaudio"},
  {"ram", "audio/x-realaudio"},
  {"rm", "audio/x-pn-realaudio"},
  {"rtf", "application/rtf"},
  {"S", "text/x-asm"},
  {"s", "text/x-asm"},
  {"s3m", "audio/s3m"},
  {"sea", "application/sea"},
  {"sh", "text/x-script.sh"},
  {"shtml", "text/html"},
  {"snd", "audio/basic"},
  {"swf", "application/x-shockwave-flash"},
  {"t", "application/x-troff"},
  {"tar", "application/x-tar"},
  {"tcl", "text/x-script.tcl"},
  {"tcsh", "text/x-script.tcsh"},
  {"tex", "application/x-tex"},
  {"text", "text/plain"},
  {"tgz", "application/x-compressed"},
  {"tif", "image/tiff"},
  {"tiff", "image/tiff"},
  {"tr", "application/x-troff"},
  {"tsv", "text/tab-separated-values"},
  {"txt", "text/plain"},
  {"wav", "audio/wav"},
  {"xm", "audio/xm"},
  {"xml", "text/xml"},
  {"yaml", "text/yaml"},
  {"yml", "text/yaml"},
  {"z", "application/x-compressed"},
  {"zip", "application/x-compressed"},
  {"zsh", "text/x-script.zsh"},
});

static const unordered_map<string, string> mime_type_for_basename({
  {"LICENSE", "text/plain"},
  {"Makefile", "text/plain"},
  {"README", "text/plain"},
});

const char* mime_type_for_filename(const string& filename) {
  size_t extension_pos = filename.rfind('.');
  if (extension_pos != string::npos) {
    try {
      string extension = filename.substr(extension_pos + 1);
      return mime_type_for_file_extension.at(extension).c_str();
    } catch (const out_of_range& e) { }
  }

  // some common (usually text) files don't have extensions
  try {
    return mime_type_for_basename.at(filename).c_str();
  } catch (const out_of_range& e) { }

  return "application/octet-stream";
}
<|endoftext|>


<commit_before>#include "General.h"
#include "Options.h"

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;

void Options::parse_args(int argc, char* argv[])
  throw(BadOptionSetting) {

  // parse command line switches, search only for global configuration file option
  // derived classes will consider application specific flags
  for(int i=1; i<argc; i++) {
    string option(argv[i]);

    if(option == "-c") {
      args["config"] = string(argv[i+1]);
      continue;
    }
  }
  // echo usage in case required application parameters are not given
  map<string, string>::const_iterator it;
  it = args.find("config");
  if(it == args.end())
    throw BadOptionSetting("Must specify global configuration file; use -c <config file> command line flag");

  // read global configuration file and set globally visible parameters
  ifstream ifs((*it).second.c_str());
  if(!ifs)
    throw BadOptionSetting(string("Could not open ") + (*it).second.c_str());

  string line, dummy;
  while(getline(ifs, line)) {
    if(line[0] == '#') continue; // skip comments

    size_t pos;
    istringstream iss(line);

    pos = line.find("input_dimension");
    if(pos != string::npos) {
      iss >> dummy >> _input_dim;
      assert(_input_dim > 0);
      continue;
    }

    pos = line.find("output_dimension");
    if(pos != string::npos) {
      iss >> dummy >> _output_dim;
      assert(_output_dim > 0);
      continue;
    }

    pos = line.find("domain_outdegree");
    if(pos != string::npos) {
      iss >> dummy >> _domain_outdegree;
      assert(_domain_outdegree > 0);
      continue;
    }

    pos = line.find("layers_number_units");
    if(pos != string::npos) {
      _lnunits.clear();
      iss >> dummy >> _r >> _s;
      int i = 0, lnu;
      while(i<_r+_s) {
	iss >> lnu;
	_lnunits.push_back(lnu);
	++i;
      }
      assert(_lnunits.size() == (uint)_r+_s);
      continue;
    }

    pos = line.find("rnn_weights_precision");
    if(pos != string::npos) {
      iss >> dummy >> _precision;
      assert(_precision > 0);
      continue;
    }

    pos = line.find("domain");
    if(pos != string::npos) {
      string d;
      iss >> dummy >> d;
      if(d == "DOAG") { _domain = DOAG; }
      else if(d == "SEQUENCE") { _domain = SEQUENCE; }
      else if(d == "LINEARCHAIN") { _domain = LINEARCHAIN; }
      else if(d == "NARYTREE") { _domain = NARYTREE; }
      else if(d == "UG") { _domain = UG; }
      else if(d == "GRID2D") { _domain = GRID2D; }
      else { throw BadOptionSetting("Unrecognised domain type"); }
      continue;
    }

    pos = line.find("transduction");
    if(pos != string::npos) {
      string trans;
      iss >> dummy >> trans;

      if(trans == "SUPER_SOURCE") { _transduction = SUPER_SOURCE; }
      else if(trans == "IO_ISOMORPH") { _transduction = IO_ISOMORPH; }
      else { throw BadOptionSetting("Transduction type not recognized"); }
      continue;
    }

    pos = line.find("problem");
    if(pos != string::npos) {
      string prob;
      iss >> dummy >> prob;

      if(prob == "REGRESSION") { _problem = REGRESSION; }
      else if(prob == "BINARYCLASS") { _problem = BINARYCLASS; }
      else if(prob == "MULTICLASS") { _problem = MULTICLASS; }
      else { throw BadOptionSetting("Problem type not recognized"); }
      continue;
    }

  }

  // raise exception if config parameters are not set
  if(!_input_dim)
    throw BadOptionSetting("Must set input_dimension to a positive value");
  if(!_output_dim)
    throw BadOptionSetting("Must set output_dimension to a positive value");
  if(!_domain_outdegree)
    throw BadOptionSetting("Must set domain_outdegree to a positive value");
  if(!_r)
    throw BadOptionSetting("Must set number of layers in folding network to a positive value");
  if(!_s)
    throw BadOptionSetting("Must set number of layers in transforming network to a positive value");
  if(!_lnunits.size())
    throw BadOptionSetting("Couldn't set architecture of the folding and tranforming networks");
  if(_transduction != SUPER_SOURCE && _transduction != IO_ISOMORPH)
    throw BadOptionSetting("Invalid transduction type: "  + _transduction);
  if(_problem & ~(REGRESSION | BINARYCLASS | MULTICLASS))
    throw BadOptionSetting("Invalid problem type");
}

void RNNTrainingOptions::parse_args(int argc, char* argv[])
  throw(Options::BadOptionSetting) {

  // parse configuration file first
  Options::parse_args(argc, argv);

  /*** parse command line and find application specific options ***/
  for (int i = 1; i < argc; i++) {
    // parse switches
    if (argv[i][0] == '-') {
      string arg(argv[i]);
      if(arg == "-c") {
	// this is already read by base object
	// TODO: should avoid considering it here
	++i;
      } else if(arg == "-n") {
	args["netname"] = string(argv[++i]);
      } else if(arg == "-l") {
	args["eta"] = string(argv[++i]);
      } else if(arg == "--alpha") {
	args["alpha"] = string(argv[++i]);
      } else if(arg == "-ni") {
	args["ni"] = string(argv[++i]);
      } else if(arg == "-e") {
	args["epochs"] = string(argv[++i]);
      } else if(arg == "-s") {
	args["savedelta"] = string(argv[++i]);
      } else if(arg == "-r") {
	args["random_net"] = string("1");
      } else if(arg == "-o") {
	args["onlinelearning"] = string("1");
      } else if(arg == "--training-set") {
	args["training_set"] = string(argv[++i]);
      } else if(arg == "--test-set") {
	args["test_set"] = string(argv[++i]);
      } else if(arg == "--validation-set") {
	args["validation_set"] = string(argv[++i]);
      } else if(arg == "--threshold-error") {
	args["threshold_error"] = string(argv[++i]);
      } else {
	cerr << "Unknown switch " << argv[i] << "\n";
	throw BadOptionSetting(_usage);
      }
    }
  }

  // prepend program name to usage string
  _usage = string(argv[0]) + " " + _usage;
}

Options* Options::instance() throw(BadOptionSetting) {
  if(_instance == 0) {
    try {
      string option_type(getenv("RNNOPTIONTYPE"));
      if(option_type == "train")
	_instance = new RNNTrainingOptions;
      else
	throw BadOptionSetting("Invalid RNNOPTIONTYPE value");
    } catch (logic_error& e) {
      cerr << e.what() << endl;
      throw BadOptionSetting("Must set RNNOPTIONTYPE envirnoment variable");
    }
  }

  return _instance;
}

// static member initialization
Options* Options::_instance = 0;

<commit_msg>Create usage string with program name.<commit_after>#include "General.h"
#include "Options.h"

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;

void Options::parse_args(int argc, char* argv[])
  throw(BadOptionSetting) {

  // prepend program name to usage string
  _usage = string(argv[0]) + " " + _usage;

  // parse command line switches, search only for global configuration file option
  // derived classes will consider application specific flags
  for(int i=1; i<argc; i++) {
    string option(argv[i]);

    if(option == "-c") {
      args["config"] = string(argv[i+1]);
      continue;
    }
  }
  // echo usage in case required application parameters are not given
  map<string, string>::const_iterator it;
  it = args.find("config");
  if(it == args.end())
    throw BadOptionSetting("Must specify global configuration file; use -c <config file> command line flag");

  // read global configuration file and set globally visible parameters
  ifstream ifs((*it).second.c_str());
  if(!ifs)
    throw BadOptionSetting(string("Could not open ") + (*it).second.c_str() + "\n\n" + _usage);

  string line, dummy;
  while(getline(ifs, line)) {
    if(line[0] == '#') continue; // skip comments

    size_t pos;
    istringstream iss(line);

    pos = line.find("input_dimension");
    if(pos != string::npos) {
      iss >> dummy >> _input_dim;
      assert(_input_dim > 0);
      continue;
    }

    pos = line.find("output_dimension");
    if(pos != string::npos) {
      iss >> dummy >> _output_dim;
      assert(_output_dim > 0);
      continue;
    }

    pos = line.find("domain_outdegree");
    if(pos != string::npos) {
      iss >> dummy >> _domain_outdegree;
      assert(_domain_outdegree > 0);
      continue;
    }

    pos = line.find("layers_number_units");
    if(pos != string::npos) {
      _lnunits.clear();
      iss >> dummy >> _r >> _s;
      int i = 0, lnu;
      while(i<_r+_s) {
	iss >> lnu;
	_lnunits.push_back(lnu);
	++i;
      }
      assert(_lnunits.size() == (uint)_r+_s);
      continue;
    }

    pos = line.find("rnn_weights_precision");
    if(pos != string::npos) {
      iss >> dummy >> _precision;
      assert(_precision > 0);
      continue;
    }

    pos = line.find("domain");
    if(pos != string::npos) {
      string d;
      iss >> dummy >> d;
      if(d == "DOAG") { _domain = DOAG; }
      else if(d == "SEQUENCE") { _domain = SEQUENCE; }
      else if(d == "LINEARCHAIN") { _domain = LINEARCHAIN; }
      else if(d == "NARYTREE") { _domain = NARYTREE; }
      else if(d == "UG") { _domain = UG; }
      else if(d == "GRID2D") { _domain = GRID2D; }
      else { throw BadOptionSetting("Unrecognised domain type"); }
      continue;
    }

    pos = line.find("transduction");
    if(pos != string::npos) {
      string trans;
      iss >> dummy >> trans;

      if(trans == "SUPER_SOURCE") { _transduction = SUPER_SOURCE; }
      else if(trans == "IO_ISOMORPH") { _transduction = IO_ISOMORPH; }
      else { throw BadOptionSetting("Transduction type not recognized"); }
      continue;
    }

    pos = line.find("problem");
    if(pos != string::npos) {
      string prob;
      iss >> dummy >> prob;

      if(prob == "REGRESSION") { _problem = REGRESSION; }
      else if(prob == "BINARYCLASS") { _problem = BINARYCLASS; }
      else if(prob == "MULTICLASS") { _problem = MULTICLASS; }
      else { throw BadOptionSetting("Problem type not recognized"); }
      continue;
    }

  }

  // raise exception if config parameters are not set
  if(!_input_dim)
    throw BadOptionSetting("Must set input_dimension to a positive value");
  if(!_output_dim)
    throw BadOptionSetting("Must set output_dimension to a positive value");
  if(!_domain_outdegree)
    throw BadOptionSetting("Must set domain_outdegree to a positive value");
  if(!_r)
    throw BadOptionSetting("Must set number of layers in folding network to a positive value");
  if(!_s)
    throw BadOptionSetting("Must set number of layers in transforming network to a positive value");
  if(!_lnunits.size())
    throw BadOptionSetting("Couldn't set architecture of the folding and tranforming networks");
  if(_transduction != SUPER_SOURCE && _transduction != IO_ISOMORPH)
    throw BadOptionSetting("Invalid transduction type: "  + _transduction);
  if(_problem & ~(REGRESSION | BINARYCLASS | MULTICLASS))
    throw BadOptionSetting("Invalid problem type");
}

void RNNTrainingOptions::parse_args(int argc, char* argv[])
  throw(Options::BadOptionSetting) {

  // parse configuration file first
  Options::parse_args(argc, argv);

  /*** parse command line and find application specific options ***/
  for (int i = 1; i < argc; i++) {
    // parse switches
    if (argv[i][0] == '-') {
      string arg(argv[i]);
      if(arg == "-c") {
	// this is already read by base object
	// TODO: should avoid considering it here
	++i;
      } else if(arg == "-n") {
	args["netname"] = string(argv[++i]);
      } else if(arg == "-l") {
	args["eta"] = string(argv[++i]);
      } else if(arg == "--alpha") {
	args["alpha"] = string(argv[++i]);
      } else if(arg == "-ni") {
	args["ni"] = string(argv[++i]);
      } else if(arg == "-e") {
	args["epochs"] = string(argv[++i]);
      } else if(arg == "-s") {
	args["savedelta"] = string(argv[++i]);
      } else if(arg == "-r") {
	args["random_net"] = string("1");
      } else if(arg == "-o") {
	args["onlinelearning"] = string("1");
      } else if(arg == "--training-set") {
	args["training_set"] = string(argv[++i]);
      } else if(arg == "--test-set") {
	args["test_set"] = string(argv[++i]);
      } else if(arg == "--validation-set") {
	args["validation_set"] = string(argv[++i]);
      } else if(arg == "--threshold-error") {
	args["threshold_error"] = string(argv[++i]);
      } else {
	cerr << "Unknown switch " << argv[i] << "\n";
	throw BadOptionSetting(_usage);
      }
    }
  }
}

Options* Options::instance() throw(BadOptionSetting) {
  if(_instance == 0) {
    try {
      string option_type(getenv("RNNOPTIONTYPE"));
      if(option_type == "train")
	_instance = new RNNTrainingOptions;
      else
	throw BadOptionSetting("Invalid RNNOPTIONTYPE value");
    } catch (logic_error& e) {
      cerr << e.what() << endl;
      throw BadOptionSetting("Must set RNNOPTIONTYPE envirnoment variable");
    }
  }

  return _instance;
}

// static member initialization
Options* Options::_instance = 0;

<|endoftext|>


<commit_before>#include "rxcpp/rx.hpp"
namespace rxu=rxcpp::util;
namespace rxs=rxcpp::sources;
namespace rxsc=rxcpp::schedulers;

#include "rxcpp/rx-test.hpp"
#include "catch.hpp"

char whitespace(char c) {
    return std::isspace(c) || std::iscntrl(c);
}

std::string trim(std::string s) {
    auto first = std::find_if_not(s.begin(), s.end(), whitespace);
    auto last = std::find_if_not(s.rbegin(), s.rend(), whitespace);
    if (last != s.rend()) {
        s.erase(s.end() - (last-s.rbegin()), s.end());
    }
    s.erase(s.begin(), first);
    return std::move(s);
}

bool tolowerLess(char lhs, char rhs) {
    return std::tolower(lhs) < std::tolower(rhs);
}

bool tolowerStringLess(const std::string& lhs, const std::string& rhs) {
    return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), tolowerLess);
}

SCENARIO("group_by", "[group_by][operators]"){
    GIVEN("1 hot observable of ints."){
        auto sc = rxsc::make_test();
        auto w = sc.create_worker();
        const rxsc::test::messages<std::string> on;
        int keyInvoked = 0;
        int marbleInvoked = 0;

        auto xs = sc.make_hot_observable({
            on.on_next(90, "error"),
            on.on_next(110, "error"),
            on.on_next(130, "error"),
            on.on_next(220, "  foo"),
            on.on_next(240, " FoO "),
            on.on_next(270, "baR  "),
            on.on_next(310, "foO "),
            on.on_next(350, " Baz   "),
            on.on_next(360, "  qux "),
            on.on_next(390, "   bar"),
            on.on_next(420, " BAR  "),
            on.on_next(470, "FOO "),
            on.on_next(480, "baz  "),
            on.on_next(510, " bAZ "),
            on.on_next(530, "    fOo    "),
            on.on_completed(570),
            on.on_next(580, "error"),
            on.on_completed(600),
            on.on_error(650, new std::runtime_error("error in completed sequence"))
        });

        WHEN("group each int with the next 2 ints"){

            auto res = w.start(
                [&]() {
                    return xs
                        .group_by(
                            [&](std::string v){
                                ++keyInvoked;
                                return trim(std::move(v));
                            },
                            [&](std::string v){
                                ++marbleInvoked;
                                std::reverse(v.begin(), v.end());
                                return v;
                            },
                            tolowerStringLess)
                        .map([](const rxcpp::grouped_observable<std::string, std::string>& g){return g.get_key();})
                        // forget type to workaround lambda deduction bug on msvc 2013
                        .as_dynamic();
                }
            );

            THEN("the output contains groups of ints"){
                auto required = rxu::to_vector({
                    on.on_next(220, "foo"),
                    on.on_next(270, "baR"),
                    on.on_next(350, "Baz"),
                    on.on_next(360, "qux"),
                    on.on_completed(570)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }

            THEN("there was one subscription and one unsubscription to the xs"){
                auto required = rxu::to_vector({
                    on.subscribe(200, 570)
                });
                auto actual = xs.subscriptions();
                REQUIRE(required == actual);
            }

            THEN("key selector was invoked for each value"){
                REQUIRE(12 == keyInvoked);
            }

            THEN("marble selector was invoked for each value"){
                REQUIRE(12 == marbleInvoked);
            }
        }
    }
}
<commit_msg>change tolower and isspace to use classic locale<commit_after>#include "rxcpp/rx.hpp"
namespace rxu=rxcpp::util;
namespace rxs=rxcpp::sources;
namespace rxsc=rxcpp::schedulers;

#include "rxcpp/rx-test.hpp"
#include "catch.hpp"

char whitespace(char c) {
    return std::isspace<char>(c, std::locale::classic());
}

std::string trim(std::string s) {
    auto first = std::find_if_not(s.begin(), s.end(), whitespace);
    auto last = std::find_if_not(s.rbegin(), s.rend(), whitespace);
    if (last != s.rend()) {
        s.erase(s.end() - (last-s.rbegin()), s.end());
    }
    s.erase(s.begin(), first);
    return std::move(s);
}

bool tolowerLess(char lhs, char rhs) {
    return std::tolower(lhs, std::locale::classic()) < std::tolower(rhs, std::locale::classic());
}

bool tolowerStringLess(const std::string& lhs, const std::string& rhs) {
    return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), tolowerLess);
}

SCENARIO("group_by", "[group_by][operators]"){
    GIVEN("1 hot observable of ints."){
        auto sc = rxsc::make_test();
        auto w = sc.create_worker();
        const rxsc::test::messages<std::string> on;
        int keyInvoked = 0;
        int marbleInvoked = 0;

        auto xs = sc.make_hot_observable({
            on.on_next(90, "error"),
            on.on_next(110, "error"),
            on.on_next(130, "error"),
            on.on_next(220, "  foo"),
            on.on_next(240, " FoO "),
            on.on_next(270, "baR  "),
            on.on_next(310, "foO "),
            on.on_next(350, " Baz   "),
            on.on_next(360, "  qux "),
            on.on_next(390, "   bar"),
            on.on_next(420, " BAR  "),
            on.on_next(470, "FOO "),
            on.on_next(480, "baz  "),
            on.on_next(510, " bAZ "),
            on.on_next(530, "    fOo    "),
            on.on_completed(570),
            on.on_next(580, "error"),
            on.on_completed(600),
            on.on_error(650, new std::runtime_error("error in completed sequence"))
        });

        WHEN("group each int with the next 2 ints"){

            auto res = w.start(
                [&]() {
                    return xs
                        .group_by(
                            [&](std::string v){
                                ++keyInvoked;
                                return trim(std::move(v));
                            },
                            [&](std::string v){
                                ++marbleInvoked;
                                std::reverse(v.begin(), v.end());
                                return v;
                            },
                            tolowerStringLess)
                        .map([](const rxcpp::grouped_observable<std::string, std::string>& g){return g.get_key();})
                        // forget type to workaround lambda deduction bug on msvc 2013
                        .as_dynamic();
                }
            );

            THEN("the output contains groups of ints"){
                auto required = rxu::to_vector({
                    on.on_next(220, "foo"),
                    on.on_next(270, "baR"),
                    on.on_next(350, "Baz"),
                    on.on_next(360, "qux"),
                    on.on_completed(570)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }

            THEN("there was one subscription and one unsubscription to the xs"){
                auto required = rxu::to_vector({
                    on.subscribe(200, 570)
                });
                auto actual = xs.subscriptions();
                REQUIRE(required == actual);
            }

            THEN("key selector was invoked for each value"){
                REQUIRE(12 == keyInvoked);
            }

            THEN("marble selector was invoked for each value"){
                REQUIRE(12 == marbleInvoked);
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
 * AscEmu Framework based on ArcEmu MMORPG Server
 * Copyright (C) 2014-2016 AscEmu Team <http://www.ascemu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "PlayerCache.h"
#include "WorldPacket.h"
#include "Unit.h"

void PlayerCache::SendPacket(WorldPacket & p) {
    WorldPacket* data = new WorldPacket(p);
    m_pendingPackets.push(data);
}

void PlayerCache::SendPacket(WorldPacket* p) {
    m_pendingPackets.push(p);
}
<commit_msg>GCC: Include changes<commit_after>/*
 * AscEmu Framework based on ArcEmu MMORPG Server
 * Copyright (C) 2014-2016 AscEmu Team <http://www.ascemu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "PlayerCache.h"
#include "Object.h"
#include "WorldPacket.h"
#include "Unit.h"

void PlayerCache::SendPacket(WorldPacket & p) {
    WorldPacket* data = new WorldPacket(p);
    m_pendingPackets.push(data);
}

void PlayerCache::SendPacket(WorldPacket* p) {
    m_pendingPackets.push(p);
}
<|endoftext|>


<commit_before>// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2015 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.

/**
 * @file
 * @brief Implementation of the measurment classes class.
 */

#include <xerus/misc/check.h>
#include <xerus/measurments.h>
#include <xerus/misc/missingFunctions.h>
#include <xerus/fullTensor.h>
#include <xerus/sparseTensor.h>
#include <xerus/ttNetwork.h>
#include <xerus/indexedTensor.h>
#include <xerus/indexedTensor_TN_operators.h>

namespace xerus {
	// --------------------- SinglePointMeasurment -----------------

	SinglePointMeasurment::SinglePointMeasurment(const std::vector<size_t>& _positions, const value_t _value) : positions(_positions), value(_value) {}

	bool SinglePointMeasurment::Comparator::operator()(const SinglePointMeasurment &_lhs, const SinglePointMeasurment &_rhs) const {
		REQUIRE(_lhs.positions.size() == _rhs.positions.size(), "");
		for (size_t i = 0; i < split_position && i < _lhs.positions.size(); ++i) {
			if (_lhs.positions[i] < _rhs.positions[i]) return true;
			if (_lhs.positions[i] > _rhs.positions[i]) return false;
		}
		for (size_t i = _lhs.positions.size(); i > split_position; --i) {
			if (_lhs.positions[i-1] < _rhs.positions[i-1]) return true;
			if (_lhs.positions[i-1] > _rhs.positions[i-1]) return false;
		}
		return false; // equality
	}

	void sort(std::vector<SinglePointMeasurment>& _set, const size_t _splitPos) {
		SinglePointMeasurment::Comparator comp(_splitPos);
// 		auto perm = misc::create_sort_permutation(_set, comp);
// 		misc::apply_permutation(_set, perm);
		std::sort(_set.begin(), _set.end(), comp);
	}

	// --------------------- SinglePointMeasurmentSet -----------------

	SinglePointMeasurmentSet::SinglePointMeasurmentSet(const std::vector<SinglePointMeasurment>& _measurments) {
		for(const SinglePointMeasurment& meas : _measurments) {
			positions.emplace_back(meas.positions);
			measuredValues.emplace_back(meas.value);
		}
	}

	size_t SinglePointMeasurmentSet::size() const {
		REQUIRE(positions.size() == measuredValues.size(), "I.E.");
		return positions.size();
	}

	size_t SinglePointMeasurmentSet::degree() const {
		IF_CHECK(
			for(size_t i = 0; i+1 < positions.size(); ++i) {
				REQUIRE(positions[i].size() == positions[i+1].size(), "Inconsitent degrees in measurment set.");
			}
		)
		return positions.empty() ? 0 : positions[0].size();
	}

	void SinglePointMeasurmentSet::add_measurment(const std::vector<size_t>& _position, const value_t _measuredValue) {
		positions.emplace_back(_position);
		measuredValues.emplace_back(_measuredValue);
	}

	bool SinglePointMeasurmentSet::Comparator::operator()(const std::vector<size_t>& _lhs, const std::vector<size_t>& _rhs) const {
		REQUIRE(_lhs.size() == _rhs.size(), "");
		for (size_t i = 0; i < split_position && i < _lhs.size(); ++i) {
			if (_lhs[i] < _rhs[i]) return true;
			if (_lhs[i] > _rhs[i]) return false;
		}
		for (size_t i = _lhs.size(); i > split_position; --i) {
			if (_lhs[i-1] < _rhs[i-1]) return true;
			if (_lhs[i-1] > _rhs[i-1]) return false;
		}
		return false; // equality
	}

	void sort(SinglePointMeasurmentSet& _set, const size_t _splitPos) {
		SinglePointMeasurmentSet::Comparator comp(_splitPos);
		misc::simultaneous_sort(_set.positions, _set.measuredValues, comp);
	}

	// --------------------- RankOneMeasurmentSet -----------------

	size_t RankOneMeasurmentSet::size() const {
		return measuredValues.size();
	}

	size_t RankOneMeasurmentSet::degree() const {
		return positions[0].size();
	}

	RankOneMeasurmentSet::RankOneMeasurmentSet(const SinglePointMeasurmentSet&  _other, const std::vector<size_t> _dimensions) {
		std::vector<FullTensor> zeroPosition;
		for(size_t j = 0; j < +_other.degree(); ++j) {
			zeroPosition.emplace_back(FullTensor({_dimensions[j]}));
		}

		for(size_t i = 0; i < _other.size(); ++i) {
			add_measurment(zeroPosition, _other.measuredValues[i]);
			for(size_t j = 0; j < _other.degree(); ++j) {
				positions.back()[j][_other.positions[i][j]] = 1.0;
			}
		}
	}

	void RankOneMeasurmentSet::add_measurment(const std::vector<FullTensor>& _position, const value_t _measuredValue) {
		IF_CHECK(
			REQUIRE(positions.size() == measuredValues.size(), "Internal Error.");
			if(size() > 0) {
				for(size_t i = 0; i < degree(); ++i) {
					REQUIRE(positions[0][i].dimensions == _position[i].dimensions, "Inconsitend dimensions obtained");
				}
			}
			for (const FullTensor & f : _position) {
				REQUIRE(f.degree() == 1, "illegal measurement");
			}
		);
		positions.emplace_back(_position);
		measuredValues.emplace_back(_measuredValue);
	}

	value_t RankOneMeasurmentSet::test_solution(const TTTensor& _solution) const {
		value_t residualNorm = 0.0;
		value_t measurementNorm = 0.0;

		Index r1, r2, i1;

		std::unique_ptr<FullTensor[]> stackMem(new FullTensor[degree()+1]);
		FullTensor* const stack = stackMem.get()+1;
		stackMem[0] = Tensor::ones({1});

		std::vector<FullTensor> intermediates(degree());
		std::vector<FullTensor> reshuffledComponents(degree());
		for(size_t d = 0; d+1 < degree(); ++d) {
			stack[d].reset({_solution.rank(d)}, DONT_SET_ZERO());
		}
		for(size_t d = 0; d < degree(); ++d) {
			intermediates[d].reset({_solution.get_component(d).dimensions[0], _solution.get_component(d).dimensions[2]}, DONT_SET_ZERO());
			reshuffledComponents[d](i1, r1, r2) = _solution.get_component(d)(r1, i1, r2);
		}

		for(size_t i = 0; i < size(); ++i) {
			for(size_t d = 0; d < degree(); ++d) {
				contract(intermediates[d], positions[i][d], false, reshuffledComponents[d], false, 1);
				contract(stack[d], stack[d-1], false, intermediates[d], false, 1);
			}

			REQUIRE(stack[degree()-1].size == 1 , "IE");

			residualNorm += misc::sqr(measuredValues[i] - stack[degree()-1][0]);
			measurementNorm += misc::sqr(measuredValues[i]);
		}

		return std::sqrt(residualNorm)/std::sqrt(measurementNorm);
	}

	bool RankOneMeasurmentSet::Comparator::operator()(const std::vector<FullTensor>& _lhs, const std::vector<FullTensor>& _rhs) const {
		REQUIRE(_lhs.size() == _rhs.size(), "I.E.");
		for (size_t i = 0; i < split_position && i < _lhs.size(); ++i) {
			REQUIRE(_lhs[i].size == _rhs[i].size && _lhs[i].degree() == 1 && _rhs[i].degree() == 1, "");
			for(size_t j = 0; j < _lhs[i].size; ++j) {
				if (_lhs[i][j] < _rhs[i][j]) return true;
				if (_lhs[i][j] > _rhs[i][j]) return false;
			}
		}
		for (size_t i = _lhs.size(); i > split_position; --i) {
			REQUIRE(_lhs[i].size == _rhs[i].size && _lhs[i].degree() == 1 && _rhs[i].degree() == 1, "");
			for(size_t j = 0; j < _lhs[i].size; ++j) {
				if (_lhs[i-1][j] < _rhs[i-1][j]) return true;
				if (_lhs[i-1][j] > _rhs[i-1][j]) return false;
			}
		}
		return false; // equality
	}

	void sort(RankOneMeasurmentSet& _set, const size_t _splitPos) {
		RankOneMeasurmentSet::Comparator comp(_splitPos);
		misc::simultaneous_sort(_set.positions, _set.measuredValues, comp);
	}
}
<commit_msg>Added openMp to measurments::test<commit_after>// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2015 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.

/**
 * @file
 * @brief Implementation of the measurment classes class.
 */

#include <xerus/misc/check.h>
#include <xerus/measurments.h>
#include <xerus/misc/missingFunctions.h>
#include <xerus/fullTensor.h>
#include <xerus/sparseTensor.h>
#include <xerus/ttNetwork.h>
#include <xerus/indexedTensor.h>
#include <xerus/indexedTensor_TN_operators.h>

namespace xerus {
	// --------------------- SinglePointMeasurment -----------------

	SinglePointMeasurment::SinglePointMeasurment(const std::vector<size_t>& _positions, const value_t _value) : positions(_positions), value(_value) {}

	bool SinglePointMeasurment::Comparator::operator()(const SinglePointMeasurment &_lhs, const SinglePointMeasurment &_rhs) const {
		REQUIRE(_lhs.positions.size() == _rhs.positions.size(), "");
		for (size_t i = 0; i < split_position && i < _lhs.positions.size(); ++i) {
			if (_lhs.positions[i] < _rhs.positions[i]) return true;
			if (_lhs.positions[i] > _rhs.positions[i]) return false;
		}
		for (size_t i = _lhs.positions.size(); i > split_position; --i) {
			if (_lhs.positions[i-1] < _rhs.positions[i-1]) return true;
			if (_lhs.positions[i-1] > _rhs.positions[i-1]) return false;
		}
		return false; // equality
	}

	void sort(std::vector<SinglePointMeasurment>& _set, const size_t _splitPos) {
		SinglePointMeasurment::Comparator comp(_splitPos);
// 		auto perm = misc::create_sort_permutation(_set, comp);
// 		misc::apply_permutation(_set, perm);
		std::sort(_set.begin(), _set.end(), comp);
	}

	// --------------------- SinglePointMeasurmentSet -----------------

	SinglePointMeasurmentSet::SinglePointMeasurmentSet(const std::vector<SinglePointMeasurment>& _measurments) {
		for(const SinglePointMeasurment& meas : _measurments) {
			positions.emplace_back(meas.positions);
			measuredValues.emplace_back(meas.value);
		}
	}

	size_t SinglePointMeasurmentSet::size() const {
		REQUIRE(positions.size() == measuredValues.size(), "I.E.");
		return positions.size();
	}

	size_t SinglePointMeasurmentSet::degree() const {
		IF_CHECK(
			for(size_t i = 0; i+1 < positions.size(); ++i) {
				REQUIRE(positions[i].size() == positions[i+1].size(), "Inconsitent degrees in measurment set.");
			}
		)
		return positions.empty() ? 0 : positions[0].size();
	}

	void SinglePointMeasurmentSet::add_measurment(const std::vector<size_t>& _position, const value_t _measuredValue) {
		positions.emplace_back(_position);
		measuredValues.emplace_back(_measuredValue);
	}

	bool SinglePointMeasurmentSet::Comparator::operator()(const std::vector<size_t>& _lhs, const std::vector<size_t>& _rhs) const {
		REQUIRE(_lhs.size() == _rhs.size(), "");
		for (size_t i = 0; i < split_position && i < _lhs.size(); ++i) {
			if (_lhs[i] < _rhs[i]) return true;
			if (_lhs[i] > _rhs[i]) return false;
		}
		for (size_t i = _lhs.size(); i > split_position; --i) {
			if (_lhs[i-1] < _rhs[i-1]) return true;
			if (_lhs[i-1] > _rhs[i-1]) return false;
		}
		return false; // equality
	}

	void sort(SinglePointMeasurmentSet& _set, const size_t _splitPos) {
		SinglePointMeasurmentSet::Comparator comp(_splitPos);
		misc::simultaneous_sort(_set.positions, _set.measuredValues, comp);
	}

	// --------------------- RankOneMeasurmentSet -----------------

	size_t RankOneMeasurmentSet::size() const {
		return measuredValues.size();
	}

	size_t RankOneMeasurmentSet::degree() const {
		return positions[0].size();
	}

	RankOneMeasurmentSet::RankOneMeasurmentSet(const SinglePointMeasurmentSet&  _other, const std::vector<size_t> _dimensions) {
		std::vector<FullTensor> zeroPosition;
		for(size_t j = 0; j < +_other.degree(); ++j) {
			zeroPosition.emplace_back(FullTensor({_dimensions[j]}));
		}

		for(size_t i = 0; i < _other.size(); ++i) {
			add_measurment(zeroPosition, _other.measuredValues[i]);
			for(size_t j = 0; j < _other.degree(); ++j) {
				positions.back()[j][_other.positions[i][j]] = 1.0;
			}
		}
	}

	void RankOneMeasurmentSet::add_measurment(const std::vector<FullTensor>& _position, const value_t _measuredValue) {
		IF_CHECK(
			REQUIRE(positions.size() == measuredValues.size(), "Internal Error.");
			if(size() > 0) {
				for(size_t i = 0; i < degree(); ++i) {
					REQUIRE(positions[0][i].dimensions == _position[i].dimensions, "Inconsitend dimensions obtained");
				}
			}
			for (const FullTensor & f : _position) {
				REQUIRE(f.degree() == 1, "illegal measurement");
			}
		);
		positions.emplace_back(_position);
		measuredValues.emplace_back(_measuredValue);
	}

	value_t RankOneMeasurmentSet::test_solution(const TTTensor& _solution) const {
		value_t residualNorm = 0.0;
		value_t measurementNorm = 0.0;

		Index r1, r2, i1;

		std::vector<FullTensor> reshuffledComponents(degree());

		for(size_t d = 0; d < degree(); ++d) {
			reshuffledComponents[d](i1, r1, r2) = _solution.get_component(d)(r1, i1, r2);
		}

		// TODO beautify
		#pragma omp parallel reduction(+: residualNorm, measurementNorm)
		{
			std::unique_ptr<FullTensor[]> stackMem(new FullTensor[degree()+1]);
			FullTensor* const stack = stackMem.get()+1;
			stackMem[0] = Tensor::ones({1});

			for(size_t d = 0; d+1 < degree(); ++d) {
				stack[d].reset({_solution.rank(d)}, DONT_SET_ZERO());
			}

			std::vector<FullTensor> intermediates(degree());

			for(size_t d = 0; d < degree(); ++d) {
				intermediates[d].reset({_solution.get_component(d).dimensions[0], _solution.get_component(d).dimensions[2]}, DONT_SET_ZERO());
			}

			#pragma omp for schedule(static)
			for(size_t i = 0; i < size(); ++i) {
				for(size_t d = 0; d < degree(); ++d) {
					contract(intermediates[d], positions[i][d], false, reshuffledComponents[d], false, 1);
					contract(stack[d], stack[d-1], false, intermediates[d], false, 1);
				}

				REQUIRE(stack[degree()-1].size == 1 , "IE");

				residualNorm += misc::sqr(measuredValues[i] - stack[degree()-1][0]);
				measurementNorm += misc::sqr(measuredValues[i]);
			}
		}

		return std::sqrt(residualNorm)/std::sqrt(measurementNorm);
	}

	bool RankOneMeasurmentSet::Comparator::operator()(const std::vector<FullTensor>& _lhs, const std::vector<FullTensor>& _rhs) const {
		REQUIRE(_lhs.size() == _rhs.size(), "I.E.");
		for (size_t i = 0; i < split_position && i < _lhs.size(); ++i) {
			REQUIRE(_lhs[i].size == _rhs[i].size && _lhs[i].degree() == 1 && _rhs[i].degree() == 1, "");
			for(size_t j = 0; j < _lhs[i].size; ++j) {
				if (_lhs[i][j] < _rhs[i][j]) return true;
				if (_lhs[i][j] > _rhs[i][j]) return false;
			}
		}
		for (size_t i = _lhs.size(); i > split_position; --i) {
			REQUIRE(_lhs[i].size == _rhs[i].size && _lhs[i].degree() == 1 && _rhs[i].degree() == 1, "");
			for(size_t j = 0; j < _lhs[i].size; ++j) {
				if (_lhs[i-1][j] < _rhs[i-1][j]) return true;
				if (_lhs[i-1][j] > _rhs[i-1][j]) return false;
			}
		}
		return false; // equality
	}

	void sort(RankOneMeasurmentSet& _set, const size_t _splitPos) {
		RankOneMeasurmentSet::Comparator comp(_splitPos);
		misc::simultaneous_sort(_set.positions, _set.measuredValues, comp);
	}
}
<|endoftext|>


<commit_before>/* Bucky Frost
 * Paul Gentemann
 * CS 381
 * File Name : splinepatch.cpp
 * Last Modified : Mon 04 Nov 2013 05:30:33 PM AKST
 * Description : A pair of spline plains, patched together, that will
 * ripple upon user input.
 */

// OpenGL/GLUT includes - DO THESE FIRST
#include <cstdlib>       // Do this before GL/GLUT includes
using std::exit;
#ifndef __APPLE__
# include <GL/glew.h>
# include <GL/glut.h>    // Includes OpenGL headers as well
#else
# include <GLEW/glew.h>
# include <GLUT/glut.h>  // Apple puts glut.h in a different place
#endif
#include "lib381/bitmapprinter.h"
#include "lib381/glslprog.h"    // For GLSL code-handling functions
#include <iostream>
using std::cout; using std::cerr; using std::endl;
#include <vector>
using std::vector;
// Global variables
const int ESCKEY = 27;          // ASCII value of Escape
const int startwinsize = 600;   // Start window width & height (pixels)
<commit_msg>Added skeleton main function. Still requires the GLUT call back function registrations.<commit_after>/* Bucky Frost
 * Paul Gentemann
 * CS 381
 * File Name : splinepatch.cpp
 * Last Modified : Mon 04 Nov 2013 05:30:33 PM AKST
 * Description : A pair of spline plains, patched together, that will
 * ripple upon user input.
 */

// OpenGL/GLUT includes - DO THESE FIRST
#include <cstdlib>       // Do this before GL/GLUT includes
using std::exit;
#ifndef __APPLE__
# include <GL/glew.h>
# include <GL/glut.h>    // Includes OpenGL headers as well
#else
# include <GLEW/glew.h>
# include <GLUT/glut.h>  // Apple puts glut.h in a different place
#endif
#include "lib381/bitmapprinter.h"
#include "lib381/glslprog.h"    // For GLSL code-handling functions
#include <iostream>
using std::cout; using std::cerr; using std::endl;
#include <vector>
using std::vector;
// Global variables
const int ESCKEY = 27;          // ASCII value of Escape
const int startwinsize = 600;   // Start window width & height (pixels)

int main(int argc, char ** argv)
{
    // Initilization of OpenGL/GLUT
    glutInit(&argc, argv);
    getShaderFilenames(vshader1fname, fshader1fname, argc, argv);

    // Set shader source filenames. Done here, as opposed to in
    //  function init, so that we can use command-line arguments.
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

    // Creating the view window
    glutInitWindowSize(startwinsize, startwinsize);
    glutInitWindowPosition(50, 50);
    glutCreateWindow("CS 381 - Shaders, Normals, Lighting, and Splines Oh My!");

    // Init GLEW & check status - exit on failure
    if (glewInit() != GLEW_OK)
    {
        cerr << "glewInit failed" << endl;
        exit(1);
    }

    // Start GLUT event handling loop
    glutMainLoop();

    return 0;
}
<|endoftext|>


<commit_before>/** eval_sql.cc                                                     -*- C++ -*-
    Jeremy Barnes, 1 August 2016
    This file is part of MLDB. Copyright 2016 Datacratic. All rights reserved.

    Lambda function written in SQL.
*/

#include "eval_sql.h"
#include "binding_contexts.h"

namespace MLDB {

BoundSqlExpression
bindSql(SqlBindingScope & scope,
        const Utf8String & expression,
        const std::vector<std::shared_ptr<ExpressionValueInfo> > & info)
{
    auto parsed = SqlExpression::parse(expression);

    auto bound = parsed->bind(scope);

    return bound;
}

ExpressionValue
evalSql(SqlBindingScope & scope,
        const Utf8String & expr,
        const SqlRowScope & rowScope,
        ExpressionValue * argsVec,
        size_t numArgs)
{
    // TODO: this signature is for when we have a binding scope that
    // knows that we can move arguments out of the way.  For now
    // we forward.

    return evalSql(scope, expr,
                   rowScope,
                   static_cast<const ExpressionValue *>(argsVec),
                   numArgs);
}

ExpressionValue
evalSql(SqlBindingScope & scope,
        const Utf8String & expr,
        const SqlRowScope & rowScope,
        const ExpressionValue * argsVec,
        size_t numArgs)
{
    std::vector<std::shared_ptr<ExpressionValueInfo> > info;
    info.reserve(numArgs);
    for (size_t i = 0;  i < numArgs;  ++i) {
        info.emplace_back(argsVec[i].getSpecializedValueInfo(false /*isconst TODO not sure about this one*/));
    }

    SqlExpressionEvalScope evalScope(scope, info);

    auto bound = bindSql(evalScope, expr, info);

    auto innerRowScope = evalScope.getRowScope(rowScope, argsVec, numArgs);

    return bound(innerRowScope, GET_ALL);
}

ExpressionValue evalSql(SqlBindingScope & scope,
                        const Utf8String & expr,
                        const SqlRowScope & rowScope,
                        const std::vector<ExpressionValue> & argsVec)
{
    return evalSql(scope, expr, rowScope, argsVec.data(), argsVec.size());
}

} // namespace MLDB

<commit_msg>Update eval_sql.cc<commit_after>/** eval_sql.cc                                                     -*- C++ -*-
    Jeremy Barnes, 1 August 2016
    This file is part of MLDB. Copyright 2016 Datacratic. All rights reserved.

    Lambda function written in SQL.
*/

#include "eval_sql.h"
#include "binding_contexts.h"

namespace MLDB {

BoundSqlExpression
bindSql(SqlBindingScope & scope,
        const Utf8String & expression,
        const std::vector<std::shared_ptr<ExpressionValueInfo> > & info)
{
    auto parsed = SqlExpression::parse(expression);

    auto bound = parsed->bind(scope);

    return bound;
}

ExpressionValue
evalSql(SqlBindingScope & scope,
        const Utf8String & expr,
        const SqlRowScope & rowScope,
        ExpressionValue * argsVec,
        size_t numArgs)
{
    // TODO: this signature is for when we have a binding scope that
    // knows that we can move arguments out of the way.  For now
    // we forward.

    return evalSql(scope, expr,
                   rowScope,
                   static_cast<const ExpressionValue *>(argsVec),
                   numArgs);
}

ExpressionValue
evalSql(SqlBindingScope & scope,
        const Utf8String & expr,
        const SqlRowScope & rowScope,
        const ExpressionValue * argsVec,
        size_t numArgs)
{
    std::vector<std::shared_ptr<ExpressionValueInfo> > info;
    info.reserve(numArgs);
    for (size_t i = 0;  i < numArgs;  ++i) {
        //We dont know the constness so we have to assume they are not
        info.emplace_back(argsVec[i].getSpecializedValueInfo(false /*isconst*/));
    }

    SqlExpressionEvalScope evalScope(scope, info);

    auto bound = bindSql(evalScope, expr, info);

    auto innerRowScope = evalScope.getRowScope(rowScope, argsVec, numArgs);

    return bound(innerRowScope, GET_ALL);
}

ExpressionValue evalSql(SqlBindingScope & scope,
                        const Utf8String & expr,
                        const SqlRowScope & rowScope,
                        const std::vector<ExpressionValue> & argsVec)
{
    return evalSql(scope, expr, rowScope, argsVec.data(), argsVec.size());
}

} // namespace MLDB

<|endoftext|>