<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
        ;

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Checkpoint at first 25-btc-reward block (210,000)<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
        (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
        ;

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of // Yo dawg, this is the secret. Checkpoint 0 hash == Genesis block hash.
        (         0, uint256("0x64a9141746cbbe06c7e1a4b7f2abb968ccdeba66cd67c1add1091b29db00578e"))
//        (         1, uint256("0x8c6d02b02c996531baf1f29637cfe122dfffbe900961e9df9f4a12f4a9f42e2e"))
//        (      1000, uint256("0xb2c469e23698d422d82e8a2e0f311b6b9e53fd834b552009479d0fe28abfae7a"))
//        (      2400, uint256("0xe0ffcb739214da82050985be90b20365f0edead5ce3723b959f5ef24478a7e0a"))
//        (      9275, uint256("0xaaccac8516a4c455f80471b868b30aaa2c75d7e897c63ef9953df3f596495cad"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;
        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Update checkpoints.cpp<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of // Yo dawg, this is the secret. Checkpoint 0 hash == Genesis block hash.
        (         0, uint256("0x64a9141746cbbe06c7e1a4b7f2abb968ccdeba66cd67c1add1091b29db00578e"))
//        (         1, uint256("0x8c6d02b02c996531baf1f29637cfe122dfffbe900961e9df9f4a12f4a9f42e2e"))
//        (      1000, uint256("0xb2c469e23698d422d82e8a2e0f311b6b9e53fd834b552009479d0fe28abfae7a"))
//        (      2400, uint256("0xe0ffcb739214da82050985be90b20365f0edead5ce3723b959f5ef24478a7e0a"))
//        (      9275, uint256("0xaaccac8516a4c455f80471b868b30aaa2c75d7e897c63ef9953df3f596495cad"))
//        (      9331, uint256("0x8f23149ea07ee5e2fa66c53b814901c279a159a7b71b2b18900b2dd3125cec3f"))

        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;
        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2013 GayCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //

    static MapCheckpoints mapCheckpoints =
            boost::assign::map_list_of
        ( 0, uint256("0xc2524ed84fcd19900c5ea917502f30b32c16f5b275209dcb34aacdcf8b9140b0"))
        ( 111, uint256("0xd96ae07d1b4f4369e67710194a3d667cff51b7e5397cc4fe384bdb38e5f8efcc"))
        ( 222, uint256("0xff5465b29628bf6738205e813c0d6ee8ab408d8191c168ac1b7b80789dd30581"))
        ( 333, uint256("0x85dbff70627fef1f09942a10f65196b5816254d66a51c81a421c8980ba78a3e5"))
        ( 444, uint256("0xd58f711eef6bfb2906d4d8c3b8db944953fb45ba5d77e9f2be382e133d9f8e97"))
        ( 555, uint256("0xa4f3efeb7c0d299016911bfe019866867f11b216824b6b9552210ac80aeb594b"))
        ( 666, uint256("0x168a07cc86eb6444e24ec9adf0dea32896462142e9b0d85dc5a78496c043472a"))
        ( 777, uint256("0x8c5af7d45b419f4d98e57f61712d9cc19561ce2ca7c30d9d65a161a12e734cf9"))
        ( 888, uint256("0xc811ce2e95d4f27f89b56d44e069ad2ef300ac5f39f52ee5fb6a5a8075531c83"))
        ( 999, uint256("0x679ac4f3c5b0ef4ae430df448b0a0cdde798fc284acbd21d6d273d75477dff71"))
        ( 1111, uint256("0xf7b5afe1cfdc36ea1f3772e58b25edc6785a48b9d4c47a6de23d8262585cbb62"))
        ( 2222, uint256("0x7be5f19a388ae74db6642839435c5f05134b772fc9e0a07af7dcff05a6ce3ecf"))
        ( 3333, uint256("0x99bd528c72ea4046979d0e0aab522382b82e4730e6d0ce5c04ba6cf17220fb35"))
        ( 4444, uint256("0x09849dd472c246b59af64ddb845f3ce7063c2f91e5abfbba41e22fb2f2add190"))
        ( 5555, uint256("0x763e4cede399c6d25566fa4c41990994657e343c0e870c89e67e8d882b03cfa5"))
        ( 6666, uint256("0xe041373ca2fc9c52ae813ea9fff866c5786b5d86faba04d2307f4fe0c161374a"))
		;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
		// return true;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
		// return 0;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
				// return NULL;
        }
        return NULL;
    }
}
<commit_msg>Update checkpoints.cpp<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2013 GayCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //

    static MapCheckpoints mapCheckpoints =
            boost::assign::map_list_of
        ( 0, uint256("0xc2524ed84fcd19900c5ea917502f30b32c16f5b275209dcb34aacdcf8b9140b0"))
        ( 111, uint256("0xd96ae07d1b4f4369e67710194a3d667cff51b7e5397cc4fe384bdb38e5f8efcc"))
        ( 222, uint256("0xff5465b29628bf6738205e813c0d6ee8ab408d8191c168ac1b7b80789dd30581"))
        ( 333, uint256("0x85dbff70627fef1f09942a10f65196b5816254d66a51c81a421c8980ba78a3e5"))
        ( 444, uint256("0xd58f711eef6bfb2906d4d8c3b8db944953fb45ba5d77e9f2be382e133d9f8e97"))
        ( 555, uint256("0xa4f3efeb7c0d299016911bfe019866867f11b216824b6b9552210ac80aeb594b"))
        ( 666, uint256("0x168a07cc86eb6444e24ec9adf0dea32896462142e9b0d85dc5a78496c043472a"))
        ( 777, uint256("0x8c5af7d45b419f4d98e57f61712d9cc19561ce2ca7c30d9d65a161a12e734cf9"))
        ( 888, uint256("0xc811ce2e95d4f27f89b56d44e069ad2ef300ac5f39f52ee5fb6a5a8075531c83"))
        ( 999, uint256("0x679ac4f3c5b0ef4ae430df448b0a0cdde798fc284acbd21d6d273d75477dff71"))
        ( 1111, uint256("0xf7b5afe1cfdc36ea1f3772e58b25edc6785a48b9d4c47a6de23d8262585cbb62"))
        ( 2222, uint256("0x7be5f19a388ae74db6642839435c5f05134b772fc9e0a07af7dcff05a6ce3ecf"))
        ( 3333, uint256("0x99bd528c72ea4046979d0e0aab522382b82e4730e6d0ce5c04ba6cf17220fb35"))
        ( 4444, uint256("0x09849dd472c246b59af64ddb845f3ce7063c2f91e5abfbba41e22fb2f2add190"))
        ( 5555, uint256("0x763e4cede399c6d25566fa4c41990994657e343c0e870c89e67e8d882b03cfa5"))
        ( 6666, uint256("0xe041373ca2fc9c52ae813ea9fff866c5786b5d86faba04d2307f4fe0c161374a"))
        ( 11111, uint256("0x8021da1033ea20570eb851bbd046d2d769808c954f9cef4871048853b329f2b7"))
	( 22222, uint256("0x4c6f8e592c442b40deb1ffc826754f6cfd293aa4c3a9605c2a6d52a23cc800df"))
	( 33333, uint256("0xf0e6f1621f453d4a1381e99eb9ea39857c934d5565d342aaad557b0b5e83b65b"))
	( 44444, uint256("0xaafa3330ab354c6fd4b6f907a0ab9f0d32d488a1e7144427263618e62c7d1594"))
	( 55555, uint256("0xd3224187d1d7da4c1c9884d4c9c28373ca16b2213b6503dc8db72ec18bb72586"))
	( 66666, uint256("0x25356865d43c0f1bb35ecc39d4241f6a55628b062faeddaef0886e2226014a05"))
	( 77777, uint256("0x334085e323bd8ed4f7843d91857504f87984c5c6599900ac51bb25d428604b2d"))
	( 88888, uint256("0x6a058ae9b55602dddd290d0fe76db69bcc9398ea564c0e79c918611497f48ec2"))
		;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
		// return true;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
		// return 0;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
				// return NULL;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>#include "NodeEdit.h"
#include "Drone.h"

#include <QGridLayout>
#include <QDialogButtonBox>
#include <QLabel>

namespace QtcUtilities {
namespace Internal {
namespace Ci {

NodeEdit::NodeEdit (QWidget *parent)
  : QDialog (parent),
  mode_ (Mode::Drone), url_ (new QLineEdit (this)),
  user_ (new QLineEdit (this)), pass_ (new QLineEdit (this)),
  savePass_ (new QCheckBox (tr ("Save password"), this))
{
  auto *layout = new QGridLayout (this);
  auto row = 0;
  layout->addWidget (new QLabel (tr ("Url")), row, 0);
  layout->addWidget (url_, row, 1);

  ++row;
  layout->addWidget (new QLabel (tr ("Username")), row, 0);
  layout->addWidget (user_, row, 1);

  ++row;
  layout->addWidget (new QLabel (tr ("Password")), row, 0);
  layout->addWidget (pass_, row, 1);

  ++row;
  layout->addWidget (savePass_, row, 0, 1, -1);

  ++row;
  auto *buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  layout->addWidget (buttons, row, 0, 1, -1);
  connect (buttons, &QDialogButtonBox::accepted, this, &NodeEdit::accept);
  connect (buttons, &QDialogButtonBox::rejected, this, &NodeEdit::reject);
}

void NodeEdit::setDrone (Drone::Settings &drone)
{
  setMode (Mode::Drone);
  url_->setText (drone.url.toString ());
  user_->setText (QString::fromUtf8 (drone.user));
  pass_->setText (QString::fromUtf8 (drone.pass));
  savePass_->setChecked (drone.savePass);
}

Drone::Settings NodeEdit::drone () const
{
  if (mode_ == Mode::Drone) {
    return {QUrl (url_->text ()), user_->text ().toUtf8 (), pass_->text ().toUtf8 (),
            savePass_->isChecked ()};
  }
  return {};
}

NodeEdit::Mode NodeEdit::mode () const
{
  return mode_;
}

void NodeEdit::setMode (Mode mode)
{
  mode_ = mode;
}

bool NodeEdit::savePass () const
{
  return savePass_->isChecked ();
}

} // namespace Ci
} // namespace Internal
} // namespace QtcUtilities
<commit_msg>Set proper echo mode in CI node properties widget.<commit_after>#include "NodeEdit.h"
#include "Drone.h"

#include <QGridLayout>
#include <QDialogButtonBox>
#include <QLabel>

namespace QtcUtilities {
namespace Internal {
namespace Ci {

NodeEdit::NodeEdit (QWidget *parent)
  : QDialog (parent),
  mode_ (Mode::Drone), url_ (new QLineEdit (this)),
  user_ (new QLineEdit (this)), pass_ (new QLineEdit (this)),
  savePass_ (new QCheckBox (tr ("Save password"), this))
{
  auto *layout = new QGridLayout (this);
  auto row = 0;
  layout->addWidget (new QLabel (tr ("Url")), row, 0);
  layout->addWidget (url_, row, 1);

  ++row;
  layout->addWidget (new QLabel (tr ("Username")), row, 0);
  layout->addWidget (user_, row, 1);

  ++row;
  layout->addWidget (new QLabel (tr ("Password")), row, 0);
  pass_->setEchoMode (QLineEdit::Password);
  layout->addWidget (pass_, row, 1);

  ++row;
  layout->addWidget (savePass_, row, 0, 1, -1);

  ++row;
  auto *buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  layout->addWidget (buttons, row, 0, 1, -1);
  connect (buttons, &QDialogButtonBox::accepted, this, &NodeEdit::accept);
  connect (buttons, &QDialogButtonBox::rejected, this, &NodeEdit::reject);
}

void NodeEdit::setDrone (Drone::Settings &drone)
{
  setMode (Mode::Drone);
  url_->setText (drone.url.toString ());
  user_->setText (QString::fromUtf8 (drone.user));
  pass_->setText (QString::fromUtf8 (drone.pass));
  savePass_->setChecked (drone.savePass);
}

Drone::Settings NodeEdit::drone () const
{
  if (mode_ == Mode::Drone) {
    return {QUrl (url_->text ()), user_->text ().toUtf8 (), pass_->text ().toUtf8 (),
            savePass_->isChecked ()};
  }
  return {};
}

NodeEdit::Mode NodeEdit::mode () const
{
  return mode_;
}

void NodeEdit::setMode (Mode mode)
{
  mode_ = mode;
}

bool NodeEdit::savePass () const
{
  return savePass_->isChecked ();
}

} // namespace Ci
} // namespace Internal
} // namespace QtcUtilities
<|endoftext|>


<commit_before>#include <atomic>
#include "percpu.hh"
#include "ref.hh"

class filetable : public referenced {
private:
  static const int cpushift = 16;
  static const int fdmask = (1 << cpushift) - 1;

public:
  static sref<filetable> alloc() {
    return sref<filetable>::transfer(new filetable());
  }

  sref<filetable> copy(bool close_cloexec = false) {
    filetable* t = new filetable(false);

    fdinfo init(nullptr, false);
    for(int cpu = 0; cpu < NCPU; cpu++) {
      for(int fd = 0; fd < NOFILE; fd++) {
        // XXX Relaxed load?
        fdinfo info;
        // Avoid reading info_ altogether if we're closing cloexec FDs
        // and this is a cloexec FD.
        if (close_cloexec && cloexec_[cpu][fd])
          info = init;
        else
          info = info_[cpu][fd].load();
        file *f = info.get_file();
        if (f && (!close_cloexec || !info.get_cloexec())) {
          // XXX f's refcount could have dropped to zero between the
          // load and here
          f->inc();
          t->info_[cpu][fd].store(
            info.with_locked(false), std::memory_order_relaxed);
          t->cloexec_[cpu][fd].store(
            info.get_cloexec(), std::memory_order_relaxed);
        } else {
          t->info_[cpu][fd].store(init, std::memory_order_relaxed);
          t->cloexec_[cpu][fd].store(true, std::memory_order_relaxed);
        }
      }
    }
    std::atomic_thread_fence(std::memory_order_release);
    return sref<filetable>::transfer(t);
  }

  bool getfile(int fd, sref<file> *sf) {
    int cpu = fd >> cpushift;
    fd = fd & fdmask;

    if (cpu < 0 || cpu >= NCPU)
      return false;

    if (fd < 0 || fd >= NOFILE)
      return false;

    file* f = info_[cpu][fd].load().get_file();
    if (!f || !sf->init_nonzero(f))
      return false;
    return true;
  }

  int allocfd(struct file *f, bool percpu = false, bool cloexec = false) {
    int cpu = percpu ? myid() : 0;
    fdinfo none(nullptr, false);
    fdinfo newinfo(f, cloexec, true);
    for (int fd = 0; fd < NOFILE; fd++) {
      // Note that we skip over locked FDs because that means they're
      // either non-null or about to be.
      if (info_[cpu][fd].load(std::memory_order_relaxed) == none &&
          cmpxch(&info_[cpu][fd], none, newinfo)) {
        // The default state of cloexec_ is 'true', so we only need to
        // write to it if this is a keep-exec FD.
        if (!cloexec)
          cloexec_[cpu][fd] = cloexec;
        // Unlock FD
        info_[cpu][fd].store(newinfo.with_locked(false),
                             std::memory_order_release);
        return (cpu << cpushift) | fd;
      }
    }
    cprintf("filetable::allocfd: failed\n");
    return -1;
  }

  void close(int fd) {
    // XXX(sbw) if f->ref_ > 1 the kernel will not actually close
    // the file when this function returns (i.e. sys_close can return
    // while the file/pipe/socket is still open).
    int cpu = fd >> cpushift;
    fd = fd & fdmask;

    if (cpu < 0 || cpu >= NCPU) {
      cprintf("filetable::close: bad fd cpu %u\n", cpu);
      return;
    }

    if (fd < 0 || fd >= NOFILE) {
      cprintf("filetable::close: bad fd %u\n", fd);
      return;
    }

    // Lock the FD to prevent concurrent modifications
    std::atomic<fdinfo> *infop = &info_[cpu][fd];
    fdinfo info = lock_fdinfo(infop);

    // Clear cloexec_ back to default state of 'true'
    if (!cloexec_[cpu][fd])
      cloexec_[cpu][fd] = true;

    // Update and unlock the FD
    fdinfo newinfo(nullptr, false);
    infop->store(newinfo, std::memory_order_release);

    // Close old file
    if (info.get_file())
      info.get_file()->dec();
    else
      cprintf("filetable::close: bad fd %u\n", fd);
  }

  bool replace(int fd, struct file* newf, bool cloexec = false) {
    assert(newf);

    int cpu = fd >> cpushift;
    fd = fd & fdmask;

    if (cpu < 0 || cpu >= NCPU) {
      cprintf("filetable::replace: bad fd cpu %u\n", cpu);
      return false;
    }

    if (fd < 0 || fd >= NOFILE) {
      cprintf("filetable::replace: bad fd %u\n", fd);
      return false;
    }

    // Lock the FD to prevent concurrent modifications
    std::atomic<fdinfo> *infop = &info_[cpu][fd];
    fdinfo oldinfo = lock_fdinfo(infop);

    // Update to new info and unlock.  It's safe to update cloexec_
    // non-atomically with info even with concurrent lock-free readers
    // because any that care will double-check the fdinfo bit.
    fdinfo newinfo(newf, cloexec);
    if (cloexec != cloexec_[cpu][fd])
      cloexec_[cpu][fd] = cloexec;
    infop->store(newinfo, std::memory_order_release);

    if (oldinfo.get_file())
      oldinfo.get_file()->dec();
    return true;
  }

private:
  filetable(bool clear = true) {
    if (!clear)
      return;
    fdinfo none(nullptr, false);
    for(int cpu = 0; cpu < NCPU; cpu++) {
      for(int fd = 0; fd < NOFILE; fd++) {
        info_[cpu][fd].store(none, std::memory_order_relaxed);
        cloexec_[cpu][fd].store(true, std::memory_order_relaxed);
      }
    }
    std::atomic_thread_fence(std::memory_order_release);
  }

  ~filetable() {
    for(int cpu = 0; cpu < NCPU; cpu++){
      for(int fd = 0; fd < NOFILE; fd++){
        fdinfo info = info_[cpu][fd].load();
        if (info.get_file())
          info.get_file()->dec();
      }
    }
  }

  filetable& operator=(const filetable&);
  filetable(const filetable& x);
  NEW_DELETE_OPS(filetable);

  class fdinfo
  {
    uintptr_t data_;

    constexpr fdinfo(uintptr_t data) : data_(data) { }

  public:
    fdinfo() = default;

    fdinfo(file* fp, bool cloexec, bool locked = false)
      : data_((uintptr_t)fp | (uintptr_t)cloexec | ((uintptr_t)locked << 1)) { }

    file* get_file() const
    {
      return (file*)(data_ & ~3);
    }

    bool get_cloexec() const
    {
      return data_ & 1;
    }

    bool get_locked() const
    {
      return data_ & 2;
    }

    fdinfo with_locked(bool locked)
    {
      return fdinfo((data_ & ~2) | ((uintptr_t)locked << 1));
    }

    bool operator==(const fdinfo &o) const
    {
      return data_ == o.data_;
    }

    bool operator!=(const fdinfo &o) const
    {
      return data_ != o.data_;
    }
  };

  fdinfo lock_fdinfo(std::atomic<fdinfo> *infop)
  {
    fdinfo info, newinfo;
    while (true) {
      info = infop->load(std::memory_order_relaxed);
    retry:
      if (info.get_locked())
        nop_pause();
      else
        break;
    }
    if (!infop->compare_exchange_weak(info, info.with_locked(true)))
      goto retry;
    return info;
  }

  percpu<std::atomic<fdinfo>[NOFILE]> info_;
  // In addition to storing O_CLOEXEC with each fdinfo so it can be
  // read atomically with the FD, we store it separately so we can
  // scan for keep-exec FDs without reading from info_, which would
  // cause unnecessary sharing between the scan and creating O_CLOEXEC
  // FDs.  To avoid unnecessary sharing on this array itself, the
  // *default* state of this array for closed FDs must be 'true', so
  // we only have to write to it when opening a keep-exec FD.
  // Modifications to this array are protected by the fdinfo lock.
  // Lock-free readers should double-check the O_CLOEXEC bit in
  // fdinfo.
  percpu<std::atomic<bool>[NOFILE]> cloexec_;
};
<commit_msg>filetable: Fix replacing a file with itself<commit_after>#include <atomic>
#include "percpu.hh"
#include "ref.hh"

class filetable : public referenced {
private:
  static const int cpushift = 16;
  static const int fdmask = (1 << cpushift) - 1;

public:
  static sref<filetable> alloc() {
    return sref<filetable>::transfer(new filetable());
  }

  sref<filetable> copy(bool close_cloexec = false) {
    filetable* t = new filetable(false);

    fdinfo init(nullptr, false);
    for(int cpu = 0; cpu < NCPU; cpu++) {
      for(int fd = 0; fd < NOFILE; fd++) {
        // XXX Relaxed load?
        fdinfo info;
        // Avoid reading info_ altogether if we're closing cloexec FDs
        // and this is a cloexec FD.
        if (close_cloexec && cloexec_[cpu][fd])
          info = init;
        else
          info = info_[cpu][fd].load();
        file *f = info.get_file();
        if (f && (!close_cloexec || !info.get_cloexec())) {
          // XXX f's refcount could have dropped to zero between the
          // load and here
          f->inc();
          t->info_[cpu][fd].store(
            info.with_locked(false), std::memory_order_relaxed);
          t->cloexec_[cpu][fd].store(
            info.get_cloexec(), std::memory_order_relaxed);
        } else {
          t->info_[cpu][fd].store(init, std::memory_order_relaxed);
          t->cloexec_[cpu][fd].store(true, std::memory_order_relaxed);
        }
      }
    }
    std::atomic_thread_fence(std::memory_order_release);
    return sref<filetable>::transfer(t);
  }

  bool getfile(int fd, sref<file> *sf) {
    int cpu = fd >> cpushift;
    fd = fd & fdmask;

    if (cpu < 0 || cpu >= NCPU)
      return false;

    if (fd < 0 || fd >= NOFILE)
      return false;

    file* f = info_[cpu][fd].load().get_file();
    if (!f || !sf->init_nonzero(f))
      return false;
    return true;
  }

  int allocfd(struct file *f, bool percpu = false, bool cloexec = false) {
    int cpu = percpu ? myid() : 0;
    fdinfo none(nullptr, false);
    fdinfo newinfo(f, cloexec, true);
    for (int fd = 0; fd < NOFILE; fd++) {
      // Note that we skip over locked FDs because that means they're
      // either non-null or about to be.
      if (info_[cpu][fd].load(std::memory_order_relaxed) == none &&
          cmpxch(&info_[cpu][fd], none, newinfo)) {
        // The default state of cloexec_ is 'true', so we only need to
        // write to it if this is a keep-exec FD.
        if (!cloexec)
          cloexec_[cpu][fd] = cloexec;
        // Unlock FD
        info_[cpu][fd].store(newinfo.with_locked(false),
                             std::memory_order_release);
        return (cpu << cpushift) | fd;
      }
    }
    cprintf("filetable::allocfd: failed\n");
    return -1;
  }

  void close(int fd) {
    // XXX(sbw) if f->ref_ > 1 the kernel will not actually close
    // the file when this function returns (i.e. sys_close can return
    // while the file/pipe/socket is still open).
    int cpu = fd >> cpushift;
    fd = fd & fdmask;

    if (cpu < 0 || cpu >= NCPU) {
      cprintf("filetable::close: bad fd cpu %u\n", cpu);
      return;
    }

    if (fd < 0 || fd >= NOFILE) {
      cprintf("filetable::close: bad fd %u\n", fd);
      return;
    }

    // Lock the FD to prevent concurrent modifications
    std::atomic<fdinfo> *infop = &info_[cpu][fd];
    fdinfo info = lock_fdinfo(infop);

    // Clear cloexec_ back to default state of 'true'
    if (!cloexec_[cpu][fd])
      cloexec_[cpu][fd] = true;

    // Update and unlock the FD
    fdinfo newinfo(nullptr, false);
    infop->store(newinfo, std::memory_order_release);

    // Close old file
    if (info.get_file())
      info.get_file()->dec();
    else
      cprintf("filetable::close: bad fd %u\n", fd);
  }

  bool replace(int fd, struct file* newf, bool cloexec = false) {
    assert(newf);

    int cpu = fd >> cpushift;
    fd = fd & fdmask;

    if (cpu < 0 || cpu >= NCPU) {
      cprintf("filetable::replace: bad fd cpu %u\n", cpu);
      return false;
    }

    if (fd < 0 || fd >= NOFILE) {
      cprintf("filetable::replace: bad fd %u\n", fd);
      return false;
    }

    // Lock the FD to prevent concurrent modifications
    std::atomic<fdinfo> *infop = &info_[cpu][fd];
    fdinfo oldinfo = lock_fdinfo(infop);

    // Update to new info and unlock.  It's safe to update cloexec_
    // non-atomically with info even with concurrent lock-free readers
    // because any that care will double-check the fdinfo bit.
    fdinfo newinfo(newf, cloexec);
    if (cloexec != cloexec_[cpu][fd])
      cloexec_[cpu][fd] = cloexec;
    infop->store(newinfo, std::memory_order_release);

    if (oldinfo.get_file() && oldinfo.get_file() != newf)
      oldinfo.get_file()->dec();
    return true;
  }

private:
  filetable(bool clear = true) {
    if (!clear)
      return;
    fdinfo none(nullptr, false);
    for(int cpu = 0; cpu < NCPU; cpu++) {
      for(int fd = 0; fd < NOFILE; fd++) {
        info_[cpu][fd].store(none, std::memory_order_relaxed);
        cloexec_[cpu][fd].store(true, std::memory_order_relaxed);
      }
    }
    std::atomic_thread_fence(std::memory_order_release);
  }

  ~filetable() {
    for(int cpu = 0; cpu < NCPU; cpu++){
      for(int fd = 0; fd < NOFILE; fd++){
        fdinfo info = info_[cpu][fd].load();
        if (info.get_file())
          info.get_file()->dec();
      }
    }
  }

  filetable& operator=(const filetable&);
  filetable(const filetable& x);
  NEW_DELETE_OPS(filetable);

  class fdinfo
  {
    uintptr_t data_;

    constexpr fdinfo(uintptr_t data) : data_(data) { }

  public:
    fdinfo() = default;

    fdinfo(file* fp, bool cloexec, bool locked = false)
      : data_((uintptr_t)fp | (uintptr_t)cloexec | ((uintptr_t)locked << 1)) { }

    file* get_file() const
    {
      return (file*)(data_ & ~3);
    }

    bool get_cloexec() const
    {
      return data_ & 1;
    }

    bool get_locked() const
    {
      return data_ & 2;
    }

    fdinfo with_locked(bool locked)
    {
      return fdinfo((data_ & ~2) | ((uintptr_t)locked << 1));
    }

    bool operator==(const fdinfo &o) const
    {
      return data_ == o.data_;
    }

    bool operator!=(const fdinfo &o) const
    {
      return data_ != o.data_;
    }
  };

  fdinfo lock_fdinfo(std::atomic<fdinfo> *infop)
  {
    fdinfo info, newinfo;
    while (true) {
      info = infop->load(std::memory_order_relaxed);
    retry:
      if (info.get_locked())
        nop_pause();
      else
        break;
    }
    if (!infop->compare_exchange_weak(info, info.with_locked(true)))
      goto retry;
    return info;
  }

  percpu<std::atomic<fdinfo>[NOFILE]> info_;
  // In addition to storing O_CLOEXEC with each fdinfo so it can be
  // read atomically with the FD, we store it separately so we can
  // scan for keep-exec FDs without reading from info_, which would
  // cause unnecessary sharing between the scan and creating O_CLOEXEC
  // FDs.  To avoid unnecessary sharing on this array itself, the
  // *default* state of this array for closed FDs must be 'true', so
  // we only have to write to it when opening a keep-exec FD.
  // Modifications to this array are protected by the fdinfo lock.
  // Lock-free readers should double-check the O_CLOEXEC bit in
  // fdinfo.
  percpu<std::atomic<bool>[NOFILE]> cloexec_;
};
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 * * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include "modules/common/math/mpc_solver.h"

#include <algorithm>
#include <iostream>
#include <memory>

#include "modules/common/log.h"
#include "modules/common/math/qp_solver/active_set_qp_solver.h"
#include "modules/common/math/qp_solver/qp_solver.h"

namespace apollo {
namespace common {
namespace math {

using Matrix = Eigen::MatrixXd;

// discrete linear predictive control solver, with control format
// x(i + 1) = A * x(i) + B * u (i) + C
bool SolveLinearMPC(Matrix &matrix_a, Matrix &matrix_b, Matrix &matrix_c,
                    Matrix &matrix_q, Matrix &matrix_r, Matrix &matrix_lower,
                    Matrix &matrix_upper, Matrix &matrix_initial_state,
                    std::vector<Matrix> &reference, double eps, int max_iter,
                    std::vector<Matrix> *control) {
  if (matrix_a.rows() != matrix_a.cols() ||
      matrix_b.rows() != matrix_a.rows() ||
      matrix_lower.rows() != matrix_upper.rows()) {
    AERROR << "One or more matrices have incompatible dimensions. Aborting.";
    return false;
  }

  unsigned int horizon = reference.size();

  // Update augment reference matrix_t
  Matrix matrix_t = Matrix::Zero(matrix_b.rows() * horizon, 1);
  for (unsigned int j = 0; j < horizon; ++j) {
    matrix_t.block(j * reference[0].size(), 0, reference[0].size(), 1) =
        reference[j];
  }

  // Update augment control matrix_v
  Matrix matrix_v = Matrix::Zero((*control)[0].rows() * horizon, 1);
  for (unsigned int j = 0; j < horizon; ++j) {
    matrix_v.block(j * (*control)[0].rows(), 0, (*control)[0].rows(), 1) =
        (*control)[j];
  }

  std::vector<Matrix> matrix_a_power(horizon);
  matrix_a_power[0] = matrix_a;
  for (unsigned int i = 1; i < matrix_a_power.size(); ++i) {
    matrix_a_power[i] = matrix_a * matrix_a_power[i - 1];
  }

  Matrix matrix_k =
      Matrix::Zero(matrix_b.rows() * horizon,
                   matrix_b.cols() * horizon);
  for (unsigned int r = 0; r < horizon; ++r) {
    for (unsigned int c = 0; c <= r; ++c) {
      matrix_k.block(r * matrix_b.rows(), c * matrix_b.cols(), matrix_b.rows(),
                     matrix_b.cols()) = matrix_a_power[r - c] * matrix_b;
    }
  }
  // Initialize matrix_k, matrix_m, matrix_t and matrix_v, matrix_qq, matrix_rr,
  // vector of matrix A power
  Matrix matrix_m = Matrix::Zero(matrix_b.rows() * horizon, 1);
  Matrix matrix_qq = Matrix::Zero(matrix_k.rows(), matrix_k.rows());
  Matrix matrix_rr = Matrix::Zero(matrix_k.cols(), matrix_k.cols());
  Matrix matrix_ll = Matrix::Zero(horizon * matrix_lower.rows(), 1);
  Matrix matrix_uu = Matrix::Zero(horizon * matrix_upper.rows(), 1);

  // Compute matrix_m
  matrix_m.block(0, 0, matrix_a.rows(), 1) =
      matrix_a * matrix_initial_state + matrix_c;
  for (unsigned int i = 1; i < horizon; ++i) {
    matrix_m.block(i * matrix_a.rows(), 0, matrix_a.rows(), 1) =
        matrix_a *
            matrix_m.block((i - 1) * matrix_a.rows(), 0, matrix_a.rows(), 1) +
        matrix_c;
  }

  // Compute matrix_ll, matrix_uu, matrix_qq, matrix_rr
  for (unsigned int i = 0; i < horizon; ++i) {
    matrix_ll.block(i * (*control)[0].rows(), 0, (*control)[0].rows(), 1) =
        matrix_lower;
    matrix_uu.block(i * (*control)[0].rows(), 0, (*control)[0].rows(), 1) =
        matrix_upper;
    matrix_qq.block(i * matrix_q.rows(), i * matrix_q.rows(), matrix_q.rows(),
                    matrix_q.rows()) = matrix_q;
    matrix_rr.block(i * matrix_r.rows(), i * matrix_r.rows(), matrix_r.cols(),
                    matrix_r.cols()) = matrix_r;
  }

  // Update matrix_m1, matrix_m2, convert MPC problem to QP problem done
  Matrix matrix_m1 = matrix_k.transpose() * matrix_qq * matrix_k + matrix_rr;
  Matrix matrix_m2 = matrix_k.transpose() * matrix_qq * (matrix_m - matrix_t);

  // Method 1: QPOASES
  Matrix matrix_inequality_constrain_ll =
      -Matrix::Identity(matrix_ll.rows(), matrix_ll.rows());
  Matrix matrix_inequality_constrain_uu =
      Matrix::Identity(matrix_uu.rows(), matrix_uu.rows());
  Matrix matrix_inequality_constrain =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.rows());
  matrix_inequality_constrain << -matrix_inequality_constrain_ll,
      -matrix_inequality_constrain_uu;
  Matrix matrix_inequality_boundary =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.cols());
  matrix_inequality_boundary << matrix_ll, -matrix_uu;
  Matrix matrix_equality_constrain =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.rows());
  Matrix matrix_equality_boundary =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.cols());

  std::unique_ptr<QpSolver> qp_solver(new ActiveSetQpSolver(
      matrix_m1, matrix_m2, matrix_inequality_constrain,
      matrix_inequality_boundary, matrix_equality_constrain,
      matrix_equality_boundary));
  auto result = qp_solver->Solve();
  if (!result) {
  AERROR << "Linear MPC solver failed";
  return false;
  }
  matrix_v = qp_solver->params();

  for (unsigned int i = 0; i < horizon; ++i) {
    (*control)[i] =
        matrix_v.block(i * (*control)[0].rows(), 0, (*control)[0].rows(), 1);
  }
  return true;
}

}  // namespace math
}  // namespace common
}  // namespace apollo
<commit_msg>Control: furture fix mpc<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 * * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include "modules/common/math/mpc_solver.h"

#include <algorithm>
#include <iostream>
#include <memory>

#include "modules/common/log.h"
#include "modules/common/math/qp_solver/active_set_qp_solver.h"
#include "modules/common/math/qp_solver/qp_solver.h"

namespace apollo {
namespace common {
namespace math {

using Matrix = Eigen::MatrixXd;

// discrete linear predictive control solver, with control format
// x(i + 1) = A * x(i) + B * u (i) + C
bool SolveLinearMPC(Matrix &matrix_a, Matrix &matrix_b, Matrix &matrix_c,
                    Matrix &matrix_q, Matrix &matrix_r, Matrix &matrix_lower,
                    Matrix &matrix_upper, Matrix &matrix_initial_state,
                    std::vector<Matrix> &reference, double eps, int max_iter,
                    std::vector<Matrix> *control) {
  if (matrix_a.rows() != matrix_a.cols() ||
      matrix_b.rows() != matrix_a.rows() ||
      matrix_lower.rows() != matrix_upper.rows()) {
    AERROR << "One or more matrices have incompatible dimensions. Aborting.";
    return false;
  }

  unsigned int horizon = reference.size();

  // Update augment reference matrix_t
  Matrix matrix_t = Matrix::Zero(matrix_b.rows() * horizon, 1);
  for (unsigned int j = 0; j < horizon; ++j) {
    matrix_t.block(j * reference[0].size(), 0, reference[0].size(), 1) =
        reference[j];
  }

  // Update augment control matrix_v
  Matrix matrix_v = Matrix::Zero((*control)[0].rows() * horizon, 1);
  for (unsigned int j = 0; j < horizon; ++j) {
    matrix_v.block(j * (*control)[0].rows(), 0, (*control)[0].rows(), 1) =
        (*control)[j];
  }

  std::vector<Matrix> matrix_a_power(horizon);
  matrix_a_power[0] = matrix_a;
  for (unsigned int i = 1; i < matrix_a_power.size(); ++i) {
    matrix_a_power[i] = matrix_a * matrix_a_power[i - 1];
  }

  Matrix matrix_k =
      Matrix::Zero(matrix_b.rows() * horizon, matrix_b.cols() * horizon);
  for (unsigned int r = 0; r < horizon; ++r) {
    for (unsigned int c = 0; c <= r; ++c) {
      matrix_k.block(r * matrix_b.rows(), c * matrix_b.cols(), matrix_b.rows(),
                     matrix_b.cols()) = matrix_a_power[r - c] * matrix_b;
    }
  }
  // Initialize matrix_k, matrix_m, matrix_t and matrix_v, matrix_qq, matrix_rr,
  // vector of matrix A power
  Matrix matrix_m = Matrix::Zero(matrix_b.rows() * horizon, 1);
  Matrix matrix_qq = Matrix::Zero(matrix_k.rows(), matrix_k.rows());
  Matrix matrix_rr = Matrix::Zero(matrix_k.cols(), matrix_k.cols());
  Matrix matrix_ll = Matrix::Zero(horizon * matrix_lower.rows(), 1);
  Matrix matrix_uu = Matrix::Zero(horizon * matrix_upper.rows(), 1);

  // Compute matrix_m
  matrix_m.block(0, 0, matrix_a.rows(), 1) =
      matrix_a * matrix_initial_state + matrix_c;
  for (unsigned int i = 1; i < horizon; ++i) {
    matrix_m.block(i * matrix_a.rows(), 0, matrix_a.rows(), 1) =
        matrix_a *
            matrix_m.block((i - 1) * matrix_a.rows(), 0, matrix_a.rows(), 1) +
        matrix_c;
  }

  // Compute matrix_ll, matrix_uu, matrix_qq, matrix_rr
  for (unsigned int i = 0; i < horizon; ++i) {
    matrix_ll.block(i * (*control)[0].rows(), 0, (*control)[0].rows(), 1) =
        matrix_lower;
    matrix_uu.block(i * (*control)[0].rows(), 0, (*control)[0].rows(), 1) =
        matrix_upper;
    matrix_qq.block(i * matrix_q.rows(), i * matrix_q.rows(), matrix_q.rows(),
                    matrix_q.rows()) = matrix_q;
    matrix_rr.block(i * matrix_r.rows(), i * matrix_r.rows(), matrix_r.cols(),
                    matrix_r.cols()) = matrix_r;
  }

  // Update matrix_m1, matrix_m2, convert MPC problem to QP problem done
  Matrix matrix_m1 = matrix_k.transpose() * matrix_qq * matrix_k + matrix_rr;
  Matrix matrix_m2 = matrix_k.transpose() * matrix_qq * (matrix_m - matrix_t);

  // Method 1: QPOASES
  Matrix matrix_inequality_constrain_ll =
      -Matrix::Identity(matrix_ll.rows(), matrix_ll.rows());
  Matrix matrix_inequality_constrain_uu =
      Matrix::Identity(matrix_uu.rows(), matrix_uu.rows());
  Matrix matrix_inequality_constrain =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.rows());
  matrix_inequality_constrain << -matrix_inequality_constrain_ll,
      -matrix_inequality_constrain_uu;
  Matrix matrix_inequality_boundary =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.cols());
  matrix_inequality_boundary << matrix_ll, -matrix_uu;
  Matrix matrix_equality_constrain =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.rows());
  Matrix matrix_equality_boundary =
      Matrix::Zero(matrix_ll.rows() + matrix_uu.rows(), matrix_ll.cols());

  std::unique_ptr<QpSolver> qp_solver(new ActiveSetQpSolver(
      matrix_m1, matrix_m2, matrix_inequality_constrain,
      matrix_inequality_boundary, matrix_equality_constrain,
      matrix_equality_boundary));
  auto result = qp_solver->Solve();
  if (!result) {
    AERROR << "Linear MPC solver failed";
    return false;
  }
  matrix_v = qp_solver->params();

  for (unsigned int i = 0; i < horizon; ++i) {
    (*control)[i] =
        matrix_v.block(i * (*control)[0].rows(), 0, (*control)[0].rows(), 1);
  }
  return true;
}

}  // namespace math
}  // namespace common
}  // namespace apollo
<|endoftext|>


<commit_before>#include "app/ParamWidget.hpp"
#include "ui/MenuOverlay.hpp"
#include "ui/TextField.hpp"
#include "app/Scene.hpp"
#include "app/ParamQuantity.hpp"
#include "app.hpp"
#include "settings.hpp"
#include "random.hpp"
#include "history.hpp"
#include "helpers.hpp"

namespace rack {

struct ParamField : TextField {
	ParamWidget *paramWidget;

	void step() override {
		// Keep selected
		app()->event->setSelected(this);
		TextField::step();
	}

	void setParamWidget(ParamWidget *paramWidget) {
		this->paramWidget = paramWidget;
		if (paramWidget->paramQuantity)
			text = paramWidget->paramQuantity->getDisplayValueString();
		selectAll();
	}

	void onSelectKey(const event::SelectKey &e) override {
		if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) {
			float oldValue = paramWidget->paramQuantity->getValue();
			if (paramWidget->paramQuantity)
				paramWidget->paramQuantity->setDisplayValueString(text);
			float newValue = paramWidget->paramQuantity->getValue();

			if (oldValue != newValue) {
				// Push ParamChange history action
				history::ParamChange *h = new history::ParamChange;
				h->moduleId = paramWidget->paramQuantity->module->id;
				h->paramId = paramWidget->paramQuantity->paramId;
				h->oldValue = oldValue;
				h->newValue = newValue;
				app()->history->push(h);
			}

			MenuOverlay *overlay = getAncestorOfType<MenuOverlay>();
			overlay->requestedDelete = true;
			e.consume(this);
		}

		if (e.action == GLFW_PRESS && e.key == GLFW_KEY_ESCAPE) {
			MenuOverlay *overlay = getAncestorOfType<MenuOverlay>();
			overlay->requestedDelete = true;
			e.consume(this);
		}

		if (!e.getConsumed())
			TextField::onSelectKey(e);
	}
};

struct ParamTooltip : Tooltip {
	ParamWidget *paramWidget;

	void step() override {
		if (paramWidget->paramQuantity) {
			// Quantity string
			text = paramWidget->paramQuantity->getString();
			// Param description
			std::string description = paramWidget->paramQuantity->getParam()->description;
			if (!description.empty())
				text += "\n" + description;
		}
		// Position at bottom-right of parameter
		box.pos = paramWidget->getAbsoluteOffset(box.size).round();
	}
};

struct ParamResetItem : MenuItem {
	ParamWidget *paramWidget;
	ParamResetItem() {
		text = "Initialize";
		rightText = WINDOW_MOD_ALT_NAME "+click";
	}
	void onAction(const event::Action &e) override {
		paramWidget->resetAction();
	}
};

struct ParamFieldItem : MenuItem {
	ParamWidget *paramWidget;
	ParamFieldItem() {
		text = "Enter value";
		rightText = WINDOW_MOD_SHIFT_NAME "+click";
	}
	void onAction(const event::Action &e) override {
		paramWidget->createParamField();
	}
};

ParamWidget::~ParamWidget() {
	if (paramQuantity)
		delete paramQuantity;
}

void ParamWidget::step() {
	if (paramQuantity) {
		float value = paramQuantity->getValue();
		// Trigger change event when paramQuantity value changes
		if (value != dirtyValue) {
			dirtyValue = value;
			event::Change eChange;
			onChange(eChange);
		}
	}

	OpaqueWidget::step();
}

void ParamWidget::draw(NVGcontext *vg) {
	Widget::draw(vg);

	// if (paramQuantity) {
	// 	nvgBeginPath(vg);
	// 	nvgRect(vg,
	// 		box.size.x - 12, box.size.y - 12,
	// 		12, 12);
	// 	nvgFillColor(vg, nvgRGBAf(1, 0, 1, 0.9));
	// 	nvgFill(vg);

	// 	std::string mapText = string::f("%d", paramQuantity->paramId);
	// 	bndLabel(vg, box.size.x - 17.0, box.size.y - 16.0, INFINITY, INFINITY, -1, mapText.c_str());
	// }
}

void ParamWidget::onButton(const event::Button &e) {
	// Right click to open context menu
	if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT && (e.mods & WINDOW_MOD_MASK) == 0) {
		createContextMenu();
		e.consume(this);
	}

	// Alt-click to reset
	if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == GLFW_MOD_ALT) {
		resetAction();
		e.consume(this);
	}

	// Shift-click to open value entry
	if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) {
		createParamField();
		e.consume(this);
	}

	if (!e.getConsumed())
		OpaqueWidget::onButton(e);
}

void ParamWidget::onEnter(const event::Enter &e) {
	if (settings::paramTooltip && !tooltip) {
		ParamTooltip *paramTooltip = new ParamTooltip;
		paramTooltip->paramWidget = this;
		app()->scene->addChild(paramTooltip);
		tooltip = paramTooltip;
	}
}

void ParamWidget::onLeave(const event::Leave &e) {
	if (tooltip) {
		app()->scene->removeChild(tooltip);
		delete tooltip;
		tooltip = NULL;
	}
}

void ParamWidget::fromJson(json_t *rootJ) {
	json_t *valueJ = json_object_get(rootJ, "value");
	if (valueJ) {
		if (paramQuantity)
			paramQuantity->setValue(json_number_value(valueJ));
	}
}

void ParamWidget::createParamField() {
	// Create ParamField
	MenuOverlay *overlay = new MenuOverlay;
	app()->scene->addChild(overlay);

	ParamField *paramField = new ParamField;
	paramField->box.size.x = 100;
	paramField->box.pos = getAbsoluteOffset(box.size).round();
	paramField->setParamWidget(this);
	overlay->addChild(paramField);
}

void ParamWidget::createContextMenu() {
	Menu *menu = createMenu();

	ParamResetItem *resetItem = new ParamResetItem;
	resetItem->paramWidget = this;
	menu->addChild(resetItem);

	ParamFieldItem *fieldItem = new ParamFieldItem;
	fieldItem->paramWidget = this;
	menu->addChild(fieldItem);
}

void ParamWidget::resetAction() {
	if (paramQuantity && paramQuantity->isBounded()) {
		float oldValue = paramQuantity->getValue();
		paramQuantity->reset();
		float newValue = paramQuantity->getValue();

		if (oldValue != newValue) {
			// Push ParamChange history action
			history::ParamChange *h = new history::ParamChange;
			h->moduleId = paramQuantity->module->id;
			h->paramId = paramQuantity->paramId;
			h->oldValue = oldValue;
			h->newValue = newValue;
			app()->history->push(h);
		}

		// Here's another way of doing it, but either works.
		// paramQuantity->getParam()->reset();
	}
}

} // namespace rack
<commit_msg>Fix ParamTooltip. Add ParamLabel to context menu.<commit_after>#include "app/ParamWidget.hpp"
#include "ui/MenuOverlay.hpp"
#include "ui/TextField.hpp"
#include "app/Scene.hpp"
#include "app/ParamQuantity.hpp"
#include "app.hpp"
#include "settings.hpp"
#include "random.hpp"
#include "history.hpp"
#include "helpers.hpp"

namespace rack {

struct ParamField : TextField {
	ParamWidget *paramWidget;

	void step() override {
		// Keep selected
		app()->event->setSelected(this);
		TextField::step();
	}

	void setParamWidget(ParamWidget *paramWidget) {
		this->paramWidget = paramWidget;
		if (paramWidget->paramQuantity)
			text = paramWidget->paramQuantity->getDisplayValueString();
		selectAll();
	}

	void onSelectKey(const event::SelectKey &e) override {
		if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) {
			float oldValue = paramWidget->paramQuantity->getValue();
			if (paramWidget->paramQuantity)
				paramWidget->paramQuantity->setDisplayValueString(text);
			float newValue = paramWidget->paramQuantity->getValue();

			if (oldValue != newValue) {
				// Push ParamChange history action
				history::ParamChange *h = new history::ParamChange;
				h->moduleId = paramWidget->paramQuantity->module->id;
				h->paramId = paramWidget->paramQuantity->paramId;
				h->oldValue = oldValue;
				h->newValue = newValue;
				app()->history->push(h);
			}

			MenuOverlay *overlay = getAncestorOfType<MenuOverlay>();
			overlay->requestedDelete = true;
			e.consume(this);
		}

		if (e.action == GLFW_PRESS && e.key == GLFW_KEY_ESCAPE) {
			MenuOverlay *overlay = getAncestorOfType<MenuOverlay>();
			overlay->requestedDelete = true;
			e.consume(this);
		}

		if (!e.getConsumed())
			TextField::onSelectKey(e);
	}
};

struct ParamTooltip : Tooltip {
	ParamWidget *paramWidget;

	void step() override {
		if (paramWidget->paramQuantity) {
			// Quantity string
			text = paramWidget->paramQuantity->getString();
			// Param description
			std::string description = paramWidget->paramQuantity->getParam()->description;
			if (!description.empty())
				text += "\n" + description;
		}
		// Position at bottom-right of parameter
		box.pos = paramWidget->getAbsoluteOffset(paramWidget->box.size).round();
		Tooltip::step();
	}
};

struct ParamLabel : MenuLabel {
	ParamWidget *paramWidget;
	void step() override {
		text = paramWidget->paramQuantity->getString();
	}
};

struct ParamResetItem : MenuItem {
	ParamWidget *paramWidget;
	ParamResetItem() {
		text = "Initialize";
		rightText = WINDOW_MOD_ALT_NAME "+click";
	}
	void onAction(const event::Action &e) override {
		paramWidget->resetAction();
	}
};

struct ParamFieldItem : MenuItem {
	ParamWidget *paramWidget;
	ParamFieldItem() {
		text = "Enter value";
		rightText = WINDOW_MOD_SHIFT_NAME "+click";
	}
	void onAction(const event::Action &e) override {
		paramWidget->createParamField();
	}
};

ParamWidget::~ParamWidget() {
	if (paramQuantity)
		delete paramQuantity;
}

void ParamWidget::step() {
	if (paramQuantity) {
		float value = paramQuantity->getValue();
		// Trigger change event when paramQuantity value changes
		if (value != dirtyValue) {
			dirtyValue = value;
			event::Change eChange;
			onChange(eChange);
		}
	}

	OpaqueWidget::step();
}

void ParamWidget::draw(NVGcontext *vg) {
	Widget::draw(vg);

	// if (paramQuantity) {
	// 	nvgBeginPath(vg);
	// 	nvgRect(vg,
	// 		box.size.x - 12, box.size.y - 12,
	// 		12, 12);
	// 	nvgFillColor(vg, nvgRGBAf(1, 0, 1, 0.9));
	// 	nvgFill(vg);

	// 	std::string mapText = string::f("%d", paramQuantity->paramId);
	// 	bndLabel(vg, box.size.x - 17.0, box.size.y - 16.0, INFINITY, INFINITY, -1, mapText.c_str());
	// }
}

void ParamWidget::onButton(const event::Button &e) {
	// Right click to open context menu
	if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT && (e.mods & WINDOW_MOD_MASK) == 0) {
		createContextMenu();
		e.consume(this);
	}

	// Alt-click to reset
	if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == GLFW_MOD_ALT) {
		resetAction();
		e.consume(this);
	}

	// Shift-click to open value entry
	if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) {
		createParamField();
		e.consume(this);
	}

	if (!e.getConsumed())
		OpaqueWidget::onButton(e);
}

void ParamWidget::onEnter(const event::Enter &e) {
	if (settings::paramTooltip && !tooltip) {
		ParamTooltip *paramTooltip = new ParamTooltip;
		paramTooltip->paramWidget = this;
		app()->scene->addChild(paramTooltip);
		tooltip = paramTooltip;
	}
}

void ParamWidget::onLeave(const event::Leave &e) {
	if (tooltip) {
		app()->scene->removeChild(tooltip);
		delete tooltip;
		tooltip = NULL;
	}
}

void ParamWidget::fromJson(json_t *rootJ) {
	json_t *valueJ = json_object_get(rootJ, "value");
	if (valueJ) {
		if (paramQuantity)
			paramQuantity->setValue(json_number_value(valueJ));
	}
}

void ParamWidget::createParamField() {
	// Create ParamField
	MenuOverlay *overlay = new MenuOverlay;
	app()->scene->addChild(overlay);

	ParamField *paramField = new ParamField;
	paramField->box.size.x = 100;
	paramField->box.pos = getAbsoluteOffset(box.size).round();
	paramField->setParamWidget(this);
	overlay->addChild(paramField);
}

void ParamWidget::createContextMenu() {
	Menu *menu = createMenu();

	ParamLabel *paramLabel = new ParamLabel;
	paramLabel->paramWidget = this;
	menu->addChild(paramLabel);

	ParamResetItem *resetItem = new ParamResetItem;
	resetItem->paramWidget = this;
	menu->addChild(resetItem);

	ParamFieldItem *fieldItem = new ParamFieldItem;
	fieldItem->paramWidget = this;
	menu->addChild(fieldItem);
}

void ParamWidget::resetAction() {
	if (paramQuantity && paramQuantity->isBounded()) {
		float oldValue = paramQuantity->getValue();
		paramQuantity->reset();
		float newValue = paramQuantity->getValue();

		if (oldValue != newValue) {
			// Push ParamChange history action
			history::ParamChange *h = new history::ParamChange;
			h->moduleId = paramQuantity->module->id;
			h->paramId = paramQuantity->paramId;
			h->oldValue = oldValue;
			h->newValue = newValue;
			app()->history->push(h);
		}

		// Here's another way of doing it, but either works.
		// paramQuantity->getParam()->reset();
	}
}

} // namespace rack
<|endoftext|>


<commit_before>#pragma once

namespace mpm {

    namespace detail {
        template <bool x> struct STATIC_ASSERTION_FAILURE;
        template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
        template <int i> struct static_assert_helper{};
    }

    template <bool B, typename T=void> struct enable_if{};
    template <typename T> struct enable_if<true, T> { typedef T type; };

    template <bool B, typename T=void> struct disable_if{};
    template <typename T> struct disable_if<false, T> { typedef T type; };
}

#define MPM_STATIC_ASSERT(expr) \
    typedef detail::static_assert_helper<sizeof(detail::STATIC_ASSERTION_FAILURE<(bool)(expr)>)> _mpm_static_assert_typedef

#define MPM_CAS(val, expected, new_val) \
    __sync_bool_compare_and_swap(val, expected, new_val);

#define MPM_EXCHG(storage, value) \
    __sync_lock_test_and_set(storage, value);

#define MPM_DISALLOW_COPY_AND_ASSIGN(Type) \
    Type(const Type&); \
    void operator=(const Type&)
<commit_msg>Don't bother giving names to unused template vars<commit_after>#pragma once

namespace mpm {

    namespace detail {
        template <bool> struct STATIC_ASSERTION_FAILURE;
        template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
        template <int> struct static_assert_helper{};
    }

    template <bool, typename T=void> struct enable_if{};
    template <typename T> struct enable_if<true, T> { typedef T type; };

    template <bool, typename T=void> struct disable_if{};
    template <typename T> struct disable_if<false, T> { typedef T type; };
}

#define MPM_STATIC_ASSERT(expr) \
    typedef detail::static_assert_helper<sizeof(detail::STATIC_ASSERTION_FAILURE<(bool)(expr)>)> _mpm_static_assert_typedef

#define MPM_CAS(val, expected, new_val) \
    __sync_bool_compare_and_swap(val, expected, new_val);

#define MPM_EXCHG(storage, value) \
    __sync_lock_test_and_set(storage, value);

#define MPM_DISALLOW_COPY_AND_ASSIGN(Type) \
    Type(const Type&); \
    void operator=(const Type&)
<|endoftext|>


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

#include <sstream>

#include <ignite/common/common.h>
#include <ignite/common/concurrent.h>
#include <ignite/common/exports.h>
#include <ignite/common/java.h>

#include "ignite/impl/ignite_environment.h"
#include "ignite/impl/ignite_impl.h"
#include "ignite/impl/utils.h"
#include "ignite/ignition.h"

using namespace ignite::common::concurrent;
using namespace ignite::common::java;
using namespace ignite::impl;
using namespace ignite::impl::utils;

namespace ignite
{
    /** Default configuration. */
    const char* DFLT_CFG = "config/default-config.xml";

    /** Whether JVM library is loaded to the process. */
    bool JVM_LIB_LOADED;

    /** Critical section for factory methods. */
    CriticalSection factoryLock;

    /** Flag indicating that at least one Ignite instance has started. */
    bool started = false;

    /**
     * Convert integer value to string.
     */
    std::string JvmMemoryString(const std::string& prefix, int32_t val)
    {
        std::ostringstream ss;
        ss << val;

        std::string valStr = ss.str();

        std::string res = std::string(prefix);
        res.append(valStr);
        res.append("m");

        return res;
    }

    /**
     * Create JVM options.
     *
     * @param cfg Configuration.
     * @param home Optional GG home.
     * @param cp Classpath.
     * @param opts Options.
     * @param optsLen Options length.
     * @return Options.
     */
    char** CreateJvmOptions(const IgniteConfiguration& cfg, const std::string* home, const std::string& cp, int* optsLen)
    {
        *optsLen = 3 + (home ? 1 : 0) + cfg.jvmOptsLen;
        char** opts = new char*[*optsLen];

        int idx = 0;

        // 1. Set classpath.
        std::string cpFull = std::string("-Djava.class.path=") + cp;

        *(opts + idx++) = CopyChars(cpFull.c_str());

        // 2. Set home.
        if (home) {
            std::string homeFull = std::string("-DIGNITE_HOME=") + *home;

            *(opts + idx++) = CopyChars(homeFull.c_str());
        }

        // 3. Set Xms, Xmx.
        std::string xmsStr = JvmMemoryString(std::string("-Xms"), cfg.jvmInitMem);
        std::string xmxStr = JvmMemoryString(std::string("-Xmx"), cfg.jvmMaxMem);

        *(opts + idx++) = CopyChars(xmsStr.c_str());
        *(opts + idx++) = CopyChars(xmxStr.c_str());

        // 4. Set the rest options.
        for (int i = 0; i < cfg.jvmOptsLen; i++) {
            char* optCopy = CopyChars(cfg.jvmOpts[i].opt);

            opts[idx++] = optCopy;
        }

        return opts;
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg)
    {
        return Start(cfg, static_cast<const char*>(NULL));
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg, IgniteError* err)
    {
        return Start(cfg, NULL, err);
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg, const char* name)
    {
        IgniteError err;

        Ignite res = Start(cfg, name, &err);

        IgniteError::ThrowIfNeeded(err);

        return res;
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg, const char* name, IgniteError* err)
    {
        bool failed = false;

        SharedPointer<IgniteEnvironment> env;
        SharedPointer<IgniteEnvironment>* envTarget = NULL;

        jobject javaRef = NULL;

        factoryLock.Enter();

        // 1. Load JVM library if needed.
        if (!JVM_LIB_LOADED)
        {
            bool jvmLibFound;
            std::string jvmLib;

            if (cfg.jvmLibPath)
            {
                std::string jvmLibPath = std::string(cfg.jvmLibPath);

                jvmLib = FindJvmLibrary(&jvmLibPath, &jvmLibFound);
            }
            else
                jvmLib = FindJvmLibrary(NULL, &jvmLibFound);

            if (!jvmLibFound)
            {
                *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_NOT_FOUND,
                    "JVM library is not found (did you set JAVA_HOME environment variable?)");

                failed = true;
            }
            else
                std::cout << "JVM LIB LOC: " << jvmLib << std::endl;

            if (!failed) {
                if (!LoadJvmLibrary(jvmLib))
                {
                    *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_LOAD_FAILED, "Failed to load JVM library.");

                    failed = true;
                }
            }

            JVM_LIB_LOADED = true;
        }

        if (!failed)
        {
            // 2. Resolve IGNITE_HOME.
            bool homeFound;
            std::string home;

            if (cfg.igniteHome)
            {
                std::string homePath = std::string(cfg.igniteHome);

                home = ResolveIgniteHome(&homePath, &homeFound);
            }
            else
                home = ResolveIgniteHome(NULL, &homeFound);

            std::cout << "IGNITE_HOME: " << home << std::endl;

            // 3. Create classpath.
            std::string cp;

            if (cfg.jvmClassPath)
            {
                std::string usrCp = cfg.jvmClassPath;

                cp = CreateIgniteClasspath(&usrCp, homeFound ? &home : NULL);
            }
            else
                cp = CreateIgniteClasspath(NULL, homeFound ? &home : NULL);

            if (!cp.empty())
            {
                std::cout << "CLASSPATH: " << cp << std::endl;

                // 4. Start JVM if needed.
                JniErrorInfo jniErr;

                env = SharedPointer<IgniteEnvironment>(new IgniteEnvironment());

                int optsLen;
                char** opts = CreateJvmOptions(cfg, homeFound ? &home : NULL, cp, &optsLen);

                envTarget = new SharedPointer<IgniteEnvironment>(env);

                SharedPointer<JniContext> ctx(
                    JniContext::Create(opts, optsLen, env.Get()->GetJniHandlers(envTarget), &jniErr));

                for (int i = 0; i < optsLen; i++)
                    ReleaseChars(*(opts + i));

                delete[] opts;

                if (!ctx.Get())
                {
                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                    failed = true;
                }

                // 5. Start Ignite.
                if (!failed)
                {
                    char* springCfgPath0 = CopyChars(cfg.springCfgPath);

                    if (!springCfgPath0)
                        springCfgPath0 = CopyChars(DFLT_CFG);

                    char* name0 = CopyChars(name);

                    interop::InteropUnpooledMemory mem(16);
                    interop::InteropOutputStream stream(&mem);
                    stream.WriteBool(false);
                    stream.Synchronize();

                    javaRef = ctx.Get()->IgnitionStart(springCfgPath0, name0, 2, mem.PointerLong(), &jniErr);

                    ReleaseChars(springCfgPath0);
                    ReleaseChars(name0);

                    if (!javaRef) {
                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                        failed = true;
                    }
                    else {
                        // 6. Ignite is started at this point.
                        env.Get()->Initialize(ctx);

                        started = true;
                    }
                }
            }
            else {
                *err = IgniteError(IgniteError::IGNITE_ERR_JVM_NO_CLASSPATH,
                    "Java classpath is empty (did you set IGNITE_HOME environment variable?)");

                failed = true;
            }
        }

        factoryLock.Leave();

        if (failed)
        {
            if (envTarget)
                delete envTarget;

            return Ignite();
        }
        else
        {
            IgniteImpl* impl = new IgniteImpl(env, javaRef);

            return Ignite(impl);
        }
    }

    Ignite Ignition::Get()
    {
        return Get(static_cast<const char*>(NULL));
    }

    Ignite Ignition::Get(IgniteError* err)
    {
        return Get(NULL, err);
    }

    Ignite Ignition::Get(const char* name)
    {
        IgniteError err;

        Ignite res = Get(name, &err);

        IgniteError::ThrowIfNeeded(err);

        return res;
    }

    Ignite Ignition::Get(const char* name, IgniteError* err)
    {
        Ignite res;

        factoryLock.Enter();

        if (started)
        {
            char* name0 = CopyChars(name);

            // 1. Create context for this operation.
            JniErrorInfo jniErr;

            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));

            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

            if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
            {
                // 2. Get environment pointer.
                long long ptr = ctx.Get()->IgnitionEnvironmentPointer(name0, &jniErr);

                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
                {
                    if (ptr != 0)
                    {
                        // 3. Obtain real environment for this instance.
                        JniHandlers* hnds = reinterpret_cast<JniHandlers*>(ptr);

                        SharedPointer<IgniteEnvironment>* env =
                            static_cast<SharedPointer<IgniteEnvironment>*>(hnds->target);

                        // 4. Get fresh node reference.
                        jobject ref = ctx.Get()->IgnitionInstance(name0, &jniErr);

                        if (err->GetCode() == IgniteError::IGNITE_SUCCESS) {
                            if (ref)
                            {
                                IgniteImpl* impl = new IgniteImpl(*env, ref);

                                res = Ignite(impl);
                            }
                            else
                                // Error: concurrent node stop.
                                *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                                    "Failed to get Ignite instance because it was stopped concurrently.");

                        }
                    }
                    else
                        // Error: no node with the given name.
                        *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                            "Failed to get Ignite instance because it is either not started yet or already stopped.");
                }
            }

            ReleaseChars(name0);
        }
        else
            // Error: no node with the given name.
            *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                "Failed to get Ignite instance because it is either not started yet or already stopped.");

        factoryLock.Leave();

        return res;
    }

    bool Ignition::Stop(const bool cancel)
    {
        return Stop(NULL, cancel);
    }

    bool Ignition::Stop(const bool cancel, IgniteError* err)
    {
        return Stop(NULL, cancel, err);
    }

    bool Ignition::Stop(const char* name, const bool cancel)
    {
        IgniteError err;

        bool res = Stop(name, cancel, &err);

        IgniteError::ThrowIfNeeded(err);

        return res;
    }

    bool Ignition::Stop(const char* name, const bool cancel, IgniteError* err)
    {
        bool res = false;

        factoryLock.Enter();

        if (started)
        {
            JniErrorInfo jniErr;

            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));

            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

            if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
            {
                char* name0 = CopyChars(name);

                bool res0 = ctx.Get()->IgnitionStop(name0, cancel, &jniErr);

                ReleaseChars(name0);

                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
                    res = res0;
            }
        }

        factoryLock.Leave();

        return res;
    }

    void Ignition::StopAll(const bool cancel)
    {
        IgniteError err;

        StopAll(cancel, &err);

        IgniteError::ThrowIfNeeded(err);
    }

    void Ignition::StopAll(const bool cancel, IgniteError* err)
    {
        factoryLock.Enter();

        if (started)
        {
            JniErrorInfo jniErr;

            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));

            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

            if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
            {
                ctx.Get()->IgnitionStopAll(cancel, &jniErr);

                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
            }
        }

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

#include <sstream>

#include <ignite/common/common.h>
#include <ignite/common/concurrent.h>
#include <ignite/common/exports.h>
#include <ignite/common/java.h>

#include "ignite/impl/ignite_environment.h"
#include "ignite/impl/ignite_impl.h"
#include "ignite/impl/utils.h"
#include "ignite/ignition.h"

using namespace ignite::common::concurrent;
using namespace ignite::common::java;
using namespace ignite::impl;
using namespace ignite::impl::utils;

namespace ignite
{
    /** Default configuration. */
    const char* DFLT_CFG = "config/default-config.xml";

    /** Whether JVM library is loaded to the process. */
    bool JVM_LIB_LOADED;

    /** Critical section for factory methods. */
    CriticalSection factoryLock;

    /** Flag indicating that at least one Ignite instance has started. */
    bool started = false;

    /**
     * Convert integer value to string.
     */
    std::string JvmMemoryString(const std::string& prefix, int32_t val)
    {
        std::ostringstream ss;
        ss << val;

        std::string valStr = ss.str();

        std::string res = std::string(prefix);
        res.append(valStr);
        res.append("m");

        return res;
    }

    /**
     * Create JVM options.
     *
     * @param cfg Configuration.
     * @param home Optional GG home.
     * @param cp Classpath.
     * @param opts Options.
     * @param optsLen Options length.
     * @return Options.
     */
    char** CreateJvmOptions(const IgniteConfiguration& cfg, const std::string* home, const std::string& cp, int* optsLen)
    {
        *optsLen = 3 + (home ? 1 : 0) + cfg.jvmOptsLen;
        char** opts = new char*[*optsLen];

        int idx = 0;

        // 1. Set classpath.
        std::string cpFull = std::string("-Djava.class.path=") + cp;

        *(opts + idx++) = CopyChars(cpFull.c_str());

        // 2. Set home.
        if (home) {
            std::string homeFull = std::string("-DIGNITE_HOME=") + *home;

            *(opts + idx++) = CopyChars(homeFull.c_str());
        }

        // 3. Set Xms, Xmx.
        std::string xmsStr = JvmMemoryString(std::string("-Xms"), cfg.jvmInitMem);
        std::string xmxStr = JvmMemoryString(std::string("-Xmx"), cfg.jvmMaxMem);

        *(opts + idx++) = CopyChars(xmsStr.c_str());
        *(opts + idx++) = CopyChars(xmxStr.c_str());

        // 4. Set the rest options.
        for (int i = 0; i < cfg.jvmOptsLen; i++) {
            char* optCopy = CopyChars(cfg.jvmOpts[i].opt);

            opts[idx++] = optCopy;
        }

        return opts;
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg)
    {
        return Start(cfg, static_cast<const char*>(NULL));
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg, IgniteError* err)
    {
        return Start(cfg, NULL, err);
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg, const char* name)
    {
        IgniteError err;

        Ignite res = Start(cfg, name, &err);

        IgniteError::ThrowIfNeeded(err);

        return res;
    }

    Ignite Ignition::Start(const IgniteConfiguration& cfg, const char* name, IgniteError* err)
    {
        bool failed = false;

        SharedPointer<IgniteEnvironment> env;
        SharedPointer<IgniteEnvironment>* envTarget = NULL;

        jobject javaRef = NULL;

        factoryLock.Enter();

        // 1. Load JVM library if needed.
        if (!JVM_LIB_LOADED)
        {
            bool jvmLibFound;
            std::string jvmLib;

            if (cfg.jvmLibPath)
            {
                std::string jvmLibPath = std::string(cfg.jvmLibPath);

                jvmLib = FindJvmLibrary(&jvmLibPath, &jvmLibFound);
            }
            else
                jvmLib = FindJvmLibrary(NULL, &jvmLibFound);

            if (!jvmLibFound)
            {
                *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_NOT_FOUND,
                    "JVM library is not found (did you set JAVA_HOME environment variable?)");

                failed = true;
            }
            else
                std::cout << "JVM LIB LOC: " << jvmLib << std::endl;

            if (!failed) {
                if (!LoadJvmLibrary(jvmLib))
                {
                    *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_LOAD_FAILED, "Failed to load JVM library.");

                    failed = true;
                }
            }

            JVM_LIB_LOADED = true;
        }

        if (!failed)
        {
            // 2. Resolve IGNITE_HOME.
            bool homeFound;
            std::string home;

            if (cfg.igniteHome)
            {
                std::string homePath = std::string(cfg.igniteHome);

                home = ResolveIgniteHome(&homePath, &homeFound);
            }
            else
                home = ResolveIgniteHome(NULL, &homeFound);

            std::cout << "IGNITE_HOME: " << home << std::endl;

            // 3. Create classpath.
            std::string cp;

            if (cfg.jvmClassPath)
            {
                std::string usrCp = cfg.jvmClassPath;

                cp = CreateIgniteClasspath(&usrCp, homeFound ? &home : NULL);
            }
            else
                cp = CreateIgniteClasspath(NULL, homeFound ? &home : NULL);

            if (!cp.empty())
            {
                std::cout << "CLASSPATH: " << cp << std::endl;

                // 4. Start JVM if needed.
                JniErrorInfo jniErr;

                env = SharedPointer<IgniteEnvironment>(new IgniteEnvironment());

                int optsLen;
                char** opts = CreateJvmOptions(cfg, homeFound ? &home : NULL, cp, &optsLen);

                for (int i = 0; i < optsLen; i++)
                {
                    std::cout << "OPTION: " << *(opts + i) << std::endl;
                }

                envTarget = new SharedPointer<IgniteEnvironment>(env);

                SharedPointer<JniContext> ctx(
                    JniContext::Create(opts, optsLen, env.Get()->GetJniHandlers(envTarget), &jniErr));

                for (int i = 0; i < optsLen; i++)
                    ReleaseChars(*(opts + i));

                delete[] opts;

                if (!ctx.Get())
                {
                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                    failed = true;
                }

                // 5. Start Ignite.
                if (!failed)
                {
                    char* springCfgPath0 = CopyChars(cfg.springCfgPath);

                    if (!springCfgPath0)
                        springCfgPath0 = CopyChars(DFLT_CFG);

                    char* name0 = CopyChars(name);

                    interop::InteropUnpooledMemory mem(16);
                    interop::InteropOutputStream stream(&mem);
                    stream.WriteBool(false);
                    stream.Synchronize();

                    javaRef = ctx.Get()->IgnitionStart(springCfgPath0, name0, 2, mem.PointerLong(), &jniErr);

                    ReleaseChars(springCfgPath0);
                    ReleaseChars(name0);

                    if (!javaRef) {
                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                        failed = true;
                    }
                    else {
                        // 6. Ignite is started at this point.
                        env.Get()->Initialize(ctx);

                        started = true;
                    }
                }
            }
            else {
                *err = IgniteError(IgniteError::IGNITE_ERR_JVM_NO_CLASSPATH,
                    "Java classpath is empty (did you set IGNITE_HOME environment variable?)");

                failed = true;
            }
        }

        factoryLock.Leave();

        if (failed)
        {
            if (envTarget)
                delete envTarget;

            return Ignite();
        }
        else
        {
            IgniteImpl* impl = new IgniteImpl(env, javaRef);

            return Ignite(impl);
        }
    }

    Ignite Ignition::Get()
    {
        return Get(static_cast<const char*>(NULL));
    }

    Ignite Ignition::Get(IgniteError* err)
    {
        return Get(NULL, err);
    }

    Ignite Ignition::Get(const char* name)
    {
        IgniteError err;

        Ignite res = Get(name, &err);

        IgniteError::ThrowIfNeeded(err);

        return res;
    }

    Ignite Ignition::Get(const char* name, IgniteError* err)
    {
        Ignite res;

        factoryLock.Enter();

        if (started)
        {
            char* name0 = CopyChars(name);

            // 1. Create context for this operation.
            JniErrorInfo jniErr;

            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));

            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

            if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
            {
                // 2. Get environment pointer.
                long long ptr = ctx.Get()->IgnitionEnvironmentPointer(name0, &jniErr);

                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
                {
                    if (ptr != 0)
                    {
                        // 3. Obtain real environment for this instance.
                        JniHandlers* hnds = reinterpret_cast<JniHandlers*>(ptr);

                        SharedPointer<IgniteEnvironment>* env =
                            static_cast<SharedPointer<IgniteEnvironment>*>(hnds->target);

                        // 4. Get fresh node reference.
                        jobject ref = ctx.Get()->IgnitionInstance(name0, &jniErr);

                        if (err->GetCode() == IgniteError::IGNITE_SUCCESS) {
                            if (ref)
                            {
                                IgniteImpl* impl = new IgniteImpl(*env, ref);

                                res = Ignite(impl);
                            }
                            else
                                // Error: concurrent node stop.
                                *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                                    "Failed to get Ignite instance because it was stopped concurrently.");

                        }
                    }
                    else
                        // Error: no node with the given name.
                        *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                            "Failed to get Ignite instance because it is either not started yet or already stopped.");
                }
            }

            ReleaseChars(name0);
        }
        else
            // Error: no node with the given name.
            *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                "Failed to get Ignite instance because it is either not started yet or already stopped.");

        factoryLock.Leave();

        return res;
    }

    bool Ignition::Stop(const bool cancel)
    {
        return Stop(NULL, cancel);
    }

    bool Ignition::Stop(const bool cancel, IgniteError* err)
    {
        return Stop(NULL, cancel, err);
    }

    bool Ignition::Stop(const char* name, const bool cancel)
    {
        IgniteError err;

        bool res = Stop(name, cancel, &err);

        IgniteError::ThrowIfNeeded(err);

        return res;
    }

    bool Ignition::Stop(const char* name, const bool cancel, IgniteError* err)
    {
        bool res = false;

        factoryLock.Enter();

        if (started)
        {
            JniErrorInfo jniErr;

            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));

            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

            if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
            {
                char* name0 = CopyChars(name);

                bool res0 = ctx.Get()->IgnitionStop(name0, cancel, &jniErr);

                ReleaseChars(name0);

                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

                if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
                    res = res0;
            }
        }

        factoryLock.Leave();

        return res;
    }

    void Ignition::StopAll(const bool cancel)
    {
        IgniteError err;

        StopAll(cancel, &err);

        IgniteError::ThrowIfNeeded(err);
    }

    void Ignition::StopAll(const bool cancel, IgniteError* err)
    {
        factoryLock.Enter();

        if (started)
        {
            JniErrorInfo jniErr;

            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));

            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);

            if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
            {
                ctx.Get()->IgnitionStopAll(cancel, &jniErr);

                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
            }
        }

        factoryLock.Leave();
    }
}
<|endoftext|>