<commit_before>#include "binlog.h"
#include "util/log.h"
#include "util/strings.h"
#include <map>

/* Binlog */

Binlog::Binlog(uint64_t seq, char cmd, char type, const leveldb::Slice &key){
	buf.append((char *)(&seq), sizeof(uint64_t));
	buf.push_back(cmd);
	buf.push_back(type);
	buf.append(key.data(), key.size());
}

uint64_t Binlog::seq() const{
	return *((uint64_t *)(buf.data()));
}

char Binlog::type() const{
	return buf[sizeof(uint64_t)];
}

char Binlog::cmd() const{
	return buf[sizeof(uint64_t) + 1];
}

const Bytes Binlog::key() const{
	return Bytes(buf.data() + HEADER_LEN, buf.size() - HEADER_LEN);
}

int Binlog::load(const leveldb::Slice &s){
	if(s.size() < HEADER_LEN){
		return -1;
	}
	buf.assign(s.data(), s.size());
	return 0;
}

std::string Binlog::dumps() const{
	std::string str;
	if(buf.size() < HEADER_LEN){
		return str;
	}
	char buf[20];
	snprintf(buf, sizeof(buf), "%llu ", this->seq());
	str.append(buf);

	switch(this->type()){
		case BinlogType::NOOP:
			str.append("noop ");
			break;
		case BinlogType::SYNC:
			str.append("sync ");
			break;
		case BinlogType::MIRROR:
			str.append("mirror ");
			break;
		case BinlogType::COPY:
			str.append("copy ");
			break;
	}
	switch(this->cmd()){
		case BinlogCommand::NONE:
			str.append("none ");
			break;
		case BinlogCommand::KSET:
			str.append("set ");
			break;
		case BinlogCommand::KDEL:
			str.append("del ");
			break;
		case BinlogCommand::HSET:
			str.append("hset ");
			break;
		case BinlogCommand::HDEL:
			str.append("hdel ");
			break;
		case BinlogCommand::ZSET:
			str.append("zset ");
			break;
		case BinlogCommand::ZDEL:
			str.append("zdel ");
			break;
		case BinlogCommand::BEGIN:
			str.append("begin ");
			break;
		case BinlogCommand::END:
			str.append("end ");
			break;
	}
	Bytes b = this->key();
	str.append(hexmem(b.data(), b.size()));
	return str;
}

/* SyncLogQueue */

static inline std::string encode_seq_key(uint64_t seq){
	seq = big_endian(seq);
	std::string ret;
	ret.push_back(DataType::SYNCLOG);
	ret.append((char *)&seq, sizeof(seq));
	return ret;
}

static inline uint64_t decode_seq_key(const leveldb::Slice &key){
	uint64_t seq = 0;
	if(key.size() == (sizeof(uint64_t) + 1) && key.data()[0] == DataType::SYNCLOG){
		seq = *((uint64_t *)(key.data() + 1));
		seq = big_endian(seq);
	}
	return seq;
}

BinlogQueue::BinlogQueue(leveldb::DB *db){
	this->db = db;
	this->min_seq = 0;
	this->last_seq = 0;
	this->tran_seq = 0;
	this->capacity = LOG_QUEUE_SIZE;

	Binlog log;
	if(this->find_last(&log) == 1){
		this->last_seq = log.seq();
	}
	if(this->find_next(1, &log) == 1){
		this->min_seq = log.seq();
	}
	log_debug("capacity: %d, min: %llu, max: %llu,", capacity, min_seq, last_seq);

	//this->merge();
		/*
	int noops = 0;
	int total = 0;
	uint64_t seq = this->min_seq;
	while(this->find_next(seq, &log) == 1){
		total ++;
		seq = log.seq() + 1;
		if(log.type() != BinlogType::NOOP){
			std::string s = log.dumps();
			//log_trace("%s", s.c_str());
			noops ++;
		}
	}
	log_debug("capacity: %d, min: %llu, max: %llu, noops: %d, total: %d",
		capacity, min_seq, last_seq, noops, total);
		*/

	// start cleaning thread
	thread_quit = false;
	pthread_t tid;
	int err = pthread_create(&tid, NULL, &BinlogQueue::log_clean_thread_func, this);
	if(err != 0){
		log_fatal("can't create thread: %s", strerror(err));
		exit(0);
	}
}

BinlogQueue::~BinlogQueue(){
	thread_quit = true;
	while(1){
		if(thread_quit == false){
			break;
		}
		usleep(100 * 1000);
	}
	log_debug("BinlogQueue finalized");
}

void BinlogQueue::begin(){
	tran_seq = last_seq;
	batch.Clear();
}

void BinlogQueue::rollback(){
	tran_seq = 0;
}

leveldb::Status BinlogQueue::commit(){
	leveldb::WriteOptions write_opts;
	leveldb::Status s = db->Write(write_opts, &batch);
	if(s.ok()){
		last_seq = tran_seq;
		tran_seq = 0;
	}
	return s;
}

void BinlogQueue::add(char type, char cmd, const leveldb::Slice &key){
	tran_seq ++;
	Binlog log(tran_seq, type, cmd, key);
	batch.Put(encode_seq_key(tran_seq), log.repr());
}

void BinlogQueue::add(char type, char cmd, const std::string &key){
	leveldb::Slice s(key);
	this->add(type, cmd, s);
}

// leveldb put
void BinlogQueue::Put(const leveldb::Slice& key, const leveldb::Slice& value){
	batch.Put(key, value);
}

// leveldb delete
void BinlogQueue::Delete(const leveldb::Slice& key){
	batch.Delete(key);
}

int BinlogQueue::find_next(uint64_t next_seq, Binlog *log) const{
	if(this->get(next_seq, log) == 1){
		return 1;
	}
	uint64_t ret = 0;
	std::string key_str = encode_seq_key(next_seq);
	leveldb::ReadOptions iterate_options;
	leveldb::Iterator *it = db->NewIterator(iterate_options);
	it->Seek(key_str);
	if(it->Valid()){
		leveldb::Slice key = it->key();
		if(decode_seq_key(key) != 0){
			leveldb::Slice val = it->value();
			if(log->load(val) == -1){
				ret = -1;
			}else{
				ret = 1;
			}
		}
	}
	delete it;
	return ret;
}

int BinlogQueue::find_last(Binlog *log) const{
	uint64_t ret = 0;
	std::string key_str = encode_seq_key(UINT64_MAX);
	leveldb::ReadOptions iterate_options;
	leveldb::Iterator *it = db->NewIterator(iterate_options);
	it->Seek(key_str);
	if(!it->Valid()){
		// Iterator::prev requires Valid, so we seek to last
		it->SeekToLast();
	}
	// UINT64_MAX is not used
	if(it->Valid()){
		it->Prev();
	}
	if(it->Valid()){
		leveldb::Slice key = it->key();
		if(decode_seq_key(key) != 0){
			leveldb::Slice val = it->value();
			if(log->load(val) == -1){
				ret = -1;
			}else{
				ret = 1;
			}
		}
	}
	delete it;
	return ret;
}

int BinlogQueue::get(uint64_t seq, Binlog *log) const{
	std::string val;
	leveldb::Status s = db->Get(leveldb::ReadOptions(), encode_seq_key(seq), &val);
	if(s.ok()){
		if(log->load(val) != -1){
			return 1;
		}
	}
	return 0;
}

int BinlogQueue::update(uint64_t seq, char type, char cmd, const std::string &key){
	Binlog log(seq, type, cmd, key);
	leveldb::Status s = db->Put(leveldb::WriteOptions(), encode_seq_key(seq), log.repr());
	if(s.ok()){
		return 0;
	}
	return -1;
}

int BinlogQueue::del(uint64_t seq){
	leveldb::Status s = db->Delete(leveldb::WriteOptions(), encode_seq_key(seq));
	if(!s.ok()){
		return -1;
	}
	return 0;
}

int BinlogQueue::del_range(uint64_t start, uint64_t end){
	while(start <= end){
		leveldb::WriteBatch batch;
		for(int count = 0; start <= end && count < 1000; start++, count++){
			batch.Delete(encode_seq_key(start));
		}
		leveldb::Status s = db->Write(leveldb::WriteOptions(), &batch);
		if(!s.ok()){
			return -1;
		}
	}
	return 0;
}

void* BinlogQueue::log_clean_thread_func(void *arg){
	BinlogQueue *logs = (BinlogQueue *)arg;

	while(!logs->thread_quit){
		usleep(200 * 1000);

		if(logs->last_seq - logs->min_seq < LOG_QUEUE_SIZE * 1.1){
			continue;
		}

		uint64_t start = logs->min_seq;
		uint64_t end = logs->last_seq - LOG_QUEUE_SIZE;
		logs->del_range(start, end);
		logs->min_seq = end + 1;
		log_debug("clean %d logs[%llu ~ %llu], %d left, max: %llu",
			end-start+1, start, end, logs->last_seq - logs->min_seq + 1, logs->last_seq);
	}
	log_debug("clean_thread quit");

	logs->thread_quit = false;
	return (void *)NULL;
}

// TESTING, slow, so not used
void BinlogQueue::merge(){
	std::map<std::string, uint64_t> key_map;
	uint64_t start = min_seq;
	uint64_t end = last_seq;
	int reduce_count = 0;
	int total = 0;
	total = end - start + 1;
	log_trace("merge begin");
	for(; start <= end; start++){
		Binlog log;
		if(this->get(start, &log) == 1){
			if(log.type() == BinlogType::NOOP){
				continue;
			}
			std::string key = log.key().String();
			std::map<std::string, uint64_t>::iterator it = key_map.find(key);
			if(it != key_map.end()){
				uint64_t seq = it->second;
				this->update(seq, BinlogType::NOOP, BinlogCommand::NONE, "");
				//log_trace("merge update %llu to NOOP", seq);
				reduce_count ++;
			}
			key_map[key] = log.seq();
		}
	}
	log_trace("merge reduce %d of %d binlogs", reduce_count, total);
}
<commit_msg>change Binlog::Binlog argument names<commit_after>#include "binlog.h"
#include "util/log.h"
#include "util/strings.h"
#include <map>

/* Binlog */

Binlog::Binlog(uint64_t seq, char type, char cmd, const leveldb::Slice &key){
	buf.append((char *)(&seq), sizeof(uint64_t));
	buf.push_back(type);
	buf.push_back(cmd);
	buf.append(key.data(), key.size());
}

uint64_t Binlog::seq() const{
	return *((uint64_t *)(buf.data()));
}

char Binlog::type() const{
	return buf[sizeof(uint64_t)];
}

char Binlog::cmd() const{
	return buf[sizeof(uint64_t) + 1];
}

const Bytes Binlog::key() const{
	return Bytes(buf.data() + HEADER_LEN, buf.size() - HEADER_LEN);
}

int Binlog::load(const leveldb::Slice &s){
	if(s.size() < HEADER_LEN){
		return -1;
	}
	buf.assign(s.data(), s.size());
	return 0;
}

std::string Binlog::dumps() const{
	std::string str;
	if(buf.size() < HEADER_LEN){
		return str;
	}
	char buf[20];
	snprintf(buf, sizeof(buf), "%llu ", this->seq());
	str.append(buf);

	switch(this->type()){
		case BinlogType::NOOP:
			str.append("noop ");
			break;
		case BinlogType::SYNC:
			str.append("sync ");
			break;
		case BinlogType::MIRROR:
			str.append("mirror ");
			break;
		case BinlogType::COPY:
			str.append("copy ");
			break;
	}
	switch(this->cmd()){
		case BinlogCommand::NONE:
			str.append("none ");
			break;
		case BinlogCommand::KSET:
			str.append("set ");
			break;
		case BinlogCommand::KDEL:
			str.append("del ");
			break;
		case BinlogCommand::HSET:
			str.append("hset ");
			break;
		case BinlogCommand::HDEL:
			str.append("hdel ");
			break;
		case BinlogCommand::ZSET:
			str.append("zset ");
			break;
		case BinlogCommand::ZDEL:
			str.append("zdel ");
			break;
		case BinlogCommand::BEGIN:
			str.append("begin ");
			break;
		case BinlogCommand::END:
			str.append("end ");
			break;
	}
	Bytes b = this->key();
	str.append(hexmem(b.data(), b.size()));
	return str;
}

/* SyncLogQueue */

static inline std::string encode_seq_key(uint64_t seq){
	seq = big_endian(seq);
	std::string ret;
	ret.push_back(DataType::SYNCLOG);
	ret.append((char *)&seq, sizeof(seq));
	return ret;
}

static inline uint64_t decode_seq_key(const leveldb::Slice &key){
	uint64_t seq = 0;
	if(key.size() == (sizeof(uint64_t) + 1) && key.data()[0] == DataType::SYNCLOG){
		seq = *((uint64_t *)(key.data() + 1));
		seq = big_endian(seq);
	}
	return seq;
}

BinlogQueue::BinlogQueue(leveldb::DB *db){
	this->db = db;
	this->min_seq = 0;
	this->last_seq = 0;
	this->tran_seq = 0;
	this->capacity = LOG_QUEUE_SIZE;

	Binlog log;
	if(this->find_last(&log) == 1){
		this->last_seq = log.seq();
	}
	if(this->find_next(1, &log) == 1){
		this->min_seq = log.seq();
	}
	log_debug("capacity: %d, min: %llu, max: %llu,", capacity, min_seq, last_seq);

	//this->merge();
		/*
	int noops = 0;
	int total = 0;
	uint64_t seq = this->min_seq;
	while(this->find_next(seq, &log) == 1){
		total ++;
		seq = log.seq() + 1;
		if(log.type() != BinlogType::NOOP){
			std::string s = log.dumps();
			//log_trace("%s", s.c_str());
			noops ++;
		}
	}
	log_debug("capacity: %d, min: %llu, max: %llu, noops: %d, total: %d",
		capacity, min_seq, last_seq, noops, total);
		*/

	// start cleaning thread
	thread_quit = false;
	pthread_t tid;
	int err = pthread_create(&tid, NULL, &BinlogQueue::log_clean_thread_func, this);
	if(err != 0){
		log_fatal("can't create thread: %s", strerror(err));
		exit(0);
	}
}

BinlogQueue::~BinlogQueue(){
	thread_quit = true;
	while(1){
		if(thread_quit == false){
			break;
		}
		usleep(100 * 1000);
	}
	log_debug("BinlogQueue finalized");
}

void BinlogQueue::begin(){
	tran_seq = last_seq;
	batch.Clear();
}

void BinlogQueue::rollback(){
	tran_seq = 0;
}

leveldb::Status BinlogQueue::commit(){
	leveldb::WriteOptions write_opts;
	leveldb::Status s = db->Write(write_opts, &batch);
	if(s.ok()){
		last_seq = tran_seq;
		tran_seq = 0;
	}
	return s;
}

void BinlogQueue::add(char type, char cmd, const leveldb::Slice &key){
	tran_seq ++;
	Binlog log(tran_seq, type, cmd, key);
	batch.Put(encode_seq_key(tran_seq), log.repr());
}

void BinlogQueue::add(char type, char cmd, const std::string &key){
	leveldb::Slice s(key);
	this->add(type, cmd, s);
}

// leveldb put
void BinlogQueue::Put(const leveldb::Slice& key, const leveldb::Slice& value){
	batch.Put(key, value);
}

// leveldb delete
void BinlogQueue::Delete(const leveldb::Slice& key){
	batch.Delete(key);
}

int BinlogQueue::find_next(uint64_t next_seq, Binlog *log) const{
	if(this->get(next_seq, log) == 1){
		return 1;
	}
	uint64_t ret = 0;
	std::string key_str = encode_seq_key(next_seq);
	leveldb::ReadOptions iterate_options;
	leveldb::Iterator *it = db->NewIterator(iterate_options);
	it->Seek(key_str);
	if(it->Valid()){
		leveldb::Slice key = it->key();
		if(decode_seq_key(key) != 0){
			leveldb::Slice val = it->value();
			if(log->load(val) == -1){
				ret = -1;
			}else{
				ret = 1;
			}
		}
	}
	delete it;
	return ret;
}

int BinlogQueue::find_last(Binlog *log) const{
	uint64_t ret = 0;
	std::string key_str = encode_seq_key(UINT64_MAX);
	leveldb::ReadOptions iterate_options;
	leveldb::Iterator *it = db->NewIterator(iterate_options);
	it->Seek(key_str);
	if(!it->Valid()){
		// Iterator::prev requires Valid, so we seek to last
		it->SeekToLast();
	}
	// UINT64_MAX is not used
	if(it->Valid()){
		it->Prev();
	}
	if(it->Valid()){
		leveldb::Slice key = it->key();
		if(decode_seq_key(key) != 0){
			leveldb::Slice val = it->value();
			if(log->load(val) == -1){
				ret = -1;
			}else{
				ret = 1;
			}
		}
	}
	delete it;
	return ret;
}

int BinlogQueue::get(uint64_t seq, Binlog *log) const{
	std::string val;
	leveldb::Status s = db->Get(leveldb::ReadOptions(), encode_seq_key(seq), &val);
	if(s.ok()){
		if(log->load(val) != -1){
			return 1;
		}
	}
	return 0;
}

int BinlogQueue::update(uint64_t seq, char type, char cmd, const std::string &key){
	Binlog log(seq, type, cmd, key);
	leveldb::Status s = db->Put(leveldb::WriteOptions(), encode_seq_key(seq), log.repr());
	if(s.ok()){
		return 0;
	}
	return -1;
}

int BinlogQueue::del(uint64_t seq){
	leveldb::Status s = db->Delete(leveldb::WriteOptions(), encode_seq_key(seq));
	if(!s.ok()){
		return -1;
	}
	return 0;
}

int BinlogQueue::del_range(uint64_t start, uint64_t end){
	while(start <= end){
		leveldb::WriteBatch batch;
		for(int count = 0; start <= end && count < 1000; start++, count++){
			batch.Delete(encode_seq_key(start));
		}
		leveldb::Status s = db->Write(leveldb::WriteOptions(), &batch);
		if(!s.ok()){
			return -1;
		}
	}
	return 0;
}

void* BinlogQueue::log_clean_thread_func(void *arg){
	BinlogQueue *logs = (BinlogQueue *)arg;

	while(!logs->thread_quit){
		usleep(200 * 1000);

		if(logs->last_seq - logs->min_seq < LOG_QUEUE_SIZE * 1.1){
			continue;
		}

		uint64_t start = logs->min_seq;
		uint64_t end = logs->last_seq - LOG_QUEUE_SIZE;
		logs->del_range(start, end);
		logs->min_seq = end + 1;
		log_debug("clean %d logs[%llu ~ %llu], %d left, max: %llu",
			end-start+1, start, end, logs->last_seq - logs->min_seq + 1, logs->last_seq);
	}
	log_debug("clean_thread quit");

	logs->thread_quit = false;
	return (void *)NULL;
}

// TESTING, slow, so not used
void BinlogQueue::merge(){
	std::map<std::string, uint64_t> key_map;
	uint64_t start = min_seq;
	uint64_t end = last_seq;
	int reduce_count = 0;
	int total = 0;
	total = end - start + 1;
	log_trace("merge begin");
	for(; start <= end; start++){
		Binlog log;
		if(this->get(start, &log) == 1){
			if(log.type() == BinlogType::NOOP){
				continue;
			}
			std::string key = log.key().String();
			std::map<std::string, uint64_t>::iterator it = key_map.find(key);
			if(it != key_map.end()){
				uint64_t seq = it->second;
				this->update(seq, BinlogType::NOOP, BinlogCommand::NONE, "");
				//log_trace("merge update %llu to NOOP", seq);
				reduce_count ++;
			}
			key_map[key] = log.seq();
		}
	}
	log_trace("merge reduce %d of %d binlogs", reduce_count, total);
}
<|endoftext|>


<commit_before><commit_msg>Unit test for UNO field item implementation.<commit_after><|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief Write key sets using yaml-cpp
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#include "write.hpp"
#include "yaml.h"

#include <kdbease.h>
#include <kdblogger.h>
#include <kdbplugin.h>

#include <fstream>

using namespace std;
using namespace kdb;

namespace
{
void addKey (YAML::Node data, NameIterator & keyIterator, Key const & key)
{
	if (keyIterator == --key.end ())
	{
		data[*keyIterator] = YAML::Node (key.getString ());
		return;
	}

	YAML::Node dictionary = (data[*keyIterator] && data[*keyIterator].IsMap ()) ? data[*keyIterator] : YAML::Node (YAML::NodeType::Map);
	data[*keyIterator] = dictionary;

	addKey (dictionary, ++keyIterator, key);
}

void addKeys (YAML::Node data, KeySet const & mappings, Key const & parent)
{
	for (auto key : mappings)
	{
		auto parentIterator = parent.begin ();
		auto keyIterator = key.begin ();
		while (parentIterator != parent.end () && keyIterator != key.end ())
		{
			parentIterator++;
			keyIterator++;
		}

		addKey (data, keyIterator, key);
	}
}

} // end namespace

/**
 * @brief This function saves the key-value pairs stored in `mappings` as YAML data in the location specified via `parent`.
 *
 * @param mappings This key set stores the mappings that should be saved as YAML data.
 * @param parent This key specifies the path to the YAML data file that should be written.
 */
void yamlcpp::yamlWrite (KeySet const & mappings, Key const & parent)
{
	ofstream output (parent.getString ());
	auto data = YAML::Node (YAML::NodeType::Map);
	addKeys (data, mappings, parent);

	output << data;
}
<commit_msg>YAML CPP: Use function to determine key iterator<commit_after>/**
 * @file
 *
 * @brief Write key sets using yaml-cpp
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#include "write.hpp"
#include "yaml.h"

#include <kdbease.h>
#include <kdblogger.h>
#include <kdbplugin.h>

#include <fstream>

using namespace std;
using namespace kdb;

namespace
{
NameIterator relativeKeyIterator (Key const & key, Key const & parent)
{
	auto parentIterator = parent.begin ();
	auto keyIterator = key.begin ();
	while (parentIterator != parent.end () && keyIterator != key.end ())
	{
		parentIterator++;
		keyIterator++;
	}
	return keyIterator;
}

void addKey (YAML::Node data, NameIterator & keyIterator, Key const & key)
{
	if (keyIterator == --key.end ())
	{
		data[*keyIterator] = YAML::Node (key.getString ());
		return;
	}

	YAML::Node dictionary = (data[*keyIterator] && data[*keyIterator].IsMap ()) ? data[*keyIterator] : YAML::Node (YAML::NodeType::Map);
	data[*keyIterator] = dictionary;

	addKey (dictionary, ++keyIterator, key);
}

void addKeys (YAML::Node data, KeySet const & mappings, Key const & parent)
{
	for (auto key : mappings)
	{
		NameIterator keyIterator = relativeKeyIterator (key, parent);
		addKey (data, keyIterator, key);
	}
}

} // end namespace

/**
 * @brief This function saves the key-value pairs stored in `mappings` as YAML data in the location specified via `parent`.
 *
 * @param mappings This key set stores the mappings that should be saved as YAML data.
 * @param parent This key specifies the path to the YAML data file that should be written.
 */
void yamlcpp::yamlWrite (KeySet const & mappings, Key const & parent)
{
	ofstream output (parent.getString ());
	auto data = YAML::Node (YAML::NodeType::Map);
	addKeys (data, mappings, parent);

	output << data;
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// 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.

#ifndef METHCLA_MEMORY_HPP_INCLUDED
#define METHCLA_MEMORY_HPP_INCLUDED

#include <boost/assert.hpp>
#include <cstddef>
#include <cstdint>

namespace Methcla { namespace Memory {

class Alignment
{
public:
    Alignment(size_t alignment)
        : m_alignment(alignment)
    {
        BOOST_ASSERT_MSG( (m_alignment & (m_alignment - 1)) == 0, "Alignment must be a power of two" );
        BOOST_ASSERT_MSG( m_alignment >= sizeof(nullptr), "Alignment must be >= sizeof(nullptr)" );
    }
    Alignment(const Alignment&) = default;

    operator size_t () const
    {
        return m_alignment;
    }

    template <typename T> bool isAligned(T size) const
    {
        return isAligned(m_alignment, size);
    }

    template <typename T> T align(T size) const
    {
        return align(m_alignment, size);
    }

    template <typename T> size_t padding(T size) const
    {
        return padding(m_alignment, size);
    }

    // Aligning pointers
    template <typename T> bool isAligned(T* ptr) const
    {
        return isAligned(reinterpret_cast<uintptr_t>(ptr));
    }

    template <typename T> T* align(T* ptr) const
    {
        return reinterpret_cast<T*>(align(reinterpret_cast<uintptr_t>(ptr)));
    }

    template <typename T> size_t padding(T* ptr) const
    {
        return padding(reinterpret_cast<uintptr_t>(ptr));
    }

    // Static alignment functions
    template <typename T> static bool isAligned(size_t alignment, T n)
    {
        return (n & ~(alignment-1)) == n;
    }

    template <typename T> static T align(size_t alignment, T n)
    {
        return (n + alignment) & ~(alignment-1);
    }

    template <typename T> static size_t padding(size_t alignment, T n)
    {
        return align(alignment, n) - n;
    }

private:
    size_t m_alignment;
};

//* Default alignment.
static const Alignment kDefaultAlignment(
#if defined(__ANDROID__)
    alignof(max_align_t)
#else
    alignof(std::max_align_t)
#endif
    );

//* Alignment needed for data accessed by SIMD instructions.
static const Alignment kSIMDAlignment(16);

//* Allocate memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* alloc(size_t size);

//* Allocate aligned memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* allocAligned(Alignment align, size_t size);

//* Free memory allocated by this allocator.
void free(void* ptr) noexcept;

//* Allocate memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocOf(size_t n=1)
{
    return static_cast<T*>(alloc(n * sizeof(T)));
}

//* Allocate aligned memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocAlignedOf(Alignment align, size_t n=1)
{
    return static_cast<T*>(allocAligned(align, n * sizeof(T)));
}

} }

#endif // METHCLA_MEMORY_HPP_INCLUDED
<commit_msg>Ensure alignment is greater than sizeof(void*) in all cases<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// 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.

#ifndef METHCLA_MEMORY_HPP_INCLUDED
#define METHCLA_MEMORY_HPP_INCLUDED

#include <boost/assert.hpp>
#include <cstddef>
#include <cstdint>

namespace Methcla { namespace Memory {

class Alignment
{
public:
    Alignment(size_t alignment)
        : m_alignment(std::max(alignment, sizeof(void*)))
    {
        BOOST_ASSERT_MSG( (m_alignment & (m_alignment - 1)) == 0, "Alignment must be a power of two" );
    }
    Alignment(const Alignment&) = default;

    operator size_t () const
    {
        return m_alignment;
    }

    template <typename T> bool isAligned(T size) const
    {
        return isAligned(m_alignment, size);
    }

    template <typename T> T align(T size) const
    {
        return align(m_alignment, size);
    }

    template <typename T> size_t padding(T size) const
    {
        return padding(m_alignment, size);
    }

    // Aligning pointers
    template <typename T> bool isAligned(T* ptr) const
    {
        return isAligned(reinterpret_cast<uintptr_t>(ptr));
    }

    template <typename T> T* align(T* ptr) const
    {
        return reinterpret_cast<T*>(align(reinterpret_cast<uintptr_t>(ptr)));
    }

    template <typename T> size_t padding(T* ptr) const
    {
        return padding(reinterpret_cast<uintptr_t>(ptr));
    }

    // Static alignment functions
    template <typename T> static bool isAligned(size_t alignment, T n)
    {
        return (n & ~(alignment-1)) == n;
    }

    template <typename T> static T align(size_t alignment, T n)
    {
        return (n + alignment) & ~(alignment-1);
    }

    template <typename T> static size_t padding(size_t alignment, T n)
    {
        return align(alignment, n) - n;
    }

private:
    size_t m_alignment;
};

//* Default alignment.
static const Alignment kDefaultAlignment(
#if defined(__ANDROID__)
    alignof(max_align_t)
#else
    alignof(std::max_align_t)
#endif
    );

//* Alignment needed for data accessed by SIMD instructions.
static const Alignment kSIMDAlignment(16);

//* Allocate memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* alloc(size_t size);

//* Allocate aligned memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* allocAligned(Alignment align, size_t size);

//* Free memory allocated by this allocator.
void free(void* ptr) noexcept;

//* Allocate memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocOf(size_t n=1)
{
    return static_cast<T*>(alloc(n * sizeof(T)));
}

//* Allocate aligned memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocAlignedOf(Alignment align, size_t n=1)
{
    return static_cast<T*>(allocAligned(align, n * sizeof(T)));
}

} }

#endif // METHCLA_MEMORY_HPP_INCLUDED
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.8  2000/06/16 20:25:23  rahulj
 * Add the -v=always option to force validation checking. Need this
 * option for running the conformance tests.
 *
 * Revision 1.7  2000/05/31 18:42:31  rahulj
 * 'Auto' validation is the default processing mode.
 *
 * Revision 1.6  2000/03/03 01:29:29  roddey
 * Added a scanReset()/parseReset() method to the scanner and
 * parsers, to allow for reset after early exit from a progressive parse.
 * Added calls to new Terminate() call to all of the samples. Improved
 * documentation in SAX and DOM parsers.
 *
 * Revision 1.5  2000/03/02 19:53:39  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.4  2000/02/11 02:32:46  abagchi
 * Removed StrX::transcode
 *
 * Revision 1.3  2000/02/06 07:47:17  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  1999/11/12 02:13:40  rahulj
 * It now validates when the -v option is specified.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:52  twl
 * Initial checkin
 *
 * Revision 1.8  1999/11/08 20:43:34  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/PlatformUtils.hpp>
#include <sax/SAXException.hpp>
#include <sax/SAXParseException.hpp>
#include <parsers/DOMParser.hpp>
#include "DOMCount.hpp"
#include <string.h>
#include <stdlib.h>

// ---------------------------------------------------------------------------
//  This is a simple program which invokes the DOMParser to build a DOM
//  tree for the specified input file. It then walks the tree and counts
//  the number of elements. The element count is then printed.
// ---------------------------------------------------------------------------
void usage()
{
    cout << "\nUsage:\n"
            "    DOMCount [-v -n] {XML file}\n\n"
            "This program invokes the XML4C DOM parser, builds\n"
            "the DOM tree, and then prints the number of elements\n"
            "found in the input XML file.\n\n"
            "Options:\n"
            "    -v=xxx      Validation scheme [always | never | auto*]\n"
            "    -n          Enable namespace processing. Defaults to off.\n\n"
            "  * = Default if not provided explicitly\n\n"
         << endl;
}

int main(int argC, char* argV[])
{
    // Initialize the XML4C system
    try
    {
        XMLPlatformUtils::Initialize();
    }

    catch (const XMLException& toCatch)
    {
         cerr << "Error during initialization! :\n"
              << StrX(toCatch.getMessage()) << endl;
         return 1;
    }

    // Check command line and extract arguments.
    if (argC < 2)
    {
        usage();
        return 1;
    }

    const char*              xmlFile = 0;
    DOMParser::ValSchemes    valScheme = DOMParser::Val_Auto;
    bool                     doNamespaces    = false;

    // See if non validating dom parser configuration is requested.
    if ((argC == 2) && !strcmp(argV[1], "-?"))
    {
        usage();
        return 2;
    }

    int argInd;
    for (argInd = 1; argInd < argC; argInd++)
    {
        // Break out on first non-dash parameter
        if (argV[argInd][0] != '-')
            break;

        if (!strncmp(argV[argInd], "-v=", 3)
        ||  !strncmp(argV[argInd], "-V=", 3))
        {
            const char* const parm = &argV[argInd][3];

            if (!strcmp(parm, "never"))
                valScheme = DOMParser::Val_Never;
            else if (!strcmp(parm, "auto"))
                valScheme = DOMParser::Val_Auto;
            else if (!strcmp(parm, "always"))
                valScheme = DOMParser::Val_Always;
            else
            {
                cerr << "Unknown -v= value: " << parm << endl;
                return 2;
            }
        }
         else if (!strcmp(argV[argInd], "-n")
              ||  !strcmp(argV[argInd], "-N"))
        {
            doNamespaces = true;
        }
         else
        {
            cerr << "Unknown option '" << argV[argInd]
                 << "', ignoring it\n" << endl;
        }
    }

    //
    //  There should be only one and only one parameter left, and that
    //  should be the file name.
    //
    if (argInd != argC - 1)
    {
        usage();
        return 1;
    }
    xmlFile = argV[argInd];

    // Instantiate the DOM parser.
    DOMParser parser;
    parser.setValidationScheme(valScheme);
    parser.setDoNamespaces(doNamespaces);

    // And create our error handler and install it
    DOMCount elementCounter;
    parser.setErrorHandler(&elementCounter);

    //
    //  Get the starting time and kick off the parse of the indicated
    //  file. Catch any exceptions that might propogate out of it.
    //
    unsigned long duration;
    try
    {
        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
        parser.parse(xmlFile);
        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
        duration = endMillis - startMillis;
    }

    catch (const XMLException& toCatch)
    {
        cerr << "\nError during parsing: '" << xmlFile << "'\n"
             << "Exception message is:  \n"
             << StrX(toCatch.getMessage()) << "\n" << endl;
        return -1;
    }

    //
    //  Extract the DOM tree, get the list of all the elements and report the
    //  length as the count of elements.
    //
    if (elementCounter.getSawErrors())
    {
        cout << "\nErrors occured, no output available\n" << endl;
    }
     else
    {
        DOM_Document doc = parser.getDocument();
        unsigned int elementCount = doc.getElementsByTagName("*").getLength();

        // Print out the stats that we collected and time taken.
        cout << xmlFile << ": " << duration << " ms ("
             << elementCount << " elems)." << endl;
    }

    // And call the termination method
    XMLPlatformUtils::Terminate();

    return 0;
}

DOMCount::DOMCount() :

    fSawErrors(false)
{
}

DOMCount::~DOMCount()
{
}

// ---------------------------------------------------------------------------
//  DOMCountHandlers: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void DOMCount::error(const SAXParseException& e)
{
    fSawErrors = true;
    cerr << "\nError at file " << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void DOMCount::fatalError(const SAXParseException& e)
{
    fSawErrors = true;
    cerr << "\nFatal Error at file " << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void DOMCount::warning(const SAXParseException& e)
{
    cerr << "\nWarning at file " << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void DOMCount::resetErrors()
{
}
<commit_msg>Modified to catch dom and general exceptions.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/PlatformUtils.hpp>
#include <sax/SAXException.hpp>
#include <sax/SAXParseException.hpp>
#include <parsers/DOMParser.hpp>
#include <dom/DOM_DOMException.hpp>
#include "DOMCount.hpp"
#include <string.h>
#include <stdlib.h>

// ---------------------------------------------------------------------------
//  This is a simple program which invokes the DOMParser to build a DOM
//  tree for the specified input file. It then walks the tree and counts
//  the number of elements. The element count is then printed.
// ---------------------------------------------------------------------------
void usage()
{
    cout << "\nUsage:\n"
            "    DOMCount [-v -n] {XML file}\n\n"
            "This program invokes the XML4C DOM parser, builds\n"
            "the DOM tree, and then prints the number of elements\n"
            "found in the input XML file.\n\n"
            "Options:\n"
            "    -v=xxx      Validation scheme [always | never | auto*]\n"
            "    -n          Enable namespace processing. Defaults to off.\n\n"
            "  * = Default if not provided explicitly\n\n"
         << endl;
}

int main(int argC, char* argV[])
{
    // Initialize the XML4C system
    try
    {
        XMLPlatformUtils::Initialize();
    }

    catch (const XMLException& toCatch)
    {
         cerr << "Error during initialization! :\n"
              << StrX(toCatch.getMessage()) << endl;
         return 1;
    }

    // Check command line and extract arguments.
    if (argC < 2)
    {
        usage();
        return 1;
    }

    const char*              xmlFile = 0;
    DOMParser::ValSchemes    valScheme = DOMParser::Val_Auto;
    bool                     doNamespaces    = false;

    // See if non validating dom parser configuration is requested.
    if ((argC == 2) && !strcmp(argV[1], "-?"))
    {
        usage();
        return 2;
    }

    int argInd;
    for (argInd = 1; argInd < argC; argInd++)
    {
        // Break out on first non-dash parameter
        if (argV[argInd][0] != '-')
            break;

        if (!strncmp(argV[argInd], "-v=", 3)
        ||  !strncmp(argV[argInd], "-V=", 3))
        {
            const char* const parm = &argV[argInd][3];

            if (!strcmp(parm, "never"))
                valScheme = DOMParser::Val_Never;
            else if (!strcmp(parm, "auto"))
                valScheme = DOMParser::Val_Auto;
            else if (!strcmp(parm, "always"))
                valScheme = DOMParser::Val_Always;
            else
            {
                cerr << "Unknown -v= value: " << parm << endl;
                return 2;
            }
        }
         else if (!strcmp(argV[argInd], "-n")
              ||  !strcmp(argV[argInd], "-N"))
        {
            doNamespaces = true;
        }
         else
        {
            cerr << "Unknown option '" << argV[argInd]
                 << "', ignoring it\n" << endl;
        }
    }

    //
    //  There should be only one and only one parameter left, and that
    //  should be the file name.
    //
    if (argInd != argC - 1)
    {
        usage();
        return 1;
    }
    xmlFile = argV[argInd];

    // Instantiate the DOM parser.
    DOMParser parser;
    parser.setValidationScheme(valScheme);
    parser.setDoNamespaces(doNamespaces);

    // And create our error handler and install it
    DOMCount elementCounter;
    parser.setErrorHandler(&elementCounter);

    //
    //  Get the starting time and kick off the parse of the indicated
    //  file. Catch any exceptions that might propogate out of it.
    //
    unsigned long duration;
    try
    {
        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
        parser.parse(xmlFile);
        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
        duration = endMillis - startMillis;
    }

    catch (const XMLException& toCatch)
    {
        cerr << "\nError during parsing: '" << xmlFile << "'\n"
             << "Exception message is:  \n"
             << StrX(toCatch.getMessage()) << "\n" << endl;
        return -1;
    }
    catch (const DOM_DOMException& toCatch)
    {
        cerr << "\nError during parsing: '" << xmlFile << "'\n"
             << "Exception message is:  \n"
             << toCatch.msg.transcode() << "\n" << endl;
        XMLPlatformUtils::Terminate();
        return 4;
    }
    catch (...)
    {
       cerr << "\nUnexpected exception during parsing: '" << xmlFile << "'\n";
        XMLPlatformUtils::Terminate();
        return 4;
    }

    //
    //  Extract the DOM tree, get the list of all the elements and report the
    //  length as the count of elements.
    //
    if (elementCounter.getSawErrors())
    {
        cout << "\nErrors occured, no output available\n" << endl;
    }
     else
    {
        DOM_Document doc = parser.getDocument();
        unsigned int elementCount = doc.getElementsByTagName("*").getLength();

        // Print out the stats that we collected and time taken.
        cout << xmlFile << ": " << duration << " ms ("
             << elementCount << " elems)." << endl;
    }

    // And call the termination method
    XMLPlatformUtils::Terminate();

    return 0;
}

DOMCount::DOMCount() :

    fSawErrors(false)
{
}

DOMCount::~DOMCount()
{
}

// ---------------------------------------------------------------------------
//  DOMCountHandlers: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void DOMCount::error(const SAXParseException& e)
{
    fSawErrors = true;
    cerr << "\nError at file " << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void DOMCount::fatalError(const SAXParseException& e)
{
    fSawErrors = true;
    cerr << "\nFatal Error at file " << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void DOMCount::warning(const SAXParseException& e)
{
    cerr << "\nWarning at file " << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void DOMCount::resetErrors()
{
}
<|endoftext|>


<commit_before>#include <iostream>                                         /* allows to perform standard input and output operations */
#include <fstream>
#include <stdio.h>                                          /* Standard input/output definitions */
#include <stdint.h>                                         /* Standard input/output definitions */
#include <stdlib.h>                                         /* defines several general purpose functions */
//#include <string>                                         /* String function definitions */
#include <unistd.h>                                         /* UNIX standard function definitions */
#include <fcntl.h>                                          /* File control definitions */
//#include <errno.h>                                          /* Error number definitions */
//#include <termios.h>                                        /* POSIX terminal control definitions */
#include <ctype.h>                                        /* isxxx() */
#include <ros/ros.h>                                        /* ROS */
#include <geometry_msgs/Twist.h>                            /* ROS Twist message */
#include <base_controller/encoders.h>                       /* Custom message /encoders */

//const char* serialport="/dev/ttyAMA0";                      /* defines used serialport */
//int serialport_bps=B38400;                                  /* defines baudrate od serialport */
int32_t EncoderL;                                           /* stores encoder value left read from md49 */
int32_t EncoderR;                                           /* stores encoder value right read from md49 */
unsigned char speed_l=128, speed_r=128;                               /* speed to set for MD49 */
unsigned char last_speed_l=128, last_speed_r=128;                               /* speed to set for MD49 */
//bool cmd_vel_received=true;
double vr = 0.0;
double vl = 0.0;
double max_vr = 0.2;
double max_vl = 0.2;
double min_vr = 0.2;
double min_vl = 0.2;
double base_width = 0.4;                                    /* Base width in meters */

unsigned char serialBuffer[18];                             /* Serial buffer to store uart data */
void read_MD49_Data (void);
void set_MD49_speed (unsigned char speed_l, unsigned char speed_r);
char* itoa(int value, char* result, int base);

using namespace std;

void cmd_vel_callback(const geometry_msgs::Twist& vel_cmd){

        if (vel_cmd.linear.x>0){
            speed_l = 255;
            speed_r = 255;
        }
        if (vel_cmd.linear.x<0){
            speed_l = 0;
            speed_r = 0;
        }
        if (vel_cmd.linear.x==0 && vel_cmd.angular.z==0){
            speed_l = 128;
            speed_r = 128;
        }
        if (vel_cmd.angular.z>0){
            speed_l = 0;
            speed_r = 255;
        }
        if (vel_cmd.angular.z<0){
            speed_l = 255;
            speed_r = 0;
        }
        if ((speed_l != last_speed_l) || (speed_r != last_speed_r)){
            set_MD49_speed(speed_l,speed_r);
            last_speed_l=speed_l;
            last_speed_r=speed_r;
        }

    /*
        //ANFANG Alternative
        if (vel_cmd.linear.x==0 && vel_cmd.angular.z==0){vl=0;vr=0;}
        else if(vel_cmd.linear.x == 0){
            // turning
            vr = vel_cmd.angular.z * base_width / 2.0;
            vl = (-1) * vr;
        }
        else if(vel_cmd.angular.z == 0){
            // forward / backward
            vl = vr = vel_cmd.linear.x;
        }
        else{
            // moving doing arcs
            vl = vel_cmd.linear.x - vel_cmd.angular.z * base_width / 2.0;
            if (vl > max_vl) {vl=max_vl;}
            if (vl < min_vl) {vl=min_vl;}
            vr = vel_cmd.linear.x + vel_cmd.angular.z * base_width / 2.0;
            if (vr > max_vr) {vr=max_vr;}
            if (vr < min_vr) {vr=min_vr;}
        }
        //ENDE Alternative
    */
}

int main( int argc, char* argv[] ){

    ros::init(argc, argv, "base_controller" );
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("/cmd_vel", 10, cmd_vel_callback);
    ros::Publisher encoders_pub = n.advertise<base_controller::encoders>("encoders",10);

    // Set nodes looprate 5Hz
    // ***********************
    ros::Rate loop_rate(5);
    ROS_INFO("base_controller running...");

    while( n.ok() )
    {
        // Publish encoder values to topic /encoders (custom message)
        // ********************************************************************
        base_controller::encoders encoders;
        encoders.encoder_l=EncoderL;
        encoders.encoder_r=EncoderR;
        encoders_pub.publish(encoders);

        // Read encoder and other data from MD49
        // *************************************
        read_MD49_Data();

        // Loop
        // ****
        //set_MD49_speed(speed_l,speed_r);
        ros::spinOnce();
        loop_rate.sleep();

    }// end.mainloop

    return 1;
} // end.main

void read_MD49_Data (void){

    //serialBuffer[0] = 82;							// 82=R Steuerbyte um alle Daten vom MD49 zu lesen
    //writeBytes(fd, 1);
    //Daten lesen und in Array schreiben
    //readBytes(fd, 18);

    string line;
    ifstream myfile ("md49_data.txt");
    if (myfile.is_open())
    {
        int i=0;
        while ( getline (myfile,line) )
        {
            //cout << line << '\n';
            char data[10];
            std::copy(line.begin(), line.end(), data);
            serialBuffer[i]=atoi(data);
            i =i++;
        }
        myfile.close();

    }
    else cout << "Unable to open file";

/*
    printf("\033[2J");        //  clear the screen
    printf("\033[H");         //  position cursor at top-left corner
    printf ("MD49-Data read from AVR-Master: \n");
    printf("====================================================== \n");
    printf("Encoder1 Byte1: %i ",serialBuffer[0]);
    printf("Byte2: %i ",serialBuffer[1]);
    printf("Byte3: % i ",serialBuffer[2]);
    printf("Byte4: %i \n",serialBuffer[3]);
    printf("Encoder2 Byte1: %i ",serialBuffer[4]);
    printf("Byte2: %i ",serialBuffer[5]);
    printf("Byte3: %i ",serialBuffer[6]);
    printf("Byte4: %i \n",serialBuffer[7]);
    printf("EncoderL: %i ",EncoderL);
    printf("EncoderR: %i \n",EncoderR);
    printf("====================================================== \n");
    printf("Speed1: %i ",serialBuffer[8]);
    printf("Speed2: %i \n",serialBuffer[9]);
    printf("Volts: %i \n",serialBuffer[10]);
    printf("Current1: %i ",serialBuffer[11]);
    printf("Current2: %i \n",serialBuffer[12]);
    printf("Error: %i \n",serialBuffer[13]);
    printf("Acceleration: %i \n",serialBuffer[14]);
    printf("Mode: %i \n",serialBuffer[15]);
    printf("Regulator: %i \n",serialBuffer[16]);
    printf("Timeout: %i \n",serialBuffer[17]);
*/

   // printf("vl= %f \n", vl);
  //  printf("vr= %f \n", vr);

    EncoderL = serialBuffer[0] << 24;                        // Put together first encoder value
    EncoderL |= (serialBuffer[1] << 16);
    EncoderL |= (serialBuffer[2] << 8);
    EncoderL |= (serialBuffer[3]);
    EncoderR = serialBuffer[4] << 24;                        // Put together second encoder value
    EncoderR |= (serialBuffer[5] << 16);
    EncoderR |= (serialBuffer[6] << 8);
    EncoderR |= (serialBuffer[7]);

}

void set_MD49_speed (unsigned char speed_l, unsigned char speed_r){
    char buffer[33];
    ofstream myfile;
    myfile.open ("md49_commands.txt");
    //myfile << "Writing this to a file.\n";
    if (speed_l==0){
        myfile << "000";
        myfile << "\n";
    }
    else if (speed_l<10){
        myfile << "00";
        myfile << itoa(speed_l,buffer,10);
    }
    else if (speed_l<100){
        myfile << "0";
        myfile << itoa(speed_l,buffer,10);
    }
    else{
        myfile << itoa(speed_l,buffer,10);
    }
    myfile << "\n";
    if (speed_r==0){
        myfile << "000";
        myfile << "\n";
    }
    else if (speed_r<10){
        myfile << "00";
        myfile << itoa(speed_r,buffer,10);
    }
    else if (speed_r<100){
        myfile << "0";
        myfile << itoa(speed_r,buffer,10);
    }
    else{
        myfile << itoa(speed_r,buffer,10);
    }
    myfile << "\n";
    myfile.close();
}

char* itoa(int value, char* result, int base) {
        // check that the base if valid
        if (base < 2 || base > 36) { *result = '\0'; return result; }

        char* ptr = result, *ptr1 = result, tmp_char;
        int tmp_value;

        do {
            tmp_value = value;
            value /= base;
            *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
        } while ( value );

        // Apply negative sign
        if (tmp_value < 0) *ptr++ = '-';
        *ptr-- = '\0';
        while(ptr1 < ptr) {
            tmp_char = *ptr;
            *ptr--= *ptr1;
            *ptr1++ = tmp_char;
        }
        return result;
    }
<commit_msg>Update code<commit_after>#include <iostream>                                         /* allows to perform standard input and output operations */
#include <fstream>
#include <stdio.h>                                          /* Standard input/output definitions */
#include <stdint.h>                                         /* Standard input/output definitions */
#include <stdlib.h>                                         /* defines several general purpose functions */
//#include <string>                                         /* String function definitions */
#include <unistd.h>                                         /* UNIX standard function definitions */
#include <fcntl.h>                                          /* File control definitions */
//#include <errno.h>                                          /* Error number definitions */
//#include <termios.h>                                        /* POSIX terminal control definitions */
#include <ctype.h>                                        /* isxxx() */
#include <ros/ros.h>                                        /* ROS */
#include <geometry_msgs/Twist.h>                            /* ROS Twist message */
#include <base_controller/encoders.h>                       /* Custom message /encoders */

//const char* serialport="/dev/ttyAMA0";                      /* defines used serialport */
//int serialport_bps=B38400;                                  /* defines baudrate od serialport */
int32_t EncoderL;                                           /* stores encoder value left read from md49 */
int32_t EncoderR;                                           /* stores encoder value right read from md49 */
unsigned char speed_l=128, speed_r=128;                               /* speed to set for MD49 */
unsigned char last_speed_l=128, last_speed_r=128;                               /* speed to set for MD49 */
//bool cmd_vel_received=true;
double vr = 0.0;
double vl = 0.0;
double max_vr = 0.2;
double max_vl = 0.2;
double min_vr = 0.2;
double min_vl = 0.2;
double base_width = 0.4;                                    /* Base width in meters */

unsigned char serialBuffer[18];                             /* Serial buffer to store uart data */
void read_MD49_Data (void);
void set_MD49_speed (unsigned char speed_l, unsigned char speed_r);
char* itoa(int value, char* result, int base);

using namespace std;

void cmd_vel_callback(const geometry_msgs::Twist& vel_cmd){

        if (vel_cmd.linear.x>0){
            speed_l = 255;
            speed_r = 255;
        }
        if (vel_cmd.linear.x<0){
            speed_l = 0;
            speed_r = 0;
        }
        if (vel_cmd.linear.x==0 && vel_cmd.angular.z==0){
            speed_l = 128;
            speed_r = 128;
        }
        if (vel_cmd.angular.z>0){
            speed_l = 0;
            speed_r = 255;
        }
        if (vel_cmd.angular.z<0){
            speed_l = 255;
            speed_r = 0;
        }
        if ((speed_l != last_speed_l) || (speed_r != last_speed_r)){
            set_MD49_speed(speed_l,speed_r);
            last_speed_l=speed_l;
            last_speed_r=speed_r;
        }

    /*
        //ANFANG Alternative
        if (vel_cmd.linear.x==0 && vel_cmd.angular.z==0){vl=0;vr=0;}
        else if(vel_cmd.linear.x == 0){
            // turning
            vr = vel_cmd.angular.z * base_width / 2.0;
            vl = (-1) * vr;
        }
        else if(vel_cmd.angular.z == 0){
            // forward / backward
            vl = vr = vel_cmd.linear.x;
        }
        else{
            // moving doing arcs
            vl = vel_cmd.linear.x - vel_cmd.angular.z * base_width / 2.0;
            if (vl > max_vl) {vl=max_vl;}
            if (vl < min_vl) {vl=min_vl;}
            vr = vel_cmd.linear.x + vel_cmd.angular.z * base_width / 2.0;
            if (vr > max_vr) {vr=max_vr;}
            if (vr < min_vr) {vr=min_vr;}
        }
        //ENDE Alternative
    */
}

int main( int argc, char* argv[] ){

    ros::init(argc, argv, "base_controller" );
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("/cmd_vel", 10, cmd_vel_callback);
    ros::Publisher encoders_pub = n.advertise<base_controller::encoders>("encoders",10);

    // Set nodes looprate 5Hz
    // ***********************
    ros::Rate loop_rate(5);
    ROS_INFO("base_controller running...");

    while( n.ok() )
    {
        // Publish encoder values to topic /encoders (custom message)
        // ********************************************************************
        base_controller::encoders encoders;
        encoders.encoder_l=EncoderL;
        encoders.encoder_r=EncoderR;
        encoders_pub.publish(encoders);

        // Read encoder and other data from MD49
        // *************************************
        read_MD49_Data();

        // Loop
        // ****
        //set_MD49_speed(speed_l,speed_r);
        ros::spinOnce();
        loop_rate.sleep();

    }// end.mainloop

    return 1;
} // end.main

void read_MD49_Data (void){

    //serialBuffer[0] = 82;							// 82=R Steuerbyte um alle Daten vom MD49 zu lesen
    //writeBytes(fd, 1);
    //Daten lesen und in Array schreiben
    //readBytes(fd, 18);

    string line;
    ifstream myfile ("md49_data.txt");
    if (myfile.is_open())
    {
        int i=0;
        while ( getline (myfile,line) )
        {
            //cout << line << '\n';
            char data[10];
            std::copy(line.begin(), line.end(), data);
            serialBuffer[i]=atoi(data);
            i =i++;
        }
        myfile.close();

    }
    else cout << "Unable to open file";

/*
    printf("\033[2J");        //  clear the screen
    printf("\033[H");         //  position cursor at top-left corner
    printf ("MD49-Data read from AVR-Master: \n");
    printf("====================================================== \n");
    printf("Encoder1 Byte1: %i ",serialBuffer[0]);
    printf("Byte2: %i ",serialBuffer[1]);
    printf("Byte3: % i ",serialBuffer[2]);
    printf("Byte4: %i \n",serialBuffer[3]);
    printf("Encoder2 Byte1: %i ",serialBuffer[4]);
    printf("Byte2: %i ",serialBuffer[5]);
    printf("Byte3: %i ",serialBuffer[6]);
    printf("Byte4: %i \n",serialBuffer[7]);
    printf("EncoderL: %i ",EncoderL);
    printf("EncoderR: %i \n",EncoderR);
    printf("====================================================== \n");
    printf("Speed1: %i ",serialBuffer[8]);
    printf("Speed2: %i \n",serialBuffer[9]);
    printf("Volts: %i \n",serialBuffer[10]);
    printf("Current1: %i ",serialBuffer[11]);
    printf("Current2: %i \n",serialBuffer[12]);
    printf("Error: %i \n",serialBuffer[13]);
    printf("Acceleration: %i \n",serialBuffer[14]);
    printf("Mode: %i \n",serialBuffer[15]);
    printf("Regulator: %i \n",serialBuffer[16]);
    printf("Timeout: %i \n",serialBuffer[17]);
*/

   // printf("vl= %f \n", vl);
  //  printf("vr= %f \n", vr);

    EncoderL = serialBuffer[0] << 24;                        // Put together first encoder value
    EncoderL |= (serialBuffer[1] << 16);
    EncoderL |= (serialBuffer[2] << 8);
    EncoderL |= (serialBuffer[3]);
    EncoderR = serialBuffer[4] << 24;                        // Put together second encoder value
    EncoderR |= (serialBuffer[5] << 16);
    EncoderR |= (serialBuffer[6] << 8);
    EncoderR |= (serialBuffer[7]);

}

void set_MD49_speed (unsigned char speed_l, unsigned char speed_r){
    char buffer[33];
    ofstream myfile;
    myfile.open ("md49_commands.txt");
    //myfile << "Writing this to a file.\n";
    if (speed_l==0){
        myfile << "000";
        myfile << "\n";
    }
    else if (speed_l<10){
        myfile << "00";
        myfile << itoa(speed_l,buffer,10);
        myfile << "\n";
    }
    else if (speed_l<100){
        myfile << "0";
        myfile << itoa(speed_l,buffer,10);
        myfile << "\n";
    }
    else{
        myfile << itoa(speed_l,buffer,10);
        myfile << "\n";
    }

    if (speed_r==0){
        myfile << "000";
        myfile << "\n";
    }
    else if (speed_r<10){
        myfile << "00";
        myfile << itoa(speed_r,buffer,10);
        myfile << "\n";
    }
    else if (speed_r<100){
        myfile << "0";
        myfile << itoa(speed_r,buffer,10);
        myfile << "\n";
    }
    else{
        myfile << itoa(speed_r,buffer,10);
        myfile << "\n";
    }
    myfile.close();
}

char* itoa(int value, char* result, int base) {
        // check that the base if valid
        if (base < 2 || base > 36) { *result = '\0'; return result; }

        char* ptr = result, *ptr1 = result, tmp_char;
        int tmp_value;

        do {
            tmp_value = value;
            value /= base;
            *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
        } while ( value );

        // Apply negative sign
        if (tmp_value < 0) *ptr++ = '-';
        *ptr-- = '\0';
        while(ptr1 < ptr) {
            tmp_char = *ptr;
            *ptr--= *ptr1;
            *ptr1++ = tmp_char;
        }
        return result;
    }
<|endoftext|>


<commit_before>#include "brandes.h"

#include <queue>
#include <stack>
#include <algorithm>
#include <thread>

template<typename T>
void Brandes<T>::process(T vertex_id, std::unordered_map<T, fType> *BC_local)
{
    std::stack<T> S;
    std::unordered_map<T, std::vector<T> > P;
    std::unordered_map<T, int> sigma;
    std::unordered_map<T, int> d;
    std::unordered_map<T, fType> delta;

    for (T w : graph_.get_vertex_ids()) {
        P[w] = std::vector<T>();
        sigma[w] = 0;
        d[w] = -1;
        delta[w] = 0;
    }

    sigma[vertex_id] = 1;
    d[vertex_id] = 0;

    std::queue<T> Q;
    Q.push(vertex_id);

    while (!Q.empty()) {
        T v = Q.front();
        Q.pop();
        S.push(v);

        for (auto w : graph_.get_neighbors(v)) {
            if (d[w] < 0) {
                Q.push(w);
                d[w] = d[v] + 1;
            }

            if (d[w] == d[v] + 1) {
                sigma[w] += sigma[v];
                P[w].emplace_back(v);
            }
        }
    }

    while (!S.empty()) {
        T v = S.top(); S.pop();

        for (T p : P[v]) {
            double result = (fType(sigma[p]) / sigma[v]) * (1.0 + delta[v]);
            delta[p] += result;
        }

        if (v != vertex_id) {
            (*BC_local)[v] += delta[v];
        }
    }

}

template<typename T>
void Brandes<T>::run_worker(const std::vector<T> &jobs, std::atomic<int> *idx) {
    std::unordered_map<T, fType> BC_local;

    for (T w : graph_.get_vertex_ids()) {
        BC_local[w] = 0;
    }

    while(true) {
        int my_index = (*idx)--;

        if (my_index < 0)
            break;

        process(jobs[my_index], &BC_local);
    }

    // Synchronized section
    {
        std::lock_guard<std::mutex> guard(bc_mutex_);
        for (auto it : BC_local) {
            BC_[it.first] += it.second;
        }
    }
}

template<typename T>
void Brandes<T>::run(const size_t thread_num) {
    std::vector<std::thread> threads;

    std::vector<T> jobs;
    std::atomic<int> index;

    // add jobs
    for (auto id : graph_.get_vertex_ids())
        jobs.emplace_back(id);

    index.store(jobs.size() - 1);

    // run threads
    for (size_t i = 0; i < thread_num; i++)
        threads.emplace_back(std::thread( [this, &jobs, &index] { run_worker(jobs, &index); }));

    // wait for them to finish
    for (auto& thread : threads)
        thread.join();
}

template<typename T>
const std::vector<std::pair<T, typename Brandes<T>::fType>>
Brandes<T>::get_result_vector() const {
    std::vector<std::pair<T, fType>> results;
    results.reserve(BC_.size());

    for (auto it : BC_) {
        results.emplace_back( std::make_pair(it.first, it.second));
    }

    sort(begin(results), end(results));
    return results;
}
<commit_msg>Modify algorithm to reduce number of threads<commit_after>#include "brandes.h"

#include <queue>
#include <stack>
#include <algorithm>
#include <thread>

template<typename T>
void Brandes<T>::process(T vertex_id, std::unordered_map<T, fType> *BC_local)
{
    std::stack<T> S;
    std::unordered_map<T, std::vector<T> > P;
    std::unordered_map<T, int> sigma;
    std::unordered_map<T, int> d;
    std::unordered_map<T, fType> delta;

    for (T w : graph_.get_vertex_ids()) {
        P[w] = std::vector<T>();
        sigma[w] = 0;
        d[w] = -1;
        delta[w] = 0;
    }

    sigma[vertex_id] = 1;
    d[vertex_id] = 0;

    std::queue<T> Q;
    Q.push(vertex_id);

    while (!Q.empty()) {
        T v = Q.front();
        Q.pop();
        S.push(v);

        for (auto w : graph_.get_neighbors(v)) {
            if (d[w] < 0) {
                Q.push(w);
                d[w] = d[v] + 1;
            }

            if (d[w] == d[v] + 1) {
                sigma[w] += sigma[v];
                P[w].emplace_back(v);
            }
        }
    }

    while (!S.empty()) {
        T v = S.top(); S.pop();

        for (T p : P[v]) {
            double result = (fType(sigma[p]) / sigma[v]) * (1.0 + delta[v]);
            delta[p] += result;
        }

        if (v != vertex_id) {
            (*BC_local)[v] += delta[v];
        }
    }

}

template<typename T>
void Brandes<T>::run_worker(const std::vector<T> &jobs, std::atomic<int> *idx) {
    std::unordered_map<T, fType> BC_local;

    for (T w : graph_.get_vertex_ids()) {
        BC_local[w] = 0;
    }

    while(true) {
        int my_index = (*idx)--;

        if (my_index < 0)
            break;

        process(jobs[my_index], &BC_local);
    }

    // Synchronized section
    {
        std::lock_guard<std::mutex> guard(bc_mutex_);
        for (auto it : BC_local) {
            BC_[it.first] += it.second;
        }
    }
}

template<typename T>
void Brandes<T>::run(const size_t thread_num) {
    std::vector<std::thread> threads;

    std::vector<T> jobs;
    std::atomic<int> index;

    // add jobs
    for (auto id : graph_.get_vertex_ids())
        jobs.emplace_back(id);

    index.store(jobs.size() - 1);

    // run threads
    for (size_t i = 0; i < thread_num-1; i++)
        threads.emplace_back(std::thread( [this, &jobs, &index] { run_worker(jobs, &index); }));

    run_worker(jobs, &index);

    // wait for others to finish
    for (auto& thread : threads)
        thread.join();
}

template<typename T>
const std::vector<std::pair<T, typename Brandes<T>::fType>>
Brandes<T>::get_result_vector() const {
    std::vector<std::pair<T, fType>> results;
    results.reserve(BC_.size());

    for (auto it : BC_) {
        results.emplace_back( std::make_pair(it.first, it.second));
    }

    sort(begin(results), end(results));
    return results;
}
<|endoftext|>


<commit_before>/*
 * main.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#include <QtGui/QApplication>
#include "PrimeSieveGUI.h"
#include "../soe/ParallelPrimeSieve.h"

#include <QSharedMemory>
#include <stdint.h>
#include <stdexcept>
#include <cstdlib>
#include <iostream>

/**
 * The Qt GUI interface is launched if the user launches the
 * application by mouse click, a ParallelPrimeSieve process is
 * launched if exactly one argument (shared memory identifier) is
 * provided.
 * @see           createProcesses(...)
 * @param argv[1] Shared memory identifier
 */
int main(int argc, char *argv[]) {
  // Qt GUI interface
  if (argc != 2) {
    QApplication a(argc, argv);
    PrimeSieveGUI w;
    w.show();
    return a.exec();
  }
  // ParallelPrimeSieve process
  else {
    // open an existing and initialized shared memory
    QSharedMemory sharedMemory(argv[1]);
    if (!sharedMemory.attach()) {
      std::cerr << "Unable to attach shared memory " << argv[1] << std::endl;
      exit(EXIT_FAILURE);
    }
    // map the attached shared memory to the results structure
    ParallelPrimeSieve::SharedMemoryPPS* sharedMemoryPPS =
        static_cast<ParallelPrimeSieve::SharedMemoryPPS*> (sharedMemory.data());
    try {
      // create a new ParallelPrimeSieve object which is initialized
      // with values from the shared memory (provided by the Qt GUI),
      // upon completion ParallelPrimeSieve communicates its results
      // back to the Qt GUI through the shared memory segment.
      ParallelPrimeSieve primesieve;
      primesieve.setSharedMemory(sharedMemoryPPS);
      primesieve.sieve(sharedMemoryPPS->threads);
    }
    catch (std::exception& ex) {
      sharedMemory.detach();
      std::cerr << "ParallelPrimeSieve error: " << ex.what() << std::endl;
      exit(EXIT_FAILURE);
    }
    sharedMemory.detach();
  }
  // exit success
  return 0;
}
<commit_msg>fixed Mac OS X application startup bug<commit_after>/*
 * main.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#include <QtGui/QApplication>
#include "PrimeSieveGUI.h"
#include "../soe/ParallelPrimeSieve.h"

#include <QSharedMemory>
#include <stdint.h>
#include <stdexcept>
#include <cstdlib>
#include <iostream>

/**
 * The primesieve GUI interface is launched if the user launches the
 * application by mouse click, a PrimeSieveProcess is launched if
 * "PrimeSieveProcess" and a shared memory identifier (process id) are
 * provided as arguments.
 * @see           PrimeSieveProcess.cpp
 * @param argv[1] ["PrimeSieveProcess"]
 * @param argv[2] [Shared memory identifier]
 */
int main(int argc, char *argv[]) {
  // PrimeSieveProcess
  if (argc == 3 && QString(argv[1]).compare("PrimeSieveProcess") == 0) {
    // open an existing and initialized shared memory
    QSharedMemory sharedMemory(argv[2]);
    if (!sharedMemory.attach()) {
      std::cerr << "Unable to attach shared memory " << argv[2] << std::endl;
      exit(EXIT_FAILURE);
    }
    // map the attached shared memory to the results structure
    ParallelPrimeSieve::SharedMemoryPPS* sharedMemoryPPS =
        static_cast<ParallelPrimeSieve::SharedMemoryPPS*> (sharedMemory.data());
    try {
      ParallelPrimeSieve primesieve;
      // initialize the ParallelPrimeSieve object with values from the
      // shared memory provided by the primesieve GUI
      primesieve.setSharedMemory(sharedMemoryPPS);
      // start sieving primes, the results are communicated back to
      // the primesieve GUI via the shared memory
      primesieve.sieve(sharedMemoryPPS->threads);
    }
    catch (std::exception& ex) {
      sharedMemory.detach();
      std::cerr << "ParallelPrimeSieve error: " << ex.what() << std::endl;
      exit(EXIT_FAILURE);
    }
    sharedMemory.detach();
    // exit success
    return 0;
  }
  else { // Qt GUI interface
    QApplication a(argc, argv);
    PrimeSieveGUI w;
    w.show();
    return a.exec();
  }
}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

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

#include "xdgaction.h"
#include "xdgicon.h"
#include <QDebug>
#include <QCoreApplication>

XdgAction::XdgAction(QObject *parent):
    QAction(parent)
{
}

XdgAction::XdgAction(const XdgDesktopFile& desktopFile, QObject *parent):
    QAction(parent)
{
    load(desktopFile);
}

XdgAction::XdgAction(const XdgDesktopFile* desktopFile, QObject *parent):
    QAction(parent)
{
    load(*desktopFile);
}

XdgAction::XdgAction(const QString& desktopFileName, QObject *parent):
    QAction(parent)
{
    XdgDesktopFile df;
    df.load(desktopFileName);
    load(df);
}

XdgAction::XdgAction(const XdgAction& other, QObject *parent):
    QAction(parent)
{
    load(other.mDesktopFile);
}

XdgAction::~XdgAction()
{
}

XdgAction& XdgAction::operator=(const XdgAction& other)
{
    load(other.mDesktopFile);
     return *this;
}

bool XdgAction::isValid() const
{
    return mDesktopFile.isValid();
}

void XdgAction::load(const XdgDesktopFile& desktopFile)
{
    mDesktopFile = desktopFile;
    if (mDesktopFile.isValid())
    {
        // & is reserved for mnemonics
        setText(mDesktopFile.name().replace(QLatin1Char('&'), QLatin1String("&&")));
        setToolTip(mDesktopFile.comment());

        connect(this, SIGNAL(triggered()), this, SLOT(runConmmand()));
        QMetaObject::invokeMethod(this, "updateIcon", Qt::QueuedConnection);
    }
    else
    {
        setText(QString());
        setToolTip(QString());
        setIcon(QIcon());
    }
}

void XdgAction::runConmmand() const
{
    if (mDesktopFile.isValid())
        mDesktopFile.startDetached();
}

void XdgAction::updateIcon()
{
    setIcon(mDesktopFile.icon());
    if (icon().isNull())
        setIcon(XdgIcon::fromTheme(QLatin1String("application-x-executable")));
    QCoreApplication::processEvents();
}
<commit_msg>xdgaction: Remove unneeded processEvents() call<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

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

#include "xdgaction.h"
#include "xdgicon.h"
#include <QDebug>
#include <QCoreApplication>

XdgAction::XdgAction(QObject *parent):
    QAction(parent)
{
}

XdgAction::XdgAction(const XdgDesktopFile& desktopFile, QObject *parent):
    QAction(parent)
{
    load(desktopFile);
}

XdgAction::XdgAction(const XdgDesktopFile* desktopFile, QObject *parent):
    QAction(parent)
{
    load(*desktopFile);
}

XdgAction::XdgAction(const QString& desktopFileName, QObject *parent):
    QAction(parent)
{
    XdgDesktopFile df;
    df.load(desktopFileName);
    load(df);
}

XdgAction::XdgAction(const XdgAction& other, QObject *parent):
    QAction(parent)
{
    load(other.mDesktopFile);
}

XdgAction::~XdgAction()
{
}

XdgAction& XdgAction::operator=(const XdgAction& other)
{
    load(other.mDesktopFile);
     return *this;
}

bool XdgAction::isValid() const
{
    return mDesktopFile.isValid();
}

void XdgAction::load(const XdgDesktopFile& desktopFile)
{
    mDesktopFile = desktopFile;
    if (mDesktopFile.isValid())
    {
        // & is reserved for mnemonics
        setText(mDesktopFile.name().replace(QLatin1Char('&'), QLatin1String("&&")));
        setToolTip(mDesktopFile.comment());

        connect(this, SIGNAL(triggered()), this, SLOT(runConmmand()));
        QMetaObject::invokeMethod(this, "updateIcon", Qt::QueuedConnection);
    }
    else
    {
        setText(QString());
        setToolTip(QString());
        setIcon(QIcon());
    }
}

void XdgAction::runConmmand() const
{
    if (mDesktopFile.isValid())
        mDesktopFile.startDetached();
}

void XdgAction::updateIcon()
{
    setIcon(mDesktopFile.icon());
    if (icon().isNull())
        setIcon(XdgIcon::fromTheme(QLatin1String("application-x-executable")));
}
<|endoftext|>


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

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2006 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 0.9.6, packaged on June, 2006.

 http://glc-lib.sourceforge.net

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

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

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

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

//! \file glc_factory.cpp implementation of the GLC_Factory class.

#include "glc_factory.h"
#include "glc_objtomesh2.h"

// init static member
GLC_Factory* GLC_Factory::m_pFactory= NULL;

//////////////////////////////////////////////////////////////////////
// static method
//////////////////////////////////////////////////////////////////////
// Return the unique instance of the factory
GLC_Factory* GLC_Factory::instance(QGLWidget *GLWidget)
{
	if(m_pFactory == NULL)
	{
		m_pFactory= new GLC_Factory(GLWidget);
	}
	return m_pFactory;
}

//////////////////////////////////////////////////////////////////////
// Constructor destructor
//////////////////////////////////////////////////////////////////////

// Protected constructor
GLC_Factory::GLC_Factory(QGLWidget *GLWidget)
: m_pQGLWidget(GLWidget)
{

}

// Destructor
GLC_Factory::~GLC_Factory()
{
	m_pFactory= NULL;
}

//////////////////////////////////////////////////////////////////////
// Create functions
//////////////////////////////////////////////////////////////////////

// Create an GLC_Point
GLC_Point* GLC_Factory::createPoint(const GLC_Vector4d &coord) const
{
	return new GLC_Point(coord);
}
// Create an GLC_Point
GLC_Point* GLC_Factory::createPoint(double x, double y, double z) const
{
	return new GLC_Point(x, y, z);
}

//  Create an GLC_Circle
GLC_Circle* GLC_Factory::createCircle(double radius, double angle) const
{
	return new GLC_Circle(radius, angle);
}
// Create an GLC_Circle by copying another GLC_Circle
GLC_Circle* GLC_Factory::createCircle(const GLC_Geometry* pCircle) const
{
	const GLC_Circle* pTempCircle= dynamic_cast<const GLC_Circle*>(pCircle);
	if (pTempCircle != NULL)
	{
		return new GLC_Circle(*pTempCircle);
	}
	else
	{
		return NULL;
	}
}
// Create an GLC_Box
GLC_Box* GLC_Factory::createBox(double lx, double ly, double lz) const
{
	return new GLC_Box(lx, ly, lz);
}

// Create an GLC_Box
GLC_Box* GLC_Factory::createBox(const GLC_BoundingBox& boundingBox) const
{
	const double lx= boundingBox.getUpper().getX() - boundingBox.getLower().getX();
	const double ly= boundingBox.getUpper().getY() - boundingBox.getLower().getY();
	const double lz= boundingBox.getUpper().getZ() - boundingBox.getLower().getZ();
	GLC_Box* pBox= new GLC_Box(lx, ly, lz);
	pBox->translate(boundingBox.getLower().getX(), boundingBox.getLower().getY()
					, boundingBox.getLower().getZ());

	return pBox;
}

// Create an GLC_Cylinder
GLC_Cylinder* GLC_Factory::createCylinder(double radius, double length) const
{
	return new GLC_Cylinder(radius, length);
}
// Create an GLC_Cylinder by copying another GLC_Cylinder
GLC_Cylinder* GLC_Factory::createCylinder(const GLC_Geometry* pCylinder) const
{
	const GLC_Cylinder* pTempCylinder= dynamic_cast<const GLC_Cylinder*>(pCylinder);
	if (pTempCylinder != NULL)
	{
		return new GLC_Cylinder(*pTempCylinder);
	}
	else
	{
		return NULL;
	}
}
// Create an GLC_Mesh with a QFile
GLC_Mesh2* GLC_Factory::createMesh(QFile &file) const
{
	GLC_ObjToMesh2 objToMesh(m_pQGLWidget);
	connect(&objToMesh, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
	return objToMesh.CreateMeshFromObj(file);
}

// Create an GLC_Mesh by copying another mesh
GLC_Mesh2* GLC_Factory::createMesh(const GLC_Geometry* pMesh) const
{
	const GLC_Mesh2* pTempMesh= dynamic_cast<const GLC_Mesh2*>(pMesh);
	if (pTempMesh != NULL)
	{
		return new GLC_Mesh2(*pTempMesh);
	}
	else
	{
		return NULL;
	}
}

// Create an GLC_Material
GLC_Material* GLC_Factory::createMaterial() const
{
	return new GLC_Material();
}

// Create an GLC_Material
GLC_Material* GLC_Factory::createMaterial(const GLfloat *pAmbiantColor) const
{
	return new GLC_Material("Material", pAmbiantColor);
}
// Create an GLC_Material
GLC_Material* GLC_Factory::createMaterial(const QColor &color) const
{
	return new GLC_Material(color);
}

GLC_Material* GLC_Factory::createMaterial(GLC_Texture* pTexture) const
{
	return new GLC_Material(pTexture, "TextureMaterial");
}
// create an material textured with a image file name
GLC_Material* GLC_Factory::createMaterial(const QString &textureFullFileName) const
{
	GLC_Texture* pTexture= createTexture(textureFullFileName);
	return createMaterial(pTexture);
}

// Create an GLC_Texture

GLC_Texture* GLC_Factory::createTexture(const QString &textureFullFileName) const
{
	return new GLC_Texture(m_pQGLWidget, textureFullFileName);
}
<commit_msg>After replacing *GLfloat by QColor, pass a QColor object to the constructor of GLC_Object which need a color.<commit_after>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2006 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 0.9.6, packaged on June, 2006.

 http://glc-lib.sourceforge.net

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

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

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

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

//! \file glc_factory.cpp implementation of the GLC_Factory class.

#include "glc_factory.h"
#include "glc_objtomesh2.h"

// init static member
GLC_Factory* GLC_Factory::m_pFactory= NULL;

//////////////////////////////////////////////////////////////////////
// static method
//////////////////////////////////////////////////////////////////////
// Return the unique instance of the factory
GLC_Factory* GLC_Factory::instance(QGLWidget *GLWidget)
{
	if(m_pFactory == NULL)
	{
		m_pFactory= new GLC_Factory(GLWidget);
	}
	return m_pFactory;
}

//////////////////////////////////////////////////////////////////////
// Constructor destructor
//////////////////////////////////////////////////////////////////////

// Protected constructor
GLC_Factory::GLC_Factory(QGLWidget *GLWidget)
: m_pQGLWidget(GLWidget)
{

}

// Destructor
GLC_Factory::~GLC_Factory()
{
	m_pFactory= NULL;
}

//////////////////////////////////////////////////////////////////////
// Create functions
//////////////////////////////////////////////////////////////////////

// Create an GLC_Point
GLC_Point* GLC_Factory::createPoint(const GLC_Vector4d &coord) const
{
	return new GLC_Point(coord,  Qt::white);
}
// Create an GLC_Point
GLC_Point* GLC_Factory::createPoint(double x, double y, double z) const
{
	return new GLC_Point(x, y, z,  Qt::white);
}

//  Create an GLC_Circle
GLC_Circle* GLC_Factory::createCircle(double radius, double angle) const
{
	return new GLC_Circle(radius, angle,  Qt::white);
}
// Create an GLC_Circle by copying another GLC_Circle
GLC_Circle* GLC_Factory::createCircle(const GLC_Geometry* pCircle) const
{
	const GLC_Circle* pTempCircle= dynamic_cast<const GLC_Circle*>(pCircle);
	if (pTempCircle != NULL)
	{
		return new GLC_Circle(*pTempCircle);
	}
	else
	{
		return NULL;
	}
}
// Create an GLC_Box
GLC_Box* GLC_Factory::createBox(double lx, double ly, double lz) const
{
	return new GLC_Box(lx, ly, lz,  Qt::white);
}

// Create an GLC_Box
GLC_Box* GLC_Factory::createBox(const GLC_BoundingBox& boundingBox) const
{
	const double lx= boundingBox.getUpper().getX() - boundingBox.getLower().getX();
	const double ly= boundingBox.getUpper().getY() - boundingBox.getLower().getY();
	const double lz= boundingBox.getUpper().getZ() - boundingBox.getLower().getZ();
	GLC_Box* pBox= new GLC_Box(lx, ly, lz,  Qt::white);
	pBox->translate(boundingBox.getLower().getX(), boundingBox.getLower().getY()
					, boundingBox.getLower().getZ());

	return pBox;
}

// Create an GLC_Cylinder
GLC_Cylinder* GLC_Factory::createCylinder(double radius, double length) const
{
	return new GLC_Cylinder(radius, length,  Qt::white);
}
// Create an GLC_Cylinder by copying another GLC_Cylinder
GLC_Cylinder* GLC_Factory::createCylinder(const GLC_Geometry* pCylinder) const
{
	const GLC_Cylinder* pTempCylinder= dynamic_cast<const GLC_Cylinder*>(pCylinder);
	if (pTempCylinder != NULL)
	{
		return new GLC_Cylinder(*pTempCylinder);
	}
	else
	{
		return NULL;
	}
}
// Create an GLC_Mesh with a QFile
GLC_Mesh2* GLC_Factory::createMesh(QFile &file) const
{
	GLC_ObjToMesh2 objToMesh(m_pQGLWidget);
	connect(&objToMesh, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
	return objToMesh.CreateMeshFromObj(file);
}

// Create an GLC_Mesh by copying another mesh
GLC_Mesh2* GLC_Factory::createMesh(const GLC_Geometry* pMesh) const
{
	const GLC_Mesh2* pTempMesh= dynamic_cast<const GLC_Mesh2*>(pMesh);
	if (pTempMesh != NULL)
	{
		return new GLC_Mesh2(*pTempMesh);
	}
	else
	{
		return NULL;
	}
}

// Create an GLC_Material
GLC_Material* GLC_Factory::createMaterial() const
{
	return new GLC_Material();
}

// Create an GLC_Material
GLC_Material* GLC_Factory::createMaterial(const GLfloat *pAmbiantColor) const
{
	return new GLC_Material("Material", pAmbiantColor);
}
// Create an GLC_Material
GLC_Material* GLC_Factory::createMaterial(const QColor &color) const
{
	return new GLC_Material(color);
}

GLC_Material* GLC_Factory::createMaterial(GLC_Texture* pTexture) const
{
	return new GLC_Material(pTexture, "TextureMaterial");
}
// create an material textured with a image file name
GLC_Material* GLC_Factory::createMaterial(const QString &textureFullFileName) const
{
	GLC_Texture* pTexture= createTexture(textureFullFileName);
	return createMaterial(pTexture);
}

// Create an GLC_Texture

GLC_Texture* GLC_Factory::createTexture(const QString &textureFullFileName) const
{
	return new GLC_Texture(m_pQGLWidget, textureFullFileName);
}
<|endoftext|>