text:
/*
 *  testPermittivitySensitivity.cpp
 *  Trogdor6
 *
 *  Created by Paul Hansen on 9/11/10.
 *  Copyright 2010 Stanford University. All rights reserved.
 *
 *  This file is covered by the MIT license.  See LICENSE.txt.
 */

#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TestPermittivitySensitivity

#include <boost/test/unit_test.hpp>

#include "TensorGridConstants.h"

#include <iomanip>

using namespace std;
using namespace RLE;
using namespace YeeUtilities;

Matrix3d sBigDot(const Matrix3<Vector3d> & lhs, const Vector3d & rhs)
{
    return Matrix3d(
        dot(lhs[0], rhs), dot(lhs[1], rhs), dot(lhs[2], rhs),
        dot(lhs[3], rhs), dot(lhs[4], rhs), dot(lhs[5], rhs),
        dot(lhs[6], rhs), dot(lhs[7], rhs), dot(lhs[8], rhs));
}

BOOST_AUTO_TEST_CASE( TestDiagonalSensitivity )
{
    const int WHATEVER = 0;
    DynamicRLE3<Precision::RationalFunction> WHO_CARES;
    TensorGridConstants tgc(WHATEVER, WHATEVER, WHO_CARES, Rect3i(0,0,0,0,0,0));

    vector<Precision::RationalFunction> materials;
    materials.push_back(Precision::RationalFunction(1.0));
    materials.push_back(Precision::RationalFunction(2.0));

    vector<DynamicRLE3<double> > fillFactors0(2, DynamicRLE3<double>(0,0,0)),
        fillFactors1(2, DynamicRLE3<double>(0,0,0));
    DynamicRLE3<double> orientations0(0,0,0), orientations1(0,0,0);
    vector<DynamicRLE3<double> > fillFactorSensitivities(2, DynamicRLE3<double>(0,0,0));
    DynamicRLE3<double> orientationSensitivities(0,0,0);

    fillFactors0[0].mark(0,0,0,0.75);
    fillFactors0[1].mark(0,0,0,0.25);
    fillFactors1[0].mark(0,0,0,0.76);
    fillFactors1[1].mark(0,0,0,0.24);

    orientations0.mark(0,0,0,0.5);
    orientations1.mark(0,0,0,0.6);

    fillFactorSensitivities[0].mark(0,0,0,0.01); // durr.  just to be sure.
    fillFactorSensitivities[1].mark(0,0,0,-0.01);

    orientationSensitivities.mark(0,0,0,0.1);

    Pointer<DynamicRLE3<Precision::RationalFunction> > dPermittivity =
        tgc.diagonalSensitivity(materials, fillFactors0,
        orientations0, fillFactorSensitivities, orientationSensitivities);

    Precision::RationalFunction xsi0 =
        tgc.diagonalElement(materials, fillFactors0,
        orientations0).at(0,0,0);
    Precision::RationalFunction xsi1 =
        tgc.diagonalElement(materials, fillFactors1,
        orientations1).at(0,0,0);
    Precision::RationalFunction dXsi = dPermittivity->at(0,0,0);

    if (0)
    {
        cerr << "Mat 1: " << xsi0 << "\nMat 2: " << xsi1 << "\n";
        cerr << "Deriv: " << dXsi << "\n";
        cerr << "DeltNum: " << xsi1.numerator()[0] - xsi0.numerator()[0] << "\n";
        cerr << "DerivNum: " << dXsi.numerator()[0] << "\n";
    }

    BOOST_CHECK(fabs(xsi1.numerator()[0] - xsi0.numerator()[0] -
        dXsi.numerator()[0]) < 0.001);
}


text:
#include <boost/test/unit_test.hpp>

#include <cpp-utils/preprocessor.h>

BOOST_AUTO_TEST_SUITE(Preprocessor_Tests)

// CPP_NARG

BOOST_AUTO_TEST_CASE(Preprocessor_NARGS_Simple)
{
  BOOST_CHECK_EQUAL(0, CPP_NARGS());
  BOOST_CHECK_EQUAL(1, CPP_NARGS(a));
  BOOST_CHECK_EQUAL(2, CPP_NARGS(a, b));
  BOOST_CHECK_EQUAL(12, CPP_NARGS(a, b, c, d, e, f, g, h, i, j, k, l));
}

BOOST_AUTO_TEST_CASE(Preprocessor_NARGS_Composed)
{
  BOOST_CHECK_EQUAL(2, CPP_NARGS(a, (b)));
  BOOST_CHECK_EQUAL(2, CPP_NARGS(a, (b, c)));
  BOOST_CHECK_EQUAL(1, CPP_NARGS((b, c)));
}

BOOST_AUTO_TEST_CASE(Preprocessor_NARGS_StringConstant)
{
  BOOST_CHECK_EQUAL("0", CPP_STRINGIFY(CPP_NARGS()));
  BOOST_CHECK_EQUAL("1", CPP_STRINGIFY(CPP_NARGS(a)));
  BOOST_CHECK_EQUAL("2", CPP_STRINGIFY(CPP_NARGS(a, b)));
  BOOST_CHECK_EQUAL("12", CPP_STRINGIFY(CPP_NARGS(a, b, c, d, e, f, g, h, i, j, k, l)));
}

BOOST_AUTO_TEST_CASE(Preprocessor_NARGS_Concat)
{
  BOOST_CHECK_EQUAL("x0x", CPP_STRINGIFY(CPP_CONCAT(x,CPP_NARGS(),x)));
  BOOST_CHECK_EQUAL("X1XX", CPP_STRINGIFY(CPP_CONCAT(X,CPP_NARGS(a),XX)));
  BOOST_CHECK_EQUAL("2AA", CPP_STRINGIFY(CPP_CONCAT(CPP_NARGS(a, b),AA)));
}

// CPP_VFUNC

#define SUM0() (0)
#define SUM1(x) (x)
#define SUM2(x,y) ((x) + (y))
#define SUM3(x,y,z) ((x) + (y) + (z))

int sum0() { return 0; }
int sum1(int x) { return x; }
int sum2(int x, int y) { return x + y; }
int sum3(int x, int y, int z) { return x + y + z; }

BOOST_AUTO_TEST_CASE(Preprocessor_VFUNC_MacroFunction)
{
#define SUM(...) CPP_VFUNC(SUM, __VA_ARGS__)
  BOOST_CHECK_EQUAL(6, SUM(1,2,3));

  int x = 3;
  BOOST_CHECK_EQUAL(6, SUM(1,2,x));
  BOOST_CHECK_EQUAL(6, SUM(x,2,1));

  //BOOST_CHECK_EQUAL(SUM(), 0);
#undef SUM
}

BOOST_AUTO_TEST_CASE(Preprocessor_VFUNC_CFunction)
{
#define SUM(...) CPP_VFUNC(sum, __VA_ARGS__)
  BOOST_CHECK_EQUAL(6, SUM(1,2,3));

  int x = 3;
  BOOST_CHECK_EQUAL(6, SUM(1,2,x));
  BOOST_CHECK_EQUAL(6, SUM(x,2,1));

  BOOST_CHECK_EQUAL(1, SUM(1));
  //BOOST_CHECK_EQUAL(SUM(), 0);
#undef SUM
}

// CPP_CONCAT

BOOST_AUTO_TEST_CASE(Preprocessor_CONCAT_Concat)
{
#define TEST_MACRO 42
  int xXx = 42;

  BOOST_CHECK_EQUAL(42, CPP_CONCAT(x,X,x));
  BOOST_CHECK_EQUAL(42, CPP_CONCAT(CPP_CONCAT(TEST,_),MACRO));
  BOOST_CHECK_EQUAL("xXx", CPP_STRINGIFY(CPP_CONCAT(CPP_CONCAT(x,X),x)));
  BOOST_CHECK_EQUAL("xXx", CPP_STRINGIFY(CPP_CONCAT(x,X,x)));

#undef TEST_MACRO
}

// CPP_STRINGIFY

BOOST_AUTO_TEST_CASE(Preprocessor_STRINGIFY_Concat)
{
  BOOST_CHECK_EQUAL("xXx", CPP_STRINGIFY(xXx));
  BOOST_CHECK_EQUAL("1+1", CPP_STRINGIFY(1+1));
  BOOST_CHECK_EQUAL("&1+1~~", CPP_STRINGIFY(&1+1~~));
  BOOST_CHECK_EQUAL("(1,1)", CPP_STRINGIFY((1,1)));
  BOOST_CHECK_EQUAL("(std::map<int,int>)", CPP_STRINGIFY((std::map<int,int>)));
}

// CPP_MACRO_BEGIN/END

BOOST_AUTO_TEST_CASE(Preprocessor_MACRO_BEGIN_END_SetVariable)
{
#define TEST_MACRO(x) CPP_MACRO_BEGIN int i = 42; x = i; CPP_MACRO_END

  int x;
  if (1)
	  TEST_MACRO(x);
  BOOST_CHECK_EQUAL(42, x);

#undef TEST_MACRO
}

BOOST_AUTO_TEST_SUITE_END()

ext: cpp


text:
#include <boost/scoped_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/pointer_cast.hpp>
#include <QPushButton>
#include <QLineEdit>
#include <QCheckBox>
#include <QButtonGroup>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "UISearchWidget.h"
#include "../BibleDatabase/TranslationManager.h"
#include "../BibleDatabase/CommandPerformSearch.h"
#include "../BibleDatabase/Translation.h"
#include "../BibleDatabase/TranslationIterator.h"
#include "QtConnectHelper.h"
#include "BackgroundWorker.h"

using namespace BibleStudyGui;
using namespace BibleDatabase;

UISearchWidget::UISearchWidget(boost::shared_ptr<const TranslationManager> translation_manager, QWidget* parent) :
    QWidget(parent),
    m_translation_manager(translation_manager),
    m_search_button(new QPushButton(tr("Search"))),
    m_search_input_field(new QLineEdit()),
    m_translation_selection_row(new QHBoxLayout),
    m_match_case_checkbox(new QCheckBox(tr("Match case"))),
    m_match_whole_word_checkbox(new QCheckBox(tr("Whole words")))
{
    QT_CONNECT(m_search_button, SIGNAL(clicked()), this, SLOT(perform_search()));
    QT_CONNECT(m_search_input_field, SIGNAL(returnPressed()), this, SLOT(perform_search()));

    m_match_case_checkbox->setChecked(true);
    m_match_whole_word_checkbox->setChecked(false);

    QVBoxLayout* search_options = new QVBoxLayout;
    search_options->addWidget(m_match_case_checkbox);
    search_options->addWidget(m_match_whole_word_checkbox);

    QHBoxLayout* search_field_row = new QHBoxLayout;
    search_field_row->addWidget(m_search_input_field);
    search_field_row->addWidget(m_search_button);
    search_field_row->addLayout(search_options);

    QVBoxLayout* layout = new QVBoxLayout;

    layout->addLayout(search_field_row);
    layout->addLayout(m_translation_selection_row);
    setLayout(layout);
}

void UISearchWidget::display_translation_check_boxes()
{
    for (TranslationIterator it = m_translation_manager->begin(); it != m_translation_manager->end(); ++it)
    {
        this->add_translation_check_box(*it);
    }

    m_translation_selection_row->addStretch(1);
}

void UISearchWidget::perform_search()
{
    if (!m_search_input_field->text().isEmpty())
    {
        emit search_started(m_search_input_field->text());

        std::vector<std::string> selected_translations;

        for (std::vector<QCheckBox*>::const_iterator it = m_translation_checkboxes.begin(); it != m_translation_checkboxes.end(); ++it)
        {
            if ((*it)->isChecked())
            {
                selected_translations.push_back((*it)->text().toStdString());
            }
        }

        int search_option = CaseSensitive;
        if (m_match_case_checkbox->checkState() == Qt::Unchecked)
        {
            search_option = CaseInsensitive;
        }

        if (m_match_whole_word_checkbox->checkState() == Qt::Checked)
        {
            search_option |= MatchWholeWord;
        }

        m_command_perform_search = boost::shared_ptr<ICommand>(new CommandPerformSearch(m_translation_manager, selected_translations, m_search_input_field->text().toStdString(), search_option));
        m_search_worker = boost::make_shared<BackgroundWorker>(m_command_perform_search);

        QT_CONNECT(m_search_worker.get(), SIGNAL(finished()), this, SLOT(search_worker_finished()));

        m_search_worker->start();
    }
}

void UISearchWidget::search_worker_finished()
{
    QT_DISCONNECT(m_search_worker.get(), SIGNAL(finished()), this, SLOT(search_worker_finished()));

    boost::shared_ptr<CommandPerformSearch> command_perform_search = boost::dynamic_pointer_cast<CommandPerformSearch>(m_command_perform_search);
    emit search_complete(command_perform_search->get_results());
}

void UISearchWidget::add_translation_check_box(boost::shared_ptr<const Translation> translation)
{
    QCheckBox* translation_check_box = new QCheckBox(translation->get_short_name().c_str());
    translation_check_box->setCheckState(Qt::Checked);
    m_translation_selection_row->addWidget(translation_check_box);
    m_translation_checkboxes.push_back(translation_check_box);
}

max_stars_repo_name: joshpeterson/BibleStudy

max_issues_repo_name: joshpeterson/BibleStudy

max_forks_repo_name: joshpeterson/BibleStudy


text:
#include "File.h"
#include <cstdio>
#include <boost/assert.hpp>
#include <unistd.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include<sys/stat.h>
using namespace ssxrver;
using namespace ssxrver::base::file;

WriteFile::WriteFile(std::string_view fileName)
    : fp_(fopen(fileName.data(), "ae")),
      writeLen_(0)
{
    int err = ferror(fp_);
    BOOST_ASSERT_MSG(err,"WriteFile error");
    setbuffer(fp_, buffer_, sizeof buffer_);
}
WriteFile::~WriteFile()
{
    flush();
    ::fclose(fp_);
}
void WriteFile::append(const char *log_, const size_t len)
{
    size_t n = 0;
    size_t remain = len;
    do
    {
        size_t x = this->write(log_ + n, remain);
        if (x == 0)
        {
            int err = ferror(fp_);
            if (err)
                fprintf(stderr, "WriteFile error");
            break;
        }

        n += x;
        remain = len - n;

    } while (remain > 0);

    writeLen_ += len;
}

ReadSmallFile::ReadSmallFile(std::string_view fileName)
:fd_(::open(fileName.data(), O_RDONLY | O_CLOEXEC)),
err_(0)
{
    buf_[0] = '\0';
    if (fd_ < 0)
    {
        err_ = errno;
    }
}

int ReadSmallFile::readToBuffer(ssize_t *size) //size传入传出参数,返回值是错误代码
{
    int err = err_;
    if(fd_ >= 0)
    {
        ssize_t n = ::pread(fd_,buf_, sizeof(buf_)-1,0);
        if(n >= 0)
        {
            if(size)
            {
                *size = static_cast<ssize_t>(n);
            }
            buf_[n] = '\0';
        }
        else
        {
            err = errno;
        }
    }
    return err;
}
//
//int ReadSmallFile::readToString(string &data){
//
//}

ReadSmallFile::~ReadSmallFile()
{
    if(fd_ >= 0){
        ::close(fd_);
    }
}

SendFileUtil::SendFileUtil(std::string_view fileName):
    inFd_(::open(fileName.data(), O_RDONLY | O_CLOEXEC)),
    offset_(0),
    err_(0) {
    if (inFd_ < 0)
    {
        err_ = errno;
    } else {
        struct stat statBuf{};
        fstat(inFd_,&statBuf);
        sendLen_ = static_cast<size_t>(statBuf.st_size);
    }
}

SendFileUtil::~SendFileUtil()
{
    if(inFd_ >= 0) {
//        LOG_DEBUG<< " close " <<inFd_;
        ::close(inFd_);
    }
}

SendFileUtil::SendFileUtil() : inFd_(-1),
offset_(0),
sendLen_(0),
err_(0) {
}

max_stars_repo_name: RandyLambert/WebServer

max_issues_repo_name: RandyLambert/WebServer

max_forks_repo_name: RandyLambert/WebServer


text:
/*
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <vector>
#include <string>
#include <cstdio>
#include <cmath> // FIXME: used by timer.h - should be included there

#include "oslexec_pvt.h"
#include "osoreader.h"

#include <boost/algorithm/string.hpp>

#include <OpenImageIO/strutil.h>
#include <OpenImageIO/dassert.h>
#include <OpenImageIO/timer.h>
#include <OpenImageIO/thread.h>
#include <OpenImageIO/filesystem.h>
#include <OpenImageIO/hash.h>

OSL_NAMESPACE_ENTER

namespace pvt {   // OSL::pvt

/// Custom subclass of OSOReader that provide callbacks that set all the
/// right fields in the ShaderMaster.
class OSOReaderToMaster : public OSOReader
{
public:
    OSOReaderToMaster (ShadingSystemImpl &shadingsys)
        : OSOReader (&shadingsys.errhandler()), m_shadingsys (shadingsys),
          m_master (new ShaderMaster (shadingsys)),
          m_reading_instruction(false), m_errors(false)
      { }
    virtual ~OSOReaderToMaster () { }
    virtual bool parse_file (const std::string &filename);
    virtual bool parse_memory (const std::string &oso);
    virtual void version (const char *specid, int major, int minor);
    virtual void shader (const char *shadertype, const char *name);
    virtual void symbol (SymType symtype, TypeSpec typespec, const char *name);
    virtual void symdefault (int def);
    virtual void symdefault (float def);
    virtual void symdefault (const char *def);
    virtual void parameter_done();
    virtual void hint (string_view hintstring);
    virtual void codemarker (const char *name);
    virtual void codeend ();
    virtual void instruction (int label, const char *opcode);
    virtual void instruction_arg (const char *name);
    virtual void instruction_jump (int target);
    virtual void instruction_end ();

    ShaderMaster::ref master () const { return m_master; }

    void add_param_default (float def, size_t offset, const Symbol& sym);
    void add_param_default (int def, size_t offset, const Symbol& sym);
    void add_param_default (const char *def, size_t offset, const Symbol& sym);

private:
    ShadingSystemImpl &m_shadingsys;  ///< Reference to the shading system
    ShaderMaster::ref m_master;       ///< Reference to our master
    size_t m_firstarg;                ///< First argument in current op
    size_t m_nargs;                   ///< Number of args so far in current op
    bool m_reading_instruction;       ///< Are we reading an op?
    ustring m_sourcefile;             ///< Current source file parsed
    int m_sourceline;                 ///< Current source code line parsed
    ustring m_codesection;            ///< Which entry point are the ops for?
    int m_codesym;                    ///< Which param is being initialized?
    int m_oso_major, m_oso_minor;     ///< oso file format version
    int m_sym_default_index;          ///< Next sym default value to fill in
    bool m_errors;                    ///< Did we hit any errors?
    typedef boost::unordered_map<ustring,int,ustringHash> UstringIntMap;
    UstringIntMap m_symmap;           ///< map sym name to index
};

bool
OSOReaderToMaster::parse_file (const std::string &filename)
{
    m_master->m_osofilename = filename;
    m_master->m_maincodebegin = 0;
    m_master->m_maincodeend = 0;
    m_codesection.clear ();
    m_codesym = -1;
    return OSOReader::parse_file (filename) && ! m_errors;
}

bool
OSOReaderToMaster::parse_memory (const std::string &oso)
{
    m_master->m_osofilename = "<none>";
    m_master->m_maincodebegin = 0;
    m_master->m_maincodeend = 0;
    m_codesection.clear ();
    m_codesym = -1;
    return OSOReader::parse_memory (oso) && ! m_errors;
}

void
OSOReaderToMaster::version (const char *specid, int major, int minor)
{
    m_oso_major = major;
    m_oso_minor = minor;
}

void
OSOReaderToMaster::shader (const char *shadertype, const char *name)
{
    m_master->m_shadername = name; //ustring(name);
    m_master->m_shadertype = shadertype_from_name (shadertype);
}

void
OSOReaderToMaster::symbol (SymType symtype, TypeSpec typespec, const char *name_)
{
    ustring name(name_);
    Symbol sym (name, typespec, symtype);
    TypeDesc t = typespec.simpletype();
    int nvals = t.aggregate * (t.is_unsized_array() ? 1 : t.numelements());
    if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
        // Skip structs for now, they're just placeholders
        if (typespec.is_structure()) {
        }
        else if (typespec.simpletype().basetype == TypeDesc::FLOAT) {
            sym.dataoffset ((int) m_master->m_fdefaults.size());
            expand (m_master->m_fdefaults, nvals);
        } else if (typespec.simpletype().basetype == TypeDesc::INT) {
            sym.dataoffset ((int) m_master->m_idefaults.size());
            expand (m_master->m_idefaults, nvals);
        } else if (typespec.simpletype().basetype == TypeDesc::STRING) {
            sym.dataoffset ((int) m_master->m_sdefaults.size());
            expand (m_master->m_sdefaults, nvals);
        } else if (typespec.is_closure_based()) {
            // Closures are pointers, so we allocate a string default taking
            // adventage of their default being NULL as well.
            sym.dataoffset ((int) m_master->m_sdefaults.size());
            expand (m_master->m_sdefaults, nvals);
        } else {
            ASSERT (0 && "unexpected type");
        }
    }
    if (sym.symtype() == SymTypeConst) {
        if (typespec.simpletype().basetype == TypeDesc::FLOAT) {
            sym.dataoffset ((int) m_master->m_fconsts.size());
            expand (m_master->m_fconsts, nvals);
        } else if (typespec.simpletype().basetype == TypeDesc::INT) {
            sym.dataoffset ((int) m_master->m_iconsts.size());
            expand (m_master->m_iconsts, nvals);
        } else if (typespec.simpletype().basetype == TypeDesc::STRING) {
            sym.dataoffset ((int) m_master->m_sconsts.size());
            expand (m_master->m_sconsts, nvals);
        } else {
            ASSERT (0 && "unexpected type");
        }
    }
#if 0
    // FIXME -- global_heap_offset is quite broken.  But also not necessary.
    // We made need to fix this later.
    if (sym.symtype() == SymTypeGlobal) {
        sym.dataoffset (m_shadingsys.global_heap_offset (sym.name()));
    }
#endif
    sym.lockgeom (m_shadingsys.lockgeom_default());
    m_master->m_symbols.push_back (sym);
    m_symmap[name] = int(m_master->m_symbols.size()) - 1;
    // Start the index at which we add specified defaults
    m_sym_default_index = 0;
}

void
OSOReaderToMaster::add_param_default (float def, size_t offset, const Symbol& sym)
{
  if (sym.typespec().is_unsized_array() && offset >= m_master->m_fdefaults.size())
      m_master->m_fdefaults.push_back(def);
  else
      m_master->m_fdefaults[offset] = def;
}

void
OSOReaderToMaster::add_param_default (int def, size_t offset, const Symbol& sym)
{
  if (sym.typespec().is_unsized_array() && offset >= m_master->m_idefaults.size())
      m_master->m_idefaults.push_back(def);
  else
      m_master->m_idefaults[offset] = def;
}

void
OSOReaderToMaster::add_param_default (const char *def, size_t offset, const Symbol& sym)
{
  if (sym.typespec().is_unsized_array() && offset >= m_master->m_sdefaults.size())
      m_master->m_sdefaults.push_back(ustring(def));
  else
      m_master->m_sdefaults[offset] = ustring(def);
}

void
OSOReaderToMaster::symdefault (int def)
{
    ASSERT (m_master->m_symbols.size() && "symdefault but no sym");
    Symbol &sym (m_master->m_symbols.back());
    size_t offset = sym.dataoffset() + m_sym_default_index;
    ++m_sym_default_index;

    if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
        if (sym.typespec().simpletype().basetype == TypeDesc::FLOAT)
            add_param_default ((float)def, offset, sym);
        else if (sym.typespec().simpletype().basetype == TypeDesc::INT)
            add_param_default (def, offset, sym);
        else {
            ASSERT (0 && "unexpected type");
        }
    } else if (sym.symtype() == SymTypeConst) {
        if (sym.typespec().simpletype().basetype == TypeDesc::FLOAT)
            m_master->m_fconsts[offset] = (float)def;
        else if (sym.typespec().simpletype().basetype == TypeDesc::INT)
            m_master->m_iconsts[offset] = def;
        else {
            ASSERT (0 && "unexpected type");
        }
    }
}

void
OSOReaderToMaster::symdefault (float def)
{
    ASSERT (m_master->m_symbols.size() && "symdefault but no sym");
    Symbol &sym (m_master->m_symbols.back());
    size_t offset = sym.dataoffset() + m_sym_default_index;
    ++m_sym_default_index;
    if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
        if (sym.typespec().simpletype().basetype == TypeDesc::FLOAT)
            add_param_default (def, offset, sym);
        else {
            ASSERT (0 && "unexpected type");
        }
    } else if (sym.symtype() == SymTypeConst) {
        if (sym.typespec().simpletype().basetype == TypeDesc::FLOAT)
            m_master->m_fconsts[offset] = def;
        else {
            ASSERTMSG (0, "unexpected type: %s (%s)",
                       sym.typespec().c_str(), sym.name().c_str());
        }
    }
}

void
OSOReaderToMaster::symdefault (const char *def)
{
    ASSERT (m_master->m_symbols.size() && "symdefault but no sym");
    Symbol &sym (m_master->m_symbols.back());
    size_t offset = sym.dataoffset() + m_sym_default_index;
    ++m_sym_default_index;
    if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
        if (sym.typespec().simpletype().basetype == TypeDesc::STRING)
            add_param_default (def, offset, sym);
        else {
            ASSERTMSG (0, "unexpected type: %s (%s)",
                       sym.typespec().c_str(), sym.name().c_str());
        }
    } else if (sym.symtype() == SymTypeConst) {
        if (sym.typespec().simpletype().basetype == TypeDesc::STRING)
            m_master->m_sconsts[offset] = ustring(def);
        else {
            ASSERTMSG (0, "unexpected type: %s (%s)",
                       sym.typespec().c_str(), sym.name().c_str());
        }
    }
}

void
OSOReaderToMaster::parameter_done ()
{
  ASSERT (m_master->m_symbols.size() && "parameter_done but no sym");
  Symbol &sym (m_master->m_symbols.back());

  // set length of unsized array parameters
  if (sym.symtype() == SymTypeParam && sym.typespec().is_unsized_array())
      sym.initializers (m_sym_default_index / sym.typespec().aggregate());
}

inline bool
starts_with (const std::string &source, const std::string &pattern)
{
    return ! strncmp (source.c_str(), pattern.c_str(), pattern.length());
}

// If the string 'source' begins with 'pattern', erase the pattern from
// the start of source and return true.  Otherwise, do not alter source
// and return false.
inline bool
extract_prefix (std::string &source, const std::string &pattern)
{
    if (starts_with (source, pattern)) {
        source.erase (0, pattern.length());
        return true;
    }
    return false;
}

// Return the prefix of source that doesn't contain any characters in
// 'stop', erase that prefix from source (up to and including the stop
// character.  Also, the returned string is trimmed of leading and trailing
// spaces if 'do_trim' is true.
static std::string
readuntil (std::string &source, const std::string &stop, bool do_trim=false)
{
    size_t e = source.find_first_of (stop);
    if (e == source.npos)
        return std::string ();
    std::string r (source, 0, e);
    source.erase (0, e == source.npos ? e : e+1);
    if (do_trim)
        boost::trim (r);
    return r;
}

void
OSOReaderToMaster::hint (string_view hintstring)
{
    std::string h (hintstring);   // FIXME -- use string_view ops here
    if (extract_prefix (h, "%filename{\"")) {
        m_sourcefile = readuntil (h, "\"");
        return;
    }
    if (extract_prefix (h, "%line{")) {
        m_sourceline = atoi (h.c_str());
        return;
    }
    if (extract_prefix (h, "%structfields{")) {
        ASSERT (m_master->m_symbols.size() && "structfields hint but no sym");
        Symbol &sym (m_master->m_symbols.back());
        StructSpec *structspec = sym.typespec().structspec();
        if (structspec->numfields() == 0) {
            while (1) {
                std::string afield = readuntil (h, ",}", true);
                if (! afield.length())
                    break;
//                std::cerr << " struct field " << afield << "\n";
                structspec->add_field (TypeSpec(), ustring(afield));
            }
        }
        return;
    }
    if (extract_prefix (h, "%mystructfield{")) {
        ASSERT (m_master->m_symbols.size() && "mystructfield hint but no sym");
        Symbol &sym (m_master->m_symbols.back());
        sym.fieldid (atoi(h.c_str()+15));
        return;
    }
    if (extract_prefix (h, "%read{")) {
        ASSERT (m_master->m_symbols.size() && "read hint but no sym");
        Symbol &sym (m_master->m_symbols.back());
        int first, last;
        sscanf (h.c_str(), "%d,%d", &first, &last);
        sym.set_read (first, last);
        return;
    }
    if (extract_prefix (h, "%write{")) {
        ASSERT (m_master->m_symbols.size() && "write hint but no sym");
        Symbol &sym (m_master->m_symbols.back());
        int first, last;
        sscanf (h.c_str(), "%d,%d", &first, &last);
        sym.set_write (first, last);
        return;
    }
    if (extract_prefix(h, "%argrw{")) {
        const char* str = h.c_str();
        ASSERT(*str == '\"');
        str++; // skip open quote
        size_t i = 0;
        for (; *str != '\"'; i++, str++) {
            ASSERT(*str == 'r' || *str == 'w' || *str == 'W' || *str == '-');
            m_master->m_ops.back().argwrite(i, *str == 'w' || *str =='W');
            m_master->m_ops.back().argread(i, *str == 'r' || *str =='W');
        }
        ASSERT(m_nargs == i);
    }
    if (extract_prefix(h, "%argderivs{")) {
        while (1) {
            std::string afield = readuntil (h, ",}", true);
            if (! afield.length())
                break;
            int arg = atoi (afield.c_str());
            if (arg >= 0)
                m_master->m_ops.back().argtakesderivs (arg, true);
        }
    }
    if (extract_prefix (h, "%meta{") && m_master->m_symbols.size()) {
        Symbol &sym (m_master->m_symbols.back());
        int lockval = -1;
        int ok = sscanf (h.c_str(), " int , lockgeom , %d", &lockval);
        if (ok)
            sym.lockgeom (lockval);
    }
}

void
OSOReaderToMaster::codemarker (const char *name)
{
    m_sourcefile.clear();
    int nextop = (int) m_master->m_ops.size();

    codeend ();   // Mark the end spot, if we were parsing ops before

    m_codesection = ustring (name);
    m_codesym = m_master->findsymbol (m_codesection);
    if (m_codesym >= 0)
        m_master->symbol(m_codesym)->initbegin (nextop);
#if 0
    std::cerr << "Read code marker " << m_codesection
              << " at instruction " << nextop
              << ", sym " << m_codesym
              << " (" << (m_codesym >= 0 ? m_master->symbol(m_codesym)->name() : ustring()) << ")"
              << "\n";
#endif
    if (m_codesection == "___main___") {
        m_master->m_maincodebegin = nextop;
    } else if (m_codesym < 0) {
        m_shadingsys.error ("Parsing shader %s: don't know what to do with code section \"%s\"",
                            m_master->shadername().c_str(), name);
        m_errors = true;
    }
}

void
OSOReaderToMaster::codeend ()
{
    int nextop = (int) m_master->m_ops.size();
    if (m_codesym >= 0) {
        // If we were previously chalking up the code to init ops for a
        // symbol, mark the end.
        m_master->symbol(m_codesym)->initend (nextop);
    } else if (m_codesection && m_codesection == "___main___") {
        // If we were previously reading ops for the ___main___ entry
        // point, mark its end properly.
        m_master->m_maincodeend = nextop;
    }
}

void
OSOReaderToMaster::instruction (int label, const char *opcode)
{
    ustring uopcode (opcode);
    Opcode op (uopcode, m_codesection);
    m_master->m_ops.push_back (op);
    m_firstarg = m_master->m_args.size();
    m_nargs = 0;
    m_reading_instruction = true;
    const OpDescriptor *od = m_shadingsys.op_descriptor (uopcode);
    if (od) {
        // Replace the name in case it was aliased for compatibility
        uopcode = od->name;
    } else {
        m_shadingsys.error ("Parsing shader \"%s\": instruction \"%s\" is not known. Maybe compiled with a too-new oslc?",
                            m_master->shadername().c_str(), opcode);
        m_errors = true;
    }
}

void
OSOReaderToMaster::instruction_arg (const char *name)
{
    ustring argname (name);
    UstringIntMap::const_iterator found = m_symmap.find (argname);
    if (found != m_symmap.end()) {
        m_master->m_args.push_back (found->second);
        ++m_nargs;
        return;
    }
    m_shadingsys.error ("Parsing shader %s: unknown arg %s",
                        m_master->shadername().c_str(), name);
    m_errors = true;
}

void
OSOReaderToMaster::instruction_jump (int target)
{
    m_master->m_ops.back().add_jump (target);
}

void
OSOReaderToMaster::instruction_end ()
{
    m_master->m_ops.back().set_args (m_firstarg, m_nargs);
    m_master->m_ops.back().source (m_sourcefile, m_sourceline);
    m_reading_instruction = false;
}

ShaderMaster::ref
ShadingSystemImpl::loadshader (string_view cname)
{
    if (! cname.size()) {
        error ("Attempt to load shader with empty name \"\".");
        return NULL;
    }
    ++m_stat_shaders_requested;
    ustring name (cname);
    lock_guard guard (m_mutex);  // Thread safety
    ShaderNameMap::const_iterator found = m_shader_masters.find (name);
    if (found != m_shader_masters.end()) {
        // if (debug())
        //     info ("Found %s in shader_masters", name.c_str());
        // Already loaded this shader, return its reference
        return (*found).second;
    }

    // Not found in the map
    OSOReaderToMaster oso (*this);
    std::string filename = OIIO::Filesystem::searchpath_find (name.string() + ".oso",
                                                        m_searchpath_dirs);
    if (filename.empty ()) {
        error ("No .oso file could be found for shader \"%s\"", name.c_str());
        return NULL;
    }
    OIIO::Timer timer;
    bool ok = oso.parse_file (filename);
    ShaderMaster::ref r = ok ? oso.master() : NULL;
    m_shader_masters[name] = r;
    double loadtime = timer();
    {
        spin_lock lock (m_stat_mutex);
        m_stat_master_load_time += loadtime;
    }
    if (ok) {
        ++m_stat_shaders_loaded;
        info ("Loaded \"%s\" (took %s)", filename.c_str(),
              Strutil::timeintervalformat(loadtime, 2).c_str());
        ASSERT (r);
        r->resolve_syms ();
        // if (debug()) {
        //     std::string s = r->print ();
        //     if (s.length())
        //         info ("%s", s.c_str());
        // }
    } else {
        error ("Unable to read \"%s\"", filename.c_str());
    }

    return r;
}

bool
ShadingSystemImpl::LoadMemoryCompiledShader (string_view shadername,
                                             string_view buffer)
{
    if (! shadername.size()) {
        error ("Attempt to load shader with empty name \"\".");
        return false;
    }
    if (! buffer.size()) {
        error ("Attempt to load shader \"%s\" with empty OSO data.", shadername);
        return false;
    }

    ustring name (shadername);
    lock_guard guard (m_mutex);  // Thread safety
    ShaderNameMap::const_iterator found = m_shader_masters.find (name);
    if (found != m_shader_masters.end()) {
        if (debug())
            info ("Preload shader %s already exists in shader_masters", name.c_str());
        return false;
    }

    // Not found in the map
    OSOReaderToMaster reader (*this);
    OIIO::Timer timer;
    bool ok = reader.parse_memory (buffer);
    ShaderMaster::ref r = ok ? reader.master() : NULL;
    m_shader_masters[name] = r;
    double loadtime = timer();
    {
        spin_lock lock (m_stat_mutex);
        m_stat_master_load_time += loadtime;
    }
    if (ok) {
        ++m_stat_shaders_loaded;
        info ("Loaded \"%s\" (took %s)", shadername,
              Strutil::timeintervalformat(loadtime, 2).c_str());
        ASSERT (r);
        r->resolve_syms ();
        // if (debug()) {
        //     std::string s = r->print ();
        //     if (s.length())
        //         info ("%s", s.c_str());
        // }
    } else {
        error ("Unable to parse preloaded shader \"%s\"", shadername);
    }

    return true;
}

}; // namespace pvt
OSL_NAMESPACE_EXIT

max_stars_repo_name: LumaPictures/OpenShadingLanguage

max_issues_repo_name: johnhaddon/OpenShadingLanguage

max_forks_repo_name: johnhaddon/OpenShadingLanguage


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2013-2017 The Anoncoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// Many builder specific things set in the config file, ENABLE_WALLET is a good example.  Don't forget to include it this way in your source files.
#if defined(HAVE_CONFIG_H)
#include "config/anoncoin-config.h"
#endif

#include "miner.h"

#include <string>

#include "amount.h"
#include "block.h"
#include "chainparams.h"
#include "hash.h"
#include "main.h"
#include "net.h"
#include "pow.h"
#include "scrypt.h"
#include "sync.h"
#include "timedata.h"
#include "transaction.h"
#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif

#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/unordered_map.hpp>

//! Used to initialize the scrypt mining hash buffers
#include <openssl/sha.h>

using namespace std;

uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0;

//////////////////////////////////////////////////////////////////////////////
//
// AnoncoinMiner
//

//
// Unconfirmed transactions in the memory pool often depend on other
// transactions in the memory pool. When we select transactions from the
// pool, we select by highest priority or fee rate, so we might consider
// transactions that depend on transactions that aren't yet in the block.
// The COrphan class keeps track of these 'temporary orphans' while
// CreateBlock is figuring out which transactions to include.
//
class COrphan
{
public:
    const CTransaction* ptx;
    set<uint256> setDependsOn;
    CFeeRate feeRate;
    double dPriority;

    COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
    {
    }

    void print() const
    {
        LogPrintf("COrphan(hash=%s, dPriority=%.1f, FeePerKb=%d)\n",
               ptx->GetHash().ToString(), dPriority, feeRate.GetFeePerK());
        BOOST_FOREACH(uint256 hash, setDependsOn)
            LogPrintf("   setDependsOn %s\n", hash.ToString());
    }
};

// We want to sort transactions by priority and fee rate, so:
typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
class TxPriorityCompare
{
    bool byFee;

public:
    TxPriorityCompare(bool _byFee) : byFee(_byFee) { }

    bool operator()(const TxPriority& a, const TxPriority& b)
    {
        if (byFee)
        {
            if (a.get<1>() == b.get<1>())
                return a.get<0>() < b.get<0>();
            return a.get<1>() < b.get<1>();
        }
        else
        {
            if (a.get<0>() == b.get<0>())
                return a.get<1>() < b.get<1>();
            return a.get<0>() < b.get<0>();
        }
    }
};

void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
{
    pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
}

CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
{
    // Create new block
    auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
    if(!pblocktemplate.get())
        return NULL;
    CBlock *pblock = &pblocktemplate->block; // pointer for convenience

    // -regtest only: allow overriding block.nVersion with
    // -blockversion=N to test forking scenarios
    //if (Params().MineBlocksOnDemand())
    if( RegTest() )
        pblock->nVersion = GetArg("-blockversion", pblock->nVersion);

    // Create coinbase tx
    CMutableTransaction txNew;
    txNew.vin.resize(1);
    txNew.vin[0].prevout.SetNull();
    txNew.vout.resize(1);
    txNew.vout[0].scriptPubKey = scriptPubKeyIn;

    // Add dummy coinbase tx as first transaction
    pblock->vtx.push_back(CTransaction());
    pblocktemplate->vTxFees.push_back(-1); // updated at end
    pblocktemplate->vTxSigOps.push_back(-1); // updated at end

    // Largest block you're willing to create:
    unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
    // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
    nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));

    // How much of the block should be dedicated to high-priority transactions,
    // included regardless of the fees they pay
    unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
    nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);

    // Minimum block size you want to create; block will be filled with free transactions
    // until there are no more or the block reaches this size:
    unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
    nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);

    // Collect memory pool transactions into the block
    CAmount nFees = 0;

    {
        LOCK2(cs_main, mempool.cs);
        CBlockIndex* pindexPrev = chainActive.Tip();
        const int nHeight = pindexPrev->nHeight + 1;
        CCoinsViewCache view(pcoinsTip);                    // Create an empty coin cache view, based on the main pcoinsTip cache

        // Priority order to process transactions
        list<COrphan> vOrphan; // list memory doesn't move
        map<uint256, vector<COrphan*> > mapDependers;
        bool fPrintPriority = GetBoolArg("-printpriority", false);

        // This vector will be sorted into a priority queue:
        vector<TxPriority> vecPriority;
        vecPriority.reserve(mempool.mapTx.size());
        for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin();
             mi != mempool.mapTx.end(); ++mi)
        {
            const CTransaction& tx = mi->second.GetTx();
            if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight))
                continue;

            COrphan* porphan = NULL;
            double dPriority = 0;
            CAmount nTotalIn = 0;
            bool fMissingInputs = false;
            BOOST_FOREACH(const CTxIn& txin, tx.vin)
            {
                // Read prev transaction
                if (!view.HaveCoins(txin.prevout.hash))
                {
                    // This should never happen; all transactions in the memory
                    // pool should connect to either transactions in the chain
                    // or other transactions in the memory pool.
                    if (!mempool.mapTx.count(txin.prevout.hash))
                    {
                        LogPrintf("ERROR: mempool transaction missing input\n");
                        if (fDebug) assert("mempool transaction missing input" == 0);
                        fMissingInputs = true;
                        if (porphan)
                            vOrphan.pop_back();
                        break;
                    }

                    // Has to wait for dependencies
                    if (!porphan)
                    {
                        // Use list for automatic deletion
                        vOrphan.push_back(COrphan(&tx));
                        porphan = &vOrphan.back();
                    }
                    mapDependers[txin.prevout.hash].push_back(porphan);
                    porphan->setDependsOn.insert(txin.prevout.hash);
                    nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue;
                    continue;
                }
                const CCoins* coins = view.AccessCoins(txin.prevout.hash);
                assert(coins);

                CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
                nTotalIn += nValueIn;

                int nConf = nHeight - coins->nHeight;

                dPriority += (double)nValueIn * nConf;
            }
            if (fMissingInputs) continue;

            // Priority is sum(valuein * age) / modified_txsize
            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
            dPriority = tx.ComputePriority(dPriority, nTxSize);

            uint256 hash = tx.GetHash();
            mempool.ApplyDeltas(hash, dPriority, nTotalIn);

            CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);

            if (porphan)
            {
                porphan->dPriority = dPriority;
                porphan->feeRate = feeRate;
            }
            else
                vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx()));
        }

        // Collect transactions into block
        uint64_t nBlockSize = 1000;
        uint64_t nBlockTx = 0;
        int nBlockSigOps = 100;
        bool fSortedByFee = (nBlockPrioritySize <= 0);

        TxPriorityCompare comparer(fSortedByFee);
        std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);

        while (!vecPriority.empty())
        {
            // Take highest priority transaction off the priority queue:
            double dPriority = vecPriority.front().get<0>();
            CFeeRate feeRate = vecPriority.front().get<1>();
            const CTransaction& tx = *(vecPriority.front().get<2>());

            std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
            vecPriority.pop_back();

            // Size limits
            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
            if (nBlockSize + nTxSize >= nBlockMaxSize)
                continue;

            // Legacy limits on sigOps:
            unsigned int nTxSigOps = GetLegacySigOpCount(tx);
            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
                continue;

            // Skip free transactions if we're past the minimum block size:
            const uint256& hash = tx.GetHash();
            double dPriorityDelta = 0;
            CAmount nFeeDelta = 0;
            mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
            if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
                continue;

            // Prioritise by fee once past the priority size or we run out of high-priority
            // transactions:
            if (!fSortedByFee &&
                ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
            {
                fSortedByFee = true;
                comparer = TxPriorityCompare(fSortedByFee);
                std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
            }

            if (!view.HaveInputs(tx))
                continue;

            CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut();

            nTxSigOps += GetP2SHSigOpCount(tx, view);
            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
                continue;

            // Note that flags: we don't want to set mempool/IsStandard()
            // policy here, but we still have to ensure that the block we
            // create only contains transactions that are valid in new blocks.
            CValidationState state;
            if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH, true))
                continue;

            UpdateCoins(tx, state, view, nHeight);

            // Added
            pblock->vtx.push_back(tx);
            pblocktemplate->vTxFees.push_back(nTxFees);
            pblocktemplate->vTxSigOps.push_back(nTxSigOps);
            nBlockSize += nTxSize;
            ++nBlockTx;
            nBlockSigOps += nTxSigOps;
            nFees += nTxFees;

            if (fPrintPriority)
            {
                LogPrintf("priority %.1f fee %s txid %s\n",
                    dPriority, feeRate.ToString(), tx.GetHash().ToString());
            }

            // Add transactions that depend on this one to the priority queue
            if (mapDependers.count(hash))
            {
                BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
                {
                    if (!porphan->setDependsOn.empty())
                    {
                        porphan->setDependsOn.erase(hash);
                        if (porphan->setDependsOn.empty())
                        {
                            vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
                            std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
                        }
                    }
                }
            }
        }

        nLastBlockTx = nBlockTx;
        nLastBlockSize = nBlockSize;
        //LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize);

        // Compute final coinbase transaction.
        txNew.vout[0].nValue = ancConsensus.GetBlockValue(nHeight, nFees);
        txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
        pblock->vtx[0] = txNew;
        pblocktemplate->vTxFees[0] = -nFees;

        // Fill in header
        // Make sure it places the sha256d hash of the previous block into this new one.
        pblock->hashPrevBlock  = pindexPrev->GetBlockSha256dHash();
        UpdateTime(pblock, pindexPrev);
        pblock->nBits          = ancConsensus.GetNextWorkRequired(pindexPrev, pblock);
        pblock->nNonce         = 0;
        pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);

        if (nHeight >= ancConsensus.nDifficultySwitchHeight6)
        {
            pblock->nVersion = 3;
        } else {
            pblock->nVersion = 2;
        }
        // Always set height locally
        pblock->nHeight = nHeight;

        //! Force both hash calculations to be updated before validity testing the block
        assert( pblock->GetHash() != uint256(0) );
        assert( pblock->CalcSha256dHash() != uintFakeHash(0) );
        assert( pblock->GetGost3411Hash() != uint256(0) );
        CValidationState state;
        if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
            throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed");
    }

    return pblocktemplate.release();
}

void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{
    // Update nExtraNonce
    static uintFakeHash hashPrevBlock;
    if (hashPrevBlock != pblock->hashPrevBlock)
    {
        nExtraNonce = 0;
        hashPrevBlock = pblock->hashPrevBlock;
    }
    ++nExtraNonce;
    unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2
    CMutableTransaction txCoinbase(pblock->vtx[0]);
    txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
    assert(txCoinbase.vin[0].scriptSig.size() <= 100);

    pblock->vtx[0] = txCoinbase;
    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
}

//#ifdef ENABLE_WALLET
//////////////////////////////////////////////////////////////////////////////
//
// Internal miner
//
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
{
    CPubKey pubkey;
    if (!reservekey.GetReservedKey(pubkey))
        return NULL;

    CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
    return CreateNewBlock(scriptPubKey);
}

bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
    LogPrintf("%s\n", pblock->ToString());
    LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));

    // Found a solution
    {
        LOCK(cs_main);
        if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockSha256dHash() )
            return error("AnoncoinMiner : generated block is stale");
    }

    // Remove key from key pool
    reservekey.KeepKey();

    // Track how many getdata requests this block gets
    {
        LOCK(wallet.cs_wallet);
        wallet.mapRequestCount[pblock->CalcSha256dHash()] = 0;
    }

    // Process this block the same as if we had received it from another node
    CValidationState state;
    if (!ProcessNewBlock(state, NULL, pblock))
        return error("AnoncoinMiner : ProcessNewBlock, block not accepted");

    return true;
}

class CHashMeter
{
private:
    const uint8_t nMinerID;     //! The ID is likely the same value as the thread number which started this hash meter
    const int64_t nSlowRunTime; //! This constant defines how long (in ms) before a logging event needs to be produced.
    int64_t nMinerStartTime;    //! in Seconds, the time for which this miner thread 1st started.
    int64_t nFastStartTime;     //! in milliSeconds, the time we started this last integration period
    int64_t nSlowStartTime;     //! in milliSeconds, the time we last logged our results
    uint64_t nFastCounter;      //! Hash count over one integration period (10sec)
    uint64_t nSlowCounter;      //! Cumulative hash count since this miner last reported a logging request
    uint64_t nCumulative;       //! Cumulative hash count since this miner was running
    double dFastKHPS;           //! The last computed Hash rate sample, in Kilo Hashes Per Second.
    double dSlowKHPS;           //! The computed Hash rate for one logging period.

public:
    //! Multithread miners will start out with a log result time one second longer than the previous thread.
    //! We want to avoid them hitting the log at exactly the same moment, and preferably in order, this is
    //! not likely, but an experiment.  Calculating the nSlowRunTime constant now and storing it saves doing
    //! that each time the UpdateAccumulations() is run, easy to change here and for speed.
    CHashMeter( const uint8_t nID ) : nMinerID(nID), nSlowRunTime( ( 10 * 60 + (int64_t)nID ) * 1000 )
    {
        int64_t nTimeNow = GetTimeMillis();

        nMinerStartTime = (nTimeNow + 500) / 1000;  //! Nearest second, with rounding
        nFastStartTime = nSlowStartTime = nTimeNow;
        nFastCounter = nSlowCounter = nCumulative = 0;
        dFastKHPS = dSlowKHPS = 0.0;
    }
    ~CHashMeter() {}

    //! Adds newly hashed counts to the primary accumulator only and starts returning true if it wants the short term result updated and logged.
    bool UpdateFastCounter( const uint16_t nHashesDone )
    {
        nFastCounter += (uint64_t)nHashesDone;
        return GetTimeMillis() - nFastStartTime > 10000;
    }

    //! Updates the longer term counters, short term measurement calculation & resets its counter and start time.
    //! Returns true if the longer mid term log entry should be updated.
    bool UpdateAccumulations()
    {
        int64_t nTimeNow = GetTimeMillis();

        nSlowCounter += nFastCounter;
        nCumulative += nFastCounter;
        dFastKHPS = (double)nFastCounter / (double)(nTimeNow - nFastStartTime);
        nFastCounter = 0;
        nFastStartTime = nTimeNow;

        //! After 10 minutes plus 1 sec x the nID, we start asking for a logging event
        return nTimeNow - nSlowStartTime > nSlowRunTime;
    }

    //! Updates the mid term (logged) measurement calculation, resets its counter and start time, then returns with the calculation in Hashes per second.
    double RestartSlowCounter()
    {
        int64_t nTimeNow = GetTimeMillis();
        int64_t nMilliSecs = nTimeNow - nSlowStartTime;

        dSlowKHPS = (double)nSlowCounter / (double)nMilliSecs;
        nSlowCounter = 0;
        nSlowStartTime = nTimeNow;

        return dSlowKHPS;
    }
    uint8_t GetMinerID() const { return nMinerID; }
    int64_t GetStartTime() const { return nMinerStartTime; }
    double GetFastKHPS() const { return dFastKHPS; }
    double GetSlowKHPS() const { return dSlowKHPS; }
    //! The total work performed so far on this miner thread can be gotten several ways, this method simply returns the total number of hashes the thread has calculated.
    uint64_t GetCumulativeHashes() const { return nCumulative; }
    //! This next one is a little more complicated, likely this is called by some routine that cares we return the correct value for time.
    //! As it marches on, this sample could have been made in the distant past, aka placed in one of the mru storage sets long ago.  So we
    //! make sure the accumulated hashes do not get added to, unless the HPSCounter was just zeroed, and most importantly to this next
    //! method,  the nFastStartTime was set to the ending time for the accumulation!
    int64_t GetCumulativeSecs() const { return ( (nFastStartTime + 500) / 1000 ) - nMinerStartTime; }
    //! Returns the Hashes per Second for the total time this hash meter has been running (within 10sec)
    double GetCumulativeHPS() const { return (double)nCumulative / (double)GetCumulativeSecs(); }

    //! Needed for inclusion in an mru set...
    friend bool operator<(const CHashMeter& a, const CHashMeter& b)
    {
        return a.nMinerID < b.nMinerID || (a.nMinerID == b.nMinerID && a.nFastStartTime < b.nFastStartTime) ||
               (a.nMinerID == b.nMinerID && a.nFastStartTime == b.nFastStartTime && a.nSlowStartTime < b.nSlowStartTime);
    }
};

static uint8_t nLastRunThreadCount = 0;
static int64_t nMiningStoppedTime = 0;

//! Global values protected by the cs_hashmeter condition variable...
static CCriticalSection cs_hashmeter;
static uint8_t nMinerThreadsRunning = 0;
//! Initialization here only requires a few bytes, actual storage maximum size will be set when the miner(s) start running.
//! We only keep ~ the last 10mins worth of 10sec short term data and ~1 days worth of 10min, these sizes will be defined
//! depending on how many threads the user wants started.
static mruset<CHashMeter> mruFastReadings(60);
static mruset<CHashMeter> mruSlowReadings(144);

typedef pair<uint16_t,double> MeterSum;
typedef boost::unordered_map<uint8_t,MeterSum> MeterMap;

static void UpdateMeterMap( uint8_t nMinerID, double dMinerKHPS, MeterMap& mapMeterSums )
{
    MeterMap::iterator it = mapMeterSums.find(nMinerID);
    if( it == mapMeterSums.end() ) {
        MeterSum newMiner;
        newMiner.first = 1;
        newMiner.second = dMinerKHPS;
        mapMeterSums[nMinerID] = newMiner;
    } else {
        (*it).second.first++;
        (*it).second.second += dMinerKHPS;
    }
}

bool GetHashMeterStats( HashMeterStats& HashMeterState )
{
    bool fResultsProduced = false;
    uint8_t nAttempts = 0; //! If lock fails, its no big deal, we'll try again for at least a couple of seconds...
    int64_t nTimeNow = GetTime();

    HashMeterState.nIDsReporting = 0;
    HashMeterState.nFastCount = HashMeterState.nSlowCount = 0;
    HashMeterState.nEarliestStartTime = nTimeNow;
    HashMeterState.nMiningStoppedTime = nMiningStoppedTime;
    HashMeterState.nRunTime = HashMeterState.nCumulativeTime = HashMeterState.nCumulativeHashes = 0;
    HashMeterState.dFastKHPS = HashMeterState.dSlowKHPS = HashMeterState.dCumulativeMHPH = 0.0;
    do {
        TRY_LOCK(cs_hashmeter, lockedmeter);
        if( lockedmeter ) {
            //! If no miners are running, we still may have results from the past stored in the longer term dataset
            //! Determine if we have some meter readings to analyze...
            HashMeterState.nFastCount = mruFastReadings.size();
            HashMeterState.nSlowCount = mruSlowReadings.size();
            //! If there are no meter readings, we are also done...
            if( HashMeterState.nFastCount || HashMeterState.nSlowCount ) {
                //! For each of the slow and fast mruReadings, we must now total the counts and hashes found from each and every miner thread separately.
                //! It requires us to keep track of that, as we go through all the mru datapoints, and gets kinda complicated to explain.  See the
                //! UpdateMeterMap() helper function that figures out if the miner ID is already in the MeterMap, or needs to be added, takes care of both.
                if( HashMeterState.nFastCount ) {
                    MeterMap mapMiner;
                    for( mruset<CHashMeter>::const_iterator it = mruFastReadings.begin(); it != mruFastReadings.end(); ++it )
                        UpdateMeterMap( (*it).GetMinerID(), (*it).GetFastKHPS(), mapMiner );
                    //! Finally we can go through each of the miner IDs that reported results and
                    //! add the averaged KHPS from each to the hash meter states final result.
                    for( MeterMap::const_iterator it = mapMiner.begin(); it != mapMiner.end(); ++it )
                        HashMeterState.dFastKHPS += (*it).second.second / (double)(*it).second.first;
                }
                //! Finally we handle the processing of the longer term 10 minute samples and calculate the final
                //! KHPS from the average we've seen in the same fashion we did for the fast mru.
                if( HashMeterState.nSlowCount ) {
                    MeterMap mapMiner;
                    for( mruset<CHashMeter>::const_iterator it = mruSlowReadings.begin(); it != mruSlowReadings.end(); ++it )
                        UpdateMeterMap( (*it).GetMinerID(), (*it).GetSlowKHPS(), mapMiner );
                    //! Again we can go through each of the miner IDs that reported results and
                    //! add the averaged KHPS to the hash meter states final result.
                    for( MeterMap::const_iterator it = mapMiner.begin(); it != mapMiner.end(); ++it )
                        HashMeterState.dSlowKHPS += (*it).second.second / (double)(*it).second.first;
                }

                //! While we know there is at least some meter readings, we can find and total the most recent accumulative
                //! hash count and total execution times, from each of the miner threads.  This time we'll do that with a
                //! simple MinerID set, we start out with no miner IDs and an iterator that points to the end of the selected
                //! mru set, that depends on if this is history or while operating live running mining threads.  In either
                //! case all we need is the most recent sample from each of the MinerID's, that also depends on if we are
                //! running or stopped at the moment.
                set<uint8_t> setMinerID;
                uint8_t nMaxId = nMinerThreadsRunning ? nMinerThreadsRunning : nLastRunThreadCount;
                mruset<CHashMeter>::const_iterator it = HashMeterState.nFastCount ? mruFastReadings.end() : mruSlowReadings.end();
                mruset<CHashMeter>::const_iterator itend = HashMeterState.nFastCount ? mruFastReadings.begin() : mruSlowReadings.begin();
                do {
                    //! ToDo: Upgrade this to use the newly invented (typedefs added to mruset.h) reverse_iterator method.
                    it--; //! 1st decrement it, as we move backwards in time from the most recent sample produced, starts out = end() of the selected mru set.
                    //! Insertion fails, and returns false if the miner ID is already in the set so we skip it, because that means we already have
                    //! that miners ID information. When we get all of them we're done, and have also totaled how many reported, which is a very
                    //! good way of knowing if they are all still running or one or more have terminated.
                    if( setMinerID.insert( (*it).GetMinerID() ).second ) {
                        //! So it must have been inserted, include this threads results in the accumulation...
                        HashMeterState.nCumulativeTime += (*it).GetCumulativeSecs();
                        HashMeterState.nCumulativeHashes += (*it).GetCumulativeHashes();
                        //! ...and keep track of the earliest start time we find, that will be when mining was initiated.
                        int64_t nMetersStartTime = (*it).GetStartTime();
                        if( HashMeterState.nEarliestStartTime > nMetersStartTime ) HashMeterState.nEarliestStartTime = nMetersStartTime;
                        //! Finally bump the number of reporting threads we have found.
                        HashMeterState.nIDsReporting++;
                    }
                //! Do this until we have all the mining thread reports, or we've run out of samples to explore.
                } while( HashMeterState.nIDsReporting < nMaxId && it != itend );

                //! We now have only one datapoint from each of the miners, and it is the most recent Cumulative run time from each of them.
                //! so we calculate the HPS and convert it into mega hashes per hour at the same time.  nCumulativeTime here is not used though
                //! or we could multiply the result by the number of nIDsReporting.  Instead we use actual time span, this effectively multiplies
                //! the result by the same factor and sets up the final result needed by the 'gethashmeter' query.  It also works if mining has
                //! stopped or is currently running.
                if( HashMeterState.nIDsReporting ) {
                    HashMeterState.nRunTime = HashMeterState.nFastCount ? nTimeNow : nMiningStoppedTime;
                    HashMeterState.nRunTime -= HashMeterState.nEarliestStartTime;
                }
                //! Should never happen, but stops divide by zero, good for debugging and not reporting garbage to the user...
                if( HashMeterState.nRunTime > 0 )
                    HashMeterState.dCumulativeMHPH = (double)(HashMeterState.nCumulativeHashes * 3600) / (double)(HashMeterState.nRunTime * 1000000);
                else
                    HashMeterState.nRunTime = -1;
            }
            fResultsProduced = true;
        } else
            MilliSleep(100);            //! Sleep for abit..
    } while( !fResultsProduced && ++nAttempts < 20 );

    return fResultsProduced;
}

bool ClearHashMeterSlowMRU()
{
    bool fCleared = false;
    uint8_t nAttempts = 0; //! If lock fails, its no big deal, we'll try again for at least a couple of seconds...

    do {
        TRY_LOCK(cs_hashmeter, lockedmeter);
        if( lockedmeter ) {
            mruSlowReadings.clear();
            fCleared = true;
        } else
            MilliSleep(100);            //! Sleep for abit..
    } while( !fCleared && ++nAttempts < 20 );

    return fCleared;
}

bool IsMinersRunning()
{
    LOCK(cs_hashmeter);
    return nMinerThreadsRunning != 0;
}

//! This procedure averages the miner threads 10 second samples, as found from over the last 10 minutes.
//! Once the totals from each thread have been created, it finds the average each of them are producing
//! and sums each of those, into the total returned.
double GetFastMiningKHPS()
{
    double dFastKHPS = 0.0;

    LOCK(cs_hashmeter);

    if( nMinerThreadsRunning ) {
        MeterMap mapMiner;
        for( mruset<CHashMeter>::const_iterator it = mruFastReadings.begin(); it != mruFastReadings.end(); ++it )
            UpdateMeterMap( (*it).GetMinerID(), (*it).GetFastKHPS(), mapMiner );
        for( MeterMap::const_iterator it = mapMiner.begin(); it != mapMiner.end(); ++it )
            dFastKHPS += (*it).second.second / (double)(*it).second.first;
    }

    return dFastKHPS;
}

//! Slow mining results can be returned even if generation has been turned off, if there are still results stored, this routine will
//! find, and return the most recent 10 minute sample from each of the threads that were(are) running, and return that value.
//! Accumulated averaging is not done, although it could be in the future.  As of this commentary it is not being used for anything.
double GetSlowMiningKHPS()
{
    double dResult = 0.0;

    LOCK(cs_hashmeter);

    uint8_t nIDsFound = 0;
    set<uint8_t> setMinerID;
    for( mruset<CHashMeter>::const_reverse_iterator it = mruSlowReadings.rbegin(); nIDsFound < nMinerThreadsRunning && it != mruSlowReadings.rend(); ++it ) {
        if( setMinerID.insert( (*it).GetMinerID() ).second ) {
            dResult += (*it).GetFastKHPS();
            nIDsFound++;
        }
    }
    return dResult;
}

void static AnoncoinMiner(CWallet *pwallet)
{
    LogPrintf("%s : v3.0 for Scrypt/GOST3411 started with (DDA) Dynamic Difficulty Awareness and (MTHM) Multi-Threaded HashMeter technologies.\n", __func__ );
    SetThreadPriority(THREAD_PRIORITY_LOWEST);
    RenameThread("anoncoin-miner");

    //! Each thread has its own key and counter
    CReserveKey reservekey(pwallet);
    uint32_t nExtraNonce = 0;

    //! Create a new Hash meter for this thread, destruction handled automatically
    uint8_t nMyID;
    {
        LOCK(cs_hashmeter);
        nMyID = ++nMinerThreadsRunning;
    }
    //! Allocating with scoped pointers means no more concern over its destruction when we're finished...

    //! Each thread gets its own Hash Meter, with a unique ID
    boost::scoped_ptr<CHashMeter> spMyMeter(new CHashMeter( nMyID ));
    //! Each thread gets its own Scrypt mining ScratchPad buffer, they are large.
    boost::scoped_ptr<char> spScratchPad( new char[ SCRYPT_SCRATCHPAD_SIZE ] );
    // Each thread gets its own scratchpad buffer, allocated in normal data storage and off the stack...
    // char* pScratchPadBuffer = (char*) ::operator new (SCRYPT_SCRATCHPAD_SIZE, nothrow);
    // if( !pScratchPadBuffer ) {
        // LogPrintf( "%s %2d: ERROR - Unable to allocate scratchpad buffer for scrypt miner...\n", __func__, nMyID );
        // return;
    //}

    try {
        while (true) {
            /*if (!RegTest()) {
                //! Busy-wait for the network to come online so we don't waste time mining
                //! on an obsolete chain. In regtest mode we expect to fly solo.
                while (vNodes.empty())
                    MilliSleep(10000);
            }*/

            /**
             * Create new block
             */
            unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
            CBlockIndex* pindexPrev = chainActive.Tip();

            auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
            if (!pblocktemplate.get())
            {
                LogPrintf("%s %2d: ERROR - Keypool ran out, please refill before restarting.\n", __func__, nMyID );
                return;
            }
            CBlock *pblock = &pblocktemplate->block;
            IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);

            //LogPrintf("%s %2d: Running with %u transactions in block (%u bytes)\n", __func__, nMyID, pblock->vtx.size(),
            //    ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));

            /**
             * Search
             */
            int64_t nStart = GetTime();
            uint256 hashTarget;
            hashTarget.SetCompact(pblock->nBits);
            std::string powHashType = "scrypt";
            while( true ) {
                bool fFound = false;
                bool fAccepted = false;
                uint16_t nHashesDone = 0;
                uint256 thash;
                //! Scan nonces looking for a solution
                while(true) {
                    if (pindexPrev->nHeight+1 >= ancConsensus.nDifficultySwitchHeight6)
                    {
                        thash = HashGOST(BEGIN(pblock->nVersion), END(pblock->nNonce));
                        pblock->nVersion = 3;
                        pblock->nHeight  = pindexPrev->nHeight+1;
                        powHashType = "gost3411";
                    } else {
                        scrypt_1024_1_1_256_sp(BEGIN(pblock->nVersion), BEGIN(thash), spScratchPad.get());
                        pblock->nVersion = 2;
                    }
                    nHashesDone++;
                    if( thash <= hashTarget ) {
                        fFound = true;
                        SetThreadPriority(THREAD_PRIORITY_NORMAL);
                        //! Found a solution
                        //! Force new proof-of-work block scrypt hash and the sha256d hash values to be calculated.
                        //! Calling GetHash() & CalcSha256dHash() with true invalidates any previous (and obsolete) ones.
                        assert( thash == pblock->GetHash() );
                        //! Basically this next line does the Scrypt calculation again once, then all the normal
                        //! validation code kicks in from the call to ProcessBlockFound(), insuring that is the case...
                        assert( pblock->CalcSha256dHash() != uintFakeHash(0) );
                        LogPrintf("%s %2d:\n", __func__, nMyID );
                        LogPrintf("proof-of-work found (%s)  \n  hash: %s  \ntarget: %s\n", powHashType.c_str(), thash.GetHex(), hashTarget.GetHex());
                        fAccepted = ProcessBlockFound(pblock, *pwallet, reservekey);
                        SetThreadPriority(THREAD_PRIORITY_LOWEST);

                        //! In regression test mode, stop mining after a block is found.
                        if( RegTest() )
                            throw boost::thread_interrupted();
                        break;
                    }
                    pblock->nNonce++;
                    //! In this inner loop, we calculate 256 hashes, if none are found, we'll try updating some other factors
                    if( (pblock->nNonce & 0xFF) == 0 )
                        break;
                }

                //!
                //if( fFound ) {
                    //if( !fAccepted )
                    //break;
                //}

                //! Meter hashes/sec production, UpdateFastCounter starts returning true if its time to log results (10 sec.)
                if( spMyMeter->UpdateFastCounter(nHashesDone) ) {
                    //! If lock fails, its no big deal, we'll try again next time, the meter update is fast & keeps accumulating...
                    TRY_LOCK(cs_hashmeter, lockedmeter);
                    if( lockedmeter ) {
                        //! Once we have the meter locked we first update our meter results, 'then' the 10 sec summary mru.
                        bool fUpdateLog = spMyMeter->UpdateAccumulations();
                        //! Now we store the whole hash meter as another (most recent) data point in the short term sample buffer,
                        //! its new start time, becomes our final timestamp and can be used outside this thread anytime in the future.
                        mruFastReadings.insert( *spMyMeter );
                        //! If it turns out that the 10 minute log update needs to be done, we update that and report it and other stuff as well, otherwise we're done.
                        if( fUpdateLog ) {
                            //! Again before saving the sample, we make sure the timestamp is updated and the meters log fields reset for another interval,
                            //! this call returns the logged HashesPermilliSec, so the value is correct for KiloHashes per second already...cool
                            double dKiloHashesPerSec = spMyMeter->RestartSlowCounter();
                            //! Store the whole hash meter as another data point in the long term sample buffer, and report that to the log.
                            mruSlowReadings.insert( *spMyMeter );
                            LogPrintf("%s %2d: reporting new 10 min sample update of %6.3f KHashes/Sec.\n", __func__, nMyID, dKiloHashesPerSec );
                        }
                    }
                }
                //! Check for stop or if block needs to be rebuilt
                boost::this_thread::interruption_point();
                //! If there are no peers we terminate the miner... except for RegTests
                if( vNodes.empty() && !RegTest() )
                    break;
                //! Having processed more than 65K hashes means updating would be a good idea...
                if( pblock->nNonce >= 0xffff0000 )
                    break;
                //! Checks for transaction changes happen at least 5 times over the coarse of one nTargetSpacing interval
                if( mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 36 )
                    break;
                //! If the previous block has changed, we must as well...
                if (pindexPrev != chainActive.Tip())
                    break;

                //! Update nTime and difficulty required (if needed) every so often
                //! Changing pblock->nTime effects the work required for Anoncoin if the blockheader time is used for PID calculations,
                //! otherwise it does not.  No older generation of the NextWorkRequired will be effected by time change.
                UpdateTime(pblock, pindexPrev);
                pblock->nBits = ancConsensus.GetNextWorkRequired(pindexPrev, pblock);
                hashTarget.SetCompact(pblock->nBits);
            } // Looping forever while true and no nonce overflow, transactions updated or new blocks arrived
        } // Looping forever while true in this thread
    } // try, errors caught and logged before terminating
    catch (const boost::thread_interrupted&)
    {
        LogPrintf("%s %2d: terminated.\n", __func__, nMyID );
        throw;
    }
    catch (const std::runtime_error &e)
    {
        LogPrintf("%s %2d: runtime error: %s\n", __func__, nMyID, e.what());
        return;
    }
    // if( pScratchPadBuffer ) delete pScratchPadBuffer;
}

void GenerateAnoncoins(bool fGenerate, CWallet* pwallet, int nThreads)
{
    static boost::thread_group* minerThreads = NULL;

    if (nThreads < 0) {
        if( RegTest() )
            nThreads = 1;
        else
            nThreads = boost::thread::hardware_concurrency();
    }

    if (minerThreads != NULL)
    {
        minerThreads->interrupt_all();
        delete minerThreads;
        minerThreads = NULL;
    }

    {
        LOCK(cs_hashmeter);
        nMinerThreadsRunning = 0;
        mruFastReadings.clear();
    }

    if (nThreads == 0 || !fGenerate) {
        nMiningStoppedTime = GetTime();
        return;
    }

    {
        LOCK(cs_hashmeter);
        mruFastReadings.max_size( nThreads * 60 );
        mruSlowReadings.max_size( nThreads * 144 );
    }

    nLastRunThreadCount = nThreads;
    nMiningStoppedTime = 0;

    minerThreads = new boost::thread_group();
    for (int i = 0; i < nThreads; i++)
        minerThreads->create_thread(boost::bind(&AnoncoinMiner, pwallet));
}

//#endif // ENABLE_WALLET

/**
 * Scrypt mining related code for block creation
 */

int static FormatHashBlocks(void* pbuffer, unsigned int len)
{
    unsigned char* pdata = (unsigned char*)pbuffer;
    unsigned int blocks = 1 + ((len + 8) / 64);
    unsigned char* pend = pdata + 64 * blocks;
    memset(pdata + len, 0, 64 * blocks - len);
    pdata[len] = 0x80;
    unsigned int bits = len * 8;
    pend[-1] = (bits >> 0) & 0xff;
    pend[-2] = (bits >> 8) & 0xff;
    pend[-3] = (bits >> 16) & 0xff;
    pend[-4] = (bits >> 24) & 0xff;
    return blocks;
}

/** Do mining precalculation, also used in rpcmining.cpp for the old getwork() */
void FormatHashBuffers(const CBlockHeader* pblock, char* pmidstate, char* pdata, char* phash1)
{
    //! Structure used for pre-building the hash buffers
    struct
    {
        struct unnamed2
        {
            int nVersion;
            uint256 hashPrevBlock;
            uint256 hashMerkleRoot;
            unsigned int nTime;
            unsigned int nBits;
            unsigned int nNonce;
        }
        block;
        unsigned char pchPadding0[64];
        uint256 hash1;
        unsigned char pchPadding1[64];
    }
    tmp;
    memset(&tmp, 0, sizeof(tmp));

    tmp.block.nVersion       = pblock->nVersion;
    tmp.block.hashPrevBlock  = pblock->hashPrevBlock;
    tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
    tmp.block.nTime          = pblock->nTime;
    tmp.block.nBits          = pblock->nBits;
    tmp.block.nNonce         = pblock->nNonce;

    FormatHashBlocks(&tmp.block, sizeof(tmp.block));
    FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));

    //! Byte swap all the input buffer
    for (unsigned int i = 0; i < sizeof(tmp)/4; i++)
        ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);

    memcpy(pdata, &tmp.block, 128);
    memcpy(phash1, &tmp.hash1, 64);
}

void FormatHashBuffers(CBlock* pblock, char* pdata, char* phash1)
{
    //
    // Pre-build hash buffers
    //
    struct
    {
        struct unnamed2
        {
            int nVersion;
            uint256 hashPrevBlock;
            uint256 hashMerkleRoot;
            unsigned int nTime;
            unsigned int nBits;
            unsigned int nNonce;
        }
        block;
        unsigned char pchPadding0[64];
        uint256 hash1;
        unsigned char pchPadding1[64];
    }
    tmp;
    memset(&tmp, 0, sizeof(tmp));

    tmp.block.nVersion       = pblock->nVersion;
    tmp.block.hashPrevBlock  = pblock->hashPrevBlock;
    tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
    tmp.block.nTime          = pblock->nTime;
    tmp.block.nBits          = pblock->nBits;
    tmp.block.nNonce         = pblock->nNonce;

    FormatHashBlocks(&tmp.block, sizeof(tmp.block));
    FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));

    // Byte swap all the input buffer
    for (unsigned int i = 0; i < sizeof(tmp)/4; i++)
        ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);

    memcpy(pdata, &tmp.block, 128);
    memcpy(phash1, &tmp.hash1, 64);
}

max_stars_repo_name: eddef/anoncoin

max_issues_repo_name: eddef/anoncoin

max_forks_repo_name: eddef/anoncoin


text:
/** @file
 * @brief Main interface function for counting mutations and/or depths
 *        from a mutations file.
 */

/*-----------------------------------------------------------------------
 * This file is a part of ShapeMapper, and is licensed under the terms  *
 * of the MIT license. Copyright 2018 Steven Busan.                     *
 *----------------------------------------------------------------------*/

#include "MutationCounter.h"

#include <memory>
#include <boost/iostreams/device/file.hpp>

// TODO: test scanning (sorted) file output
// TODO: option for max variant insert length to store (poor quality reads could potentially use up a fair amount of memory otherwise)

// FIXME: move mutation collapsing and quality filtering functions to MutationParser, so
//        output of that stage is actually usable for other applications

namespace mutation_counter {

    /**
     * @brief Count sequencing depth, variants, and/or mutations from parsed mutations.
     *
     * @param filename        Input file (mutations and reconstructed target
     *                        sequences). Typically from mutation_parser::parseSam()
     * @param seq_len         Length of reference sequence. Ignored if 0. If provided,
     *                        output files are guaranteed to have this many lines, even
     *                        if there are regions with no read coverage.
     * @param primer_pairs    Number of amplicon primer pairs (if any) used to filter
     *                        mapped reads.
     * @param depth_out       Sequencing depth output file. Ignored if
     *                        zero-length.
     * @param variant_out     Sequence variants and counts output file. Ignored
     *                        if zero-length.
     * @param count_out       Mutation counts output file. Ignored if zero-length.
     * @param input_is_sorted Set true if mutations came from a BAM/SAM file
     *                        sorted by left index. If true, less memory will
     *                        be used, as counts will be periodically written
     *                        to file instead of all at once at the end of
     *                        execution.
     * @param separate_ambig_counts
     *                        Count mutations derived from ambiguously-aligned mutations
     *                        in separate columns with the additional header "_ambig".
     */
    void countSelected(const std::vector<std::string> &filenames,
                       const int seq_len,
                       const int primer_pairs,
                       const std::string &variant_out,
                       const std::string &count_out,
                       const bool hist,
                       const bool input_is_sorted,
                       const bool separate_ambig_counts,
                       bool debug,
                       bool warn_on_no_mapped = false) {
        // set selected output columns (this is a global from MutationCounter.h)
        std::vector<std::string> new_column_names;
        for (std::vector<std::string>::iterator it = column_names.begin();
             it != column_names.end();
             ++it) {
            new_column_names.push_back((*it));
            if (separate_ambig_counts){
                new_column_names.push_back((*it)+"_ambig");
            }
        }
        new_column_names.push_back("read_depth");
        new_column_names.push_back("effective_depth");
        new_column_names.push_back("off_target_mapped_depth");
        new_column_names.push_back("low_mapq_mapped_depth");
        if (primer_pairs > 0) {
            for (int i=1; i<=primer_pairs; i++){
                new_column_names.push_back("primer_pair_"+std::to_string(i)+"_mapped_depth");
            }
        } else {
            new_column_names.push_back("mapped_depth");
        }
        column_names = new_column_names;

        // ------------------------------------------------------------------------------
        // open input files, do some checks, set up streams

        // this garbage is needed because streams don't support move
        std::vector<std::unique_ptr<BI::filtering_istream>> files;

        for (auto & filename : filenames) {
            // again, this junk is required because streams don't support move
            files.emplace_back(
                    std::unique_ptr<BI::filtering_istream>(new BI::filtering_istream()));

            files.back()->push(BI::newline_filter(BI::newline::posix));
            try {
                int file_size = BF::file_size(filename);
                if (file_size == 0) {
                    if (warn_on_no_mapped) {
                        std::cout << "WARNING: Input file " + filename + " is empty." << std::endl;
                    } else {
                        throw std::runtime_error("ERROR: Input file " + filename + " is empty.");
                    }
                }
            } catch (BF::filesystem_error &e) { }

            BI::file_source fs(filename);
            if (not fs.is_open()) {
                // Do additional checks to see if the file exists or if it's a permissions issue
                if (!(BF::is_regular_file(filename))) {
                    throw std::runtime_error("ERROR: Input file " + filename + " not found.");
                }
                throw std::runtime_error("ERROR: Could not open input file " + filename +
                                         " - unknown error.\nCheck file and folder permissions.");
            }
            if (BF::extension(BF::path(filename)) == ".gz") {
                // decompress gzip if file looks compressed
                files.back()->push(BI::gzip_decompressor());
            }
            files.back()->push(fs);

        }

        // ------------------------------------------------------------------------------
        // open output files, set up streams

        std::vector<bool> so;
        std::vector <std::string> out_names = {variant_out,
                                               count_out};
        std::vector <std::shared_ptr<std::ofstream>> out_files;
        for (int i = 0; i < out_names.size(); ++i) {
            if (out_names[i].length() == 0) {
                out_files.emplace_back(new std::ofstream());
                so.push_back(false);
                continue;
            }
            //std::ofstream *file_out = new std::ofstream(out_names[i], std::ios_base::out | std::ios_base::binary);
            std::shared_ptr <std::ofstream> file_out(
                    new std::ofstream(out_names[i], std::ios_base::out | std::ios_base::binary));

            if (!(*file_out)) {
                throw std::runtime_error(
                        "ERROR: Could not open output file " + out_names[i] + "\nCheck file and folder permissions.");
            }
            std::unique_ptr <BI::filtering_ostream> out(new BI::filtering_ostream);
            if (BF::extension(BF::path(out_names[i])) == ".gz") {
                // compress using gzip if requested
                out->push(BI::gzip_compressor());
            }
            out->push((*file_out));
            out_files.push_back(file_out);
            so.push_back(true);
        }

        // ---------------------------------------------------------------------------

        VariantCounter vc;
        MutationCounter mc;

        if (so[1]) { *out_files[1] << mc.printHeader(); }

        std::string line;

        std::string read_id;
        int mapping_category;
        int primer_pair;
        int left_target_pos;
        int right_target_pos;
        std::vector<bool> mapping_depth;
        std::vector<bool> local_effective_depth;
        std::vector<bool> local_effective_count;
        std::vector<Mutation> processed_mutations;

        size_t count = 0;
        std::vector<std::string> input_lines(files.size());
        std::vector<bool> eof(files.size());
        std::vector<std::string> non_empty_lines;
        while(true) {
            for (int i=0; i<files.size(); i++) {
                eof[i] = !std::getline(*(files[i]), input_lines[i]);
            }

            // terminate if we reach the end of all files
            if (std::all_of(eof.begin(), eof.end(), [](bool v){return v;})) {
                break;
            }
            // interleave all inputs by line if present
            for (int i=0; i<files.size(); i++) {
                if (not eof[i]) { non_empty_lines.push_back(input_lines[i]); }
            }

            for (auto & line : non_empty_lines) {
                // process single line

                count += 1;

	            if(debug) { std::cout << "line " << count << ": " << line << std::endl << std::flush; }

                boost::tie(read_id,
                           mapping_category,
                           primer_pair,
                           left_target_pos,
                           right_target_pos,
                           mapping_depth,
                           local_effective_depth,
                           local_effective_count,
                           processed_mutations) = parseProcessedMutations(line);

                if(debug) { std::cout << "read_id: " << read_id << std::endl << std::flush; }
                if(debug) { std::cout << "mapping_category: " << mapping_category << "\n" <<std::flush; }
                if(debug) { std::cout << "primer_pair: " << std::to_string(primer_pair) << "\n" << std::flush; }
                if(debug) { std::cout << "left_target_pos: " << left_target_pos << std::endl << std::flush; }
                if(debug) { std::cout << "right_target_pos: " << right_target_pos << std::endl << std::flush; }
                if(debug) { std::cout << "mapping_depth: " << util::toString(mapping_depth) << "\n" << std::flush; }
                if(debug) { std::cout << "local_effective_depth: " << util::toString(local_effective_depth) << std::endl << std::flush; }
                if(debug) { std::cout << "local_effective_count: " << util::toString(local_effective_count) << std::endl << std::flush; }
                if(debug) { std::cout << "mutations: " << toString(processed_mutations) << std::endl << std::flush; }

                if (so[0]) { vc.updateRightBound(right_target_pos); }
                if (so[1]) { mc.updateRightBound(right_target_pos); }

                if (input_is_sorted) {
                    // use less memory if the input file is sorted. Print and remove counts to
                    // the left of the current read
                    if (so[0]) { *out_files[0] << vc.updateLeftBound(left_target_pos); }
                    if (so[1]) { *out_files[1] << mc.updateLeftBound(left_target_pos); }
                }

                if (so[0]) {
                    vc.updateCounts(processed_mutations,
                                    local_effective_depth,
                                    local_effective_count,
                                    left_target_pos);
                }
                if (so[1]) {
                    mc.updateCounts(processed_mutations,
                                    mapping_category,
                                    primer_pair,
                                    mapping_depth,
                                    local_effective_depth,
                                    local_effective_count,
                                    left_target_pos,
                                    separate_ambig_counts,
                                    debug);
                }

                /*if (count%100000==0){
                    std::cout << "Counted "<<count<<" reads" <<std::endl;
                }*/
            }
            non_empty_lines.resize(0);

        }
        if (count < 1) {
            if (warn_on_no_mapped) {
                std::cout << "WARNING: No reads were found in the input files." << std::endl;
            } else {
                throw std::runtime_error("ERROR: Input files contained no reads.");
            }
        }

        // update right end to last nucleotide in sequence
        // (ensures that output files will have the correct
        //  number of lines even if there are no reads that cover
        //  the 3-prime end of the sequence).
        if (seq_len>0) {
            // (bounds are given in 0-based coordinates)
            if (so[0]) { vc.updateRightBound(seq_len-1); }
            if (so[1]) { mc.updateRightBound(seq_len-1); }
        }

        // print any remaining values in each deque
        if (so[0]) { *out_files[0] << vc.printAllValues(); }
        if (so[1]) { *out_files[1] << mc.printAllValues(); }

        // write read length and mutations per read histograms
        // TODO: make separate output files for these tables
        if (hist) {
            std::cout << mc.printHistograms();
        }
    }

}


text:
#include <Eigen/Core>
#include <Eigen/Dense>
#include <CGAL/barycenter.h>
#include <CGAL/Simple_cartesian.h>
#include <boost/iterator/transform_iterator.hpp>

// Typedefs.
using Kernel   = CGAL::Simple_cartesian<double>;
using Point_2  = Kernel::Point_2;
using VectorXd = Eigen::VectorXd;
using MatrixXd = Eigen::MatrixXd;

using Output_iterator =
  std::back_insert_iterator< std::vector<double> >;

int main() {

  // Create a set of vertices.
  const std::vector<Point_2> vertices = {
    Point_2(0.0, 0.0), Point_2(0.75, 0.25), Point_2(0.5, 0.5), Point_2(0.4, -0.2) };

  // Create a set of query points.
  const std::vector<Point_2> queries = {
    Point_2(0.2, 0.2), Point_2(0.3, 0.3), Point_2(0.4, 0.4) };

  // Create a lambda function with affine coordinates.
  // This implementation is based on the following paper:
  // S. Waldron. Affine generalized barycentric coordinates.
  // Jaen Journal on Approximation, 3(2):209-226, 2011.
  // This function is a model of the `AnalyticWeights_2` concept.
  const auto affine = [&](
    const Point_2& query,
    Output_iterator coordinates) {

    const std::size_t n = vertices.size();
    const auto lambda = [](const Point_2& p){ return std::make_pair(p, 1.0); };
    const Point_2 b = CGAL::barycenter(
      boost::make_transform_iterator(vertices.begin(), lambda),
      boost::make_transform_iterator(vertices.end()  , lambda), Kernel());

    MatrixXd V(2, n);
    for (std::size_t i = 0; i < n; ++i) {
      V(0, i) = vertices[i].x() - b.x();
      V(1, i) = vertices[i].y() - b.y();
    }

    const auto A   = V.adjoint();
    const auto mat = V * A;
    const auto inv = mat.inverse();

    Point_2 diff; VectorXd vec(2);
    for (std::size_t i = 0; i < n; ++i) {
      const double x = query.x() - b.x();
      const double y = query.y() - b.y();
      diff = Point_2(x, y);

      vec(0) = V(0, i);
      vec(1) = V(1, i);
      const auto res = inv * vec;

      *(coordinates++) =
        diff.x() * res(0) + diff.y() * res(1) + 1.0 / double(n);
    }
  };

  // Compute affine coordinates for all query points.
  std::cout << std::endl << "affine coordinates (all queries): " << std::endl << std::endl;

  std::vector<double> coordinates;
  coordinates.reserve(4);
  for (const auto& query : queries) {
    coordinates.clear();
    affine(query, std::back_inserter(coordinates));
    for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
      std::cout << coordinates[i] << ", ";
    }
    std::cout << coordinates[coordinates.size() - 1] << std::endl;
  }
  std::cout << std::endl;

  return EXIT_SUCCESS;
}

max_stars_repo_name: ffteja/cgal

max_issues_repo_name: ffteja/cgal

max_forks_repo_name: ffteja/cgal