<commit_before>#ifndef UTILS_HPP_
#define UTILS_HPP_

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <stdexcept>
#include <string>
#include <vector>

#include "containers/printf_buffer.hpp"
#include "errors.hpp"
#include "config/args.hpp"

struct const_charslice {
    const char *beg, *end;
    const_charslice(const char *beg_, const char *end_) : beg(beg_), end(end_) { }
    const_charslice() : beg(NULL), end(NULL) { }
};

typedef uint64_t microtime_t;

microtime_t current_microtime();

/* General exception to be thrown when some process is interrupted. It's in
`utils.hpp` because I can't think where else to put it */
class interrupted_exc_t : public std::exception {
public:
    const char *what() const throw () {
        return "interrupted";
    }
};

/* Pad a value to the size of a cache line to avoid false sharing.
 * TODO: This is implemented as a struct with subtraction rather than a union
 * so that it gives an error when trying to pad a value bigger than
 * CACHE_LINE_SIZE. If that's needed, this may have to be done differently.
 */
template<typename value_t>
struct cache_line_padded_t {
    value_t value;
    char padding[CACHE_LINE_SIZE - sizeof(value_t)];
};

void *malloc_aligned(size_t size, size_t alignment = 64);

template <class T1, class T2>
T1 ceil_aligned(T1 value, T2 alignment) {
    return value + alignment - (((value + alignment - 1) % alignment) + 1);
}

template <class T1, class T2>
T1 ceil_divide(T1 dividend, T2 alignment) {
    return (dividend + alignment - 1) / alignment;
}

template <class T1, class T2>
T1 floor_aligned(T1 value, T2 alignment) {
    return value - (value % alignment);
}

template <class T1, class T2>
T1 ceil_modulo(T1 value, T2 alignment) {
    T1 x = (value + alignment - 1) % alignment;
    return value + alignment - ((x < 0 ? x + alignment : x) + 1);
}

inline bool divides(int64_t x, int64_t y) {
    return y % x == 0;
}

int gcd(int x, int y);

int64_t round_up_to_power_of_two(int64_t x);

typedef uint64_t ticks_t;
ticks_t secs_to_ticks(float secs);
ticks_t get_ticks();
time_t get_secs();
int64_t get_ticks_res();
double ticks_to_secs(ticks_t ticks);

// HEY: Maybe debugf and log_call and TRACEPOINT should be placed in
// debugf.hpp (and debugf.cc).
/* Debugging printing API (prints current thread in addition to message) */
void debug_print_quoted_string(append_only_printf_buffer_t *buf, const uint8_t *s, size_t n);
void debugf_prefix_buf(printf_buffer_t<1000> *buf);
void debugf_dump_buf(printf_buffer_t<1000> *buf);

// Primitive debug_print declarations.
void debug_print(append_only_printf_buffer_t *buf, uint64_t x);
void debug_print(append_only_printf_buffer_t *buf, const std::string& s);

#ifndef NDEBUG
void debugf(const char *msg, ...) __attribute__((format (printf, 1, 2)));
template <class T>
void debugf_print(const char *msg, const T& obj) {
    printf_buffer_t<1000> buf;
    debugf_prefix_buf(&buf);
    buf.appendf("%s: ", msg);
    debug_print(&buf, obj);
    buf.appendf("\n");
    debugf_dump_buf(&buf);
}
#else
#define debugf(...) ((void)0)
#define debugf_print(...) ((void)0)
#endif

class rng_t {
public:
// Returns a random number in [0, n).  Is not perfectly uniform; the
// bias tends to get worse when RAND_MAX is far from a multiple of n.
    int randint(int n);
    explicit rng_t(int seed = -1);
private:
    struct drand48_data buffer_;
    DISABLE_COPYING(rng_t);
};

int randint(int n);
std::string rand_string(int len);

bool begins_with_minus(const char *string);
// strtoul() and strtoull() will for some reason not fail if the input begins
// with a minus sign. strtou64_strict() does.  Also we fix the constness of the
// end parameter.
int64_t strtoi64_strict(const char *string, const char **end, int base);
uint64_t strtou64_strict(const char *string, const char **end, int base);

// These functions return false and set the result to 0 if the conversion fails or
// does not consume the whole string.
MUST_USE bool strtoi64_strict(const std::string &str, int base, int64_t *out_result);
MUST_USE bool strtou64_strict(const std::string &str, int base, uint64_t *out_result);

std::string strprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
std::string vstrprintf(const char *format, va_list ap);

// formatted time:
// yyyy-mm-ddThh:mm:ss.nnnnnnnnn   (29 characters)
const size_t formatted_time_length = 29;    // not including null

void format_time(struct timespec time, append_only_printf_buffer_t *buf);
std::string format_time(struct timespec time);

struct timespec parse_time(const std::string &str) THROWS_ONLY(std::runtime_error);

/* Printing binary data to stdout in a nice format */

void print_hd(const void *buf, size_t offset, size_t length);

// Fast string compare

int sized_strcmp(const uint8_t *str1, int len1, const uint8_t *str2, int len2);

/* The home thread mixin is a mixin for objects that can only be used
on a single thread. Its thread ID is exposed as the `home_thread()`
method. Some subclasses of `home_thread_mixin_t` can move themselves to
another thread, modifying the field real_home_thread. */

#define INVALID_THREAD (-1)

class home_thread_mixin_t {
public:
    int home_thread() const { return real_home_thread; }

#ifndef NDEBUG
    void assert_thread() const;
#else
    void assert_thread() const { }
#endif  // NDEBUG

protected:
    explicit home_thread_mixin_t(int specified_home_thread);
    home_thread_mixin_t();
    virtual ~home_thread_mixin_t() { }

    int real_home_thread;

private:
    // Things with home threads should not be copyable, since we don't
    // want to nonchalantly copy their real_home_thread variable.
    DISABLE_COPYING(home_thread_mixin_t);
};

/* `on_thread_t` switches to the given thread in its constructor, then switches
back in its destructor. For example:

    printf("Suppose we are on thread 1.\n");
    {
        on_thread_t thread_switcher(2);
        printf("Now we are on thread 2.\n");
    }
    printf("And now we are on thread 1 again.\n");

*/

class on_thread_t : public home_thread_mixin_t {
public:
    explicit on_thread_t(int thread);
    ~on_thread_t();
};

template <class InputIterator, class UnaryPredicate>
bool all_match_predicate(InputIterator begin, InputIterator end, UnaryPredicate f) {
    bool res = true;
    for (; begin != end; begin++) {
        res &= f(*begin);
    }
    return res;
}

template <class T, class UnaryPredicate>
bool all_in_container_match_predicate (const T &container, UnaryPredicate f) {
    return all_match_predicate(container.begin(), container.end(), f);
}

bool notf(bool x);

/* Translates to and from `0123456789ABCDEF`. */
bool hex_to_int(char c, int *out);
char int_to_hex(int i);

std::string read_file(const char *path);

struct path_t {
    std::vector<std::string> nodes;
    bool is_absolute;
};

path_t parse_as_path(const std::string &);
std::string render_as_path(const path_t &);

enum region_join_result_t { REGION_JOIN_OK, REGION_JOIN_BAD_JOIN, REGION_JOIN_BAD_REGION };

template <class T>
void delete_a_thing(T *thing_to_delete) {
    delete thing_to_delete;
}

template <class T>
class assignment_sentry_t {
public:
    assignment_sentry_t(T *v, const T &value) :
        var(v), old_value(*var) {
        *var = value;
    }
    ~assignment_sentry_t() {
        *var = old_value;
    }
private:
    T *var;
    T old_value;
};

#endif // UTILS_HPP_
<commit_msg>Removed the unused function delete_a_thing.<commit_after>#ifndef UTILS_HPP_
#define UTILS_HPP_

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <stdexcept>
#include <string>
#include <vector>

#include "containers/printf_buffer.hpp"
#include "errors.hpp"
#include "config/args.hpp"

struct const_charslice {
    const char *beg, *end;
    const_charslice(const char *beg_, const char *end_) : beg(beg_), end(end_) { }
    const_charslice() : beg(NULL), end(NULL) { }
};

typedef uint64_t microtime_t;

microtime_t current_microtime();

/* General exception to be thrown when some process is interrupted. It's in
`utils.hpp` because I can't think where else to put it */
class interrupted_exc_t : public std::exception {
public:
    const char *what() const throw () {
        return "interrupted";
    }
};

/* Pad a value to the size of a cache line to avoid false sharing.
 * TODO: This is implemented as a struct with subtraction rather than a union
 * so that it gives an error when trying to pad a value bigger than
 * CACHE_LINE_SIZE. If that's needed, this may have to be done differently.
 */
template<typename value_t>
struct cache_line_padded_t {
    value_t value;
    char padding[CACHE_LINE_SIZE - sizeof(value_t)];
};

void *malloc_aligned(size_t size, size_t alignment = 64);

template <class T1, class T2>
T1 ceil_aligned(T1 value, T2 alignment) {
    return value + alignment - (((value + alignment - 1) % alignment) + 1);
}

template <class T1, class T2>
T1 ceil_divide(T1 dividend, T2 alignment) {
    return (dividend + alignment - 1) / alignment;
}

template <class T1, class T2>
T1 floor_aligned(T1 value, T2 alignment) {
    return value - (value % alignment);
}

template <class T1, class T2>
T1 ceil_modulo(T1 value, T2 alignment) {
    T1 x = (value + alignment - 1) % alignment;
    return value + alignment - ((x < 0 ? x + alignment : x) + 1);
}

inline bool divides(int64_t x, int64_t y) {
    return y % x == 0;
}

int gcd(int x, int y);

int64_t round_up_to_power_of_two(int64_t x);

typedef uint64_t ticks_t;
ticks_t secs_to_ticks(float secs);
ticks_t get_ticks();
time_t get_secs();
int64_t get_ticks_res();
double ticks_to_secs(ticks_t ticks);

// HEY: Maybe debugf and log_call and TRACEPOINT should be placed in
// debugf.hpp (and debugf.cc).
/* Debugging printing API (prints current thread in addition to message) */
void debug_print_quoted_string(append_only_printf_buffer_t *buf, const uint8_t *s, size_t n);
void debugf_prefix_buf(printf_buffer_t<1000> *buf);
void debugf_dump_buf(printf_buffer_t<1000> *buf);

// Primitive debug_print declarations.
void debug_print(append_only_printf_buffer_t *buf, uint64_t x);
void debug_print(append_only_printf_buffer_t *buf, const std::string& s);

#ifndef NDEBUG
void debugf(const char *msg, ...) __attribute__((format (printf, 1, 2)));
template <class T>
void debugf_print(const char *msg, const T& obj) {
    printf_buffer_t<1000> buf;
    debugf_prefix_buf(&buf);
    buf.appendf("%s: ", msg);
    debug_print(&buf, obj);
    buf.appendf("\n");
    debugf_dump_buf(&buf);
}
#else
#define debugf(...) ((void)0)
#define debugf_print(...) ((void)0)
#endif

class rng_t {
public:
// Returns a random number in [0, n).  Is not perfectly uniform; the
// bias tends to get worse when RAND_MAX is far from a multiple of n.
    int randint(int n);
    explicit rng_t(int seed = -1);
private:
    struct drand48_data buffer_;
    DISABLE_COPYING(rng_t);
};

int randint(int n);
std::string rand_string(int len);

bool begins_with_minus(const char *string);
// strtoul() and strtoull() will for some reason not fail if the input begins
// with a minus sign. strtou64_strict() does.  Also we fix the constness of the
// end parameter.
int64_t strtoi64_strict(const char *string, const char **end, int base);
uint64_t strtou64_strict(const char *string, const char **end, int base);

// These functions return false and set the result to 0 if the conversion fails or
// does not consume the whole string.
MUST_USE bool strtoi64_strict(const std::string &str, int base, int64_t *out_result);
MUST_USE bool strtou64_strict(const std::string &str, int base, uint64_t *out_result);

std::string strprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
std::string vstrprintf(const char *format, va_list ap);

// formatted time:
// yyyy-mm-ddThh:mm:ss.nnnnnnnnn   (29 characters)
const size_t formatted_time_length = 29;    // not including null

void format_time(struct timespec time, append_only_printf_buffer_t *buf);
std::string format_time(struct timespec time);

struct timespec parse_time(const std::string &str) THROWS_ONLY(std::runtime_error);

/* Printing binary data to stdout in a nice format */

void print_hd(const void *buf, size_t offset, size_t length);

// Fast string compare

int sized_strcmp(const uint8_t *str1, int len1, const uint8_t *str2, int len2);

/* The home thread mixin is a mixin for objects that can only be used
on a single thread. Its thread ID is exposed as the `home_thread()`
method. Some subclasses of `home_thread_mixin_t` can move themselves to
another thread, modifying the field real_home_thread. */

#define INVALID_THREAD (-1)

class home_thread_mixin_t {
public:
    int home_thread() const { return real_home_thread; }

#ifndef NDEBUG
    void assert_thread() const;
#else
    void assert_thread() const { }
#endif  // NDEBUG

protected:
    explicit home_thread_mixin_t(int specified_home_thread);
    home_thread_mixin_t();
    virtual ~home_thread_mixin_t() { }

    int real_home_thread;

private:
    // Things with home threads should not be copyable, since we don't
    // want to nonchalantly copy their real_home_thread variable.
    DISABLE_COPYING(home_thread_mixin_t);
};

/* `on_thread_t` switches to the given thread in its constructor, then switches
back in its destructor. For example:

    printf("Suppose we are on thread 1.\n");
    {
        on_thread_t thread_switcher(2);
        printf("Now we are on thread 2.\n");
    }
    printf("And now we are on thread 1 again.\n");

*/

class on_thread_t : public home_thread_mixin_t {
public:
    explicit on_thread_t(int thread);
    ~on_thread_t();
};

template <class InputIterator, class UnaryPredicate>
bool all_match_predicate(InputIterator begin, InputIterator end, UnaryPredicate f) {
    bool res = true;
    for (; begin != end; begin++) {
        res &= f(*begin);
    }
    return res;
}

template <class T, class UnaryPredicate>
bool all_in_container_match_predicate (const T &container, UnaryPredicate f) {
    return all_match_predicate(container.begin(), container.end(), f);
}

bool notf(bool x);

/* Translates to and from `0123456789ABCDEF`. */
bool hex_to_int(char c, int *out);
char int_to_hex(int i);

std::string read_file(const char *path);

struct path_t {
    std::vector<std::string> nodes;
    bool is_absolute;
};

path_t parse_as_path(const std::string &);
std::string render_as_path(const path_t &);

enum region_join_result_t { REGION_JOIN_OK, REGION_JOIN_BAD_JOIN, REGION_JOIN_BAD_REGION };

template <class T>
class assignment_sentry_t {
public:
    assignment_sentry_t(T *v, const T &value) :
        var(v), old_value(*var) {
        *var = value;
    }
    ~assignment_sentry_t() {
        *var = old_value;
    }
private:
    T *var;
    T old_value;
};

#endif // UTILS_HPP_
<|endoftext|>


<commit_before>//----------------------------  template.cc  ---------------------------
//    $Id: gradients.cc 22693 2010-11-11 20:11:47Z kanschat $
//    Version: $Name$
//
//    Copyright (C) 2005, 2008, 2009, 2010 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  template.cc  ---------------------------

// Controls that the covariant matrix is calculated properly. It uses
// a Q1 finite element to calculate the scalar product of the gradient
// of a projected function (a monomial) with the tangential to the
// cell surface taken in the cell midpoint.  The result obtained is
// compared with the exact one in the <1,2> case.

#include "../tests.h"
#include <fstream>
#include <base/logstream.h>
#include <string>

// all include files needed for the program

#include <base/function.h>
#include <base/function_lib.h>
#include <base/quadrature_lib.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <lac/constraint_matrix.h>
#include <fe/mapping.h>
#include <fe/mapping_q1.h>
#include <fe/fe_dgq.h>
#include <fe/fe_q.h>
#include <fe/fe_values.h>
#include <grid/tria.h>
#include <grid/grid_in.h>
#include <grid/grid_out.h>
#include <numerics/vectors.h>
#include <numerics/data_out.h>

#include <cmath>

std::ofstream logfile("gradients_1/output");

template <int dim, int spacedim>
void test(std::string filename, unsigned int degree = 1)

{
  Triangulation<dim, spacedim> triangulation;
  GridIn<dim, spacedim> gi;

  gi.attach_triangulation (triangulation);
  std::ifstream in (filename.c_str());
  gi.read_ucd (in);

				// finite elements used for the
				// projection
  const FE_Q<dim,spacedim> fe (degree);
  const MappingQ<dim, spacedim> mapping(degree);

  DoFHandler<dim,spacedim> dof_handler (triangulation);
  dof_handler.distribute_dofs (fe);

  deallog
      << "no. of cells "<< triangulation.n_cells() <<std::endl;
  deallog
      << "no. of dofs "<< dof_handler.n_dofs()<< std::endl;
  deallog
      << "no. of dofs per cell "<< fe.dofs_per_cell<< std::endl;

				//  definition of the exact function
				//  and calculation of the projected
				//  one
  Vector<double> projected_one(dof_handler.n_dofs());

  Functions::CosineFunction<spacedim> the_function;

  // Tensor<1,spacedim> exp;
  // exp[0]=1;
  // exp[1]=0;
  // if(spacedim==3)
  //     exp[2]=0;
  // Functions::Monomial<spacedim> the_function(exp);

  const QGauss<dim> quad(2*fe.degree+1);
  ConstraintMatrix constraints;
  constraints.close();
  VectorTools::project(mapping, dof_handler, constraints,
		       quad, the_function, projected_one);

  deallog << "L2 norm of projected vector: "
	  << projected_one.l2_norm() << endl;

				// compute the H1 difference
  Vector<float> difference_per_cell (triangulation.n_active_cells());
  VectorTools::integrate_difference (dof_handler, projected_one,
				     the_function, difference_per_cell,
				     quad, VectorTools::H1_norm);

  deallog << "H1 error: " << difference_per_cell.l2_norm() << endl;
}

int main ()
{
  logfile.precision (4);
  deallog.attach(logfile);
  deallog.depth_console(3);
  deallog.threshold_double(1.e-12);

    deallog<<"Test <1,2>, Q1, Q2, Q3"<<std::endl;
    test<1,2>("grids/circle_4.inp",1);
    test<1,2>("grids/circle_4.inp",2);
    test<1,2>("grids/circle_4.inp",3);

    deallog<<std::endl;

    deallog<<"Test <2,3>, Q1, Q2, Q3"<<std::endl;
    test<2,3>("grids/sphere_1.inp",1);
    test<2,3>("grids/sphere_1.inp",2);
    test<2,3>("grids/sphere_1.inp",3);

    return 0;
}

<commit_msg>Avoid output to the screen.<commit_after>//----------------------------  template.cc  ---------------------------
//    $Id: gradients.cc 22693 2010-11-11 20:11:47Z kanschat $
//    Version: $Name$
//
//    Copyright (C) 2005, 2008, 2009, 2010 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  template.cc  ---------------------------

// Controls that the covariant matrix is calculated properly. It uses
// a Q1 finite element to calculate the scalar product of the gradient
// of a projected function (a monomial) with the tangential to the
// cell surface taken in the cell midpoint.  The result obtained is
// compared with the exact one in the <1,2> case.

#include "../tests.h"
#include <fstream>
#include <base/logstream.h>
#include <string>

// all include files needed for the program

#include <base/function.h>
#include <base/function_lib.h>
#include <base/quadrature_lib.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <lac/constraint_matrix.h>
#include <fe/mapping.h>
#include <fe/mapping_q1.h>
#include <fe/fe_dgq.h>
#include <fe/fe_q.h>
#include <fe/fe_values.h>
#include <grid/tria.h>
#include <grid/grid_in.h>
#include <grid/grid_out.h>
#include <numerics/vectors.h>
#include <numerics/data_out.h>

#include <cmath>

std::ofstream logfile("gradients_1/output");

template <int dim, int spacedim>
void test(std::string filename, unsigned int degree = 1)

{
  Triangulation<dim, spacedim> triangulation;
  GridIn<dim, spacedim> gi;

  gi.attach_triangulation (triangulation);
  std::ifstream in (filename.c_str());
  gi.read_ucd (in);

				// finite elements used for the
				// projection
  const FE_Q<dim,spacedim> fe (degree);
  const MappingQ<dim, spacedim> mapping(degree);

  DoFHandler<dim,spacedim> dof_handler (triangulation);
  dof_handler.distribute_dofs (fe);

  deallog
      << "no. of cells "<< triangulation.n_cells() <<std::endl;
  deallog
      << "no. of dofs "<< dof_handler.n_dofs()<< std::endl;
  deallog
      << "no. of dofs per cell "<< fe.dofs_per_cell<< std::endl;

				//  definition of the exact function
				//  and calculation of the projected
				//  one
  Vector<double> projected_one(dof_handler.n_dofs());

  Functions::CosineFunction<spacedim> the_function;

  // Tensor<1,spacedim> exp;
  // exp[0]=1;
  // exp[1]=0;
  // if(spacedim==3)
  //     exp[2]=0;
  // Functions::Monomial<spacedim> the_function(exp);

  const QGauss<dim> quad(2*fe.degree+1);
  ConstraintMatrix constraints;
  constraints.close();
  VectorTools::project(mapping, dof_handler, constraints,
		       quad, the_function, projected_one);

  deallog << "L2 norm of projected vector: "
	  << projected_one.l2_norm() << endl;

				// compute the H1 difference
  Vector<float> difference_per_cell (triangulation.n_active_cells());
  VectorTools::integrate_difference (dof_handler, projected_one,
				     the_function, difference_per_cell,
				     quad, VectorTools::H1_norm);

  deallog << "H1 error: " << difference_per_cell.l2_norm() << endl;
}

int main ()
{
  logfile.precision (4);
  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-12);

    deallog<<"Test <1,2>, Q1, Q2, Q3"<<std::endl;
    test<1,2>("grids/circle_4.inp",1);
    test<1,2>("grids/circle_4.inp",2);
    test<1,2>("grids/circle_4.inp",3);

    deallog<<std::endl;

    deallog<<"Test <2,3>, Q1, Q2, Q3"<<std::endl;
    test<2,3>("grids/sphere_1.inp",1);
    test<2,3>("grids/sphere_1.inp",2);
    test<2,3>("grids/sphere_1.inp",3);

    return 0;
}

<|endoftext|>


<commit_before>/*------------------------------------------------------------------------------

    Copyright (c) 2004 Media Development Loan Fund

    This file is part of the LiveSupport project.
    http://livesupport.campware.org/
    To report bugs, send an e-mail to bugs@campware.org

    LiveSupport is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    LiveSupport is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with LiveSupport; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Author   : $Author$
    Version  : $Revision$
    Location : $URL$

------------------------------------------------------------------------------*/

/* ============================================================ include files */

#include "SchedulerDaemon.h"
#include "BaseTestMethod.h"

using namespace LiveSupport::Scheduler;

/* ===================================================  local data structures */

/* ================================================  local constants & macros */

/*------------------------------------------------------------------------------
 *  The XML-RPC host to connect to.
 *----------------------------------------------------------------------------*/
std::string LiveSupport::Scheduler::BaseTestMethod::xmlRpcHost;

/*------------------------------------------------------------------------------
 *  The XML-RPC port number to connect to.
 *----------------------------------------------------------------------------*/
unsigned int LiveSupport::Scheduler::BaseTestMethod::xmlRpcPort;

/*------------------------------------------------------------------------------
 *  A flag to indicate if configuration has already been done.
 *----------------------------------------------------------------------------*/
bool LiveSupport::Scheduler::BaseTestMethod::configured = false;

/* ===============================================  local function prototypes */

/* =============================================================  module code */

/*------------------------------------------------------------------------------
 *  Read configuration information.
 *----------------------------------------------------------------------------*/
void
LiveSupport::Scheduler::
BaseTestMethod :: configure(std::string configFileName)
                                                        throw (std::exception)
{
    if (!configured) {
        Ptr<SchedulerDaemon>::Ref   scheduler = SchedulerDaemon::getInstance();

        try {
            std::auto_ptr<xmlpp::DomParser>
                            parser(new xmlpp::DomParser(configFileName, true));
            const xmlpp::Document * document = parser->get_document();
            scheduler->configure(*(document->get_root_node()));
        } catch (std::invalid_argument &e) {
            std::cerr << "semantic error in configuration file" << std::endl
                      << e.what() << std::endl;
        } catch (xmlpp::exception &e) {
            std::cerr << "error parsing configuration file" << std::endl
                      << e.what() << std::endl;
        }

        xmlRpcHost = scheduler->getXmlRpcHost();
        xmlRpcPort = scheduler->getXmlRpcPort();
    }
}

<commit_msg>minor bugfix; the 'configured' variable was never set to true<commit_after>/*------------------------------------------------------------------------------

    Copyright (c) 2004 Media Development Loan Fund

    This file is part of the LiveSupport project.
    http://livesupport.campware.org/
    To report bugs, send an e-mail to bugs@campware.org

    LiveSupport is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    LiveSupport is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with LiveSupport; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Author   : $Author$
    Version  : $Revision$
    Location : $URL$

------------------------------------------------------------------------------*/

/* ============================================================ include files */

#include "SchedulerDaemon.h"
#include "BaseTestMethod.h"

using namespace LiveSupport::Scheduler;

/* ===================================================  local data structures */

/* ================================================  local constants & macros */

/*------------------------------------------------------------------------------
 *  The XML-RPC host to connect to.
 *----------------------------------------------------------------------------*/
std::string LiveSupport::Scheduler::BaseTestMethod::xmlRpcHost;

/*------------------------------------------------------------------------------
 *  The XML-RPC port number to connect to.
 *----------------------------------------------------------------------------*/
unsigned int LiveSupport::Scheduler::BaseTestMethod::xmlRpcPort;

/*------------------------------------------------------------------------------
 *  A flag to indicate if configuration has already been done.
 *----------------------------------------------------------------------------*/
bool LiveSupport::Scheduler::BaseTestMethod::configured = false;

/* ===============================================  local function prototypes */

/* =============================================================  module code */

/*------------------------------------------------------------------------------
 *  Read configuration information.
 *----------------------------------------------------------------------------*/
void
LiveSupport::Scheduler::
BaseTestMethod :: configure(std::string configFileName)
                                                        throw (std::exception)
{
    if (!configured) {
        Ptr<SchedulerDaemon>::Ref   scheduler = SchedulerDaemon::getInstance();

        try {
            std::auto_ptr<xmlpp::DomParser>
                            parser(new xmlpp::DomParser(configFileName, true));
            const xmlpp::Document * document = parser->get_document();
            scheduler->configure(*(document->get_root_node()));
        } catch (std::invalid_argument &e) {
            std::cerr << "semantic error in configuration file" << std::endl
                      << e.what() << std::endl;
        } catch (xmlpp::exception &e) {
            std::cerr << "error parsing configuration file" << std::endl
                      << e.what() << std::endl;
        }

        xmlRpcHost = scheduler->getXmlRpcHost();
        xmlRpcPort = scheduler->getXmlRpcPort();
        configured = true;
    }
}

<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post
    Copyright (C) 2014 Pedro Côrte-Real

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "decoders/DcrDecoder.h"
#include "common/Common.h"                // for uint32, uchar8, ushort16
#include "common/NORangesSet.h"           // for NORangesSet
#include "decoders/RawDecoderException.h" // for RawDecoderException (ptr o...
#include "decompressors/HuffmanTable.h"   // for HuffmanTable
#include "io/ByteStream.h"                // for ByteStream
#include "io/IOException.h"               // for IOException
#include "tiff/TiffEntry.h"               // for TiffEntry, TiffDataType::T...
#include "tiff/TiffIFD.h"                 // for TiffRootIFD, TiffIFD
#include "tiff/TiffTag.h"                 // for TiffTag, TiffTag::COMPRESSION
#include <cassert>                        // for assert
#include <memory>                         // for unique_ptr
#include <string>                         // for operator==, string

using std::min;

namespace rawspeed {

class CameraMetaData;

bool DcrDecoder::isAppropriateDecoder(const TiffRootIFD* rootIFD,
                                      const Buffer* file) {
  const auto id = rootIFD->getID();
  const std::string& make = id.make;

  // FIXME: magic

  return make == "Kodak";
}

void DcrDecoder::checkImageDimensions() {
  if (width > 4516 || height > 3012)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);
}

RawImage DcrDecoder::decodeRawInternal() {
  SimpleTiffDecoder::prepareForRawDecoding();

  ByteStream input(mFile, off);

  int compression = raw->getEntry(COMPRESSION)->getU32();
  if (65000 == compression) {
    TiffEntry *ifdoffset = mRootIFD->getEntryRecursive(KODAK_IFD);
    if (!ifdoffset)
      ThrowRDE("Couldn't find the Kodak IFD offset");

    NORangesSet<Buffer> ifds;

    assert(ifdoffset != nullptr);
    TiffRootIFD kodakifd(nullptr, &ifds, ifdoffset->getRootIfdData(),
                         ifdoffset->getU32());

    TiffEntry *linearization = kodakifd.getEntryRecursive(KODAK_LINEARIZATION);
    if (!linearization || linearization->count != 1024 ||
        linearization->type != TIFF_SHORT)
      ThrowRDE("Couldn't find the linearization table");

    assert(linearization != nullptr);
    auto linTable = linearization->getU16Array(1024);

    RawImageCurveGuard curveHandler(&mRaw, linTable, uncorrectedRawValues);

    // FIXME: dcraw does all sorts of crazy things besides this to fetch
    //        WB from what appear to be presets and calculate it in weird ways
    //        The only file I have only uses this method, if anybody careas look
    //        in dcraw.c parse_kodak_ifd() for all that weirdness
    TiffEntry* blob = kodakifd.getEntryRecursive(static_cast<TiffTag>(0x03fd));
    if (blob && blob->count == 72) {
      mRaw->metadata.wbCoeffs[0] = 2048.0F / blob->getU16(20);
      mRaw->metadata.wbCoeffs[1] = 2048.0F / blob->getU16(21);
      mRaw->metadata.wbCoeffs[2] = 2048.0F / blob->getU16(22);
    }

    try {
      decodeKodak65000(&input, width, height);
    } catch (IOException &) {
      mRaw->setError("IO error occurred while reading image. Returning partial result.");
    }
  } else
    ThrowRDE("Unsupported compression %d", compression);

  return mRaw;
}

void DcrDecoder::decodeKodak65000(ByteStream* input, uint32 w, uint32 h) {
  ushort16 buf[256];
  uint32 pred[2];
  uchar8* data = mRaw->getData();
  uint32 pitch = mRaw->pitch;

  uint32 random = 0;
  for (uint32 y = 0; y < h; y++) {
    auto* dest = reinterpret_cast<ushort16*>(&data[y * pitch]);
    for (uint32 x = 0 ; x < w; x += 256) {
      pred[0] = pred[1] = 0;
      uint32 len = min(256U, w - x);
      decodeKodak65000Segment(input, buf, len);
      for (uint32 i = 0; i < len; i++) {
        pred[i & 1] += buf[i];

        ushort16 value = pred[i & 1];
        if (value > 1023)
          ThrowRDE("Value out of bounds %d", value);
        if(uncorrectedRawValues)
          dest[x+i] = value;
        else
          mRaw->setWithLookUp(value, reinterpret_cast<uchar8*>(&dest[x + i]),
                              &random);
      }
    }
  }
}

void DcrDecoder::decodeKodak65000Segment(ByteStream* input, ushort16* out,
                                         uint32 bsize) {
  uchar8 blen[768];
  uint64 bitbuf=0;
  uint32 bits=0;

  bsize = (bsize + 3) & -4;
  for (uint32 i=0; i < bsize; i+=2) {
    blen[i] = input->peekByte() & 15;
    blen[i + 1] = input->getByte() >> 4;
  }
  if ((bsize & 7) == 4) {
    bitbuf = (static_cast<uint64>(input->getByte())) << 8UL;
    bitbuf += (static_cast<int>(input->getByte()));
    bits = 16;
  }
  for (uint32 i=0; i < bsize; i++) {
    uint32 len = blen[i];
    if (bits < len) {
      for (uint32 j=0; j < 32; j+=8) {
        bitbuf += static_cast<long long>(static_cast<int>(input->getByte()))
                  << (bits + (j ^ 8));
      }
      bits += 32;
    }
    uint32 diff = static_cast<uint32>(bitbuf) & (0xffff >> (16 - len));
    bitbuf >>= len;
    bits -= len;
    diff = len != 0 ? HuffmanTable::signExtended(diff, len) : diff;
    out[i] = diff;
  }
}

void DcrDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
  setMetaData(meta, "", 0);
}

} // namespace rawspeed
<commit_msg>DcrDecoder::decodeRawInternal(): don't catch IOException.<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post
    Copyright (C) 2014 Pedro Côrte-Real

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "decoders/DcrDecoder.h"
#include "common/Common.h"                // for uint32, uchar8, ushort16
#include "common/NORangesSet.h"           // for NORangesSet
#include "decoders/RawDecoderException.h" // for RawDecoderException (ptr o...
#include "decompressors/HuffmanTable.h"   // for HuffmanTable
#include "io/ByteStream.h"                // for ByteStream
#include "io/IOException.h"               // for IOException
#include "tiff/TiffEntry.h"               // for TiffEntry, TiffDataType::T...
#include "tiff/TiffIFD.h"                 // for TiffRootIFD, TiffIFD
#include "tiff/TiffTag.h"                 // for TiffTag, TiffTag::COMPRESSION
#include <cassert>                        // for assert
#include <memory>                         // for unique_ptr
#include <string>                         // for operator==, string

using std::min;

namespace rawspeed {

class CameraMetaData;

bool DcrDecoder::isAppropriateDecoder(const TiffRootIFD* rootIFD,
                                      const Buffer* file) {
  const auto id = rootIFD->getID();
  const std::string& make = id.make;

  // FIXME: magic

  return make == "Kodak";
}

void DcrDecoder::checkImageDimensions() {
  if (width > 4516 || height > 3012)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);
}

RawImage DcrDecoder::decodeRawInternal() {
  SimpleTiffDecoder::prepareForRawDecoding();

  ByteStream input(mFile, off);

  int compression = raw->getEntry(COMPRESSION)->getU32();
  if (65000 == compression) {
    TiffEntry *ifdoffset = mRootIFD->getEntryRecursive(KODAK_IFD);
    if (!ifdoffset)
      ThrowRDE("Couldn't find the Kodak IFD offset");

    NORangesSet<Buffer> ifds;

    assert(ifdoffset != nullptr);
    TiffRootIFD kodakifd(nullptr, &ifds, ifdoffset->getRootIfdData(),
                         ifdoffset->getU32());

    TiffEntry *linearization = kodakifd.getEntryRecursive(KODAK_LINEARIZATION);
    if (!linearization || linearization->count != 1024 ||
        linearization->type != TIFF_SHORT)
      ThrowRDE("Couldn't find the linearization table");

    assert(linearization != nullptr);
    auto linTable = linearization->getU16Array(1024);

    RawImageCurveGuard curveHandler(&mRaw, linTable, uncorrectedRawValues);

    // FIXME: dcraw does all sorts of crazy things besides this to fetch
    //        WB from what appear to be presets and calculate it in weird ways
    //        The only file I have only uses this method, if anybody careas look
    //        in dcraw.c parse_kodak_ifd() for all that weirdness
    TiffEntry* blob = kodakifd.getEntryRecursive(static_cast<TiffTag>(0x03fd));
    if (blob && blob->count == 72) {
      mRaw->metadata.wbCoeffs[0] = 2048.0F / blob->getU16(20);
      mRaw->metadata.wbCoeffs[1] = 2048.0F / blob->getU16(21);
      mRaw->metadata.wbCoeffs[2] = 2048.0F / blob->getU16(22);
    }

    decodeKodak65000(&input, width, height);
  } else
    ThrowRDE("Unsupported compression %d", compression);

  return mRaw;
}

void DcrDecoder::decodeKodak65000(ByteStream* input, uint32 w, uint32 h) {
  ushort16 buf[256];
  uint32 pred[2];
  uchar8* data = mRaw->getData();
  uint32 pitch = mRaw->pitch;

  uint32 random = 0;
  for (uint32 y = 0; y < h; y++) {
    auto* dest = reinterpret_cast<ushort16*>(&data[y * pitch]);
    for (uint32 x = 0 ; x < w; x += 256) {
      pred[0] = pred[1] = 0;
      uint32 len = min(256U, w - x);
      decodeKodak65000Segment(input, buf, len);
      for (uint32 i = 0; i < len; i++) {
        pred[i & 1] += buf[i];

        ushort16 value = pred[i & 1];
        if (value > 1023)
          ThrowRDE("Value out of bounds %d", value);
        if(uncorrectedRawValues)
          dest[x+i] = value;
        else
          mRaw->setWithLookUp(value, reinterpret_cast<uchar8*>(&dest[x + i]),
                              &random);
      }
    }
  }
}

void DcrDecoder::decodeKodak65000Segment(ByteStream* input, ushort16* out,
                                         uint32 bsize) {
  uchar8 blen[768];
  uint64 bitbuf=0;
  uint32 bits=0;

  bsize = (bsize + 3) & -4;
  for (uint32 i=0; i < bsize; i+=2) {
    blen[i] = input->peekByte() & 15;
    blen[i + 1] = input->getByte() >> 4;
  }
  if ((bsize & 7) == 4) {
    bitbuf = (static_cast<uint64>(input->getByte())) << 8UL;
    bitbuf += (static_cast<int>(input->getByte()));
    bits = 16;
  }
  for (uint32 i=0; i < bsize; i++) {
    uint32 len = blen[i];
    if (bits < len) {
      for (uint32 j=0; j < 32; j+=8) {
        bitbuf += static_cast<long long>(static_cast<int>(input->getByte()))
                  << (bits + (j ^ 8));
      }
      bits += 32;
    }
    uint32 diff = static_cast<uint32>(bitbuf) & (0xffff >> (16 - len));
    bitbuf >>= len;
    bits -= len;
    diff = len != 0 ? HuffmanTable::signExtended(diff, len) : diff;
    out[i] = diff;
  }
}

void DcrDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
  setMetaData(meta, "", 0);
}

} // namespace rawspeed
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 1999-2009 Soeren Sonnenburg
 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "classifier/svm/LibSVM.h"
#include "lib/io.h"

using namespace shogun;

#ifdef HAVE_BOOST_SERIALIZATION
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(CLibSVM);
#endif //HAVE_BOOST_SERIALIZATION

CLibSVM::CLibSVM(LIBSVM_SOLVER_TYPE st)
: CSVM(), model(NULL), solver_type(st)
{
}

CLibSVM::CLibSVM(float64_t C, CKernel* k, CLabels* lab)
: CSVM(C, k, lab), model(NULL), solver_type(LIBSVM_C_SVC)
{
	problem = svm_problem();
}

CLibSVM::~CLibSVM()
{
}

bool CLibSVM::train(CFeatures* data)
{
	struct svm_node* x_space;

	ASSERT(labels && labels->get_num_labels());
	ASSERT(labels->is_two_class_labeling());

	if (data)
	{
		if (labels->get_num_labels() != data->get_num_vectors())
			SG_ERROR("Number of training vectors does not match number of labels\n");
		kernel->init(data, data);
	}

	problem.l=labels->get_num_labels();
	SG_INFO( "%d trainlabels\n", problem.l);

	// check length of linear term
	if (!linear_term.empty() &&
			labels->get_num_labels() != (int32_t)linear_term.size())
	{
		SG_ERROR("Number of training vectors does not match length of linear term\n");
	}

	// set linear term
	if (!linear_term.empty())
	{
		// set with linear term from base class
		problem.pv = get_linear_term_array();

	}
	else
	{
		// fill with minus ones
		problem.pv = new float64_t[problem.l];

		for (int i=0; i!=problem.l; i++) {
			problem.pv[i] = -1.0;
		}
	}

	problem.y=new float64_t[problem.l];
	problem.x=new struct svm_node*[problem.l];
    problem.C=new float64_t[problem.l];

	x_space=new struct svm_node[2*problem.l];

	for (int32_t i=0; i<problem.l; i++)
	{
		problem.y[i]=labels->get_label(i);
		problem.x[i]=&x_space[2*i];
		x_space[2*i].index=i;
		x_space[2*i+1].index=-1;
	}

	int32_t weights_label[2]={-1,+1};
	float64_t weights[2]={1.0,get_C2()/get_C1()};

	ASSERT(kernel && kernel->has_features());
    ASSERT(kernel->get_num_vec_lhs()==problem.l);

	param.svm_type=solver_type; // C SVM or NU_SVM
	param.kernel_type = LINEAR;
	param.degree = 3;
	param.gamma = 0;	// 1/k
	param.coef0 = 0;
	param.nu = get_nu();
	param.kernel=kernel;
	param.cache_size = kernel->get_cache_size();
	param.max_train_time = max_train_time;
	param.C = get_C1();
	param.eps = epsilon;
	param.p = 0.1;
	param.shrinking = 1;
	param.nr_weight = 2;
	param.weight_label = weights_label;
	param.weight = weights;
	param.use_bias = get_bias_enabled();

	const char* error_msg = svm_check_parameter(&problem, &param);

	if(error_msg)
		SG_ERROR("Error: %s\n",error_msg);

	model = svm_train(&problem, &param);

	if (model)
	{
		ASSERT(model->nr_class==2);
		ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef && model->sv_coef[0]));

		int32_t num_sv=model->l;

		create_new_model(num_sv);
		CSVM::set_objective(model->objective);

		float64_t sgn=model->label[0];

		set_bias(-sgn*model->rho[0]);

		for (int32_t i=0; i<num_sv; i++)
		{
			set_support_vector(i, (model->SV[i])->index);
			set_alpha(i, sgn*model->sv_coef[0][i]);
		}

		delete[] problem.x;
		delete[] problem.y;
		delete[] problem.pv;
        delete[] problem.C;

		delete[] x_space;

		svm_destroy_model(model);
		model=NULL;
		return true;
	}
	else
		return false;
}
<commit_msg>minor cleanup<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 1999-2009 Soeren Sonnenburg
 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "classifier/svm/LibSVM.h"
#include "lib/io.h"

using namespace shogun;

#ifdef HAVE_BOOST_SERIALIZATION
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(CLibSVM);
#endif //HAVE_BOOST_SERIALIZATION

CLibSVM::CLibSVM(LIBSVM_SOLVER_TYPE st)
: CSVM(), model(NULL), solver_type(st)
{
}

CLibSVM::CLibSVM(float64_t C, CKernel* k, CLabels* lab)
: CSVM(C, k, lab), model(NULL), solver_type(LIBSVM_C_SVC)
{
	problem = svm_problem();
}

CLibSVM::~CLibSVM()
{
}

bool CLibSVM::train(CFeatures* data)
{
	struct svm_node* x_space;

	ASSERT(labels && labels->get_num_labels());
	ASSERT(labels->is_two_class_labeling());

	if (data)
	{
		if (labels->get_num_labels() != data->get_num_vectors())
			SG_ERROR("Number of training vectors does not match number of labels\n");
		kernel->init(data, data);
	}

	problem.l=labels->get_num_labels();
	SG_INFO( "%d trainlabels\n", problem.l);

	// check length of linear term
	if (!linear_term.empty() &&
			labels->get_num_labels() != (int32_t)linear_term.size())
	{
		SG_ERROR("Number of training vectors does not match length of linear term\n");
	}

	// set linear term
	if (!linear_term.empty())
	{
		// set with linear term from base class
		problem.pv = get_linear_term_array();

	}
	else
	{
		// fill with minus ones
		problem.pv = new float64_t[problem.l];

		for (int i=0; i!=problem.l; i++)
			problem.pv[i] = -1.0;
	}

	problem.y=new float64_t[problem.l];
	problem.x=new struct svm_node*[problem.l];
    problem.C=new float64_t[problem.l];

	x_space=new struct svm_node[2*problem.l];

	for (int32_t i=0; i<problem.l; i++)
	{
		problem.y[i]=labels->get_label(i);
		problem.x[i]=&x_space[2*i];
		x_space[2*i].index=i;
		x_space[2*i+1].index=-1;
	}

	int32_t weights_label[2]={-1,+1};
	float64_t weights[2]={1.0,get_C2()/get_C1()};

	ASSERT(kernel && kernel->has_features());
    ASSERT(kernel->get_num_vec_lhs()==problem.l);

	param.svm_type=solver_type; // C SVM or NU_SVM
	param.kernel_type = LINEAR;
	param.degree = 3;
	param.gamma = 0;	// 1/k
	param.coef0 = 0;
	param.nu = get_nu();
	param.kernel=kernel;
	param.cache_size = kernel->get_cache_size();
	param.max_train_time = max_train_time;
	param.C = get_C1();
	param.eps = epsilon;
	param.p = 0.1;
	param.shrinking = 1;
	param.nr_weight = 2;
	param.weight_label = weights_label;
	param.weight = weights;
	param.use_bias = get_bias_enabled();

	const char* error_msg = svm_check_parameter(&problem, &param);

	if(error_msg)
		SG_ERROR("Error: %s\n",error_msg);

	model = svm_train(&problem, &param);

	if (model)
	{
		ASSERT(model->nr_class==2);
		ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef && model->sv_coef[0]));

		int32_t num_sv=model->l;

		create_new_model(num_sv);
		CSVM::set_objective(model->objective);

		float64_t sgn=model->label[0];

		set_bias(-sgn*model->rho[0]);

		for (int32_t i=0; i<num_sv; i++)
		{
			set_support_vector(i, (model->SV[i])->index);
			set_alpha(i, sgn*model->sv_coef[0][i]);
		}

		delete[] problem.x;
		delete[] problem.y;
		delete[] problem.pv;
        delete[] problem.C;

		delete[] x_space;

		svm_destroy_model(model);
		model=NULL;
		return true;
	}
	else
		return false;
}
<|endoftext|>


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

#include "bloom.h"

#include "primitives/transaction.h"
#include "hash.h"
#include "script/script.h"
#include "script/standard.h"
#include "streams.h"

#include <math.h>
#include <stdlib.h>

#include <boost/foreach.hpp>

#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
#define LN2 0.6931471805599453094172321214581765680755001343602552

using namespace std;

CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) :
    /**
     * The ideal size for a bloom filter with a given number of elements and false positive rate is:
     * - nElements * log(fp rate) / ln(2)^2
     * We ignore filter parameters which will create a bloom filter larger than the protocol limits
     */
    vData(min((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8),
    /**
     * The ideal number of hash functions is filter size * ln(2) / number of elements
     * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
     * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
     */
    isFull(false),
    isEmpty(false),
    nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)),
    nTweak(nTweakIn),
    nFlags(nFlagsIn)
{
}

// Private constructor used by CRollingBloomFilter
CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn) :
    vData((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)) / 8),
    isFull(false),
    isEmpty(true),
    nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)),
    nTweak(nTweakIn),
    nFlags(BLOOM_UPDATE_NONE)
{
}

inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const
{
    // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
    return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
}

void CBloomFilter::insert(const vector<unsigned char>& vKey)
{
    if (isFull)
        return;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Sets bit nIndex of vData
        vData[nIndex >> 3] |= (1 << (7 & nIndex));
    }
    isEmpty = false;
}

void CBloomFilter::insert(const COutPoint& outpoint)
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    insert(data);
}

void CBloomFilter::insert(const uint256& hash)
{
    vector<unsigned char> data(hash.begin(), hash.end());
    insert(data);
}

bool CBloomFilter::contains(const vector<unsigned char>& vKey) const
{
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Checks bit nIndex of vData
        if (!(vData[nIndex >> 3] & (1 << (7 & nIndex))))
            return false;
    }
    return true;
}

bool CBloomFilter::contains(const COutPoint& outpoint) const
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    return contains(data);
}

bool CBloomFilter::contains(const uint256& hash) const
{
    vector<unsigned char> data(hash.begin(), hash.end());
    return contains(data);
}

void CBloomFilter::clear()
{
    vData.assign(vData.size(),0);
    isFull = false;
    isEmpty = true;
}

bool CBloomFilter::IsWithinSizeConstraints() const
{
    return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
}

bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
{
    bool fFound = false;
    // Match if the filter contains the hash of tx
    //  for finding tx when they appear in a block
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    const uint256& hash = tx.GetHash();
    if (contains(hash))
        fFound = true;

    for (unsigned int i = 0; i < tx.vout.size(); i++)
    {
        const CTxOut& txout = tx.vout[i];
        // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
        // If this matches, also add the specific output that was matched.
        // This means clients don't have to update the filter themselves when a new relevant tx
        // is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
        CScript::const_iterator pc = txout.scriptPubKey.begin();
        vector<unsigned char> data;
        while (pc < txout.scriptPubKey.end())
        {
            opcodetype opcode;
            if (!txout.scriptPubKey.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
            {
                fFound = true;
                if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
                    insert(COutPoint(hash, i));
                else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
                {
                    txnouttype type;
                    vector<vector<unsigned char> > vSolutions;
                    if (Solver(txout.scriptPubKey, type, vSolutions) &&
                            (type == TX_PUBKEY || type == TX_MULTISIG))
                        insert(COutPoint(hash, i));
                }
                break;
            }
        }
    }

    if (fFound)
        return true;

    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    {
        // Match if the filter contains an outpoint tx spends
        if (contains(txin.prevout))
            return true;

        // Match if the filter contains any arbitrary script data element in any scriptSig in tx
        CScript::const_iterator pc = txin.scriptSig.begin();
        vector<unsigned char> data;
        while (pc < txin.scriptSig.end())
        {
            opcodetype opcode;
            if (!txin.scriptSig.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
                return true;
        }
    }

    return false;
}

void CBloomFilter::UpdateEmptyFull()
{
    bool full = true;
    bool empty = true;
    for (unsigned int i = 0; i < vData.size(); i++)
    {
        full &= vData[i] == 0xff;
        empty &= vData[i] == 0;
    }
    isFull = full;
    isEmpty = empty;
}

CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) :
    b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak)
{
    // Implemented using two bloom filters of 2 * nElements each.
    // We fill them up, and clear them, staggered, every nElements
    // inserted, so at least one always contains the last nElements
    // inserted.
    nBloomSize = nElements * 2;
    nInsertions = 0;
}

void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
{
    if (nInsertions == 0) {
        b1.clear();
    } else if (nInsertions == nBloomSize / 2) {
        b2.clear();
    }
    b1.insert(vKey);
    b2.insert(vKey);
    if (++nInsertions == nBloomSize) {
        nInsertions = 0;
    }
}

void CRollingBloomFilter::insert(const uint256& hash)
{
    if (nInsertions == 0) {
        b1.clear();
    } else if (nInsertions == nBloomSize / 2) {
        b2.clear();
    }
    b1.insert(hash);
    b2.insert(hash);
    if (++nInsertions == nBloomSize) {
        nInsertions = 0;
    }
}

bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
{
    if (nInsertions < nBloomSize / 2) {
        return b2.contains(vKey);
    }
    return b1.contains(vKey);
}

bool CRollingBloomFilter::contains(const uint256& hash) const
{
    if (nInsertions < nBloomSize / 2) {
        return b2.contains(hash);
    }
    return b1.contains(hash);
}

void CRollingBloomFilter::clear()
{
    b1.clear();
    b2.clear();
    nInsertions = 0;
}
<commit_msg>Reuse vector hashing code for uint256<commit_after>// Copyright (c) 2012-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bloom.h"

#include "primitives/transaction.h"
#include "hash.h"
#include "script/script.h"
#include "script/standard.h"
#include "streams.h"

#include <math.h>
#include <stdlib.h>

#include <boost/foreach.hpp>

#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
#define LN2 0.6931471805599453094172321214581765680755001343602552

using namespace std;

CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) :
    /**
     * The ideal size for a bloom filter with a given number of elements and false positive rate is:
     * - nElements * log(fp rate) / ln(2)^2
     * We ignore filter parameters which will create a bloom filter larger than the protocol limits
     */
    vData(min((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8),
    /**
     * The ideal number of hash functions is filter size * ln(2) / number of elements
     * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
     * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
     */
    isFull(false),
    isEmpty(false),
    nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)),
    nTweak(nTweakIn),
    nFlags(nFlagsIn)
{
}

// Private constructor used by CRollingBloomFilter
CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn) :
    vData((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)) / 8),
    isFull(false),
    isEmpty(true),
    nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)),
    nTweak(nTweakIn),
    nFlags(BLOOM_UPDATE_NONE)
{
}

inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const
{
    // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
    return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
}

void CBloomFilter::insert(const vector<unsigned char>& vKey)
{
    if (isFull)
        return;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Sets bit nIndex of vData
        vData[nIndex >> 3] |= (1 << (7 & nIndex));
    }
    isEmpty = false;
}

void CBloomFilter::insert(const COutPoint& outpoint)
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    insert(data);
}

void CBloomFilter::insert(const uint256& hash)
{
    vector<unsigned char> data(hash.begin(), hash.end());
    insert(data);
}

bool CBloomFilter::contains(const vector<unsigned char>& vKey) const
{
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Checks bit nIndex of vData
        if (!(vData[nIndex >> 3] & (1 << (7 & nIndex))))
            return false;
    }
    return true;
}

bool CBloomFilter::contains(const COutPoint& outpoint) const
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    return contains(data);
}

bool CBloomFilter::contains(const uint256& hash) const
{
    vector<unsigned char> data(hash.begin(), hash.end());
    return contains(data);
}

void CBloomFilter::clear()
{
    vData.assign(vData.size(),0);
    isFull = false;
    isEmpty = true;
}

bool CBloomFilter::IsWithinSizeConstraints() const
{
    return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
}

bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
{
    bool fFound = false;
    // Match if the filter contains the hash of tx
    //  for finding tx when they appear in a block
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    const uint256& hash = tx.GetHash();
    if (contains(hash))
        fFound = true;

    for (unsigned int i = 0; i < tx.vout.size(); i++)
    {
        const CTxOut& txout = tx.vout[i];
        // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
        // If this matches, also add the specific output that was matched.
        // This means clients don't have to update the filter themselves when a new relevant tx
        // is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
        CScript::const_iterator pc = txout.scriptPubKey.begin();
        vector<unsigned char> data;
        while (pc < txout.scriptPubKey.end())
        {
            opcodetype opcode;
            if (!txout.scriptPubKey.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
            {
                fFound = true;
                if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
                    insert(COutPoint(hash, i));
                else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
                {
                    txnouttype type;
                    vector<vector<unsigned char> > vSolutions;
                    if (Solver(txout.scriptPubKey, type, vSolutions) &&
                            (type == TX_PUBKEY || type == TX_MULTISIG))
                        insert(COutPoint(hash, i));
                }
                break;
            }
        }
    }

    if (fFound)
        return true;

    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    {
        // Match if the filter contains an outpoint tx spends
        if (contains(txin.prevout))
            return true;

        // Match if the filter contains any arbitrary script data element in any scriptSig in tx
        CScript::const_iterator pc = txin.scriptSig.begin();
        vector<unsigned char> data;
        while (pc < txin.scriptSig.end())
        {
            opcodetype opcode;
            if (!txin.scriptSig.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
                return true;
        }
    }

    return false;
}

void CBloomFilter::UpdateEmptyFull()
{
    bool full = true;
    bool empty = true;
    for (unsigned int i = 0; i < vData.size(); i++)
    {
        full &= vData[i] == 0xff;
        empty &= vData[i] == 0;
    }
    isFull = full;
    isEmpty = empty;
}

CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) :
    b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak)
{
    // Implemented using two bloom filters of 2 * nElements each.
    // We fill them up, and clear them, staggered, every nElements
    // inserted, so at least one always contains the last nElements
    // inserted.
    nBloomSize = nElements * 2;
    nInsertions = 0;
}

void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
{
    if (nInsertions == 0) {
        b1.clear();
    } else if (nInsertions == nBloomSize / 2) {
        b2.clear();
    }
    b1.insert(vKey);
    b2.insert(vKey);
    if (++nInsertions == nBloomSize) {
        nInsertions = 0;
    }
}

void CRollingBloomFilter::insert(const uint256& hash)
{
    vector<unsigned char> data(hash.begin(), hash.end());
    insert(data);
}

bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
{
    if (nInsertions < nBloomSize / 2) {
        return b2.contains(vKey);
    }
    return b1.contains(vKey);
}

bool CRollingBloomFilter::contains(const uint256& hash) const
{
    vector<unsigned char> data(hash.begin(), hash.end());
    return contains(data);
}

void CRollingBloomFilter::clear()
{
    b1.clear();
    b2.clear();
    nInsertions = 0;
}
<|endoftext|>


<commit_before>#include "buffer.hh"

#include "buffer_manager.hh"
#include "window.hh"
#include "assert.hh"
#include "utils.hh"
#include "context.hh"
#include "utf8.hh"

#include <algorithm>

namespace Kakoune
{

Buffer::Buffer(String name, Flags flags, std::vector<String> lines)
    : m_name(std::move(name)), m_flags(flags | Flags::NoUndo),
      m_history(), m_history_cursor(m_history.begin()),
      m_last_save_undo_index(0),
      m_timestamp(0),
      m_hooks(GlobalHooks::instance()),
      m_options(GlobalOptions::instance())
{
    BufferManager::instance().register_buffer(*this);

    if (lines.empty())
        lines.emplace_back("\n");

    ByteCount pos = 0;
    m_lines.reserve(lines.size());
    for (auto& line : lines)
    {
        assert(not line.empty() and line.back() == '\n');
        m_lines.emplace_back(Line{ pos, std::move(line) });
        pos += m_lines.back().length();
    }

    Editor editor_for_hooks(*this);
    Context context(editor_for_hooks);
    if (flags & Flags::File and flags & Flags::New)
        m_hooks.run_hook("BufNew", m_name, context);
    else
        m_hooks.run_hook("BufOpen", m_name, context);

    m_hooks.run_hook("BufCreate", m_name, context);

    // now we may begin to record undo data
    m_flags = flags;
}

Buffer::~Buffer()
{
    {
        Editor hook_editor{*this};
        Context hook_context{hook_editor};
        m_hooks.run_hook("BufClose", m_name, hook_context);
    }

    BufferManager::instance().unregister_buffer(*this);
    assert(m_change_listeners.empty());
}

BufferIterator Buffer::iterator_at(const BufferCoord& line_and_column,
                                   bool avoid_eol) const
{
    return BufferIterator(*this, clamp(line_and_column, avoid_eol));
}

ByteCount Buffer::line_length(LineCount line) const
{
    assert(line < line_count());
    ByteCount end = (line < line_count() - 1) ?
                    m_lines[line + 1].start : character_count();
    return end - m_lines[line].start;
}

BufferCoord Buffer::clamp(const BufferCoord& line_and_column,
                          bool avoid_eol) const
{
    if (m_lines.empty())
        return BufferCoord();

    BufferCoord result(line_and_column.line, line_and_column.column);
    result.line = Kakoune::clamp(result.line, 0_line, line_count() - 1);
    ByteCount max_col = std::max(0_byte, line_length(result.line) - (avoid_eol ? 2 : 1));
    result.column = Kakoune::clamp(result.column, 0_byte, max_col);
    return result;
}

BufferIterator Buffer::iterator_at_line_begin(LineCount line) const
{
    line = Kakoune::clamp(line, 0_line, line_count()-1);
    assert(line_length(line) > 0);
    return BufferIterator(*this, { line, 0 });
}

BufferIterator Buffer::iterator_at_line_begin(const BufferIterator& iterator) const
{
    return iterator_at_line_begin(iterator.line());
}

BufferIterator Buffer::iterator_at_line_end(LineCount line) const
{
    line = Kakoune::clamp(line, 0_line, line_count()-1);
    assert(line_length(line) > 0);
    return ++BufferIterator(*this, { line, line_length(line) - 1 });
}

BufferIterator Buffer::iterator_at_line_end(const BufferIterator& iterator) const
{
    return iterator_at_line_end(iterator.line());
}

BufferIterator Buffer::begin() const
{
    return BufferIterator(*this, { 0_line, 0 });
}

BufferIterator Buffer::end() const
{
    if (m_lines.empty())
        return BufferIterator(*this, { 0_line, 0 });
    return BufferIterator(*this, { line_count()-1, m_lines.back().length() });
}

ByteCount Buffer::character_count() const
{
    if (m_lines.empty())
        return 0;
    return m_lines.back().start + m_lines.back().length();
}

LineCount Buffer::line_count() const
{
    return LineCount(m_lines.size());
}

String Buffer::string(const BufferIterator& begin, const BufferIterator& end) const
{
    String res;
    for (LineCount line = begin.line(); line <= end.line(); ++line)
    {
       ByteCount start = 0;
       if (line == begin.line())
           start = begin.column();
       ByteCount count = -1;
       if (line == end.line())
           count = end.column() - start;
       res += m_lines[line].content.substr(start, count);
    }
    return res;
}

void Buffer::commit_undo_group()
{
    if (m_flags & Flags::NoUndo)
        return;

    if (m_current_undo_group.empty())
        return;

    m_history.erase(m_history_cursor, m_history.end());

    m_history.push_back(std::move(m_current_undo_group));
    m_current_undo_group.clear();
    m_history_cursor = m_history.end();

    if (m_history.size() < m_last_save_undo_index)
        m_last_save_undo_index = -1;
}

// A Modification holds a single atomic modification to Buffer
struct Buffer::Modification
{
    enum Type { Insert, Erase };

    Type           type;
    BufferIterator position;
    String         content;

    Modification(Type type, BufferIterator position, String content)
        : type(type), position(position), content(std::move(content)) {}

    Modification inverse() const
    {
        Type inverse_type = Insert;
        switch (type)
        {
        case Insert: inverse_type = Erase;  break;
        case Erase:  inverse_type = Insert; break;
        default: assert(false);
        }
        return {inverse_type, position, content};
    }
};

bool Buffer::undo()
{
    commit_undo_group();

    if (m_history_cursor == m_history.begin())
        return false;

    --m_history_cursor;

    for (const Modification& modification : reversed(*m_history_cursor))
        apply_modification(modification.inverse());
    return true;
}

bool Buffer::redo()
{
    if (m_history_cursor == m_history.end())
        return false;

    assert(m_current_undo_group.empty());

    for (const Modification& modification : *m_history_cursor)
        apply_modification(modification);

    ++m_history_cursor;
    return true;
}

void Buffer::check_invariant() const
{
#ifdef KAK_DEBUG
    ByteCount start = 0;
    assert(not m_lines.empty());
    for (auto& line : m_lines)
    {
        assert(line.start == start);
        assert(line.length() > 0);
        assert(line.content.back() == '\n');
        start += line.length();
    }
#endif
}

void Buffer::do_insert(const BufferIterator& pos, const String& content)
{
    assert(pos.is_valid() and (pos.is_end() or utf8::is_character_start(pos)));
    assert(not contains(content, '\0'));
    ++m_timestamp;
    ByteCount offset = pos.offset();

    // all following lines advanced by length
    for (LineCount i = pos.line()+1; i < line_count(); ++i)
        m_lines[i].start += content.length();

    BufferIterator begin_it;
    BufferIterator end_it;
    // if we inserted at the end of the buffer, we have created a new
    // line without inserting a '\n'
    if (pos.is_end())
    {
        ByteCount start = 0;
        for (ByteCount i = 0; i < content.length(); ++i)
        {
            if (content[i] == '\n')
            {
                m_lines.push_back({ offset + start, content.substr(start, i + 1 - start) });
                start = i + 1;
            }
        }
        if (start != content.length())
            m_lines.push_back({ offset + start, content.substr(start) });

        begin_it = pos.column() == 0 ? pos : BufferIterator{*this, { pos.line() + 1, 0 }};
        end_it = end();
    }
    else
    {
        String prefix = m_lines[pos.line()].content.substr(0, pos.column());
        String suffix = m_lines[pos.line()].content.substr(pos.column());

        auto line_it = m_lines.begin() + (int)pos.line();
        line_it = m_lines.erase(line_it);

        ByteCount start = 0;
        for (ByteCount i = 0; i < content.length(); ++i)
        {
            if (content[i] == '\n')
            {
                String line_content = content.substr(start, i + 1 - start);
                if (start == 0)
                {
                    line_content = prefix + line_content;
                    line_it = m_lines.insert(line_it, { offset + start - prefix.length(),
                                                        std::move(line_content) });
                }
                else
                    line_it = m_lines.insert(line_it, { offset + start,
                                                        std::move(line_content) });

                ++line_it;
                start = i + 1;
            }
        }
        if (start == 0)
            line_it = m_lines.insert(line_it, { offset + start - prefix.length(), prefix + content + suffix });
        else if (start != content.length() or not suffix.empty())
            line_it = m_lines.insert(line_it, { offset + start, content.substr(start) + suffix });
        else
            --line_it;

        begin_it = pos;
        end_it = BufferIterator(*this, { LineCount(line_it - m_lines.begin()),
                                         line_it->length() - suffix.length() });
    }

    check_invariant();

    for (auto listener : m_change_listeners)
        listener->on_insert(begin_it, end_it);
}

void Buffer::do_erase(const BufferIterator& begin, const BufferIterator& end)
{
    assert(begin.is_valid());
    assert(end.is_valid());
    assert(utf8::is_character_start(begin) and
           (end.is_end() or utf8::is_character_start(end)));
    ++m_timestamp;
    const ByteCount length = end - begin;
    String prefix = m_lines[begin.line()].content.substr(0, begin.column());
    String suffix = m_lines[end.line()].content.substr(end.column());
    Line new_line = { m_lines[begin.line()].start, prefix + suffix };

    if (new_line.length() != 0)
    {
        m_lines.erase(m_lines.begin() + (int)begin.line(), m_lines.begin() + (int)end.line());
        m_lines[begin.line()] = std::move(new_line);
    }
    else
        m_lines.erase(m_lines.begin() + (int)begin.line(), m_lines.begin() + (int)end.line() + 1);

    for (LineCount i = begin.line()+1; i < line_count(); ++i)
        m_lines[i].start -= length;

    check_invariant();

    for (auto listener : m_change_listeners)
        listener->on_erase(begin, end);
}

void Buffer::apply_modification(const Modification& modification)
{
    const String& content = modification.content;
    BufferIterator pos = modification.position;

    // this may happen when a modification applied at the
    // end of the buffer has been inverted for an undo.
    if (not pos.is_end() and pos.column() == m_lines[pos.line()].length())
        pos = { pos.buffer(), { pos.line() + 1, 0 }};

    assert(pos.is_valid());
    switch (modification.type)
    {
    case Modification::Insert:
    {
        do_insert(pos, content);
        break;
    }
    case Modification::Erase:
    {
        ByteCount count = content.length();
        BufferIterator end = pos + count;
        assert(string(pos, end) == content);
        do_erase(pos, end);
        break;
    }
    default:
        assert(false);
    }
}

void Buffer::insert(BufferIterator pos, String content)
{
    if (content.empty())
        return;

    if (pos.is_end() and content.back() != '\n')
        content += '\n';

    if (not (m_flags & Flags::NoUndo))
        m_current_undo_group.emplace_back(Modification::Insert, pos, content);
    do_insert(pos, content);
}

void Buffer::erase(BufferIterator begin, BufferIterator end)
{
    if (end.is_end() and (begin.column() != 0 or begin.is_begin()))
        --end;

    if (begin == end)
        return;

    if (not (m_flags & Flags::NoUndo))
        m_current_undo_group.emplace_back(Modification::Erase, begin,
                                          string(begin, end));
    do_erase(begin, end);
}

bool Buffer::is_modified() const
{
    size_t history_cursor_index = m_history_cursor - m_history.begin();
    return m_last_save_undo_index != history_cursor_index
           or not m_current_undo_group.empty();
}

void Buffer::notify_saved()
{
    if (not m_current_undo_group.empty())
        commit_undo_group();

    m_flags &= ~Flags::New;
    size_t history_cursor_index = m_history_cursor - m_history.begin();
    if (m_last_save_undo_index != history_cursor_index)
    {
        ++m_timestamp;
        m_last_save_undo_index = history_cursor_index;
    }
}

}
<commit_msg>Buffer: optimize do_insert to minimize changes in m_lines vector<commit_after>#include "buffer.hh"

#include "buffer_manager.hh"
#include "window.hh"
#include "assert.hh"
#include "utils.hh"
#include "context.hh"
#include "utf8.hh"

#include <algorithm>

namespace Kakoune
{

Buffer::Buffer(String name, Flags flags, std::vector<String> lines)
    : m_name(std::move(name)), m_flags(flags | Flags::NoUndo),
      m_history(), m_history_cursor(m_history.begin()),
      m_last_save_undo_index(0),
      m_timestamp(0),
      m_hooks(GlobalHooks::instance()),
      m_options(GlobalOptions::instance())
{
    BufferManager::instance().register_buffer(*this);

    if (lines.empty())
        lines.emplace_back("\n");

    ByteCount pos = 0;
    m_lines.reserve(lines.size());
    for (auto& line : lines)
    {
        assert(not line.empty() and line.back() == '\n');
        m_lines.emplace_back(Line{ pos, std::move(line) });
        pos += m_lines.back().length();
    }

    Editor editor_for_hooks(*this);
    Context context(editor_for_hooks);
    if (flags & Flags::File and flags & Flags::New)
        m_hooks.run_hook("BufNew", m_name, context);
    else
        m_hooks.run_hook("BufOpen", m_name, context);

    m_hooks.run_hook("BufCreate", m_name, context);

    // now we may begin to record undo data
    m_flags = flags;
}

Buffer::~Buffer()
{
    {
        Editor hook_editor{*this};
        Context hook_context{hook_editor};
        m_hooks.run_hook("BufClose", m_name, hook_context);
    }

    BufferManager::instance().unregister_buffer(*this);
    assert(m_change_listeners.empty());
}

BufferIterator Buffer::iterator_at(const BufferCoord& line_and_column,
                                   bool avoid_eol) const
{
    return BufferIterator(*this, clamp(line_and_column, avoid_eol));
}

ByteCount Buffer::line_length(LineCount line) const
{
    assert(line < line_count());
    ByteCount end = (line < line_count() - 1) ?
                    m_lines[line + 1].start : character_count();
    return end - m_lines[line].start;
}

BufferCoord Buffer::clamp(const BufferCoord& line_and_column,
                          bool avoid_eol) const
{
    if (m_lines.empty())
        return BufferCoord();

    BufferCoord result(line_and_column.line, line_and_column.column);
    result.line = Kakoune::clamp(result.line, 0_line, line_count() - 1);
    ByteCount max_col = std::max(0_byte, line_length(result.line) - (avoid_eol ? 2 : 1));
    result.column = Kakoune::clamp(result.column, 0_byte, max_col);
    return result;
}

BufferIterator Buffer::iterator_at_line_begin(LineCount line) const
{
    line = Kakoune::clamp(line, 0_line, line_count()-1);
    assert(line_length(line) > 0);
    return BufferIterator(*this, { line, 0 });
}

BufferIterator Buffer::iterator_at_line_begin(const BufferIterator& iterator) const
{
    return iterator_at_line_begin(iterator.line());
}

BufferIterator Buffer::iterator_at_line_end(LineCount line) const
{
    line = Kakoune::clamp(line, 0_line, line_count()-1);
    assert(line_length(line) > 0);
    return ++BufferIterator(*this, { line, line_length(line) - 1 });
}

BufferIterator Buffer::iterator_at_line_end(const BufferIterator& iterator) const
{
    return iterator_at_line_end(iterator.line());
}

BufferIterator Buffer::begin() const
{
    return BufferIterator(*this, { 0_line, 0 });
}

BufferIterator Buffer::end() const
{
    if (m_lines.empty())
        return BufferIterator(*this, { 0_line, 0 });
    return BufferIterator(*this, { line_count()-1, m_lines.back().length() });
}

ByteCount Buffer::character_count() const
{
    if (m_lines.empty())
        return 0;
    return m_lines.back().start + m_lines.back().length();
}

LineCount Buffer::line_count() const
{
    return LineCount(m_lines.size());
}

String Buffer::string(const BufferIterator& begin, const BufferIterator& end) const
{
    String res;
    for (LineCount line = begin.line(); line <= end.line(); ++line)
    {
       ByteCount start = 0;
       if (line == begin.line())
           start = begin.column();
       ByteCount count = -1;
       if (line == end.line())
           count = end.column() - start;
       res += m_lines[line].content.substr(start, count);
    }
    return res;
}

void Buffer::commit_undo_group()
{
    if (m_flags & Flags::NoUndo)
        return;

    if (m_current_undo_group.empty())
        return;

    m_history.erase(m_history_cursor, m_history.end());

    m_history.push_back(std::move(m_current_undo_group));
    m_current_undo_group.clear();
    m_history_cursor = m_history.end();

    if (m_history.size() < m_last_save_undo_index)
        m_last_save_undo_index = -1;
}

// A Modification holds a single atomic modification to Buffer
struct Buffer::Modification
{
    enum Type { Insert, Erase };

    Type           type;
    BufferIterator position;
    String         content;

    Modification(Type type, BufferIterator position, String content)
        : type(type), position(position), content(std::move(content)) {}

    Modification inverse() const
    {
        Type inverse_type = Insert;
        switch (type)
        {
        case Insert: inverse_type = Erase;  break;
        case Erase:  inverse_type = Insert; break;
        default: assert(false);
        }
        return {inverse_type, position, content};
    }
};

bool Buffer::undo()
{
    commit_undo_group();

    if (m_history_cursor == m_history.begin())
        return false;

    --m_history_cursor;

    for (const Modification& modification : reversed(*m_history_cursor))
        apply_modification(modification.inverse());
    return true;
}

bool Buffer::redo()
{
    if (m_history_cursor == m_history.end())
        return false;

    assert(m_current_undo_group.empty());

    for (const Modification& modification : *m_history_cursor)
        apply_modification(modification);

    ++m_history_cursor;
    return true;
}

void Buffer::check_invariant() const
{
#ifdef KAK_DEBUG
    ByteCount start = 0;
    assert(not m_lines.empty());
    for (auto& line : m_lines)
    {
        assert(line.start == start);
        assert(line.length() > 0);
        assert(line.content.back() == '\n');
        start += line.length();
    }
#endif
}

void Buffer::do_insert(const BufferIterator& pos, const String& content)
{
    assert(pos.is_valid() and (pos.is_end() or utf8::is_character_start(pos)));
    assert(not contains(content, '\0'));

    if (content.empty())
        return;

    ++m_timestamp;
    ByteCount offset = pos.offset();

    // all following lines advanced by length
    for (LineCount i = pos.line()+1; i < line_count(); ++i)
        m_lines[i].start += content.length();

    BufferIterator begin_it;
    BufferIterator end_it;
    // if we inserted at the end of the buffer, we have created a new
    // line without inserting a '\n'
    if (pos.is_end())
    {
        ByteCount start = 0;
        for (ByteCount i = 0; i < content.length(); ++i)
        {
            if (content[i] == '\n')
            {
                m_lines.push_back({ offset + start, content.substr(start, i + 1 - start) });
                start = i + 1;
            }
        }
        if (start != content.length())
            m_lines.push_back({ offset + start, content.substr(start) });

        begin_it = pos.column() == 0 ? pos : BufferIterator{*this, { pos.line() + 1, 0 }};
        end_it = end();
    }
    else
    {
        String prefix = m_lines[pos.line()].content.substr(0, pos.column());
        String suffix = m_lines[pos.line()].content.substr(pos.column());

        std::vector<Line> new_lines;

        ByteCount start = 0;
        for (ByteCount i = 0; i < content.length(); ++i)
        {
            if (content[i] == '\n')
            {
                String line_content = content.substr(start, i + 1 - start);
                if (start == 0)
                {
                    line_content = prefix + line_content;
                    new_lines.push_back({ offset + start - prefix.length(),
                                          std::move(line_content) });
                }
                else
                    new_lines.push_back({ offset + start, std::move(line_content) });
                start = i + 1;
            }
        }
        if (start == 0)
            new_lines.push_back({ offset + start - prefix.length(), prefix + content + suffix });
        else if (start != content.length() or not suffix.empty())
            new_lines.push_back({ offset + start, content.substr(start) + suffix });

        LineCount last_line = pos.line() + new_lines.size() - 1;

        auto line_it = m_lines.begin() + (int)pos.line();
        *line_it = std::move(*new_lines.begin());
        m_lines.insert(line_it+1, std::make_move_iterator(new_lines.begin() + 1),
                       std::make_move_iterator(new_lines.end()));

        begin_it = pos;
        end_it = BufferIterator{*this, { last_line, m_lines[last_line].length() - suffix.length() }};
    }

    check_invariant();

    for (auto listener : m_change_listeners)
        listener->on_insert(begin_it, end_it);
}

void Buffer::do_erase(const BufferIterator& begin, const BufferIterator& end)
{
    assert(begin.is_valid());
    assert(end.is_valid());
    assert(utf8::is_character_start(begin) and
           (end.is_end() or utf8::is_character_start(end)));
    ++m_timestamp;
    const ByteCount length = end - begin;
    String prefix = m_lines[begin.line()].content.substr(0, begin.column());
    String suffix = m_lines[end.line()].content.substr(end.column());
    Line new_line = { m_lines[begin.line()].start, prefix + suffix };

    if (new_line.length() != 0)
    {
        m_lines.erase(m_lines.begin() + (int)begin.line(), m_lines.begin() + (int)end.line());
        m_lines[begin.line()] = std::move(new_line);
    }
    else
        m_lines.erase(m_lines.begin() + (int)begin.line(), m_lines.begin() + (int)end.line() + 1);

    for (LineCount i = begin.line()+1; i < line_count(); ++i)
        m_lines[i].start -= length;

    check_invariant();

    for (auto listener : m_change_listeners)
        listener->on_erase(begin, end);
}

void Buffer::apply_modification(const Modification& modification)
{
    const String& content = modification.content;
    BufferIterator pos = modification.position;

    // this may happen when a modification applied at the
    // end of the buffer has been inverted for an undo.
    if (not pos.is_end() and pos.column() == m_lines[pos.line()].length())
        pos = { pos.buffer(), { pos.line() + 1, 0 }};

    assert(pos.is_valid());
    switch (modification.type)
    {
    case Modification::Insert:
    {
        do_insert(pos, content);
        break;
    }
    case Modification::Erase:
    {
        ByteCount count = content.length();
        BufferIterator end = pos + count;
        assert(string(pos, end) == content);
        do_erase(pos, end);
        break;
    }
    default:
        assert(false);
    }
}

void Buffer::insert(BufferIterator pos, String content)
{
    if (content.empty())
        return;

    if (pos.is_end() and content.back() != '\n')
        content += '\n';

    if (not (m_flags & Flags::NoUndo))
        m_current_undo_group.emplace_back(Modification::Insert, pos, content);
    do_insert(pos, content);
}

void Buffer::erase(BufferIterator begin, BufferIterator end)
{
    if (end.is_end() and (begin.column() != 0 or begin.is_begin()))
        --end;

    if (begin == end)
        return;

    if (not (m_flags & Flags::NoUndo))
        m_current_undo_group.emplace_back(Modification::Erase, begin,
                                          string(begin, end));
    do_erase(begin, end);
}

bool Buffer::is_modified() const
{
    size_t history_cursor_index = m_history_cursor - m_history.begin();
    return m_last_save_undo_index != history_cursor_index
           or not m_current_undo_group.empty();
}

void Buffer::notify_saved()
{
    if (not m_current_undo_group.empty())
        commit_undo_group();

    m_flags &= ~Flags::New;
    size_t history_cursor_index = m_history_cursor - m_history.begin();
    if (m_last_save_undo_index != history_cursor_index)
    {
        ++m_timestamp;
        m_last_save_undo_index = history_cursor_index;
    }
}

}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include <stdlib.h>
#include <fstream>
#include <iostream>
#include "boost/filesystem.hpp"

#include "context.h"
#include "env.h"
#include "error.h"
#include "recorder.h"
#include "agent.h"
#include "timer.h"
#include "dynamic_module.h"

namespace fs = boost::filesystem;
using cyclus::DynamicModule;
using cyclus::AgentSpec;
using cyclus::Agent;

TEST(DynamicLoadingTests, ConstructTestFacility) {
  cyclus::Recorder rec;
  cyclus::Timer ti;
  cyclus::Context* ctx = new cyclus::Context(&ti, &rec);
  EXPECT_NO_THROW(DynamicModule::Make(ctx, AgentSpec("TestFacility:TestFacility:TestFacility")));
  EXPECT_NO_THROW(DynamicModule::CloseAll());
}

TEST(DynamicLoadingTests, LoadLibError) {
  cyclus::Recorder rec;
  cyclus::Timer ti;
  cyclus::Context* ctx = new cyclus::Context(&ti, &rec);
  EXPECT_THROW(DynamicModule::Make(ctx, AgentSpec("foo:foo:not_a_fac")), cyclus::IOError);
}

TEST(DynamicLoadingTests, CloneTestFacility) {
  cyclus::Recorder rec;
  cyclus::Timer ti;
  cyclus::Context* ctx = new cyclus::Context(&ti, &rec);
  EXPECT_NO_THROW(Agent* fac = DynamicModule::Make(ctx, AgentSpec("TestFacility:TestFacility:TestFacility"));
                  Agent* clone = fac->Clone(););
  DynamicModule::CloseAll();
}
<commit_msg>minor agent spec updates<commit_after>#include <gtest/gtest.h>

#include <stdlib.h>
#include <fstream>
#include <iostream>
#include "boost/filesystem.hpp"

#include "context.h"
#include "env.h"
#include "error.h"
#include "recorder.h"
#include "agent.h"
#include "timer.h"
#include "dynamic_module.h"

namespace fs = boost::filesystem;
using cyclus::DynamicModule;
using cyclus::AgentSpec;
using cyclus::Agent;

TEST(DynamicLoadingTests, ConstructTestFacility) {
  cyclus::Recorder rec;
  cyclus::Timer ti;
  cyclus::Context* ctx = new cyclus::Context(&ti, &rec);
  EXPECT_NO_THROW(DynamicModule::Make(ctx, AgentSpec("tests:TestFacility:TestFacility")));
  EXPECT_NO_THROW(DynamicModule::CloseAll());
}

TEST(DynamicLoadingTests, LoadLibError) {
  cyclus::Recorder rec;
  cyclus::Timer ti;
  cyclus::Context* ctx = new cyclus::Context(&ti, &rec);
  EXPECT_THROW(DynamicModule::Make(ctx, AgentSpec("foo:foo:not_a_fac")), cyclus::IOError);
}

TEST(DynamicLoadingTests, CloneTestFacility) {
  cyclus::Recorder rec;
  cyclus::Timer ti;
  cyclus::Context* ctx = new cyclus::Context(&ti, &rec);
  EXPECT_NO_THROW(Agent* fac = DynamicModule::Make(ctx, AgentSpec("tests:TestFacility:TestFacility"));
                  Agent* clone = fac->Clone(););
  DynamicModule::CloseAll();
}
<|endoftext|>