<commit_before>

#include "config.h"
#include "storage/StorageImpl.h"
#include "storage/DevicegraphImpl.h"
#include "storage/Devices/DiskImpl.h"
#include "storage/Devices/MdImpl.h"
#include "storage/Devices/FilesystemImpl.h"
#include "storage/SystemInfo/SystemInfo.h"
#include "storage/Actiongraph.h"
#include "storage/Utils/AppUtil.h"
#include "storage/Utils/Mockup.h"

namespace storage
{

    Storage::Impl::Impl(const Storage& storage, const Environment& environment)
	: storage(storage), environment(environment), arch(false), tmp_dir("libstorage-XXXXXX")
    {
	y2mil("constructed Storage with " << environment);
	y2mil("libstorage version " VERSION);

	Devicegraph* probed = create_devicegraph("probed");

	switch (environment.get_probe_mode())
	{
	    case ProbeMode::STANDARD: {
		probe(probed);
	    } break;

	    case ProbeMode::STANDARD_WRITE_DEVICEGRAPH: {
		probe(probed);
		probed->save(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::STANDARD_WRITE_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::RECORD);
		probe(probed);
		Mockup::save(environment.get_mockup_filename());
	    } break;

	    case ProbeMode::NONE: {
	    } break;

	    case ProbeMode::READ_DEVICEGRAPH: {
		probed->load(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::READ_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::PLAYBACK);
		Mockup::load(environment.get_mockup_filename());
		probe(probed);
	    } break;
	}

	y2mil("probed devicegraph begin");
	y2mil(*probed);
	y2mil("probed devicegraph end");

	copy_devicegraph("probed", "staging");
    }

    Storage::Impl::~Impl()
    {
	// TODO: Make sure logger is destroyed after this object
    }

    void
    Storage::Impl::probe(Devicegraph* probed)
    {
	SystemInfo systeminfo;

	arch = systeminfo.getArch();

	EtcFstab fstab("/etc");

	// TODO

	// Pass 1: Detect all BlkDevices and some Holders, e.g. between
	// Partitionable, PartitionTable and Partitions.

	for (const string& name : Disk::Impl::probe_disks(systeminfo))
	{
	    Disk* disk = Disk::create(probed, name);
	    disk->get_impl().probe_pass_1(probed, systeminfo);
	}

	for (const string& name : Md::Impl::probe_mds(systeminfo))
	{
	    Md* md = Md::create(probed, name);
	    md->get_impl().probe_pass_1(probed, systeminfo);
	}

	// Pass 2: Detect remaining Holders, e.g. MdUsers. This is not
	// possible in pass 1 since a Md can use other Mds (e.g. md0 using md1
	// and md2).

	for (Md* md : probed->get_all_mds())
	{
	    md->get_impl().probe_pass_2(probed, systeminfo);
	}

	// Pass 3: Detect filesystems.

	for (Devicegraph::Impl::vertex_descriptor vertex : probed->get_impl().vertices())
	{
	    BlkDevice* blk_device = dynamic_cast<BlkDevice*>(probed->get_impl()[vertex]);
	    if (!blk_device)
		continue;

	    if (blk_device->num_children() != 0)
		continue;

	    Blkid::Entry entry;
	    if (systeminfo.getBlkid().getEntry(blk_device->get_name(), entry))
	    {
		if (entry.is_fs)
		{
		    // TODO temporary until all fs are implemented
		    if (entry.fs_type != FsType::EXT4 && entry.fs_type != FsType::BTRFS &&
			entry.fs_type != FsType::XFS && entry.fs_type != FsType::SWAP &&
			entry.fs_type != FsType::NTFS && entry.fs_type != FsType::VFAT)
			continue;

		    Filesystem* filesystem = blk_device->create_filesystem(entry.fs_type);
		    filesystem->get_impl().probe_pass_3(probed, systeminfo, fstab);
		}
	    }
	}
    }

    Devicegraph*
    Storage::Impl::get_devicegraph(const string& name)
    {
	if (name == "probed")
	    ST_THROW(Exception("invalid name"));

	map<string, Devicegraph>::iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	return &it->second;
    }

    const Devicegraph*
    Storage::Impl::get_devicegraph(const string& name) const
    {
	map<string, Devicegraph>::const_iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::get_staging()
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_staging() const
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_probed() const
    {
	return get_devicegraph("probed");
    }

    vector<string>
    Storage::Impl::get_devicegraph_names() const
    {
	vector<string> ret;

	for (const map<string, Devicegraph>::value_type& it : devicegraphs)
	    ret.push_back(it.first);

	return ret;
    }

    Devicegraph*
    Storage::Impl::create_devicegraph(const string& name)
    {
	pair<map<string, Devicegraph>::iterator, bool> tmp =
	    devicegraphs.emplace(piecewise_construct, forward_as_tuple(name),
				 forward_as_tuple(&storage));
	if (!tmp.second)
	    ST_THROW(Exception("device graph already exists"));

	map<string, Devicegraph>::iterator it = tmp.first;

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::copy_devicegraph(const string& source_name, const string& dest_name)
    {
	const Devicegraph* tmp1 = static_cast<const Impl*>(this)->get_devicegraph(source_name);

	Devicegraph* tmp2 = create_devicegraph(dest_name);

	tmp1->copy(*tmp2);

	return tmp2;
    }

    void
    Storage::Impl::remove_devicegraph(const string& name)
    {
	map<string, Devicegraph>::const_iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	devicegraphs.erase(it1);
    }

    void
    Storage::Impl::restore_devicegraph(const string& name)
    {
	map<string, Devicegraph>::iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	map<string, Devicegraph>::iterator it2 = devicegraphs.find("staging");
	if (it2 == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	it1->second.get_impl().swap(it2->second.get_impl());
	devicegraphs.erase(it1);
    }

    bool
    Storage::Impl::exist_devicegraph(const string& name) const
    {
	return devicegraphs.find(name) != devicegraphs.end();
    }

    bool
    Storage::Impl::equal_devicegraph(const string& lhs, const string& rhs) const
    {
	return *get_devicegraph(lhs) == *get_devicegraph(rhs);
    }

    void
    Storage::Impl::check() const
    {
	for (const map<string, Devicegraph>::value_type& key_value : devicegraphs)
	{
	    key_value.second.check();
	}

	// TODO check that a object has the same type in every devicegraph
    }

    string
    Storage::Impl::prepend_rootprefix(const string& mountpoint) const
    {
	if (mountpoint == "swap" || rootprefix.empty())
	    return mountpoint;

	if (mountpoint == "/")
	    return rootprefix;
	else
	    return rootprefix + mountpoint;
    }

    const Actiongraph*
    Storage::Impl::calculate_actiongraph()
    {
	actiongraph.reset(new Actiongraph(storage, get_probed(), get_staging()));

	return actiongraph.get();
    }

    void
    Storage::Impl::commit(const CommitCallbacks* commit_callbacks)
    {
	ST_CHECK_PTR(actiongraph.get());

	actiongraph->get_impl().commit(commit_callbacks);

	// TODO somehow update probed
    }

}
<commit_msg>- probe mds only if blkid found some<commit_after>

#include "config.h"
#include "storage/StorageImpl.h"
#include "storage/DevicegraphImpl.h"
#include "storage/Devices/DiskImpl.h"
#include "storage/Devices/MdImpl.h"
#include "storage/Devices/FilesystemImpl.h"
#include "storage/SystemInfo/SystemInfo.h"
#include "storage/Actiongraph.h"
#include "storage/Utils/AppUtil.h"
#include "storage/Utils/Mockup.h"

namespace storage
{

    Storage::Impl::Impl(const Storage& storage, const Environment& environment)
	: storage(storage), environment(environment), arch(false), tmp_dir("libstorage-XXXXXX")
    {
	y2mil("constructed Storage with " << environment);
	y2mil("libstorage version " VERSION);

	Devicegraph* probed = create_devicegraph("probed");

	switch (environment.get_probe_mode())
	{
	    case ProbeMode::STANDARD: {
		probe(probed);
	    } break;

	    case ProbeMode::STANDARD_WRITE_DEVICEGRAPH: {
		probe(probed);
		probed->save(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::STANDARD_WRITE_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::RECORD);
		probe(probed);
		Mockup::save(environment.get_mockup_filename());
	    } break;

	    case ProbeMode::NONE: {
	    } break;

	    case ProbeMode::READ_DEVICEGRAPH: {
		probed->load(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::READ_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::PLAYBACK);
		Mockup::load(environment.get_mockup_filename());
		probe(probed);
	    } break;
	}

	y2mil("probed devicegraph begin");
	y2mil(*probed);
	y2mil("probed devicegraph end");

	copy_devicegraph("probed", "staging");
    }

    Storage::Impl::~Impl()
    {
	// TODO: Make sure logger is destroyed after this object
    }

    void
    Storage::Impl::probe(Devicegraph* probed)
    {
	SystemInfo systeminfo;

	arch = systeminfo.getArch();

	EtcFstab fstab("/etc");

	// TODO

	// Pass 1: Detect all BlkDevices and some Holders, e.g. between
	// Partitionable, PartitionTable and Partitions.

	for (const string& name : Disk::Impl::probe_disks(systeminfo))
	{
	    Disk* disk = Disk::create(probed, name);
	    disk->get_impl().probe_pass_1(probed, systeminfo);
	}

	if (systeminfo.getBlkid().any_md())
	{
	    // TODO check whether md tools are installed

	    for (const string& name : Md::Impl::probe_mds(systeminfo))
	    {
		Md* md = Md::create(probed, name);
		md->get_impl().probe_pass_1(probed, systeminfo);
	    }
	}

	// Pass 2: Detect remaining Holders, e.g. MdUsers. This is not
	// possible in pass 1 since a Md can use other Mds (e.g. md0 using md1
	// and md2).

	for (Md* md : probed->get_all_mds())
	{
	    md->get_impl().probe_pass_2(probed, systeminfo);
	}

	// Pass 3: Detect filesystems.

	for (Devicegraph::Impl::vertex_descriptor vertex : probed->get_impl().vertices())
	{
	    BlkDevice* blk_device = dynamic_cast<BlkDevice*>(probed->get_impl()[vertex]);
	    if (!blk_device)
		continue;

	    if (blk_device->num_children() != 0)
		continue;

	    Blkid::Entry entry;
	    if (systeminfo.getBlkid().getEntry(blk_device->get_name(), entry))
	    {
		if (entry.is_fs)
		{
		    // TODO temporary until all fs are implemented
		    if (entry.fs_type != FsType::EXT4 && entry.fs_type != FsType::BTRFS &&
			entry.fs_type != FsType::XFS && entry.fs_type != FsType::SWAP &&
			entry.fs_type != FsType::NTFS && entry.fs_type != FsType::VFAT)
			continue;

		    Filesystem* filesystem = blk_device->create_filesystem(entry.fs_type);
		    filesystem->get_impl().probe_pass_3(probed, systeminfo, fstab);
		}
	    }
	}
    }

    Devicegraph*
    Storage::Impl::get_devicegraph(const string& name)
    {
	if (name == "probed")
	    ST_THROW(Exception("invalid name"));

	map<string, Devicegraph>::iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	return &it->second;
    }

    const Devicegraph*
    Storage::Impl::get_devicegraph(const string& name) const
    {
	map<string, Devicegraph>::const_iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::get_staging()
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_staging() const
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_probed() const
    {
	return get_devicegraph("probed");
    }

    vector<string>
    Storage::Impl::get_devicegraph_names() const
    {
	vector<string> ret;

	for (const map<string, Devicegraph>::value_type& it : devicegraphs)
	    ret.push_back(it.first);

	return ret;
    }

    Devicegraph*
    Storage::Impl::create_devicegraph(const string& name)
    {
	pair<map<string, Devicegraph>::iterator, bool> tmp =
	    devicegraphs.emplace(piecewise_construct, forward_as_tuple(name),
				 forward_as_tuple(&storage));
	if (!tmp.second)
	    ST_THROW(Exception("device graph already exists"));

	map<string, Devicegraph>::iterator it = tmp.first;

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::copy_devicegraph(const string& source_name, const string& dest_name)
    {
	const Devicegraph* tmp1 = static_cast<const Impl*>(this)->get_devicegraph(source_name);

	Devicegraph* tmp2 = create_devicegraph(dest_name);

	tmp1->copy(*tmp2);

	return tmp2;
    }

    void
    Storage::Impl::remove_devicegraph(const string& name)
    {
	map<string, Devicegraph>::const_iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	devicegraphs.erase(it1);
    }

    void
    Storage::Impl::restore_devicegraph(const string& name)
    {
	map<string, Devicegraph>::iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	map<string, Devicegraph>::iterator it2 = devicegraphs.find("staging");
	if (it2 == devicegraphs.end())
	    ST_THROW(Exception("device graph not found"));

	it1->second.get_impl().swap(it2->second.get_impl());
	devicegraphs.erase(it1);
    }

    bool
    Storage::Impl::exist_devicegraph(const string& name) const
    {
	return devicegraphs.find(name) != devicegraphs.end();
    }

    bool
    Storage::Impl::equal_devicegraph(const string& lhs, const string& rhs) const
    {
	return *get_devicegraph(lhs) == *get_devicegraph(rhs);
    }

    void
    Storage::Impl::check() const
    {
	for (const map<string, Devicegraph>::value_type& key_value : devicegraphs)
	{
	    key_value.second.check();
	}

	// TODO check that a object has the same type in every devicegraph
    }

    string
    Storage::Impl::prepend_rootprefix(const string& mountpoint) const
    {
	if (mountpoint == "swap" || rootprefix.empty())
	    return mountpoint;

	if (mountpoint == "/")
	    return rootprefix;
	else
	    return rootprefix + mountpoint;
    }

    const Actiongraph*
    Storage::Impl::calculate_actiongraph()
    {
	actiongraph.reset(new Actiongraph(storage, get_probed(), get_staging()));

	return actiongraph.get();
    }

    void
    Storage::Impl::commit(const CommitCallbacks* commit_callbacks)
    {
	ST_CHECK_PTR(actiongraph.get());

	actiongraph->get_impl().commit(commit_callbacks);

	// TODO somehow update probed
    }

}
<|endoftext|>


<commit_before>/***************************************************************************
 *            test_stream.cpp
 *
 *  Fri Oct 5  13:40:22 2003
 *  Copyright  2003  Roman Dementiev
 *  dementiev@mpi-sb.mpg.de
 ****************************************************************************/

#include "stxxl/stream"
#include "stxxl/vector"
#include <vector>

//! \example stream/test_stream.cpp
//! This is an example of how to use some basic algorithms from
//! stream package. The example sorts characters of a string producing
//! array of sorted tuples (character,index position).
//!

#define USE_FORMRUNS_N_MERGE // comment if you want to use one 'sort' algorithm
                             // without producing intermediate sorted runs.

#define USE_EXTERNAL_ARRAY // comment if you want to use internal vectors as
                           // input/output of the algorithm

#define block_size (8 * 1024)

typedef stxxl::tuple<char, int> tuple_type;

#ifdef USE_EXTERNAL_ARRAY
typedef stxxl::VECTOR_GENERATOR<char>::result input_array_type;
typedef stxxl::VECTOR_GENERATOR<tuple_type>::result output_array_type;
#else
typedef std::vector<char> input_array_type;
typedef std::vector<tuple_type> output_array_type;
#endif

using namespace stxxl;
using stxxl::stream::streamify;
using stxxl::stream::streamify_traits;
using stxxl::stream::make_tuple;
using stxxl::tuple;

const char * phrase = "Hasta la vista, baby";

template <class Container_, class It_>
void fill_input_array(Container_ & container, It_ p)
{
    while (*p)
    {
        container.push_back(*p);
        ++p;
    }
}

template <class ValTp>
struct counter
{
    typedef ValTp value_type;

    value_type cnt;
    counter() : cnt(0) { }

    value_type operator()  ()
    {
        value_type ret = cnt;
        ++cnt;
        return ret;
    }
};

typedef counter<int> counter_type;

struct cmp_type : std::binary_function<tuple_type, tuple_type, bool>
{
    typedef tuple_type value_type;
    bool operator ()  (const value_type & a, const value_type & b) const
    {
        return a.first < b.first;
    }

    value_type min_value() const
    {
        return value_type((std::numeric_limits < char > ::min)(), 0);
    }
    value_type max_value() const
    {
        return value_type((std::numeric_limits < char > ::max)(), 0);
    }
};

struct cmp_int : std::binary_function<int, int, bool>
{
    typedef int value_type;
    bool operator ()  (const value_type & a, const value_type & b) const
    {
        return a > b;
    }

    value_type max_value() const
    {
        return ((std::numeric_limits < value_type > ::min)());
    }
    value_type min_value() const
    {
        return ((std::numeric_limits < value_type > ::max)());
    }
};

int main()
{
    input_array_type input;
    output_array_type output;

    stxxl::stats * s = stxxl::stats::get_instance();

    std::cout << *s;

    fill_input_array(input, phrase);

    output.resize(input.size());

    // HERE streaming part begins (streamifying)
    // create input stream
#ifdef BOOST_MSVC
    typedef streamify_traits<input_array_type::iterator>::stream_type input_stream_type;
#else
    typedef typeof(streamify(input.begin(), input.end())) input_stream_type;
#endif

    input_stream_type input_stream = streamify(input.begin(), input.end());

    // create counter stream
#ifdef BOOST_MSVC
    typedef stxxl::stream::generator2stream<counter_type> counter_stream_type;
#else
    typedef __typeof (streamify(counter_type())) counter_stream_type;
#endif
    counter_stream_type counter_stream = streamify(counter_type());

    // create tuple stream
    typedef make_tuple<input_stream_type, counter_stream_type> tuple1_stream_type;
    tuple1_stream_type tuples1_stream(input_stream, counter_stream);

#ifdef USE_FORMRUNS_N_MERGE
    // sort tuples by character
    // 1. form runs
    typedef stream::runs_creator<tuple1_stream_type, cmp_type, block_size> run_creator_type;
    run_creator_type runscreator(tuples1_stream, cmp_type(), 128 * 1024);
    // 2. merge runs
    typedef stream::runs_merger<run_creator_type::sorted_runs_type, cmp_type> runs_merger_type;
    runs_merger_type sorted_stream(runscreator.result(), cmp_type(), 128 * 1024);
#else
    // sort tuples by character
    // (combination of the previous two steps in one algorithm: form runs and merge)
    typedef stream::sort<tuple1_stream_type, cmp_type, block_size> sorted_stream_type;
    sorted_stream_type sorted_stream(tuples1_stream, cmp_type(), 128 * 1024);
#endif

    // HERE streaming part ends (materializing)
    output_array_type::iterator o = materialize(sorted_stream, output.begin(), output.end());
    // or materialize(sorted_stream,output.begin());
    assert(o == output.end() );

    STXXL_MSG("input string (character,position) :");
    for (unsigned i = 0; i < input.size(); ++i)
    {
        STXXL_MSG("('" << input[i] << "'," << i << ")");
    }
    STXXL_MSG("sorted tuples (character,position):");
    for (unsigned i = 0; i < input.size(); ++i)
    {
        STXXL_MSG("('" << output[i].first << "'," << output[i].second << ")");
    }

    std::cout << *s;

    std::vector<int> InternalArray(1024 * 1024);
    std::sort(InternalArray.begin(), InternalArray.end(), cmp_int());
    stxxl::sort < 1024 * 1024 > (                                       InternalArray.begin(),
                                                                        InternalArray.end(),
                                                                        cmp_int(),
                                                                        1024 * 1024 * 10,
                                                                        stxxl::RC());
}
<commit_msg>rename some variables (from parallel_pipelining r527, r528)<commit_after>/***************************************************************************
 *            test_stream.cpp
 *
 *  Fri Oct 5  13:40:22 2003
 *  Copyright  2003  Roman Dementiev
 *  dementiev@mpi-sb.mpg.de
 ****************************************************************************/

#include "stxxl/stream"
#include "stxxl/vector"
#include <vector>

//! \example stream/test_stream.cpp
//! This is an example of how to use some basic algorithms from the
//! stream package. The example sorts characters of a string producing an
//! array of sorted tuples (character, index position).
//!

#define USE_FORMRUNS_N_MERGE // comment if you want to use one 'sort' algorithm
                             // without producing intermediate sorted runs.

#define USE_EXTERNAL_ARRAY // comment if you want to use internal vectors as
                           // input/output of the algorithm

#define block_size (8 * 1024)

typedef stxxl::tuple<char, int> tuple_type;

#ifdef USE_EXTERNAL_ARRAY
typedef stxxl::VECTOR_GENERATOR<char>::result input_array_type;
typedef stxxl::VECTOR_GENERATOR<tuple_type>::result output_array_type;
#else
typedef std::vector<char> input_array_type;
typedef std::vector<tuple_type> output_array_type;
#endif

using namespace stxxl;
using stxxl::stream::streamify;
using stxxl::stream::streamify_traits;
using stxxl::stream::make_tuple;
using stxxl::tuple;

const char * phrase = "Hasta la vista, baby";

template <class Container_, class It_>
void fill_input_array(Container_ & container, It_ p)
{
    while (*p)
    {
        container.push_back(*p);
        ++p;
    }
}

template <class ValTp>
struct counter
{
    typedef ValTp value_type;

    value_type cnt;
    counter() : cnt(0) { }

    value_type operator()  ()
    {
        value_type ret = cnt;
        ++cnt;
        return ret;
    }
};

typedef counter<int> counter_type;

struct cmp_type : std::binary_function<tuple_type, tuple_type, bool>
{
    typedef tuple_type value_type;
    bool operator ()  (const value_type & a, const value_type & b) const
    {
        return a.first < b.first;
    }

    value_type min_value() const
    {
        return value_type((std::numeric_limits < char > ::min)(), 0);
    }
    value_type max_value() const
    {
        return value_type((std::numeric_limits < char > ::max)(), 0);
    }
};

struct cmp_int : std::binary_function<int, int, bool>
{
    typedef int value_type;
    bool operator ()  (const value_type & a, const value_type & b) const
    {
        return a > b;
    }

    value_type max_value() const
    {
        return ((std::numeric_limits < value_type > ::min)());
    }
    value_type min_value() const
    {
        return ((std::numeric_limits < value_type > ::max)());
    }
};

int main()
{
    input_array_type input;
    output_array_type output;

    stxxl::stats * s = stxxl::stats::get_instance();

    std::cout << *s;

    fill_input_array(input, phrase);

    output.resize(input.size());

    // HERE streaming part begins (streamifying)
    // create input stream
#ifdef BOOST_MSVC
    typedef streamify_traits<input_array_type::iterator>::stream_type input_stream_type;
#else
    typedef typeof(streamify(input.begin(), input.end())) input_stream_type;
#endif

    input_stream_type input_stream = streamify(input.begin(), input.end());

    // create counter stream
#ifdef BOOST_MSVC
    typedef stxxl::stream::generator2stream<counter_type> counter_stream_type;
#else
    typedef typeof(streamify(counter_type())) counter_stream_type;
#endif
    counter_stream_type counter_stream = streamify(counter_type());

    // create tuple stream
    typedef make_tuple<input_stream_type, counter_stream_type> tuple_stream_type;
    tuple_stream_type tuple_stream(input_stream, counter_stream);

#ifdef USE_FORMRUNS_N_MERGE
    // sort tuples by character
    // 1. form runs
    typedef stream::runs_creator<tuple_stream_type, cmp_type, block_size> runs_creator_stream_type;
    runs_creator_stream_type runs_creator_stream(tuple_stream, cmp_type(), 128 * 1024);
    // 2. merge runs
    typedef stream::runs_merger<runs_creator_stream_type::sorted_runs_type, cmp_type> runs_merger_stream_type;
    runs_merger_stream_type sorted_stream(runs_creator_stream.result(), cmp_type(), 128 * 1024);
#else
    // sort tuples by character
    // (combination of the previous two steps in one algorithm: form runs and merge)
    typedef stream::sort<tuple_stream_type, cmp_type, block_size> sorted_stream_type;
    sorted_stream_type sorted_stream(tuple_stream, cmp_type(), 128 * 1024);
#endif

    // HERE streaming part ends (materializing)
    output_array_type::iterator o = materialize(sorted_stream, output.begin(), output.end());
    // or materialize(sorted_stream,output.begin());
    assert(o == output.end() );

    STXXL_MSG("input string (character,position) :");
    for (unsigned i = 0; i < input.size(); ++i)
    {
        STXXL_MSG("('" << input[i] << "'," << i << ")");
    }
    STXXL_MSG("sorted tuples (character,position):");
    for (unsigned i = 0; i < input.size(); ++i)
    {
        STXXL_MSG("('" << output[i].first << "'," << output[i].second << ")");
    }

    std::cout << *s;

    std::vector<int> InternalArray(1024 * 1024);
    std::sort(InternalArray.begin(), InternalArray.end(), cmp_int());
    stxxl::sort<1024 * 1024>(InternalArray.begin(), InternalArray.end(),
                             cmp_int(), 1024 * 1024 * 10, stxxl::RC());
}
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// This test is based on Truth Cube experimental dataset that is obtained from:
/// "Establishing Physical Standards for Real Time Soft Tissue Simulation" project.
///  URL: http://biorobotics.harvard.edu/truthcube/truthcube.html

#include "SurgSim/Physics/RenderTests/RenderTest.h"

#include "SurgSim/Framework/ApplicationData.h"
#include "SurgSim/Graphics/PointCloudRepresentation.h"
#include "SurgSim/Graphics/OsgPointCloudRepresentation.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/Vector.h"
#include "SurgSim/Math/RigidTransform.h"

using SurgSim::Math::Vector3d;
using SurgSim::Math::Quaterniond;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::makeRigidTransform;

namespace SurgSim
{
namespace Physics
{

typedef SurgSim::DataStructures::Vertices<void> CloudMesh;

struct TruthCube
{
	// Data positions of uncompressed data
	std::vector<Vector3d> cubeData0;

	// Data positions of 5% strain
	std::vector<Vector3d> cubeData1;

	// Data positions of  12.5% strain
	std::vector<Vector3d> cubeData2;

	// Data positions of  18.25% strain
	std::vector<Vector3d> cubeData3;
};

struct TruthCubeRenderTests : public RenderTests
{
	/// Parsing Truth Cube data from an external file
	/// \param truthCube a container of cube data for all strains
	/// \return True if the Truth Cube Data is successful loaded, otherwise false
	bool parseTruthCubeData(std::shared_ptr<TruthCube> truthCube)
	{
		// Position of uncompressed data, 5% strain, 12.5% strain, 18.25% strain
		Vector3d position0, position1, position2, position3;

		const int numCommentLine = 7;
		std::string lineId;
		char comma;
		int i,j,k, index = 0;

		const SurgSim::Framework::ApplicationData data("config.txt");

		std::string filename = data.findFile("uniaxial_positions.csv");

		std::ifstream datafile(filename);

		if (! datafile.good())
		{
			return false;
		}

		while (std::getline(datafile, lineId))
		{
			if (++index > numCommentLine)
			{
				std::stringstream strstream(lineId);
				strstream >> i >> comma >> j >> comma >> k >> comma
					>> position0.x() >> comma >> position0.y() >> comma >> position0.z() >> comma
					>> position1.x() >> comma >> position1.y() >> comma >> position1.z() >> comma
					>> position2.x() >> comma >> position2.y() >> comma >> position2.z() >> comma
					>> position3.x() >> comma >> position3.y() >> comma >> position3.z();

				// Store proper strains for each cubeData
				truthCube->cubeData0.push_back(position0);
				truthCube->cubeData1.push_back(position1);
				truthCube->cubeData2.push_back(position2);
				truthCube->cubeData3.push_back(position3);
			}
		}
			return true;

	};

	void doInitialize()
	{
		// Initialize truthCube variable
		truthCube = std::make_shared<TruthCube>();

		// Parsing TruthCube data
		parseTruthCubeData(truthCube);
	};

	void runTest(std::shared_ptr<SurgSim::Graphics::OsgPointCloudRepresentation<void>> representation)
	{
		representation->setPointSize(4.0);
		RigidTransform3d pose = makeRigidTransform(Quaterniond::Identity(), Vector3d::Zero());
		representation->setInitialPose(pose);

		viewElement->addComponent(representation);
		viewElement->enableManipulator(true);
		viewElement->setManipulatorParameters(Vector3d(0.0, 140.0, 0.0), Vector3d::Zero());

		/// Run the thread
		runtime->start();

		boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
	}

	std::shared_ptr<TruthCube> truthCube;
};

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Uncompressed)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube uncompressed");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube uncompressed data into point cloud
	for (size_t i = 0; i < truthCube->cubeData0.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData0[i]));
	}

	runTest(representation);
}

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Compressed_5)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube 5% strain");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube data into point cloud
	for (size_t i = 0; i < truthCube->cubeData1.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData1[i]));
	}

	runTest(representation);
}

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Compressed_12_5)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube 12.5 strain");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube data into point cloud
	for (size_t i = 0; i < truthCube->cubeData2.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData2[i]));
	}

	runTest(representation);
}

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Compressed_18_25)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube 18.25%");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube data into point cloud
	for (size_t i = 0; i < truthCube->cubeData3.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData3[i]));
	}

	runTest(representation);
}

}; // namespace Physics
}; // namespace SurgSim
<commit_msg>Updata index space of return statement.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// This test is based on Truth Cube experimental dataset that is obtained from:
/// "Establishing Physical Standards for Real Time Soft Tissue Simulation" project.
///  URL: http://biorobotics.harvard.edu/truthcube/truthcube.html

#include "SurgSim/Physics/RenderTests/RenderTest.h"

#include "SurgSim/Framework/ApplicationData.h"
#include "SurgSim/Graphics/PointCloudRepresentation.h"
#include "SurgSim/Graphics/OsgPointCloudRepresentation.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/Vector.h"
#include "SurgSim/Math/RigidTransform.h"

using SurgSim::Math::Vector3d;
using SurgSim::Math::Quaterniond;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::makeRigidTransform;

namespace SurgSim
{
namespace Physics
{

typedef SurgSim::DataStructures::Vertices<void> CloudMesh;

struct TruthCube
{
	// Data positions of uncompressed data
	std::vector<Vector3d> cubeData0;

	// Data positions of 5% strain
	std::vector<Vector3d> cubeData1;

	// Data positions of  12.5% strain
	std::vector<Vector3d> cubeData2;

	// Data positions of  18.25% strain
	std::vector<Vector3d> cubeData3;
};

struct TruthCubeRenderTests : public RenderTests
{
	/// Parsing Truth Cube data from an external file
	/// \param truthCube a container of cube data for all strains
	/// \return True if the Truth Cube Data is successful loaded, otherwise false
	bool parseTruthCubeData(std::shared_ptr<TruthCube> truthCube)
	{
		// Position of uncompressed data, 5% strain, 12.5% strain, 18.25% strain
		Vector3d position0, position1, position2, position3;

		const int numCommentLine = 7;
		std::string lineId;
		char comma;
		int i,j,k, index = 0;

		const SurgSim::Framework::ApplicationData data("config.txt");

		std::string filename = data.findFile("uniaxial_positions.csv");

		std::ifstream datafile(filename);

		if (! datafile.good())
		{
			return false;
		}

		while (std::getline(datafile, lineId))
		{
			if (++index > numCommentLine)
			{
				std::stringstream strstream(lineId);
				strstream >> i >> comma >> j >> comma >> k >> comma
					>> position0.x() >> comma >> position0.y() >> comma >> position0.z() >> comma
					>> position1.x() >> comma >> position1.y() >> comma >> position1.z() >> comma
					>> position2.x() >> comma >> position2.y() >> comma >> position2.z() >> comma
					>> position3.x() >> comma >> position3.y() >> comma >> position3.z();

				// Store proper strains for each cubeData
				truthCube->cubeData0.push_back(position0);
				truthCube->cubeData1.push_back(position1);
				truthCube->cubeData2.push_back(position2);
				truthCube->cubeData3.push_back(position3);
			}
		}
		return true;

	};

	void doInitialize()
	{
		// Initialize truthCube variable
		truthCube = std::make_shared<TruthCube>();

		// Parsing TruthCube data
		parseTruthCubeData(truthCube);
	};

	void runTest(std::shared_ptr<SurgSim::Graphics::OsgPointCloudRepresentation<void>> representation)
	{
		representation->setPointSize(4.0);
		RigidTransform3d pose = makeRigidTransform(Quaterniond::Identity(), Vector3d::Zero());
		representation->setInitialPose(pose);

		viewElement->addComponent(representation);
		viewElement->enableManipulator(true);
		viewElement->setManipulatorParameters(Vector3d(0.0, 140.0, 0.0), Vector3d::Zero());

		/// Run the thread
		runtime->start();

		boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
	}

	std::shared_ptr<TruthCube> truthCube;
};

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Uncompressed)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube uncompressed");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube uncompressed data into point cloud
	for (size_t i = 0; i < truthCube->cubeData0.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData0[i]));
	}

	runTest(representation);
}

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Compressed_5)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube 5% strain");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube data into point cloud
	for (size_t i = 0; i < truthCube->cubeData1.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData1[i]));
	}

	runTest(representation);
}

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Compressed_12_5)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube 12.5 strain");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube data into point cloud
	for (size_t i = 0; i < truthCube->cubeData2.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData2[i]));
	}

	runTest(representation);
}

TEST_F(TruthCubeRenderTests, LoadTruthCubeData_Compressed_18_25)
{
	doInitialize();

	auto representation = std::make_shared<SurgSim::Graphics::OsgPointCloudRepresentation<void>>
		("TruthCube 18.25%");
	auto pointCloud = representation->getVertices();

	/// Loading the Truth Cube data into point cloud
	for (size_t i = 0; i < truthCube->cubeData3.size(); ++i)
	{
		pointCloud->addVertex(CloudMesh::VertexType(truthCube->cubeData3[i]));
	}

	runTest(representation);
}

}; // namespace Physics
}; // namespace SurgSim
<|endoftext|>


<commit_before>/*!
 * \file WRATHDefaultTextAttributePacker.cpp
 * \brief file WRATHDefaultTextAttributePacker.cpp
 *
 * Copyright 2013 by Nomovok Ltd.
 *
 * Contact: info@nomovok.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@nomovok.com>
 *
 */

#include "WRATHConfig.hpp"
#include "WRATHDefaultTextAttributePacker.hpp"
#include "WRATHInterleavedAttributes.hpp"
#include "WRATHCanvas.hpp"

namespace
{
  typedef vec4 position_type;
  typedef vec2 glyph_stretch_type;
  typedef vecN<GLushort,2> glyph_size_type;
  typedef vecN<GLushort,2> glyph_bottom_left_type;
  typedef vecN<GLushort,2> glyph_normalized_coordinate_type;
  typedef vecN<GLubyte,4> color_type;
  typedef GLfloat custom_glyph_data_type;

  class character_attribute:
    public WRATHInterleavedAttributes<position_type, //position -- 0
                                      glyph_stretch_type, //stretch -- 1
                                      glyph_size_type, //glyph_size -- 2
                                      glyph_bottom_left_type, //glyph bottom left -- 3
                                      glyph_normalized_coordinate_type, //glyph_normalized -- 4
                                      color_type, //color --5
                                      custom_glyph_data_type //custom_data --6
                                      >
  {
  public:

    custom_glyph_data_type&
    custom_glyph_data(void)
    {
      return get<WRATHDefaultTextAttributePacker::custom_data_location>();
    }

    glyph_normalized_coordinate_type&
    glyph_normalized_coordinate(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_normalized_coordinate_location>();
    }

    color_type&
    color(void)
    {
      return get<WRATHDefaultTextAttributePacker::color_location>();
    }

    glyph_bottom_left_type&
    glyph_bottom_left(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_bottom_left_texel_location>();
    }

    glyph_size_type&
    glyph_size(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_size_location>();
    }

    position_type&
    position(void)
    {
      return get<WRATHDefaultTextAttributePacker::position_location>();
    }

    glyph_stretch_type&
    glyph_stretch(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_stretch_location>();
    }

    void
    position_xy(const vec2 &v)
    {
      position().x()=v.x();
      position().y()=v.y();
    }

  };

  typedef WRATHDefaultTextAttributePacker* WRATHDefaultTextAttributePackerPtr;
  WRATHDefaultTextAttributePackerPtr&
  the_ptr(int e)
  {
    static vecN<WRATHDefaultTextAttributePackerPtr,2> R(NULL, NULL);
    return R[e];
  }

  typedef const char *attribute_label_type;

  const_c_array<attribute_label_type>
  packer_attribute_names(void)
  {
    static const attribute_label_type attribute_labels[]=
      {
        "pos",
        "glyph_stretch",
        "glyph_size",
        "glyph_bottom_left_texel",
        "glyph_normalized_coordinate",
        "color",

	/*
	  Danger: Must make this match with the generated
	  GLSL found in WRATHFontShaderSpecifier::fetch_texture_font_drawer()
	 */
        "custom_data0",
      };
    static const_c_array<attribute_label_type> R(attribute_labels, 7);
    return R;
  }

  const char*
  packer_label(enum WRATHGenericTextAttributePacker::PackerType subpacker)
  {
    return subpacker==WRATHGenericTextAttributePacker::SubPrimitivePacker?
      "WRATHDefaultTextAttributePacker-SubPrimitives":
      "WRATHDefaultTextAttributePacker-FullQuad";
  }

  color_type
  interpolate_color(const vecN<WRATHText::color_type, 4> &input_color,
                    vec2 glyph_coord)
  {
    color_type R;

    glyph_coord.y()=std::abs(glyph_coord.y());

    // why is .x not abs'd as well?
    //glyph_coord.x()=std::abs(glyph_coord.x());

    /*
      Do bilinear interpolation..
    */
    for(int I=0; I<4; ++I)
      {
        vec4 values_at_corner(input_color[0][I], //bottom_left_corner
                              input_color[1][I], //bottom_right_corner
                              input_color[2][I], //top_right_corner
                              input_color[3][I]);//top_left_corner

        float bottom, top, v;

        bottom= values_at_corner[0] + glyph_coord.x()*( values_at_corner[1]-values_at_corner[0]);
        top=values_at_corner[3] + glyph_coord.x()*( values_at_corner[2]-values_at_corner[3]);

        v=bottom + glyph_coord.y()*(top-bottom);
        R[I]=static_cast<WRATHText::color_type::value_type>(v);
      }

    return R;
  }
}

WRATHDefaultTextAttributePacker::
WRATHDefaultTextAttributePacker(enum PackerType subpacker):
  WRATHGenericTextAttributePacker(sizeof(character_attribute),
                                  packer_label(subpacker),
                                  subpacker,
                                  packer_attribute_names().begin(),
                                  packer_attribute_names().end())
{
  WRATHassert(the_ptr(subpacker)==NULL);
  the_ptr(subpacker)=this;
}

WRATHDefaultTextAttributePacker::
~WRATHDefaultTextAttributePacker()
{
  WRATHassert(the_ptr(type())==this);
  the_ptr(type())=NULL;
}

WRATHDefaultTextAttributePacker*
WRATHDefaultTextAttributePacker::
fetch(enum PackerType e)
{
  if(the_ptr(e)==NULL)
    {
      WRATHNew WRATHDefaultTextAttributePacker(e);
    }
  WRATHassert(the_ptr(e)!=NULL);
  return the_ptr(e);
}

void
WRATHDefaultTextAttributePacker::
attribute_key(WRATHAttributeStoreKey &pkey) const
{
  pkey
    .type_and_format(type_tag<character_attribute>());

  pkey.m_attribute_format_location[color_location].m_normalized=GL_TRUE;
}

void
WRATHDefaultTextAttributePacker::
pack_attribute(enum WRATHFormattedTextStream::corner_type ct,
               const glyph_data &in_glyph,
               const vec2 &normalized_glyph_coordinate_float,
               vecN<GLshort,2> /*normalized_glyph_coordinate_short*/,
               c_array<uint8_t> packing_destination,
               const PackerState&) const
{
  c_array<character_attribute> attr;

  attr=packing_destination.reinterpret_pointer<character_attribute>();

  ivec2 native_bl(in_glyph.m_glyph->texel_lower_left(WRATHTextureFont::native_value));
  ivec2 native_sz(in_glyph.m_glyph->texel_size(WRATHTextureFont::native_value));

  attr[0].position()=position_type(in_glyph.m_native_position[0].x(),
                                   in_glyph.m_native_position[0].y(),
                                   in_glyph.m_z_position,
                                   in_glyph.m_scale);
  attr[0].glyph_stretch()=glyph_stretch_type(in_glyph.m_horizontal_stretching,
                                             in_glyph.m_vertical_stretching);
  attr[0].glyph_size()=glyph_size_type(native_sz.x(), native_sz.y());
  attr[0].glyph_bottom_left()=glyph_bottom_left_type(native_bl.x(), native_bl.y());
  attr[0].glyph_normalized_coordinate()=normalized_glyph_coordinate_short;
  attr[0].custom_glyph_data()=in_glyph.m_glyph->fetch_custom_float(0);

  if(ct==WRATHFormattedTextStream::not_corner)
    {
      attr[0].color()=interpolate_color(in_glyph.m_color,
                                        normalized_glyph_coordinate_float);
    }
  else
    {
      attr[0].color()=in_glyph.m_color[ct];
    }
}

<commit_msg>corrections to putting normalized coordinate back<commit_after>/*!
 * \file WRATHDefaultTextAttributePacker.cpp
 * \brief file WRATHDefaultTextAttributePacker.cpp
 *
 * Copyright 2013 by Nomovok Ltd.
 *
 * Contact: info@nomovok.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@nomovok.com>
 *
 */

#include "WRATHConfig.hpp"
#include "WRATHDefaultTextAttributePacker.hpp"
#include "WRATHInterleavedAttributes.hpp"
#include "WRATHCanvas.hpp"

namespace
{
  typedef vec4 position_type;
  typedef vec2 glyph_stretch_type;
  typedef vecN<GLushort,2> glyph_size_type;
  typedef vecN<GLushort,2> glyph_bottom_left_type;
  typedef vecN<GLshort,2> glyph_normalized_coordinate_type;
  typedef vecN<GLubyte,4> color_type;
  typedef GLfloat custom_glyph_data_type;

  class character_attribute:
    public WRATHInterleavedAttributes<position_type, //position -- 0
                                      glyph_stretch_type, //stretch -- 1
                                      glyph_size_type, //glyph_size -- 2
                                      glyph_bottom_left_type, //glyph bottom left -- 3
                                      glyph_normalized_coordinate_type, //glyph_normalized -- 4
                                      color_type, //color --5
                                      custom_glyph_data_type //custom_data --6
                                      >
  {
  public:

    custom_glyph_data_type&
    custom_glyph_data(void)
    {
      return get<WRATHDefaultTextAttributePacker::custom_data_location>();
    }

    glyph_normalized_coordinate_type&
    glyph_normalized_coordinate(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_normalized_coordinate_location>();
    }

    color_type&
    color(void)
    {
      return get<WRATHDefaultTextAttributePacker::color_location>();
    }

    glyph_bottom_left_type&
    glyph_bottom_left(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_bottom_left_texel_location>();
    }

    glyph_size_type&
    glyph_size(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_size_location>();
    }

    position_type&
    position(void)
    {
      return get<WRATHDefaultTextAttributePacker::position_location>();
    }

    glyph_stretch_type&
    glyph_stretch(void)
    {
      return get<WRATHDefaultTextAttributePacker::glyph_stretch_location>();
    }

    void
    position_xy(const vec2 &v)
    {
      position().x()=v.x();
      position().y()=v.y();
    }

  };

  typedef WRATHDefaultTextAttributePacker* WRATHDefaultTextAttributePackerPtr;
  WRATHDefaultTextAttributePackerPtr&
  the_ptr(int e)
  {
    static vecN<WRATHDefaultTextAttributePackerPtr,2> R(NULL, NULL);
    return R[e];
  }

  typedef const char *attribute_label_type;

  const_c_array<attribute_label_type>
  packer_attribute_names(void)
  {
    static const attribute_label_type attribute_labels[]=
      {
        "pos",
        "glyph_stretch",
        "glyph_size",
        "glyph_bottom_left_texel",
        "glyph_normalized_coordinate",
        "color",

	/*
	  Danger: Must make this match with the generated
	  GLSL found in WRATHFontShaderSpecifier::fetch_texture_font_drawer()
	 */
        "custom_data0",
      };
    static const_c_array<attribute_label_type> R(attribute_labels, 7);
    return R;
  }

  const char*
  packer_label(enum WRATHGenericTextAttributePacker::PackerType subpacker)
  {
    return subpacker==WRATHGenericTextAttributePacker::SubPrimitivePacker?
      "WRATHDefaultTextAttributePacker-SubPrimitives":
      "WRATHDefaultTextAttributePacker-FullQuad";
  }

  color_type
  interpolate_color(const vecN<WRATHText::color_type, 4> &input_color,
                    vec2 glyph_coord)
  {
    color_type R;

    glyph_coord.y()=std::abs(glyph_coord.y());

    // why is .x not abs'd as well?
    //glyph_coord.x()=std::abs(glyph_coord.x());

    /*
      Do bilinear interpolation..
    */
    for(int I=0; I<4; ++I)
      {
        vec4 values_at_corner(input_color[0][I], //bottom_left_corner
                              input_color[1][I], //bottom_right_corner
                              input_color[2][I], //top_right_corner
                              input_color[3][I]);//top_left_corner

        float bottom, top, v;

        bottom= values_at_corner[0] + glyph_coord.x()*( values_at_corner[1]-values_at_corner[0]);
        top=values_at_corner[3] + glyph_coord.x()*( values_at_corner[2]-values_at_corner[3]);

        v=bottom + glyph_coord.y()*(top-bottom);
        R[I]=static_cast<WRATHText::color_type::value_type>(v);
      }

    return R;
  }
}

WRATHDefaultTextAttributePacker::
WRATHDefaultTextAttributePacker(enum PackerType subpacker):
  WRATHGenericTextAttributePacker(sizeof(character_attribute),
                                  packer_label(subpacker),
                                  subpacker,
                                  packer_attribute_names().begin(),
                                  packer_attribute_names().end())
{
  WRATHassert(the_ptr(subpacker)==NULL);
  the_ptr(subpacker)=this;
}

WRATHDefaultTextAttributePacker::
~WRATHDefaultTextAttributePacker()
{
  WRATHassert(the_ptr(type())==this);
  the_ptr(type())=NULL;
}

WRATHDefaultTextAttributePacker*
WRATHDefaultTextAttributePacker::
fetch(enum PackerType e)
{
  if(the_ptr(e)==NULL)
    {
      WRATHNew WRATHDefaultTextAttributePacker(e);
    }
  WRATHassert(the_ptr(e)!=NULL);
  return the_ptr(e);
}

void
WRATHDefaultTextAttributePacker::
attribute_key(WRATHAttributeStoreKey &pkey) const
{
  pkey
    .type_and_format(type_tag<character_attribute>());

  pkey.m_attribute_format_location[color_location].m_normalized=GL_TRUE;
  pkey.m_attribute_format_location[glyph_normalized_coordinate_location].m_normalized=GL_TRUE;
}

void
WRATHDefaultTextAttributePacker::
pack_attribute(enum WRATHFormattedTextStream::corner_type ct,
               const glyph_data &in_glyph,
               const vec2 &normalized_glyph_coordinate_float,
               vecN<GLshort,2> normalized_glyph_coordinate_short,
               c_array<uint8_t> packing_destination,
               const PackerState&) const
{
  c_array<character_attribute> attr;

  attr=packing_destination.reinterpret_pointer<character_attribute>();

  ivec2 native_bl(in_glyph.m_glyph->texel_lower_left(WRATHTextureFont::native_value));
  ivec2 native_sz(in_glyph.m_glyph->texel_size(WRATHTextureFont::native_value));

  attr[0].position()=position_type(in_glyph.m_native_position[0].x(),
                                   in_glyph.m_native_position[0].y(),
                                   in_glyph.m_z_position,
                                   in_glyph.m_scale);
  attr[0].glyph_stretch()=glyph_stretch_type(in_glyph.m_horizontal_stretching,
                                             in_glyph.m_vertical_stretching);
  attr[0].glyph_size()=glyph_size_type(native_sz.x(), native_sz.y());
  attr[0].glyph_bottom_left()=glyph_bottom_left_type(native_bl.x(), native_bl.y());
  attr[0].glyph_normalized_coordinate()=normalized_glyph_coordinate_short;
  attr[0].custom_glyph_data()=in_glyph.m_glyph->fetch_custom_float(0);

  if(ct==WRATHFormattedTextStream::not_corner)
    {
      attr[0].color()=interpolate_color(in_glyph.m_color,
                                        normalized_glyph_coordinate_float);
    }
  else
    {
      attr[0].color()=in_glyph.m_color[ct];
    }
}

<|endoftext|>


<commit_before>// $Id$
//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Oystein Djuvsland                                     *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/// @file   AliHLTTriggerBarrelGeomMultiplicity.cxx
/// @author Oystein Djuvsland
/// @date   2009-10-08
/// @brief  HLT trigger component for charged particle multiplicity
///         within a geometrical acceptance in the central barrel.

// see header file for class documentation
// or
// refer to README to build package
// or
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt

#include "AliHLTTriggerBarrelGeomMultiplicity.h"
#include "AliHLTTriggerDetectorGeom.h"
#include "AliHLTTriggerDecisionParameters.h"
#include "AliESDEvent.h"
#include "AliHLTTriggerDecision.h"
#include "AliHLTDomainEntry.h"
#include "AliHLTGlobalBarrelTrack.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "TFile.h"
#include "AliHLTTrigger.h"

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTTriggerBarrelGeomMultiplicity)

AliHLTTriggerBarrelGeomMultiplicity::AliHLTTriggerBarrelGeomMultiplicity()
  : AliHLTTrigger()
  , fSolenoidBz(0)
  , fMinTracks(1)
  , fDetectorArray(0)
  , fTriggerDecisionPars(0)
  , fTriggerName(0)
  , fOCDBEntry(0)
{
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
  fDetectorArray = new TObjArray(1);

  fDetectorArray = new TObjArray;

}

AliHLTTriggerBarrelGeomMultiplicity::~AliHLTTriggerBarrelGeomMultiplicity()
{
  // see header file for class documentation
}

const char* AliHLTTriggerBarrelGeomMultiplicity::GetTriggerName() const
{
  // see header file for class documentation
  //  const char* name = fTriggerName;
  //  if(name) return name;
  return "BarrelGeomMultiplicityTrigger";
}

AliHLTComponent* AliHLTTriggerBarrelGeomMultiplicity::Spawn()
{
  // see header file for class documentation
  return new AliHLTTriggerBarrelGeomMultiplicity;
}

int AliHLTTriggerBarrelGeomMultiplicity::Reconfigure(const char *cdbEntry, const char *chainId)
{
  // see header file for class documentation

  // configure from the specified entry or the default
  const char* entry=cdbEntry;

  if (!entry)
    {
      HLTDebug("No CDB path specified");
      entry = fOCDBEntry;
    }

  return GetDetectorGeomsFromCDBObject(entry, chainId);
}

int AliHLTTriggerBarrelGeomMultiplicity::DoTrigger()
{
  // see header file for class documentation
  int iResult=0;
  int numberOfTracks=-1;

  if (!fTriggerDecisionPars) {
    iResult=-ENODEV;
  }

  // try the ESD as input
  const TObject* obj = GetFirstInputObject(kAliHLTAllDataTypes, "AliESDEvent");
n  AliESDEvent* esd = dynamic_cast<AliESDEvent*>(const_cast<TObject*>(obj));
  TString description;

  if (esd != NULL)
    {
      numberOfTracks=0;
      esd->GetStdContent();
      for (Int_t i = 0; i < esd->GetNumberOfTracks(); i++)
	{
	  if (CheckCondition(esd->GetTrack(i), esd->GetMagneticField())) numberOfTracks++;
	}
    }

  // try the AliHLTExternal track data as input
  if (iResult>=0 && numberOfTracks<0)
    {
      for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack);
	   pBlock!=NULL; pBlock=GetNextInputBlock())
	{
	  if (numberOfTracks<0) numberOfTracks=0;
	  vector<AliHLTGlobalBarrelTrack> tracks;
	  if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast<const AliHLTTracksData*>(pBlock->fPtr), pBlock->fSize, tracks))>0)
	    {
	      for (vector<AliHLTGlobalBarrelTrack>::iterator element=tracks.begin();
		   element!=tracks.end(); element++)
		{
		  if (CheckCondition(&(*element), fSolenoidBz)) numberOfTracks++;
		}
	    }
	  else if (iResult<0)
	    {
	      HLTError("can not extract tracks from data block of type %s (specification %08x) of size %d: error %d",
		       DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification, pBlock->fSize, iResult);
	    }
	}
    }

  bool condition=false;
  description="Geometrical conditions not matched";
  AliHLTReadoutList readout;

  if (numberOfTracks>=fMinTracks)
    {
      condition=true;
      description=fTriggerDecisionPars->GetDescription();
      readout=fTriggerDecisionPars->GetReadoutListParameter();
      HLTDebug("Geometrical acceptance trigger %s triggered", fTriggerDecisionPars->GetTriggerName().Data());
    }

  AliHLTTriggerDecision decision(
				 condition,
				 fTriggerDecisionPars->GetTriggerName().Data(),
				 AliHLTTriggerDomain(readout),
				 description.Data()
				 );
  TriggerEvent(&decision, kAliHLTDataTypeTObject|kAliHLTDataOriginOut);

  return iResult;

}

template<class T>
bool AliHLTTriggerBarrelGeomMultiplicity::CheckCondition(T* track, float b)
{
  bool ret = false;

  // see header file for class documentation
  if (!track) return false;

  ret = IsInDetectors(track, b);

  return ret;

}

template<class T>
bool AliHLTTriggerBarrelGeomMultiplicity::IsInDetectors(T* track, float b)
{
  // See header file for class documentation
  for(Int_t i = 0; i < fDetectorArray->GetEntries(); i++)
    {
      AliHLTTriggerDetectorGeom *det = static_cast<AliHLTTriggerDetectorGeom*>(fDetectorArray->At(i));

      Double_t trackPoint[3];
      Double_t normVector[3];

      det->GetInitialPoint(trackPoint);
      det->GetNormVector(normVector);

      bool ret = track->Intersect(trackPoint, normVector, b);

      if(ret)
	{
	  if(det->IsInDetector(trackPoint)) return true;
	}
    }
  return false;
}

int AliHLTTriggerBarrelGeomMultiplicity::DoInit(int argc, const char** argv)
{
  // see header file for class documentation

  // first configure the default
  int iResult=0;

  if (iResult>=0 && argc>0)
    iResult=ConfigureFromArgumentString(argc, argv);

  if (!fTriggerDecisionPars) {
    HLTError("decision parameter not initialized");
    iResult=-ENODEV;
  }

  return iResult;
}

int AliHLTTriggerBarrelGeomMultiplicity::DoDeinit()
 {
  // see header file for class documentation
  return 0;
}

int AliHLTTriggerBarrelGeomMultiplicity::ReadPreprocessorValues(const char* /*modules*/)
{
    // see header file for function documentation
  int nDetectorGeoms=0;

  // TODO 2009-10-10: implementation
  // for the moment very quick, just reload the magnetic field
  return ConfigureFromCDBTObjString(kAliHLTCDBSolenoidBz);
}

int AliHLTTriggerBarrelGeomMultiplicity::GetDetectorGeomsFromCDBObject(const char *cdbEntry, const char* chainId)
{
    // see header file for function documentation
  int nDetectorGeoms=0;

  if(fDetectorArray)
    {
      fDetectorArray->Clear();
    }
  else
    {
      fDetectorArray = new TObjArray();
    }

  const char *path = cdbEntry;

  if(!path) path = fOCDBEntry;

  if(path)
    {
      //     const char* chainId=GetChainId();
      HLTInfo("configure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
      AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
      if (pEntry)
	{
	  TObjArray* pArr=dynamic_cast<TObjArray*>(pEntry->GetObject());
	  if (pArr)
	    {

	      for(int i = 0; i < pArr->GetEntries(); i++)
		{
		  if(!strcmp(pArr->At(i)->ClassName(), "AliHLTTriggerDecisionParameters"))
		    {
		      fTriggerDecisionPars = dynamic_cast<AliHLTTriggerDecisionParameters*>(pArr->At(i));
		    }
		  else if(pArr->At(i)->InheritsFrom("AliHLTTriggerDetectorGeom"))
		    {
		      fDetectorArray->AddLast(dynamic_cast<AliHLTTriggerDetectorGeom*>(pArr->At(i)));
		      nDetectorGeoms++;
		      HLTDebug("received detector geometry of type %s", pArr->At(i)->ClassName());
		    }
		  else
		    {
		      HLTWarning("Unknown object of type %s in configuration object", pArr->At(i)->ClassName());
		    }
		}
	    }
	  else
	    {
	      HLTError("configuration object \"%s\" has wrong type, required TObjArray", path);
	      nDetectorGeoms=-EINVAL;
	    }
	}
      else
	{
	  HLTError("can not fetch object \"%s\" from OCDB", path);
	  nDetectorGeoms=-ENOENT;
	}
    }

  HLTInfo("received %d detector geometries", nDetectorGeoms);

  return nDetectorGeoms;
}

int AliHLTTriggerBarrelGeomMultiplicity::GetDetectorGeomsFromFile(const char *filename)
{
    // see header file for function documentation
  int nDetectorGeoms=0;

  if(fDetectorArray)
    {
      fDetectorArray->Clear();
    }
  else
    {
      fDetectorArray = new TObjArray();
    }

  if (filename)
    {
      TFile *geomfile = TFile::Open(filename, "READ");

      if(geomfile)
	{
	  HLTInfo("configure from file \"%s\"", filename);
	  TObjArray* pArr=dynamic_cast<TObjArray*>(geomfile->Get("GeomConf"));
	  if (pArr)
	    {

	      for(int i = 0; i < pArr->GetEntries(); i++)
		{
		  if(!strcmp(pArr->At(i)->ClassName(), "AliHLTTriggerDecisionParameters"))
		    {
		      fTriggerDecisionPars = dynamic_cast<AliHLTTriggerDecisionParameters*>(pArr->At(i));
		    }
		  else if(pArr->At(i)->InheritsFrom("AliHLTTriggerDetectorGeom"))
		    {
		      fDetectorArray->AddLast(dynamic_cast<AliHLTTriggerDetectorGeom*>(pArr->At(i)));
		      nDetectorGeoms++;
		      HLTDebug("received detector geometry of type %s", pArr->At(i)->ClassName());
		    }
		  else
		    {
		      HLTWarning("Unknown object of type %s in configuration object", pArr->At(i)->ClassName());
		    }
		}
	    }
	  else
	    {
	      HLTError("configuration object has wrong type, required TObjArray");
	      nDetectorGeoms=-EINVAL;
	    }
	  }
      else
	{
	  HLTError("could not open file \"%s\"", filename);
	  nDetectorGeoms=-ENOENT;
	}
    }
  else
    {
      HLTError("ROOT file name not specified");
    }
  HLTInfo("received %d detector geometries", nDetectorGeoms);

  return nDetectorGeoms;
}

int AliHLTTriggerBarrelGeomMultiplicity::ScanConfigurationArgument(int argc, const char** argv)
{
  // See header file for class documentation
  if (argc<=0) return 0;
  int i=0;
  TString argument=argv[i];

  if (argument.CompareTo("-geomfile")==0)
    {
      if (++i>=argc) return -EPROTO;

      GetDetectorGeomsFromFile(argv[i]);

      return 2;
    }

  if (argument.CompareTo("-triggername")==0)
    {
      if (++i>=argc) return -EPROTO;

      fTriggerName = new char[128];
      sprintf(fTriggerName, argv[i]);

      fOCDBEntry = fTriggerName;

      return 2;
  }
  return 0;
}

<commit_msg>- adding debug output to trigger component<commit_after>// $Id$
//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Oystein Djuvsland                                     *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/// @file   AliHLTTriggerBarrelGeomMultiplicity.cxx
/// @author Oystein Djuvsland
/// @date   2009-10-08
/// @brief  HLT trigger component for charged particle multiplicity
///         within a geometrical acceptance in the central barrel.

// see header file for class documentation
// or
// refer to README to build package
// or
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt

#include "AliHLTTriggerBarrelGeomMultiplicity.h"
#include "AliHLTTriggerDetectorGeom.h"
#include "AliHLTTriggerDecisionParameters.h"
#include "AliESDEvent.h"
#include "AliHLTTriggerDecision.h"
#include "AliHLTDomainEntry.h"
#include "AliHLTGlobalBarrelTrack.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "TFile.h"
#include "AliHLTTrigger.h"

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTTriggerBarrelGeomMultiplicity)

AliHLTTriggerBarrelGeomMultiplicity::AliHLTTriggerBarrelGeomMultiplicity()
  : AliHLTTrigger()
  , fSolenoidBz(0)
  , fMinTracks(1)
  , fDetectorArray(0)
  , fTriggerDecisionPars(0)
  , fTriggerName(0)
  , fOCDBEntry(0)
{
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
  fDetectorArray = new TObjArray(1);

  fDetectorArray = new TObjArray;

}

AliHLTTriggerBarrelGeomMultiplicity::~AliHLTTriggerBarrelGeomMultiplicity()
{
  // see header file for class documentation
}

const char* AliHLTTriggerBarrelGeomMultiplicity::GetTriggerName() const
{
  // see header file for class documentation

  return "BarrelGeomMultiplicityTrigger";
}

AliHLTComponent* AliHLTTriggerBarrelGeomMultiplicity::Spawn()
{
  // see header file for class documentation
  return new AliHLTTriggerBarrelGeomMultiplicity;
}

int AliHLTTriggerBarrelGeomMultiplicity::Reconfigure(const char *cdbEntry, const char *chainId)
{
  // see header file for class documentation

  // configure from the specified entry or the default
  const char* entry=cdbEntry;

  if (!entry)
    {
      HLTDebug("No CDB path specified");
      entry = fOCDBEntry;
    }

  return GetDetectorGeomsFromCDBObject(entry, chainId);
}

int AliHLTTriggerBarrelGeomMultiplicity::DoTrigger()
{
  // see header file for class documentation
  int iResult=0;
  int numberOfTracks=-1;

  if (!fTriggerDecisionPars) {
    iResult=-ENODEV;
  }

  // try the ESD as input
  const TObject* obj = GetFirstInputObject(kAliHLTAllDataTypes, "AliESDEvent");
n  AliESDEvent* esd = dynamic_cast<AliESDEvent*>(const_cast<TObject*>(obj));
  TString description;

  if (esd != NULL)
    {
      numberOfTracks=0;
      esd->GetStdContent();
      for (Int_t i = 0; i < esd->GetNumberOfTracks(); i++)
	{
	  if (CheckCondition(esd->GetTrack(i), esd->GetMagneticField())) numberOfTracks++;
	}
    }

  // try the AliHLTExternal track data as input
  if (iResult>=0 && numberOfTracks<0)
    {
      for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack);
	   pBlock!=NULL; pBlock=GetNextInputBlock())
	{
	  if (numberOfTracks<0) numberOfTracks=0;
	  vector<AliHLTGlobalBarrelTrack> tracks;
	  if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast<const AliHLTTracksData*>(pBlock->fPtr), pBlock->fSize, tracks))>0)
	    {
	      for (vector<AliHLTGlobalBarrelTrack>::iterator element=tracks.begin();
		   element!=tracks.end(); element++)
		{
		  if (CheckCondition(&(*element), fSolenoidBz)) numberOfTracks++;
		}
	    }
	  else if (iResult<0)
	    {
	      HLTError("can not extract tracks from data block of type %s (specification %08x) of size %d: error %d",
		       DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification, pBlock->fSize, iResult);
	    }
	}
    }

  bool condition=false;
  description="Geometrical conditions not matched";
  AliHLTReadoutList readout;

  if (numberOfTracks>=fMinTracks)
    {
      condition=true;
      description=fTriggerDecisionPars->GetDescription();
      readout=fTriggerDecisionPars->GetReadoutListParameter();
      HLTDebug("Geometrical acceptance trigger %s triggered", fTriggerDecisionPars->GetTriggerName().Data());
    }

  AliHLTTriggerDecision decision(
				 condition,
				 fTriggerDecisionPars->GetTriggerName().Data(),
				 AliHLTTriggerDomain(readout),
				 description.Data()
				 );
  TriggerEvent(&decision, kAliHLTDataTypeTObject|kAliHLTDataOriginOut);

  return iResult;

}

template<class T>
bool AliHLTTriggerBarrelGeomMultiplicity::CheckCondition(T* track, float b)
{
  bool ret = false;

  // see header file for class documentation
  if (!track) return false;

  ret = IsInDetectors(track, b);

  return ret;

}

template<class T>
bool AliHLTTriggerBarrelGeomMultiplicity::IsInDetectors(T* track, float b)
{
  // See header file for class documentation
  for(Int_t i = 0; i < fDetectorArray->GetEntries(); i++)
    {
      AliHLTTriggerDetectorGeom *det = static_cast<AliHLTTriggerDetectorGeom*>(fDetectorArray->At(i));

      Double_t trackPoint[3];
      Double_t normVector[3];

      det->GetInitialPoint(trackPoint);
      det->GetNormVector(normVector);

      bool ret = track->Intersect(trackPoint, normVector, b);

      if(ret)
	{
	  if(det->IsInDetector(trackPoint)) return true;
	}
    }
  return false;
}

int AliHLTTriggerBarrelGeomMultiplicity::DoInit(int argc, const char** argv)
{
  // see header file for class documentation

  // first configure the default
  int iResult=0;

  if (iResult>=0 && argc>0)
    iResult=ConfigureFromArgumentString(argc, argv);

  if (!fTriggerDecisionPars) {
    HLTError("decision parameter not initialized");
    iResult=-ENODEV;
  }

  return iResult;
}

int AliHLTTriggerBarrelGeomMultiplicity::DoDeinit()
 {
  // see header file for class documentation
  return 0;
}

int AliHLTTriggerBarrelGeomMultiplicity::ReadPreprocessorValues(const char* /*modules*/)
{
    // see header file for function documentation
  int nDetectorGeoms=0;

  // TODO 2009-10-10: implementation
  // for the moment very quick, just reload the magnetic field
  return ConfigureFromCDBTObjString(kAliHLTCDBSolenoidBz);
}

int AliHLTTriggerBarrelGeomMultiplicity::GetDetectorGeomsFromCDBObject(const char *cdbEntry, const char* chainId)
{
    // see header file for function documentation
  int nDetectorGeoms=0;

  if(fDetectorArray)
    {
      fDetectorArray->Clear();
    }
  else
    {
      fDetectorArray = new TObjArray();
    }

  const char *path = cdbEntry;

  if(!path) path = fOCDBEntry;

  if(path)
    {
      //     const char* chainId=GetChainId();
      HLTInfo("configure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
      AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
      if (pEntry)
	{
	  TObjArray* pArr=dynamic_cast<TObjArray*>(pEntry->GetObject());
	  if (pArr)
	    {

	      for(int i = 0; i < pArr->GetEntries(); i++)
		{
		  if(!strcmp(pArr->At(i)->ClassName(), "AliHLTTriggerDecisionParameters"))
		    {
		      fTriggerDecisionPars = dynamic_cast<AliHLTTriggerDecisionParameters*>(pArr->At(i));
		    }
		  else if(pArr->At(i)->InheritsFrom("AliHLTTriggerDetectorGeom"))
		    {
		      fDetectorArray->AddLast(dynamic_cast<AliHLTTriggerDetectorGeom*>(pArr->At(i)));
		      nDetectorGeoms++;
		      HLTDebug("received detector geometry of type %s", pArr->At(i)->ClassName());
		    }
		  else
		    {
		      HLTWarning("Unknown object of type %s in configuration object", pArr->At(i)->ClassName());
		    }
		}
	    }
	  else
	    {
	      HLTError("configuration object \"%s\" has wrong type, required TObjArray", path);
	      nDetectorGeoms=-EINVAL;
	    }
	}
      else
	{
	  HLTError("can not fetch object \"%s\" from OCDB", path);
	  nDetectorGeoms=-ENOENT;
	}
    }

  HLTInfo("received %d detector geometries", nDetectorGeoms);

  return nDetectorGeoms;
}

int AliHLTTriggerBarrelGeomMultiplicity::GetDetectorGeomsFromFile(const char *filename)
{
    // see header file for function documentation
  int nDetectorGeoms=0;

  if(fDetectorArray)
    {
      fDetectorArray->Clear();
    }
  else
    {
      fDetectorArray = new TObjArray();
    }

  if (filename)
    {
      TFile *geomfile = TFile::Open(filename, "READ");

      if(geomfile)
	{
	  HLTInfo("configure from file \"%s\"", filename);
	  TObjArray* pArr=dynamic_cast<TObjArray*>(geomfile->Get("GeomConf"));
	  if (pArr)
	    {

	      for(int i = 0; i < pArr->GetEntries(); i++)
		{
		  if(!strcmp(pArr->At(i)->ClassName(), "AliHLTTriggerDecisionParameters"))
		    {
		      fTriggerDecisionPars = dynamic_cast<AliHLTTriggerDecisionParameters*>(pArr->At(i));
		    }
		  else if(pArr->At(i)->InheritsFrom("AliHLTTriggerDetectorGeom"))
		    {
		      fDetectorArray->AddLast(dynamic_cast<AliHLTTriggerDetectorGeom*>(pArr->At(i)));
		      nDetectorGeoms++;
		      HLTDebug("received detector geometry of type %s", pArr->At(i)->ClassName());
		    }
		  else
		    {
		      HLTWarning("Unknown object of type %s in configuration object", pArr->At(i)->ClassName());
		    }
		}
	    }
	  else
	    {
	      HLTError("configuration object has wrong type, required TObjArray");
	      nDetectorGeoms=-EINVAL;
	    }
	  }
      else
	{
	  HLTError("could not open file \"%s\"", filename);
	  nDetectorGeoms=-ENOENT;
	}
    }
  else
    {
      HLTError("ROOT file name not specified");
    }
  HLTInfo("received %d detector geometries", nDetectorGeoms);

  return nDetectorGeoms;
}

int AliHLTTriggerBarrelGeomMultiplicity::ScanConfigurationArgument(int argc, const char** argv)
{
  // See header file for class documentation
  if (argc<=0) return 0;
  int i=0;
  TString argument=argv[i];

  if (argument.CompareTo("-geomfile")==0)
    {
      if (++i>=argc) return -EPROTO;

      GetDetectorGeomsFromFile(argv[i]);

      return 2;
    }

  if (argument.CompareTo("-triggername")==0)
    {
      if (++i>=argc) return -EPROTO;

      fTriggerName = new char[128];
      sprintf(fTriggerName, argv[i]);

      fOCDBEntry = fTriggerName;

      return 2;
  }
  return 0;
}

<|endoftext|>


<commit_before>#ifndef CMDSTAN_ARGUMENTS_ARG_NUM_THREADS_HPP
#define CMDSTAN_ARGUMENTS_ARG_NUM_THREADS_HPP

#include <cmdstan/arguments/singleton_argument.hpp>
#include <stan/math/prim/core/init_threadpool_tbb.hpp>

namespace cmdstan {

class arg_num_threads : public int_argument {
 public:
  arg_num_threads() : int_argument() {
    _name = "num_threads";
    _description = std::string(
        "Number of threads available to the program. For full effect, the "
        "model must be compiled with STAN_THREADS=true.");
#ifdef STAN_THREADS
    _validity = "num_threads > 0 || num_threads == -1";
#else
    _validity = "num_threads == 1";
#endif
    _default = "1 or the value of the STAN_NUM_THREADS environment variable if set.";
    _default_value = stan::math::internal::get_num_threads();
    _good_value = 1.0;
    _bad_value = -2.0;
    _constrained = true;
    _value = _default_value;
  }
#ifdef STAN_THREADS
  bool is_valid(int value) { return value > -2 && value != 0; }
#else
  bool is_valid(int value) { return value == 1; }
#endif
};

}  // namespace cmdstan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)<commit_after>#ifndef CMDSTAN_ARGUMENTS_ARG_NUM_THREADS_HPP
#define CMDSTAN_ARGUMENTS_ARG_NUM_THREADS_HPP

#include <cmdstan/arguments/singleton_argument.hpp>
#include <stan/math/prim/core/init_threadpool_tbb.hpp>

namespace cmdstan {

class arg_num_threads : public int_argument {
 public:
  arg_num_threads() : int_argument() {
    _name = "num_threads";
    _description = std::string(
        "Number of threads available to the program. For full effect, the "
        "model must be compiled with STAN_THREADS=true.");
#ifdef STAN_THREADS
    _validity = "num_threads > 0 || num_threads == -1";
#else
    _validity = "num_threads == 1";
#endif
    _default
        = "1 or the value of the STAN_NUM_THREADS environment variable if set.";
    _default_value = stan::math::internal::get_num_threads();
    _good_value = 1.0;
    _bad_value = -2.0;
    _constrained = true;
    _value = _default_value;
  }
#ifdef STAN_THREADS
  bool is_valid(int value) { return value > -2 && value != 0; }
#else
  bool is_valid(int value) { return value == 1; }
#endif
};

}  // namespace cmdstan
#endif
<|endoftext|>


<commit_before>// Ouzel by Elviss Strazdins

#ifndef OUZEL_UTILS_LOG_HPP
#define OUZEL_UTILS_LOG_HPP

#include <atomic>
#include <cstring>
#include <mutex>
#include <string>
#include <type_traits>
#include "../math/Matrix.hpp"
#include "../math/Quaternion.hpp"
#include "../math/Size.hpp"
#include "../math/Vector.hpp"
#include "../storage/Path.hpp"
#include "Bit.hpp"

namespace ouzel
{
    class Logger;

    template<typename T, typename = void>
    struct isContainer: public std::false_type {};

    template<typename T>
    struct isContainer<T,
        std::void_t<
            decltype(std::declval<T>().begin()),
            decltype(std::declval<T>().end())
        >>: public std::true_type {};

    class Log final
    {
    public:
        enum class Level
        {
            off,
            error,
            warning,
            info,
            all
        };

        explicit Log(const Logger& initLogger, Level initLevel = Level::info):
            logger(initLogger), level(initLevel)
        {
        }

        Log(const Log& other):
            logger(other.logger),
            level(other.level),
            s(other.s)
        {
        }

        Log(Log&& other) noexcept:
            logger(other.logger),
            level(other.level),
            s(std::move(other.s))
        {
            other.level = Level::info;
        }

        Log& operator=(const Log& other)
        {
            if (&other == this) return *this;

            level = other.level;
            s = other.s;

            return *this;
        }

        Log& operator=(Log&& other) noexcept
        {
            if (&other == this) return *this;

            level = other.level;
            other.level = Level::info;
            s = std::move(other.s);

            return *this;
        }

        ~Log();

        Log& operator<<(const bool val)
        {
            s += val ? "true" : "false";
            return *this;
        }

        Log& operator<<(char val)
        {
            s += val;
            return *this;
        }

        Log& operator<<(const std::uint8_t val)
        {
            constexpr char digits[] = "0123456789abcdef";
            s.push_back(digits[(val >> 4) & 0x0F]);
            s.push_back(digits[(val >> 0) & 0x0F]);
            return *this;
        }

        template <typename T, std::enable_if_t<std::is_arithmetic_v<T> &&
            !std::is_same_v<T, bool> &&
            !std::is_same_v<T, std::uint8_t>>* = nullptr>
        Log& operator<<(const T val)
        {
            s += std::to_string(val);
            return *this;
        }

        Log& operator<<(const std::string& val)
        {
            s += val;
            return *this;
        }

        Log& operator<<(const char* val)
        {
            s += val;
            return *this;
        }

        template <typename T, std::enable_if_t<!std::is_same_v<T, char>>* = nullptr>
        Log& operator<<(const T* val)
        {
            constexpr char digits[] = "0123456789abcdef";

            const auto ptrValue = bitCast<std::uintptr_t>(val);

            for (std::size_t i = 0; i < sizeof(val) * 2; ++i)
                s.push_back(digits[(ptrValue >> (sizeof(ptrValue) * 2 - i - 1) * 4) & 0x0F]);

            return *this;
        }

        template <typename T, std::enable_if_t<isContainer<T>::value || std::is_array_v<T>>* = nullptr>
        Log& operator<<(const T& val)
        {
            bool first = true;
            for (const auto& i : val)
            {
                if (!first) s += ", ";
                first = false;
                operator<<(i);
            }

            return *this;
        }

    private:
        const Logger& logger;
        Level level = Level::info;
        std::string s;
    };

    class Logger final
    {
    public:
        explicit Logger(Log::Level initThreshold = Log::Level::all):
            threshold(initThreshold)
        {
        }

        Logger(const Logger&) = delete;
        Logger& operator=(const Logger&) = delete;
        Logger(Logger&&) = delete;
        Logger& operator=(Logger&&) = delete;

        Log log(const Log::Level level = Log::Level::info) const
        {
            return Log(*this, level);
        }

        void log(const std::string& str, const Log::Level level = Log::Level::info) const
        {
            if (level <= threshold)
            {
#ifndef __EMSCRIPTEN__
                std::scoped_lock lock(logMutex);
#endif
                logString(str, level);
            }
        }

    private:
        static void logString(const std::string& str, const Log::Level level = Log::Level::info);

#ifdef DEBUG
        std::atomic<Log::Level> threshold{Log::Level::all};
#else
        std::atomic<Log::Level> threshold{Log::Level::info};
#endif

#ifndef __EMSCRIPTEN__
        mutable std::mutex logMutex;
#endif
    };

    inline Log::~Log()
    {
        if (!s.empty())
            logger.log(s, level);
    }

    template <class T, std::size_t N, std::size_t M>
    Log& operator<<(Log& log, const Matrix<T, N, M>& val)
    {
        bool first = true;

        for (const T c : val.m)
        {
            if (!first) log << ",";
            first = false;
            log << c;
        }

        return log;
    }

    template <class T, std::size_t N>
    Log& operator<<(Log& log, const Size<T, N>& val)
    {
        bool first = true;

        for (const T c : val.v)
        {
            if (!first) log << ",";
            first = false;
            log << c;
        }
        return log;
    }

    template <class T, std::size_t N>
    Log& operator<<(Log& log, const Vector<T, N>& val)
    {
        bool first = true;

        for (const T c : val.v)
        {
            if (!first) log << ",";
            first = false;
            log << c;
        }
        return log;
    }

    template <typename T>
    Log& operator<<(Log& log, const Quaternion<T>& val)
    {
        return log << "[" << val.v[0] << "," << val.v[1] << "," << val.v[2] << "," << val.v[3] << "]";
    }

    inline Log& operator<<(Log& log, const storage::Path& val)
    {
        log << val.getGeneric();
        return log;
    }

    extern Logger logger;
}

#endif // OUZEL_UTILS_LOG_HPP
<commit_msg>Add a constexpr bool variable for container check<commit_after>// Ouzel by Elviss Strazdins

#ifndef OUZEL_UTILS_LOG_HPP
#define OUZEL_UTILS_LOG_HPP

#include <atomic>
#include <cstring>
#include <mutex>
#include <string>
#include <type_traits>
#include "../math/Matrix.hpp"
#include "../math/Quaternion.hpp"
#include "../math/Size.hpp"
#include "../math/Vector.hpp"
#include "../storage/Path.hpp"
#include "Bit.hpp"

namespace ouzel
{
    class Logger;

    template<typename T, typename = void>
    struct IsContainer: public std::false_type {};

    template<typename T>
    struct IsContainer<T,
        std::void_t<
            decltype(std::declval<T>().begin()),
            decltype(std::declval<T>().end())
        >>: public std::true_type {};

    template<typename T>
    inline constexpr bool isContainer = IsContainer<T>::value;

    class Log final
    {
    public:
        enum class Level
        {
            off,
            error,
            warning,
            info,
            all
        };

        explicit Log(const Logger& initLogger, Level initLevel = Level::info):
            logger(initLogger), level(initLevel)
        {
        }

        Log(const Log& other):
            logger(other.logger),
            level(other.level),
            s(other.s)
        {
        }

        Log(Log&& other) noexcept:
            logger(other.logger),
            level(other.level),
            s(std::move(other.s))
        {
            other.level = Level::info;
        }

        Log& operator=(const Log& other)
        {
            if (&other == this) return *this;

            level = other.level;
            s = other.s;

            return *this;
        }

        Log& operator=(Log&& other) noexcept
        {
            if (&other == this) return *this;

            level = other.level;
            other.level = Level::info;
            s = std::move(other.s);

            return *this;
        }

        ~Log();

        Log& operator<<(const bool val)
        {
            s += val ? "true" : "false";
            return *this;
        }

        Log& operator<<(char val)
        {
            s += val;
            return *this;
        }

        Log& operator<<(const std::uint8_t val)
        {
            constexpr char digits[] = "0123456789abcdef";
            s.push_back(digits[(val >> 4) & 0x0F]);
            s.push_back(digits[(val >> 0) & 0x0F]);
            return *this;
        }

        template <typename T, std::enable_if_t<std::is_arithmetic_v<T> &&
            !std::is_same_v<T, bool> &&
            !std::is_same_v<T, std::uint8_t>>* = nullptr>
        Log& operator<<(const T val)
        {
            s += std::to_string(val);
            return *this;
        }

        Log& operator<<(const std::string& val)
        {
            s += val;
            return *this;
        }

        Log& operator<<(const char* val)
        {
            s += val;
            return *this;
        }

        template <typename T, std::enable_if_t<!std::is_same_v<T, char>>* = nullptr>
        Log& operator<<(const T* val)
        {
            constexpr char digits[] = "0123456789abcdef";

            const auto ptrValue = bitCast<std::uintptr_t>(val);

            for (std::size_t i = 0; i < sizeof(val) * 2; ++i)
                s.push_back(digits[(ptrValue >> (sizeof(ptrValue) * 2 - i - 1) * 4) & 0x0F]);

            return *this;
        }

        template <typename T, std::enable_if_t<isContainer<T> || std::is_array_v<T>>* = nullptr>
        Log& operator<<(const T& val)
        {
            bool first = true;
            for (const auto& i : val)
            {
                if (!first) s += ", ";
                first = false;
                operator<<(i);
            }

            return *this;
        }

    private:
        const Logger& logger;
        Level level = Level::info;
        std::string s;
    };

    class Logger final
    {
    public:
        explicit Logger(Log::Level initThreshold = Log::Level::all):
            threshold(initThreshold)
        {
        }

        Logger(const Logger&) = delete;
        Logger& operator=(const Logger&) = delete;
        Logger(Logger&&) = delete;
        Logger& operator=(Logger&&) = delete;

        Log log(const Log::Level level = Log::Level::info) const
        {
            return Log(*this, level);
        }

        void log(const std::string& str, const Log::Level level = Log::Level::info) const
        {
            if (level <= threshold)
            {
#ifndef __EMSCRIPTEN__
                std::scoped_lock lock(logMutex);
#endif
                logString(str, level);
            }
        }

    private:
        static void logString(const std::string& str, const Log::Level level = Log::Level::info);

#ifdef DEBUG
        std::atomic<Log::Level> threshold{Log::Level::all};
#else
        std::atomic<Log::Level> threshold{Log::Level::info};
#endif

#ifndef __EMSCRIPTEN__
        mutable std::mutex logMutex;
#endif
    };

    inline Log::~Log()
    {
        if (!s.empty())
            logger.log(s, level);
    }

    template <class T, std::size_t N, std::size_t M>
    Log& operator<<(Log& log, const Matrix<T, N, M>& val)
    {
        bool first = true;

        for (const T c : val.m)
        {
            if (!first) log << ",";
            first = false;
            log << c;
        }

        return log;
    }

    template <class T, std::size_t N>
    Log& operator<<(Log& log, const Size<T, N>& val)
    {
        bool first = true;

        for (const T c : val.v)
        {
            if (!first) log << ",";
            first = false;
            log << c;
        }
        return log;
    }

    template <class T, std::size_t N>
    Log& operator<<(Log& log, const Vector<T, N>& val)
    {
        bool first = true;

        for (const T c : val.v)
        {
            if (!first) log << ",";
            first = false;
            log << c;
        }
        return log;
    }

    template <typename T>
    Log& operator<<(Log& log, const Quaternion<T>& val)
    {
        return log << "[" << val.v[0] << "," << val.v[1] << "," << val.v[2] << "," << val.v[3] << "]";
    }

    inline Log& operator<<(Log& log, const storage::Path& val)
    {
        log << val.getGeneric();
        return log;
    }

    extern Logger logger;
}

#endif // OUZEL_UTILS_LOG_HPP
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "frtconfigagent.h"
#include "frtconfigrequestv3.h"
#include <vespa/config/common/trace.h>

#include <vespa/log/log.h>
LOG_SETUP(".config.frt.frtconfigagent");

namespace config {

FRTConfigAgent::FRTConfigAgent(const IConfigHolder::SP & holder, const TimingValues & timingValues)
    : _holder(holder),
      _timingValues(timingValues),
      _configState(),
      _latest(),
      _waitTime(0),
      _numConfigured(0),
      _failedRequests(0),
      _nextTimeout(_timingValues.initialTimeout)
{
}

FRTConfigAgent::~FRTConfigAgent() {}

void
FRTConfigAgent::handleResponse(const ConfigRequest & request, ConfigResponse::UP response)
{
    if (LOG_WOULD_LOG(spam)) {
        const ConfigKey & key(request.getKey());
        LOG(spam, "current state for %s: generation %" PRId64 " md5 %s", key.toString().c_str(), _configState.generation, _configState.md5.c_str());
    }
    if (response->validateResponse() && !response->isError()) {
        handleOKResponse(request, std::move(response));
    } else {
        handleErrorResponse(request, std::move(response));
    }
}

void
FRTConfigAgent::handleOKResponse(const ConfigRequest & request, ConfigResponse::UP response)
{
    _failedRequests = 0;
    response->fill();
    if (LOG_WOULD_LOG(spam)) {
        LOG(spam, "trace(%s)", response->getTrace().toString().c_str());
    }

    ConfigState newState = response->getConfigState();
    if ( ! request.verifyState(newState)) {
        handleUpdatedGeneration(response->getKey(), newState, response->getValue());
    }
    setWaitTime(_timingValues.successDelay, 1);
    _nextTimeout = _timingValues.successTimeout;
}

void
FRTConfigAgent::handleUpdatedGeneration(const ConfigKey & key, const ConfigState & newState, const ConfigValue & configValue)
{
    if (LOG_WOULD_LOG(spam)) {
        LOG(spam, "new generation %" PRId64 " md5:%s for key %s", newState.generation, newState.md5.c_str(), key.toString().c_str());
        LOG(spam, "Old config: md5:%s \n%s", _latest.getMd5().c_str(), _latest.asJson().c_str());
        LOG(spam, "New config: md5:%s \n%s", configValue.getMd5().c_str(), configValue.asJson().c_str());
    }
    bool changed = false;
    if (_latest.getMd5() != configValue.getMd5()) {
        _latest = configValue;
        changed = true;
    }
    _configState = newState;

    if (LOG_WOULD_LOG(spam)) {
        LOG(spam, "updating holder for key %s,", key.toString().c_str());
    }
    _holder->handle(ConfigUpdate::UP(new ConfigUpdate(_latest, changed, newState.generation)));
    _numConfigured++;
}

void
FRTConfigAgent::handleErrorResponse(const ConfigRequest & request, ConfigResponse::UP response)
{
    _failedRequests++;
    int multiplier = std::min(_failedRequests, _timingValues.maxDelayMultiplier);
    setWaitTime(_numConfigured > 0 ? _timingValues.configuredErrorDelay : _timingValues.unconfiguredDelay, multiplier);
    _nextTimeout = _timingValues.errorTimeout;
    const ConfigKey & key(request.getKey());
    LOG(info, "Error response or no response from config server (key: %s) (errcode=%d, validresponse:%d), trying again in %" PRIu64 " milliseconds", key.toString().c_str(), response->errorCode(), response->hasValidResponse() ? 1 : 0, _waitTime);
}

void
FRTConfigAgent::setWaitTime(uint64_t delay, int multiplier)
{
    uint64_t prevWait = _waitTime;
    _waitTime = _timingValues.fixedDelay + (multiplier * delay);
    LOG(spam, "Adjusting waittime from %" PRIu64 " to %" PRIu64, prevWait, _waitTime);
}

uint64_t FRTConfigAgent::getTimeout() const { return _nextTimeout; }
uint64_t FRTConfigAgent::getWaitTime() const { return _waitTime; }
const ConfigState & FRTConfigAgent::getConfigState() const { return _configState; }

}
<commit_msg>= default<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "frtconfigagent.h"
#include "frtconfigrequestv3.h"
#include <vespa/config/common/trace.h>

#include <vespa/log/log.h>
LOG_SETUP(".config.frt.frtconfigagent");

namespace config {

FRTConfigAgent::FRTConfigAgent(const IConfigHolder::SP & holder, const TimingValues & timingValues)
    : _holder(holder),
      _timingValues(timingValues),
      _configState(),
      _latest(),
      _waitTime(0),
      _numConfigured(0),
      _failedRequests(0),
      _nextTimeout(_timingValues.initialTimeout)
{
}

FRTConfigAgent::~FRTConfigAgent() = default;

void
FRTConfigAgent::handleResponse(const ConfigRequest & request, ConfigResponse::UP response)
{
    if (LOG_WOULD_LOG(spam)) {
        const ConfigKey & key(request.getKey());
        LOG(spam, "current state for %s: generation %" PRId64 " md5 %s", key.toString().c_str(), _configState.generation, _configState.md5.c_str());
    }
    if (response->validateResponse() && !response->isError()) {
        handleOKResponse(request, std::move(response));
    } else {
        handleErrorResponse(request, std::move(response));
    }
}

void
FRTConfigAgent::handleOKResponse(const ConfigRequest & request, ConfigResponse::UP response)
{
    _failedRequests = 0;
    response->fill();
    if (LOG_WOULD_LOG(spam)) {
        LOG(spam, "trace(%s)", response->getTrace().toString().c_str());
    }

    ConfigState newState = response->getConfigState();
    if ( ! request.verifyState(newState)) {
        handleUpdatedGeneration(response->getKey(), newState, response->getValue());
    }
    setWaitTime(_timingValues.successDelay, 1);
    _nextTimeout = _timingValues.successTimeout;
}

void
FRTConfigAgent::handleUpdatedGeneration(const ConfigKey & key, const ConfigState & newState, const ConfigValue & configValue)
{
    if (LOG_WOULD_LOG(spam)) {
        LOG(spam, "new generation %" PRId64 " md5:%s for key %s", newState.generation, newState.md5.c_str(), key.toString().c_str());
        LOG(spam, "Old config: md5:%s \n%s", _latest.getMd5().c_str(), _latest.asJson().c_str());
        LOG(spam, "New config: md5:%s \n%s", configValue.getMd5().c_str(), configValue.asJson().c_str());
    }
    bool changed = false;
    if (_latest.getMd5() != configValue.getMd5()) {
        _latest = configValue;
        changed = true;
    }
    _configState = newState;

    if (LOG_WOULD_LOG(spam)) {
        LOG(spam, "updating holder for key %s,", key.toString().c_str());
    }
    _holder->handle(ConfigUpdate::UP(new ConfigUpdate(_latest, changed, newState.generation)));
    _numConfigured++;
}

void
FRTConfigAgent::handleErrorResponse(const ConfigRequest & request, ConfigResponse::UP response)
{
    _failedRequests++;
    int multiplier = std::min(_failedRequests, _timingValues.maxDelayMultiplier);
    setWaitTime(_numConfigured > 0 ? _timingValues.configuredErrorDelay : _timingValues.unconfiguredDelay, multiplier);
    _nextTimeout = _timingValues.errorTimeout;
    const ConfigKey & key(request.getKey());
    LOG(info, "Error response or no response from config server (key: %s) (errcode=%d, validresponse:%d), trying again in %" PRIu64 " milliseconds", key.toString().c_str(), response->errorCode(), response->hasValidResponse() ? 1 : 0, _waitTime);
}

void
FRTConfigAgent::setWaitTime(uint64_t delay, int multiplier)
{
    uint64_t prevWait = _waitTime;
    _waitTime = _timingValues.fixedDelay + (multiplier * delay);
    LOG(spam, "Adjusting waittime from %" PRIu64 " to %" PRIu64, prevWait, _waitTime);
}

uint64_t FRTConfigAgent::getTimeout() const { return _nextTimeout; }
uint64_t FRTConfigAgent::getWaitTime() const { return _waitTime; }
const ConfigState & FRTConfigAgent::getConfigState() const { return _configState; }

}
<|endoftext|>