<commit_before>#include "TableMetadata.h"

/***
 * Returns the allocation number of bytes required to allocate a type of data
 * @param VT Cassandra Type
 * @return Allocation size needed to store data of type VT
 */
uint16_t TableMetadata::compute_size_of(const ColumnMeta &CM) const {
    switch (CM.type) {
        case CASS_VALUE_TYPE_TEXT:
        case CASS_VALUE_TYPE_VARCHAR:
        case CASS_VALUE_TYPE_ASCII: {
            return sizeof(char *);
        }
        case CASS_VALUE_TYPE_VARINT:
        case CASS_VALUE_TYPE_BIGINT: {
            return sizeof(int64_t);
        }
        case CASS_VALUE_TYPE_BLOB: {
            return sizeof(unsigned char *);
        }
        case CASS_VALUE_TYPE_BOOLEAN: {
            return sizeof(bool);
        }
        case CASS_VALUE_TYPE_COUNTER: {
            return sizeof(uint32_t);
        }
        case CASS_VALUE_TYPE_DECIMAL: {
            //TODO
            std::cerr << "Parse decimals data type supported yet" << std::endl;
            break;
        }
        case CASS_VALUE_TYPE_DOUBLE: {
            return sizeof(double);
        }
        case CASS_VALUE_TYPE_FLOAT: {
            return sizeof(float);
        }
        case CASS_VALUE_TYPE_INT: {
            return sizeof(int32_t);
        }
        case CASS_VALUE_TYPE_TIMESTAMP: {
            //TODO
            std::cerr << "Timestamp data type supported yet" << std::endl;
            break;
        }
        case CASS_VALUE_TYPE_UUID: {
            return sizeof(uint64_t *);
        }
        case CASS_VALUE_TYPE_TIMEUUID: {
            std::cerr << "TIMEUUID data type supported yet" << std::endl;
            //TODO
            break;
        }
        case CASS_VALUE_TYPE_INET: {
            //TODO
            std::cerr << "INET data type supported yet" << std::endl;
            break;
        }
        case CASS_VALUE_TYPE_DATE: {
            std::cerr << "Date data type supported yet" << std::endl;

            //TODO
            break;
        }
        case CASS_VALUE_TYPE_TIME: {
            std::cerr << "Time data type supported yet" << std::endl;
            //TODO

            break;
        }
        case CASS_VALUE_TYPE_SMALL_INT: {
            return sizeof(int16_t);
        }
        case CASS_VALUE_TYPE_TINY_INT: {
            return sizeof(int8_t);
        }
        case CASS_VALUE_TYPE_LIST: {
            std::cerr << "List data type supported yet" << std::endl;
            //TODO
            break;
        }
        case CASS_VALUE_TYPE_MAP: {
            std::cerr << "Map data type supported yet" << std::endl;
            //TODO

            break;
        }
        case CASS_VALUE_TYPE_SET: {
            std::cerr << "Set data type supported yet" << std::endl;
            //TODO

            break;
        }
        case CASS_VALUE_TYPE_TUPLE: {
            return sizeof(void *);
        }
        case CASS_VALUE_TYPE_UDT: {
            throw ModuleException("Can't parse data: User defined type not supported");
        }
        case CASS_VALUE_TYPE_CUSTOM:
        case CASS_VALUE_TYPE_UNKNOWN:
        default: {
            throw ModuleException("Can't parse data: Unknown data type or user defined type");
            //TODO
        }
    }
    return 0;
}

std::map<std::string, ColumnMeta> TableMetadata::getMetaTypes(CassIterator *iterator) {
    std::map<std::string, ColumnMeta> metadatas;
    const CassColumnMeta *cmeta;
    const char *value;
    size_t length;
    const CassDataType *type;
    while (cass_iterator_next(iterator)) {
        cmeta = cass_iterator_get_column_meta(iterator);
        cass_column_meta_name(cmeta, &value, &length);
        type = cass_column_meta_data_type(cmeta);
        if (cass_data_type_type(type) == CASS_VALUE_TYPE_TUPLE) {
            uint32_t n_subtypes = (uint32_t) cass_data_type_sub_type_count(type);
            std::vector<ColumnMeta> v(n_subtypes);
            uint32_t offset = 0;
            CassValueType cvt;
            uint16_t size;
            for (uint32_t subtype = 0; subtype < n_subtypes; ++subtype) {
                metadatas[value].type = cass_data_type_type(type);
                metadatas[value].col_type = cass_column_meta_type(cmeta);
                cvt = cass_data_type_type(cass_data_type_sub_data_type(type, subtype));
                ColumnMeta cm = ColumnMeta();
                cm.info.insert(std::pair<std::string, std::string>("name_tuple_col", value));
                cm.type = cvt;
                cm.position = offset;
                size = compute_size_of(cm);
                offset += size;
                cm.size = size;
                v[subtype] = cm;
            }
            metadatas[value].pointer = std::make_shared<std::vector<ColumnMeta>>(v);

        } else {
            metadatas[value].type = cass_data_type_type(type);
            metadatas[value].col_type = cass_column_meta_type(cmeta);
        }
    }
    cass_iterator_free(iterator);
    return metadatas;
}

TableMetadata::TableMetadata(const char *table_name, const char *keyspace_name,
                             std::vector<std::map<std::string, std::string>> &keys_names,
                             std::vector<std::map<std::string, std::string>> &columns_names,
                             const CassSession *session) {

    if (keys_names.empty()) throw ModuleException("TableMetadata: No keys received");

    uint32_t n_keys = (uint32_t) keys_names.size();
    uint32_t n_cols = (uint32_t) columns_names.size(); //TODO check for *
    for (uint32_t i = 0; i < n_keys; ++i) {
        std::transform(keys_names[i]["name"].begin(), keys_names[i]["name"].end(), keys_names[i]["name"].begin(),
                       ::tolower);
    }
    for (uint32_t i = 0; i < n_cols; ++i) {
        std::transform(columns_names[i]["name"].begin(), columns_names[i]["name"].end(),
                       columns_names[i]["name"].begin(), ::tolower);
    }
    this->table = std::string(table_name);
    std::transform(this->table.begin(), this->table.end(), this->table.begin(), ::tolower);
    this->keyspace = std::string(keyspace_name);
    std::transform(this->keyspace.begin(), this->keyspace.end(), this->keyspace.begin(), ::tolower);

    const CassSchemaMeta *schema_meta = cass_session_get_schema_meta(session);
    if (!schema_meta) {
        std::string error_msg = "TableMetadata constructor: Cassandra schema doesn't exist, probably not connected...";
        if (session == NULL) error_msg += "session with cassandra not stablished";
        throw ModuleException(error_msg.c_str());
    }

    const CassKeyspaceMeta *keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, this->keyspace.c_str());
    if (!keyspace_meta) {
        throw ModuleException("The keyspace " + std::string(keyspace_name) + " has no metadatas,"
                                                                             "check the keyspace name and make sure it exists");
    }

    const CassTableMeta *table_meta = cass_keyspace_meta_table_by_name(keyspace_meta, this->table.c_str());
    if (!table_meta || (cass_table_meta_column_count(table_meta) == 0)) {
        throw ModuleException("The table " + std::string(table_name) + " has no metadatas,"
                                                                       " check the table name and make sure it exists");
    }

//TODO Switch to unordered maps for efficiency

    CassIterator *iterator = cass_iterator_columns_from_table_meta(table_meta);

    std::map<std::string, ColumnMeta> metadatas = getMetaTypes(iterator);
    cass_iterator_free(iterator);
    cass_schema_meta_free(schema_meta);

    std::string key = keys_names[0]["name"];
    if (key.empty()) throw ModuleException("Empty key name given on position 0");
    std::string select_where = key + "=? ";
    std::string keys = key;
    std::string col;
    std::string tokens_keys = "";
    if (metadatas[key].col_type == CASS_COLUMN_TYPE_PARTITION_KEY) tokens_keys += key;

    for (uint16_t i = 1; i < n_keys; ++i) {
        key = keys_names[i]["name"];
        if (key.empty()) throw ModuleException("Empty key name given on position: " + std::to_string(i));
        keys += "," + key;
        select_where += "AND " + key + "=? ";
        if (metadatas[key].col_type == CASS_COLUMN_TYPE_PARTITION_KEY) {
            if (!tokens_keys.empty()) tokens_keys += ",";
            tokens_keys += key;
        }
    }
    if (tokens_keys.empty()) throw ModuleException("No partition key detected among the keys: " + keys);

    std::string cols = "";
    if (!columns_names.empty()) {
        cols += columns_names[0]["name"]; //TODO Check for *
        if (cols.empty()) throw ModuleException("Empty column name given on position 0");
        for (uint16_t i = 1; i < n_cols; ++i) {
            col = columns_names[i]["name"];
            if (col.empty()) throw ModuleException("Empty column name given onposition: " + std::to_string(i));
            cols += "," + col;
        }
    }
    std::string keys_and_cols = keys;
    if (!cols.empty()) keys_and_cols += ", " + cols;
    else cols = keys;

    std::string select_tokens_where = " token(" + tokens_keys + ")>=? AND token(" + tokens_keys + ")<? ";
    select = "SELECT " + cols + " FROM " + this->keyspace + "." + this->table + " WHERE " + select_where + ";";

    select_keys_tokens =
            "SELECT " + keys + " FROM " + this->keyspace + "." + this->table + " WHERE " + select_tokens_where + ";";
    select_tokens_values =
            "SELECT " + cols + " FROM " + this->keyspace + "." + this->table + " WHERE " + select_tokens_where + ";";

    select_tokens_all = "SELECT " + keys_and_cols + " FROM " + this->keyspace + "." + this->table + " WHERE " +
                        select_tokens_where + ";";

    insert = "INSERT INTO " + this->keyspace + "." + this->table + "(" + keys_and_cols + ")" + "VALUES (?";
    for (uint16_t i = 1; i < n_keys + n_cols; ++i) {
        insert += ",?";
    }
    insert += ");";

    delete_row = "DELETE  FROM " + this->keyspace + "." + this->table + " WHERE " + select_where + ";";

    std::vector<ColumnMeta> keys_meta(n_keys);
    std::vector<ColumnMeta> cols_meta(n_cols);

    if (!columns_names.empty()) {
        cols_meta[0] = metadatas[columns_names[0]["name"]];
        cols_meta[0].info = columns_names[0];
        cols_meta[0].size = compute_size_of(cols_meta[0]);
        cols_meta[0].position = 0;
        for (uint16_t i = 1; i < cols_meta.size(); ++i) {
            cols_meta[i] = metadatas[columns_names[i]["name"]];
            cols_meta[i].info = columns_names[i];
            cols_meta[i].size = compute_size_of(cols_meta[i]);
            cols_meta[i].position = cols_meta[i - 1].position + cols_meta[i - 1].size;
        }
    }

    keys_meta[0] = metadatas[keys_names[0]["name"]];
    keys_meta[0].info = keys_names[0];
    keys_meta[0].size = compute_size_of(keys_meta[0]);
    keys_meta[0].position = 0;
    for (uint16_t i = 1; i < keys_meta.size(); ++i) {
        keys_meta[i] = metadatas[keys_names[i]["name"]];
        keys_meta[i].info = keys_names[i];
        keys_meta[i].size = compute_size_of(keys_meta[i]);
        keys_meta[i].position = keys_meta[i - 1].position + keys_meta[i - 1].size;
    }

    std::vector<ColumnMeta> items_meta(cols_meta);
    items_meta.insert(items_meta.begin(), keys_meta.begin(), keys_meta.end());
    uint16_t keys_offset = keys_meta[n_keys - 1].position + keys_meta[n_keys - 1].size;

    for (uint16_t i = (uint16_t) keys_meta.size(); i < items_meta.size(); ++i) {
        items_meta[i].position += keys_offset;
    }

    this->cols = std::make_shared<std::vector<ColumnMeta> >(cols_meta);
    this->keys = std::make_shared<std::vector<ColumnMeta> >(keys_meta);
    this->items = std::make_shared<std::vector<ColumnMeta> >(items_meta);
}<commit_msg>Remove double free<commit_after>#include "TableMetadata.h"

/***
 * Returns the allocation number of bytes required to allocate a type of data
 * @param VT Cassandra Type
 * @return Allocation size needed to store data of type VT
 */
uint16_t TableMetadata::compute_size_of(const ColumnMeta &CM) const {
    switch (CM.type) {
        case CASS_VALUE_TYPE_TEXT:
        case CASS_VALUE_TYPE_VARCHAR:
        case CASS_VALUE_TYPE_ASCII: {
            return sizeof(char *);
        }
        case CASS_VALUE_TYPE_VARINT:
        case CASS_VALUE_TYPE_BIGINT: {
            return sizeof(int64_t);
        }
        case CASS_VALUE_TYPE_BLOB: {
            return sizeof(unsigned char *);
        }
        case CASS_VALUE_TYPE_BOOLEAN: {
            return sizeof(bool);
        }
        case CASS_VALUE_TYPE_COUNTER: {
            return sizeof(uint32_t);
        }
        case CASS_VALUE_TYPE_DECIMAL: {
            //TODO
            std::cerr << "Parse decimals data type supported yet" << std::endl;
            break;
        }
        case CASS_VALUE_TYPE_DOUBLE: {
            return sizeof(double);
        }
        case CASS_VALUE_TYPE_FLOAT: {
            return sizeof(float);
        }
        case CASS_VALUE_TYPE_INT: {
            return sizeof(int32_t);
        }
        case CASS_VALUE_TYPE_TIMESTAMP: {
            //TODO
            std::cerr << "Timestamp data type supported yet" << std::endl;
            break;
        }
        case CASS_VALUE_TYPE_UUID: {
            return sizeof(uint64_t *);
        }
        case CASS_VALUE_TYPE_TIMEUUID: {
            std::cerr << "TIMEUUID data type supported yet" << std::endl;
            //TODO
            break;
        }
        case CASS_VALUE_TYPE_INET: {
            //TODO
            std::cerr << "INET data type supported yet" << std::endl;
            break;
        }
        case CASS_VALUE_TYPE_DATE: {
            std::cerr << "Date data type supported yet" << std::endl;

            //TODO
            break;
        }
        case CASS_VALUE_TYPE_TIME: {
            std::cerr << "Time data type supported yet" << std::endl;
            //TODO

            break;
        }
        case CASS_VALUE_TYPE_SMALL_INT: {
            return sizeof(int16_t);
        }
        case CASS_VALUE_TYPE_TINY_INT: {
            return sizeof(int8_t);
        }
        case CASS_VALUE_TYPE_LIST: {
            std::cerr << "List data type supported yet" << std::endl;
            //TODO
            break;
        }
        case CASS_VALUE_TYPE_MAP: {
            std::cerr << "Map data type supported yet" << std::endl;
            //TODO

            break;
        }
        case CASS_VALUE_TYPE_SET: {
            std::cerr << "Set data type supported yet" << std::endl;
            //TODO

            break;
        }
        case CASS_VALUE_TYPE_TUPLE: {
            return sizeof(void *);
        }
        case CASS_VALUE_TYPE_UDT: {
            throw ModuleException("Can't parse data: User defined type not supported");
        }
        case CASS_VALUE_TYPE_CUSTOM:
        case CASS_VALUE_TYPE_UNKNOWN:
        default: {
            throw ModuleException("Can't parse data: Unknown data type or user defined type");
            //TODO
        }
    }
    return 0;
}

std::map<std::string, ColumnMeta> TableMetadata::getMetaTypes(CassIterator *iterator) {
    std::map<std::string, ColumnMeta> metadatas;
    const CassColumnMeta *cmeta;
    const char *value;
    size_t length;
    const CassDataType *type;
    while (cass_iterator_next(iterator)) {
        cmeta = cass_iterator_get_column_meta(iterator);
        cass_column_meta_name(cmeta, &value, &length);
        type = cass_column_meta_data_type(cmeta);
        if (cass_data_type_type(type) == CASS_VALUE_TYPE_TUPLE) {
            uint32_t n_subtypes = (uint32_t) cass_data_type_sub_type_count(type);
            std::vector<ColumnMeta> v(n_subtypes);
            uint32_t offset = 0;
            CassValueType cvt;
            uint16_t size;
            for (uint32_t subtype = 0; subtype < n_subtypes; ++subtype) {
                metadatas[value].type = cass_data_type_type(type);
                metadatas[value].col_type = cass_column_meta_type(cmeta);
                cvt = cass_data_type_type(cass_data_type_sub_data_type(type, subtype));
                ColumnMeta cm = ColumnMeta();
                cm.info.insert(std::pair<std::string, std::string>("name_tuple_col", value));
                cm.type = cvt;
                cm.position = offset;
                size = compute_size_of(cm);
                offset += size;
                cm.size = size;
                v[subtype] = cm;
            }
            metadatas[value].pointer = std::make_shared<std::vector<ColumnMeta>>(v);

        } else {
            metadatas[value].type = cass_data_type_type(type);
            metadatas[value].col_type = cass_column_meta_type(cmeta);
        }
    }
    return metadatas;
}

TableMetadata::TableMetadata(const char *table_name, const char *keyspace_name,
                             std::vector<std::map<std::string, std::string>> &keys_names,
                             std::vector<std::map<std::string, std::string>> &columns_names,
                             const CassSession *session) {

    if (keys_names.empty()) throw ModuleException("TableMetadata: No keys received");

    uint32_t n_keys = (uint32_t) keys_names.size();
    uint32_t n_cols = (uint32_t) columns_names.size(); //TODO check for *
    for (uint32_t i = 0; i < n_keys; ++i) {
        std::transform(keys_names[i]["name"].begin(), keys_names[i]["name"].end(), keys_names[i]["name"].begin(),
                       ::tolower);
    }
    for (uint32_t i = 0; i < n_cols; ++i) {
        std::transform(columns_names[i]["name"].begin(), columns_names[i]["name"].end(),
                       columns_names[i]["name"].begin(), ::tolower);
    }
    this->table = std::string(table_name);
    std::transform(this->table.begin(), this->table.end(), this->table.begin(), ::tolower);
    this->keyspace = std::string(keyspace_name);
    std::transform(this->keyspace.begin(), this->keyspace.end(), this->keyspace.begin(), ::tolower);

    const CassSchemaMeta *schema_meta = cass_session_get_schema_meta(session);
    if (!schema_meta) {
        std::string error_msg = "TableMetadata constructor: Cassandra schema doesn't exist, probably not connected...";
        if (session == NULL) error_msg += "session with cassandra not stablished";
        throw ModuleException(error_msg.c_str());
    }

    const CassKeyspaceMeta *keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, this->keyspace.c_str());
    if (!keyspace_meta) {
        throw ModuleException("The keyspace " + std::string(keyspace_name) + " has no metadatas,"
                                                                             "check the keyspace name and make sure it exists");
    }

    const CassTableMeta *table_meta = cass_keyspace_meta_table_by_name(keyspace_meta, this->table.c_str());
    if (!table_meta || (cass_table_meta_column_count(table_meta) == 0)) {
        throw ModuleException("The table " + std::string(table_name) + " has no metadatas,"
                                                                       " check the table name and make sure it exists");
    }

//TODO Switch to unordered maps for efficiency

    CassIterator *iterator = cass_iterator_columns_from_table_meta(table_meta);

    std::map<std::string, ColumnMeta> metadatas = getMetaTypes(iterator);
    cass_iterator_free(iterator);
    cass_schema_meta_free(schema_meta);

    std::string key = keys_names[0]["name"];
    if (key.empty()) throw ModuleException("Empty key name given on position 0");
    std::string select_where = key + "=? ";
    std::string keys = key;
    std::string col;
    std::string tokens_keys = "";
    if (metadatas[key].col_type == CASS_COLUMN_TYPE_PARTITION_KEY) tokens_keys += key;

    for (uint16_t i = 1; i < n_keys; ++i) {
        key = keys_names[i]["name"];
        if (key.empty()) throw ModuleException("Empty key name given on position: " + std::to_string(i));
        keys += "," + key;
        select_where += "AND " + key + "=? ";
        if (metadatas[key].col_type == CASS_COLUMN_TYPE_PARTITION_KEY) {
            if (!tokens_keys.empty()) tokens_keys += ",";
            tokens_keys += key;
        }
    }
    if (tokens_keys.empty()) throw ModuleException("No partition key detected among the keys: " + keys);

    std::string cols = "";
    if (!columns_names.empty()) {
        cols += columns_names[0]["name"]; //TODO Check for *
        if (cols.empty()) throw ModuleException("Empty column name given on position 0");
        for (uint16_t i = 1; i < n_cols; ++i) {
            col = columns_names[i]["name"];
            if (col.empty()) throw ModuleException("Empty column name given onposition: " + std::to_string(i));
            cols += "," + col;
        }
    }
    std::string keys_and_cols = keys;
    if (!cols.empty()) keys_and_cols += ", " + cols;
    else cols = keys;

    std::string select_tokens_where = " token(" + tokens_keys + ")>=? AND token(" + tokens_keys + ")<? ";
    select = "SELECT " + cols + " FROM " + this->keyspace + "." + this->table + " WHERE " + select_where + ";";

    select_keys_tokens =
            "SELECT " + keys + " FROM " + this->keyspace + "." + this->table + " WHERE " + select_tokens_where + ";";
    select_tokens_values =
            "SELECT " + cols + " FROM " + this->keyspace + "." + this->table + " WHERE " + select_tokens_where + ";";

    select_tokens_all = "SELECT " + keys_and_cols + " FROM " + this->keyspace + "." + this->table + " WHERE " +
                        select_tokens_where + ";";

    insert = "INSERT INTO " + this->keyspace + "." + this->table + "(" + keys_and_cols + ")" + "VALUES (?";
    for (uint16_t i = 1; i < n_keys + n_cols; ++i) {
        insert += ",?";
    }
    insert += ");";

    delete_row = "DELETE  FROM " + this->keyspace + "." + this->table + " WHERE " + select_where + ";";

    std::vector<ColumnMeta> keys_meta(n_keys);
    std::vector<ColumnMeta> cols_meta(n_cols);

    if (!columns_names.empty()) {
        cols_meta[0] = metadatas[columns_names[0]["name"]];
        cols_meta[0].info = columns_names[0];
        cols_meta[0].size = compute_size_of(cols_meta[0]);
        cols_meta[0].position = 0;
        for (uint16_t i = 1; i < cols_meta.size(); ++i) {
            cols_meta[i] = metadatas[columns_names[i]["name"]];
            cols_meta[i].info = columns_names[i];
            cols_meta[i].size = compute_size_of(cols_meta[i]);
            cols_meta[i].position = cols_meta[i - 1].position + cols_meta[i - 1].size;
        }
    }

    keys_meta[0] = metadatas[keys_names[0]["name"]];
    keys_meta[0].info = keys_names[0];
    keys_meta[0].size = compute_size_of(keys_meta[0]);
    keys_meta[0].position = 0;
    for (uint16_t i = 1; i < keys_meta.size(); ++i) {
        keys_meta[i] = metadatas[keys_names[i]["name"]];
        keys_meta[i].info = keys_names[i];
        keys_meta[i].size = compute_size_of(keys_meta[i]);
        keys_meta[i].position = keys_meta[i - 1].position + keys_meta[i - 1].size;
    }

    std::vector<ColumnMeta> items_meta(cols_meta);
    items_meta.insert(items_meta.begin(), keys_meta.begin(), keys_meta.end());
    uint16_t keys_offset = keys_meta[n_keys - 1].position + keys_meta[n_keys - 1].size;

    for (uint16_t i = (uint16_t) keys_meta.size(); i < items_meta.size(); ++i) {
        items_meta[i].position += keys_offset;
    }

    this->cols = std::make_shared<std::vector<ColumnMeta> >(cols_meta);
    this->keys = std::make_shared<std::vector<ColumnMeta> >(keys_meta);
    this->items = std::make_shared<std::vector<ColumnMeta> >(items_meta);
}<|endoftext|>


<commit_before>#include "Config.h"

#include "common/FileNameTools.h"

#include <fstream>

namespace d2d
{

Config* Config::m_instance = NULL;

const char* FILENAME = "config.json";

Config::Config()
{
	m_use_dtex = true;
}

Config* Config::Instance()
{
	if (!m_instance)
	{
		m_instance = new Config();
		if (FilenameTools::isExist(FILENAME)) {
			m_instance->LoadFromFile(FILENAME);
		}
	}
	return m_instance;
}

void Config::GetStrings(const std::string& key,
						std::vector<std::string>& val) const
{
	Json::Value str_list = m_value[key];
	if (!str_list.isNull())
	{
		int i = 0;
		Json::Value str = str_list[i++];
		while (!str.isNull()) {
			val.push_back(str.asString());
			str = str_list[i++];
		}
	}
}

void Config::LoadFromFile(const char* filename)
{
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filename);
	std::locale::global(std::locale("C"));
	reader.parse(fin, m_value);
	fin.close();

	m_use_dtex = m_value["use_dtex"].asBool();
}

}<commit_msg>[CHANGED] 默认关闭dtex<commit_after>#include "Config.h"

#include "common/FileNameTools.h"

#include <fstream>

namespace d2d
{

Config* Config::m_instance = NULL;

const char* FILENAME = "config.json";

Config::Config()
{
	m_use_dtex = false;
}

Config* Config::Instance()
{
	if (!m_instance)
	{
		m_instance = new Config();
		if (FilenameTools::isExist(FILENAME)) {
			m_instance->LoadFromFile(FILENAME);
		}
	}
	return m_instance;
}

void Config::GetStrings(const std::string& key,
						std::vector<std::string>& val) const
{
	Json::Value str_list = m_value[key];
	if (!str_list.isNull())
	{
		int i = 0;
		Json::Value str = str_list[i++];
		while (!str.isNull()) {
			val.push_back(str.asString());
			str = str_list[i++];
		}
	}
}

void Config::LoadFromFile(const char* filename)
{
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filename);
	std::locale::global(std::locale("C"));
	reader.parse(fin, m_value);
	fin.close();

	m_use_dtex = m_value["use_dtex"].asBool();
}

}<|endoftext|>


<commit_before><commit_msg>[drape] [tracks] Allow to render tracks for 20 zoomLevel MAPSME-12900<commit_after><|endoftext|>


<commit_before>#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* local */
#include "stateval/StateMachineThread.h"
#include "stateval/StateMachine.h"
#include "Logger.h"

/* STD */
#include <iostream>
#include <string>
#include <map>
#include <cassert>

using namespace std;

static Logger logger ("stateval.StateMachineThread");

StateMachineThread::StateMachineThread (StateMachine &sm) :
  Threading::Thread(),
  mEventMutex(),
  mEventsInQueue(),
  mSM(&sm),
  mSignalList(),
  mSignalBroadcast()
{
}

StateMachineThread::~StateMachineThread ()
{
  LOG4CXX_TRACE (logger, "~StateMachineThread");
  cancel ();
}

void StateMachineThread::start ()
{
  LOG4CXX_TRACE (logger, "+StateMachineThread::start ()");
  Thread::start();
  LOG4CXX_TRACE (logger, "-StateMachineThread::start ()");
}

void StateMachineThread::signal_cancel() // from thread
{
    mEventsInQueue.signal ();
}

void StateMachineThread::run ()
{
  LOG4CXX_TRACE (logger, "+run");

  while (isRunning())
  {
    LOG4CXX_TRACE (logger, "+run::running while");

    mEventMutex.lock ();

    // this waiting loop runs until someone pushed an event to the event queue
    while (mSM->eventQueue.empty())
    {
      LOG4CXX_TRACE (logger, "!mSM->eventQueue.empty()");
      // here is the point the loop waits if no event is in the event queue
      mEventsInQueue.wait (mEventMutex);
      if (!isRunning())
      {
          mEventMutex.unlock ();
          LOG4CXX_TRACE (logger, "!isRunning()");
          return;
      }
    }
    LOG4CXX_TRACE (logger, "mSM->eventQueue.empty()");

    int event = mSM->eventQueue.front();
    mEventMutex.unlock ();

    LOG4CXX_DEBUG (logger, "EventQueue size: " << mSM->eventQueue.size ());

    mSM->evaluateState (event);

    // pop element after working
    LOG4CXX_DEBUG (logger, "EventQueue size: " << mSM->eventQueue.size ());

        // emit event signals
    multimap <int, SignalSignal*>::iterator findResult = mSignalList.find (event);
    multimap <int, SignalSignal*>::iterator lastElement = mSignalList.upper_bound (event);

    if (findResult != mSignalList.end ())
    {
    // emit also multible signals...
      for ( ; findResult != lastElement; ++findResult)
      {
        LOG4CXX_DEBUG (logger, "call event '" << event << "' to app");
        SignalSignal *signal = (*findResult).second;
        signal->emit (event);
      }
    }
    LOG4CXX_TRACE (logger, "-run::running while");

    // emit the signal broadcast
    // this is e.g. useful to dispatch signals to another thread
    mSignalBroadcast.emit (event);

    mEventMutex.lock ();
    mSM->popEvent ();
    mEventMutex.unlock ();

    LOG4CXX_TRACE (logger, "-run");
  }
}

void StateMachineThread::pushEvent (int event)
{
  mEventMutex.lock ();
  mSM->pushEvent (event);
  mEventsInQueue.signal ();
  mEventMutex.unlock ();
}

void StateMachineThread::pushEvent (const std::string &event)
{
  pushEvent (mSM->findMapingEvent (event));
}

void StateMachineThread::connect (int event, const SignalSlot& slot)
{
  SignalSignal* signal = new SignalSignal();
	mSignalList.insert (pair <int, SignalSignal*> (event, signal));

  signal->connect (slot);
}

void StateMachineThread::connect (const SignalSlot& slot)
{
  mSignalBroadcast.connect (slot);
}

void StateMachineThread::disconnect (int event)
{
	// delete event signals
  multimap <int, SignalSignal*>::iterator findResult = mSignalList.find (event);
  multimap <int, SignalSignal*>::iterator lastElement = mSignalList.upper_bound (event);

  if (findResult != mSignalList.end ())
  {
    // delete all connected handlers
    for ( ; findResult != lastElement; ++findResult)
    {
      SignalSignal *signal = findResult->second;
      delete signal;

     // TODO from hdusel: Forget to remove the element from the multimap?
     // Discuss this with Andreas.
    }
  }
}

void StateMachineThread::disconnectAll ()
{
	for (std::multimap <int, SignalSignal*>::iterator s_it = mSignalList.begin ();
	     s_it != mSignalList.end ();
	     ++s_it)
	{
		int event = (*s_it).first;
		SignalSignal *signal = (*s_it).second;

		delete signal;
	}
}
<commit_msg>logging cosmetic<commit_after>#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* local */
#include "stateval/StateMachineThread.h"
#include "stateval/StateMachine.h"
#include "Logger.h"

/* STD */
#include <iostream>
#include <string>
#include <map>
#include <cassert>

using namespace std;

static Logger logger ("stateval.StateMachineThread");

StateMachineThread::StateMachineThread (StateMachine &sm) :
  Threading::Thread(),
  mEventMutex(),
  mEventsInQueue(),
  mSM(&sm),
  mSignalList(),
  mSignalBroadcast()
{
}

StateMachineThread::~StateMachineThread ()
{
  LOG4CXX_TRACE (logger, "~StateMachineThread");

  cancel ();

  LOG4CXX_TRACE (logger, "~StateMachineThread (canceled)");

  join ();

  LOG4CXX_TRACE (logger, "~StateMachineThread (joined)");
}

void StateMachineThread::start ()
{
  LOG4CXX_TRACE (logger, "+StateMachineThread::start ()");
  Thread::start();
  LOG4CXX_TRACE (logger, "-StateMachineThread::start ()");
}

void StateMachineThread::signal_cancel() // from thread
{
  mEventsInQueue.signal ();
}

void StateMachineThread::run ()
{
  LOG4CXX_TRACE (logger, "+run");

  while (isRunning())
  {
    LOG4CXX_TRACE (logger, "+run::running while");

    mEventMutex.lock ();

    // this waiting loop runs until someone pushed an event to the event queue
    while (mSM->eventQueue.empty())
    {
      LOG4CXX_TRACE (logger, "!mSM->eventQueue.empty()");
      // here is the point the loop waits if no event is in the event queue
      mEventsInQueue.wait (mEventMutex);
      if (!isRunning())
      {
          mEventMutex.unlock ();
          LOG4CXX_TRACE (logger, "!isRunning()");
          return;
      }
    }
    LOG4CXX_TRACE (logger, "mSM->eventQueue.empty()");

    int event = mSM->eventQueue.front();
    mEventMutex.unlock ();

    LOG4CXX_DEBUG (logger, "+EventQueue size: " << mSM->eventQueue.size ());

    mSM->evaluateState (event);

    // pop element after working
    LOG4CXX_DEBUG (logger, "-EventQueue size: " << mSM->eventQueue.size ());

        // emit event signals
    multimap <int, SignalSignal*>::iterator findResult = mSignalList.find (event);
    multimap <int, SignalSignal*>::iterator lastElement = mSignalList.upper_bound (event);

    if (findResult != mSignalList.end ())
    {
      // emit also multible signals...
      for ( ; findResult != lastElement; ++findResult)
      {
        LOG4CXX_DEBUG (logger, "call event '" << event << "' to app");
        SignalSignal *signal = (*findResult).second;
        signal->emit (event);
      }
    }
    LOG4CXX_TRACE (logger, "-run::running while");

    // emit the signal broadcast
    // this is e.g. useful to dispatch signals to another thread
    mSignalBroadcast.emit (event);

    mEventMutex.lock ();
    mSM->popEvent ();
    mEventMutex.unlock ();

    LOG4CXX_TRACE (logger, "-run");
  }
}

void StateMachineThread::pushEvent (int event)
{
  mEventMutex.lock ();
  mSM->pushEvent (event);
  mEventsInQueue.signal ();
  mEventMutex.unlock ();
}

void StateMachineThread::pushEvent (const std::string &event)
{
  pushEvent (mSM->findMapingEvent (event));
}

void StateMachineThread::connect (int event, const SignalSlot& slot)
{
  SignalSignal* signal = new SignalSignal();
	mSignalList.insert (pair <int, SignalSignal*> (event, signal));

  signal->connect (slot);
}

void StateMachineThread::connect (const SignalSlot& slot)
{
  mSignalBroadcast.connect (slot);
}

void StateMachineThread::disconnect (int event)
{
	// delete event signals
  multimap <int, SignalSignal*>::iterator findResult = mSignalList.find (event);
  multimap <int, SignalSignal*>::iterator lastElement = mSignalList.upper_bound (event);

  if (findResult != mSignalList.end ())
  {
    // delete all connected handlers
    for ( ; findResult != lastElement; ++findResult)
    {
      SignalSignal *signal = findResult->second;
      delete signal;

     // TODO from hdusel: Forget to remove the element from the multimap?
     // Discuss this with Andreas.
    }
  }
}

void StateMachineThread::disconnectAll ()
{
	for (std::multimap <int, SignalSignal*>::iterator s_it = mSignalList.begin ();
	     s_it != mSignalList.end ();
	     ++s_it)
	{
		int event = (*s_it).first;
		SignalSignal *signal = (*s_it).second;

		delete signal;
	}
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief SpiMasterLowLevelInterruptBased class header for SPIv2 in STM32
 *
 * \author Copyright (C) 2016-2018 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 */

#ifndef SOURCE_CHIP_STM32_PERIPHERALS_SPIV2_INCLUDE_DISTORTOS_CHIP_SPIMASTERLOWLEVELINTERRUPTBASED_HPP_
#define SOURCE_CHIP_STM32_PERIPHERALS_SPIV2_INCLUDE_DISTORTOS_CHIP_SPIMASTERLOWLEVELINTERRUPTBASED_HPP_

#include "distortos/devices/communication/SpiMasterLowLevel.hpp"

namespace distortos
{

namespace chip
{

class SpiPeripheral;

/**
 * SpiMasterLowLevelInterruptBased class is a low-level SPI master driver for SPIv2 in STM32.
 *
 * This driver uses interrupts for data transfers.
 *
 * \ingroup devices
 */

class SpiMasterLowLevelInterruptBased : public devices::SpiMasterLowLevel
{
public:

	/**
	 * \brief SpiMasterLowLevelInterruptBased's constructor
	 *
	 * \param [in] spiPeripheral is a reference to raw SPI peripheral
	 */

	constexpr explicit SpiMasterLowLevelInterruptBased(const SpiPeripheral& spiPeripheral) :
			spiPeripheral_{spiPeripheral},
			spiMasterBase_{},
			readBuffer_{},
			writeBuffer_{},
			size_{},
			readPosition_{},
			writePosition_{},
			dummyData_{},
			started_{},
			wordLength_{8}
	{

	}

	/**
	 * \brief SpiMasterLowLevel's destructor
	 *
	 * Does nothing if driver is already stopped. If it's not, performs forced stop of operation.
	 */

	~SpiMasterLowLevelInterruptBased() override;

	/**
	 * \brief Configures parameters of low-level SPI master driver.
	 *
	 * \param [in] mode is the desired SPI mode
	 * \param [in] clockFrequency is the desired clock frequency, Hz
	 * \param [in] wordLength selects word length, bits, [4; 16] or [minSpiWordLength; maxSpiWordLength]
	 * \param [in] lsbFirst selects whether MSB (false) or LSB (true) is transmitted first
	 * \param [in] dummyData is the dummy data that will be sent if write buffer of transfer is nullptr
	 *
	 * \return pair with return code (0 on success, error code otherwise) and real clock frequency; error codes:
	 * - EBADF - the driver is not started;
	 * - EBUSY - transfer is in progress;
	 * - error codes returned by configureSpi();
	 */

	std::pair<int, uint32_t> configure(devices::SpiMode mode, uint32_t clockFrequency, uint8_t wordLength,
			bool lsbFirst, uint32_t dummyData) override;

	/**
	 * \brief Interrupt handler
	 *
	 * \note this must not be called by user code
	 */

	void interruptHandler();

	/**
	 * \brief Starts low-level SPI master driver.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EBADF - the driver is not stopped;
	 */

	int start() override;

	/**
	 * \brief Starts asynchronous transfer.
	 *
	 * This function returns immediately. When the transfer is physically finished (either expected number of bytes were
	 * written and read or an error was detected), SpiMasterBase::transferCompleteEvent() will be executed.
	 *
	 * \param [in] spiMasterBase is a reference to SpiMasterBase object that will be notified about completed transfer
	 * \param [in] writeBuffer is the buffer with data that will be written, nullptr to send dummy data
	 * \param [out] readBuffer is the buffer with data that will be read, nullptr to ignore received data
	 * \param [in] size is the size of transfer (size of \a writeBuffer and/or \a readBuffer), bytes, must be even if
	 * number of data bits is in range (8; 16], divisible by 3 if number of data bits is in range (16; 24] or divisible
	 * by 4 if number of data bits is in range (24; 32]
	 *
	 * \return 0 on success, error code otherwise:
	 * - EBADF - the driver is not started;
	 * - EBUSY - transfer is in progress;
	 * - EINVAL - \a size is invalid;
	 */

	int startTransfer(devices::SpiMasterBase& spiMasterBase, const void* writeBuffer, void* readBuffer,
			size_t size) override;

	/**
	 * \brief Stops low-level SPI master driver.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EBADF - the driver is not started;
	 * - EBUSY - transfer is in progress;
	 */

	int stop() override;

private:

	/**
	 * \return true if driver is started, false otherwise
	 */

	bool isStarted() const
	{
		return started_;
	}

	/**
	 * \return true if transfer is in progress, false otherwise
	 */

	bool isTransferInProgress() const
	{
		return size_ != 0;
	}

	/**
	 * \brief Writes next item to SPI peripheral.
	 */

	void writeNextItem();

	/// reference to raw SPI peripheral
	const SpiPeripheral& spiPeripheral_;

	/// pointer to SpiMasterBase object associated with this one
	devices::SpiMasterBase* volatile spiMasterBase_;

	/// buffer to which the data is being written, nullptr to ignore received data
	uint8_t* volatile readBuffer_;

	/// buffer with data that is being transmitted, nullptr to send dummy data
	const uint8_t* volatile writeBuffer_;

	/// size of transfer (size of \a readBuffer_ and/or \a writeBuffer_), bytes
	volatile size_t size_;

	/// current position in \a readBuffer_
	volatile size_t readPosition_;

	/// current position in \a writeBuffer_
	volatile size_t writePosition_;

	/// dummy data that will be sent if write buffer of transfer is nullptr
	uint16_t dummyData_;

	/// true if driver is started, false otherwise
	bool started_;

	/// selected word length, bits, {8, 16}
	uint8_t wordLength_;
};

}	// namespace chip

}	// namespace distortos

#endif	// SOURCE_CHIP_STM32_PERIPHERALS_SPIV2_INCLUDE_DISTORTOS_CHIP_SPIMASTERLOWLEVELINTERRUPTBASED_HPP_
<commit_msg>Fix comment in STM32 SPIv2 SpiMasterLowLevelInterruptBased<commit_after>/**
 * \file
 * \brief SpiMasterLowLevelInterruptBased class header for SPIv2 in STM32
 *
 * \author Copyright (C) 2016-2018 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 */

#ifndef SOURCE_CHIP_STM32_PERIPHERALS_SPIV2_INCLUDE_DISTORTOS_CHIP_SPIMASTERLOWLEVELINTERRUPTBASED_HPP_
#define SOURCE_CHIP_STM32_PERIPHERALS_SPIV2_INCLUDE_DISTORTOS_CHIP_SPIMASTERLOWLEVELINTERRUPTBASED_HPP_

#include "distortos/devices/communication/SpiMasterLowLevel.hpp"

namespace distortos
{

namespace chip
{

class SpiPeripheral;

/**
 * SpiMasterLowLevelInterruptBased class is a low-level SPI master driver for SPIv2 in STM32.
 *
 * This driver uses interrupts for data transfers.
 *
 * \ingroup devices
 */

class SpiMasterLowLevelInterruptBased : public devices::SpiMasterLowLevel
{
public:

	/**
	 * \brief SpiMasterLowLevelInterruptBased's constructor
	 *
	 * \param [in] spiPeripheral is a reference to raw SPI peripheral
	 */

	constexpr explicit SpiMasterLowLevelInterruptBased(const SpiPeripheral& spiPeripheral) :
			spiPeripheral_{spiPeripheral},
			spiMasterBase_{},
			readBuffer_{},
			writeBuffer_{},
			size_{},
			readPosition_{},
			writePosition_{},
			dummyData_{},
			started_{},
			wordLength_{8}
	{

	}

	/**
	 * \brief SpiMasterLowLevelInterruptBased's destructor
	 *
	 * Does nothing if driver is already stopped. If it's not, performs forced stop of operation.
	 */

	~SpiMasterLowLevelInterruptBased() override;

	/**
	 * \brief Configures parameters of low-level SPI master driver.
	 *
	 * \param [in] mode is the desired SPI mode
	 * \param [in] clockFrequency is the desired clock frequency, Hz
	 * \param [in] wordLength selects word length, bits, [4; 16] or [minSpiWordLength; maxSpiWordLength]
	 * \param [in] lsbFirst selects whether MSB (false) or LSB (true) is transmitted first
	 * \param [in] dummyData is the dummy data that will be sent if write buffer of transfer is nullptr
	 *
	 * \return pair with return code (0 on success, error code otherwise) and real clock frequency; error codes:
	 * - EBADF - the driver is not started;
	 * - EBUSY - transfer is in progress;
	 * - error codes returned by configureSpi();
	 */

	std::pair<int, uint32_t> configure(devices::SpiMode mode, uint32_t clockFrequency, uint8_t wordLength,
			bool lsbFirst, uint32_t dummyData) override;

	/**
	 * \brief Interrupt handler
	 *
	 * \note this must not be called by user code
	 */

	void interruptHandler();

	/**
	 * \brief Starts low-level SPI master driver.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EBADF - the driver is not stopped;
	 */

	int start() override;

	/**
	 * \brief Starts asynchronous transfer.
	 *
	 * This function returns immediately. When the transfer is physically finished (either expected number of bytes were
	 * written and read or an error was detected), SpiMasterBase::transferCompleteEvent() will be executed.
	 *
	 * \param [in] spiMasterBase is a reference to SpiMasterBase object that will be notified about completed transfer
	 * \param [in] writeBuffer is the buffer with data that will be written, nullptr to send dummy data
	 * \param [out] readBuffer is the buffer with data that will be read, nullptr to ignore received data
	 * \param [in] size is the size of transfer (size of \a writeBuffer and/or \a readBuffer), bytes, must be even if
	 * number of data bits is in range (8; 16], divisible by 3 if number of data bits is in range (16; 24] or divisible
	 * by 4 if number of data bits is in range (24; 32]
	 *
	 * \return 0 on success, error code otherwise:
	 * - EBADF - the driver is not started;
	 * - EBUSY - transfer is in progress;
	 * - EINVAL - \a size is invalid;
	 */

	int startTransfer(devices::SpiMasterBase& spiMasterBase, const void* writeBuffer, void* readBuffer,
			size_t size) override;

	/**
	 * \brief Stops low-level SPI master driver.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EBADF - the driver is not started;
	 * - EBUSY - transfer is in progress;
	 */

	int stop() override;

private:

	/**
	 * \return true if driver is started, false otherwise
	 */

	bool isStarted() const
	{
		return started_;
	}

	/**
	 * \return true if transfer is in progress, false otherwise
	 */

	bool isTransferInProgress() const
	{
		return size_ != 0;
	}

	/**
	 * \brief Writes next item to SPI peripheral.
	 */

	void writeNextItem();

	/// reference to raw SPI peripheral
	const SpiPeripheral& spiPeripheral_;

	/// pointer to SpiMasterBase object associated with this one
	devices::SpiMasterBase* volatile spiMasterBase_;

	/// buffer to which the data is being written, nullptr to ignore received data
	uint8_t* volatile readBuffer_;

	/// buffer with data that is being transmitted, nullptr to send dummy data
	const uint8_t* volatile writeBuffer_;

	/// size of transfer (size of \a readBuffer_ and/or \a writeBuffer_), bytes
	volatile size_t size_;

	/// current position in \a readBuffer_
	volatile size_t readPosition_;

	/// current position in \a writeBuffer_
	volatile size_t writePosition_;

	/// dummy data that will be sent if write buffer of transfer is nullptr
	uint16_t dummyData_;

	/// true if driver is started, false otherwise
	bool started_;

	/// selected word length, bits, [4; 16] or [minSpiWordLength; maxSpiWordLength]
	uint8_t wordLength_;
};

}	// namespace chip

}	// namespace distortos

#endif	// SOURCE_CHIP_STM32_PERIPHERALS_SPIV2_INCLUDE_DISTORTOS_CHIP_SPIMASTERLOWLEVELINTERRUPTBASED_HPP_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: generatedtypeset.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 02:06:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef INCLUDED_codemaker_generatedtypeset_hxx
#define INCLUDED_codemaker_generatedtypeset_hxx

#include "rtl/string.hxx"

#include <hash_set>

/// @HTML

namespace codemaker {

/**
   A simple class to track which types have already been processed by a code
   maker.

This class is not multi-thread–safe.

 */
class GeneratedTypeSet {
public:
    GeneratedTypeSet() {}

    ~GeneratedTypeSet() {}

    /**
       Add a type to the set of generated types.

If the type was already present, nothing happens.

       @param type a UNO type registry name
     */
    void add(rtl::OString const & type) { m_set.insert(type); }

    /**
       Checks whether a given type has already been generated.

       @param type a UNO type registry name

       @return true iff the given type has already been generated
     */
    bool contains(rtl::OString const & type) const
    { return m_set.find(type) != m_set.end(); }

private:
    GeneratedTypeSet(GeneratedTypeSet &); // not implemented
    void operator =(GeneratedTypeSet); // not implemented

    std::hash_set< rtl::OString, rtl::OStringHash > m_set;
};

}

#endif
<commit_msg>INTEGRATION: CWS jsc3 (1.3.16); FILE MERGED 2006/01/20 13:00:05 jsc 1.3.16.1: #i56247# unify include guards<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: generatedtypeset.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-15 09:10:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX
#define INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX

#ifndef _RTL_STRING_HXX_
#include "rtl/string.hxx"
#endif

#include <hash_set>

/// @HTML

namespace codemaker {

/**
   A simple class to track which types have already been processed by a code
   maker.

This class is not multi-thread–safe.

 */
class GeneratedTypeSet {
public:
    GeneratedTypeSet() {}

    ~GeneratedTypeSet() {}

    /**
       Add a type to the set of generated types.

If the type was already present, nothing happens.

       @param type a UNO type registry name
     */
    void add(rtl::OString const & type) { m_set.insert(type); }

    /**
       Checks whether a given type has already been generated.

       @param type a UNO type registry name

       @return true iff the given type has already been generated
     */
    bool contains(rtl::OString const & type) const
    { return m_set.find(type) != m_set.end(); }

private:
    GeneratedTypeSet(GeneratedTypeSet &); // not implemented
    void operator =(GeneratedTypeSet); // not implemented

    std::hash_set< rtl::OString, rtl::OStringHash > m_set;
};

}

#endif // INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Resolver.h"

//--- standard modules used ----------------------------------------------------
#include "SysLog.h"
#include "Socket.h"
#include "Dbg.h"

//--- c-library modules used ---------------------------------------------------
#include <ctype.h> // for isdigit test..

#if !defined(WIN32)
#include <arpa/nameser.h>	// for inet_ntop gethostbyname etc.
#include <arpa/inet.h>		// for inet_ntop gethostbyname etc.
#include <resolv.h>			// for inet_ntop gethostbyname etc.
#include <netdb.h>			// for gethostbyname etc.
#include <sys/socket.h>		// for gethostbyname etc.
#include <netinet/in.h>		// for gethostbyname etc.
#else
#include <io.h>
#endif

#define	INET_ADDRSTRLEN		16	// "ddd.ddd.ddd.ddd\0"
/* Define following even if IPv6 not supported, so we can always allocate
   an adequately-sized buffer, without #ifdefs in the code. */
#ifndef INET6_ADDRSTRLEN
/* $$.Ic INET6_ADDRSTRLEN$$ */
#define	INET6_ADDRSTRLEN	46	/* max size of IPv6 address string:
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"
1234567890123456789012345678901234567890123456 */
#endif

#if defined(__sun)
#define SystemSpecific(className)		_NAME2_(Sun, className)
#elif defined(__linux__)
#define SystemSpecific(className)		_NAME2_(Linux, className)
#elif defined(WIN32)
#define SystemSpecific(className)		_NAME2_(Win32, className)
#else //we suggest Linux (for posix)
#define SystemSpecific(className)		_NAME2_(Linux, className)
#endif

class EXPORTDECL_FOUNDATION SystemSpecific(Resolver): public Resolver
{
public:
	SystemSpecific(Resolver)() {}
	~SystemSpecific(Resolver)() {}

	virtual bool DNS2IP(String &ipAddress, const String &dnsName);
	virtual bool IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr);
};

//---- Resolver ----------------------------------------------------------------

String Resolver::DNS2IPAddress( const String &dnsName )
{
	StartTrace(Resolver.DNS2IPAddress);
	// no need to change Server IP address if localhost (?)
	if ( (dnsName.Length() <= 0) || isdigit( dnsName.At(0) ) ) {
		return dnsName;
	} else {
		String ipAddress;
		SystemSpecific(Resolver) sysResolver;

		if ( sysResolver.DNS2IP(ipAddress, dnsName) ) {
			return ipAddress;
		}

		String logMsg("Resolving of DNS Name<");
		logMsg << dnsName << "> failed";
		SysLog::Error(logMsg);
	}
	return "127.0.0.1";
}

String Resolver::IPAddress2DNS( const String &ipAddress )
{
	unsigned long addr = EndPoint::MakeInetAddr(ipAddress);
	String dnsName("localhost");

	SystemSpecific(Resolver) sysResolver;

	if ( !sysResolver.IP2DNS(dnsName, ipAddress, addr) ) {
		String logMsg("Resolving of IPAddress <");
		logMsg << ipAddress << "> failed";
		SysLog::Error(logMsg);
	}
	dnsName.ToLower();
	return dnsName;
}

Resolver::Resolver() {}
Resolver::~Resolver() {}

//--- system dependent subclasses ----
#if defined(__sun)
extern "C" const char *inet_ntop __P((int af, const void *src, char *dst, size_t s));

bool SunResolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent he;
	const int bufSz = 8192;
	char buf[bufSz];
	int err = 0;

	if (gethostbyname_r(dnsName, &he, buf, bufSz, &err)) {
		char **pptr;
		char str[INET6_ADDRSTRLEN];
		pptr = he.h_addr_list;
		ipAddress = inet_ntop(he.h_addrtype, *pptr, str, sizeof(str));
		return true;
	}
	return false;
}

bool SunResolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent he;
	int err;

	const int bufSz = 8192;
	char buf[bufSz];

	if (gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &he, buf, bufSz, &err)) {
		dnsName = he.h_name;
		return true;
	}
	return false;
}

#endif

#if defined(__linux__)

bool LinuxResolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent he;
	struct hostent *res;
	const int bufSz = 8192;
	char buf[bufSz];
	int err;

	if (gethostbyname_r(dnsName, &he, buf, bufSz, &res, &err) == 0) {
		char **pptr;
		char str[INET6_ADDRSTRLEN];
		pptr = he.h_addr_list;
		ipAddress = inet_ntop(he.h_addrtype, *pptr, str, sizeof(str));
		return true;
	}
	return false;
}

bool LinuxResolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent he;
	struct hostent *res = 0;
	int err = 0;

	const int bufSz = 8192;
	char buf[bufSz];

	int result = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &he, buf, bufSz, &res, &err);
	if ( result == 0 && err == NETDB_SUCCESS) {
		dnsName = res->h_name;
		return true;
	}
	return false;
}

#endif

#if defined(WIN32)

bool Win32Resolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent   *ptrHe;

	if ( ptrHe = gethostbyname(dnsName)) { // in windows thread scope
		struct in_addr *iaddr = (struct in_addr *) * ptrHe->h_addr_list;
		ipAddress = inet_ntoa(*iaddr);
		return true;
	}
	// for tracing possible errors
	// long error= WSAGetLastError ();

	return false;
}

bool Win32Resolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent *hePtr;
	if (hePtr = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) {
		dnsName = (hePtr->h_name);
		return true;
	}
	return false;
}

#endif
<commit_msg>Resolver for Mac OS X<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Resolver.h"

//--- standard modules used ----------------------------------------------------
#include "SysLog.h"
#include "Socket.h"
#include "Dbg.h"

//--- c-library modules used ---------------------------------------------------
#include <ctype.h> // for isdigit test..

#if !defined(WIN32)
#include <arpa/nameser.h>	// for inet_ntop gethostbyname etc.
#include <arpa/inet.h>		// for inet_ntop gethostbyname etc.
#include <resolv.h>			// for inet_ntop gethostbyname etc.
#include <netdb.h>			// for gethostbyname etc.
#include <sys/socket.h>		// for gethostbyname etc.
#include <netinet/in.h>		// for gethostbyname etc.
#else
#include <io.h>
#endif

#define	INET_ADDRSTRLEN		16	// "ddd.ddd.ddd.ddd\0"
/* Define following even if IPv6 not supported, so we can always allocate
   an adequately-sized buffer, without #ifdefs in the code. */
#ifndef INET6_ADDRSTRLEN
/* $$.Ic INET6_ADDRSTRLEN$$ */
#define	INET6_ADDRSTRLEN	46	/* max size of IPv6 address string:
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"
1234567890123456789012345678901234567890123456 */
#endif

#if defined(__sun)
#define SystemSpecific(className)		_NAME2_(Sun, className)
#elif defined(WIN32)
#define SystemSpecific(className)		_NAME2_(Win32, className)
#elif defined(__APPLE__)
#define SystemSpecific(className)		_NAME2_(Apple, className)
#else //we suggest Linux (for posix)
#define SystemSpecific(className)		_NAME2_(Linux, className)
#endif

class EXPORTDECL_FOUNDATION SystemSpecific(Resolver): public Resolver
{
public:
	SystemSpecific(Resolver)() {}
	~SystemSpecific(Resolver)() {}

	virtual bool DNS2IP(String &ipAddress, const String &dnsName);
	virtual bool IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr);
};

//---- Resolver ----------------------------------------------------------------

String Resolver::DNS2IPAddress( const String &dnsName )
{
	StartTrace(Resolver.DNS2IPAddress);
	// no need to change Server IP address if localhost (?)
	if ( (dnsName.Length() <= 0) || isdigit( dnsName.At(0) ) ) {
		return dnsName;
	} else {
		String ipAddress;
		SystemSpecific(Resolver) sysResolver;

		if ( sysResolver.DNS2IP(ipAddress, dnsName) ) {
			return ipAddress;
		}

		String logMsg("Resolving of DNS Name<");
		logMsg << dnsName << "> failed";
		SysLog::Error(logMsg);
	}
	return "127.0.0.1";
}

String Resolver::IPAddress2DNS( const String &ipAddress )
{
	unsigned long addr = EndPoint::MakeInetAddr(ipAddress);
	String dnsName("localhost");

	SystemSpecific(Resolver) sysResolver;

	if ( !sysResolver.IP2DNS(dnsName, ipAddress, addr) ) {
		String logMsg("Resolving of IPAddress <");
		logMsg << ipAddress << "> failed";
		SysLog::Error(logMsg);
	}
	dnsName.ToLower();
	return dnsName;
}

Resolver::Resolver() {}
Resolver::~Resolver() {}

//--- system dependent subclasses ----
#if defined(__sun)
extern "C" const char *inet_ntop __P((int af, const void *src, char *dst, size_t s));

bool SunResolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent he;
	const int bufSz = 8192;
	char buf[bufSz];
	int err = 0;

	if (gethostbyname_r(dnsName, &he, buf, bufSz, &err)) {
		char **pptr;
		char str[INET6_ADDRSTRLEN];
		pptr = he.h_addr_list;
		ipAddress = inet_ntop(he.h_addrtype, *pptr, str, sizeof(str));
		return true;
	}
	return false;
}

bool SunResolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent he;
	int err;

	const int bufSz = 8192;
	char buf[bufSz];

	if (gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &he, buf, bufSz, &err)) {
		dnsName = he.h_name;
		return true;
	}
	return false;
}

#elif defined(WIN32)

bool Win32Resolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent   *ptrHe;

	if ( ptrHe = gethostbyname(dnsName)) { // in windows thread scope
		struct in_addr *iaddr = (struct in_addr *) * ptrHe->h_addr_list;
		ipAddress = inet_ntoa(*iaddr);
		return true;
	}
	// for tracing possible errors
	// long error= WSAGetLastError ();

	return false;
}

bool Win32Resolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent *hePtr;
	if (hePtr = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) {
		dnsName = (hePtr->h_name);
		return true;
	}
	return false;
}

#elif defined(__APPLE__)

bool AppleResolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent   *ptrHe;
	int error_num = 0;

	if (ptrHe = getipnodebyname(dnsName, AF_INET, AI_DEFAULT, &error_num)) {
		struct in_addr *iaddr = (struct in_addr *) * ptrHe->h_addr_list;
		ipAddress = inet_ntoa(*iaddr);
		freehostent(ptrHe);
		return true;
	}

	return false;
}

bool AppleResolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent *ptrHe;
	int error_num = 0;
	if (ptrHe = getipnodebyaddr((char *)&addr, sizeof(addr), AF_INET, &error_num)) {
		dnsName = (ptrHe->h_name);
		freehostent(ptrHe);
		return true;
	}
	return false;
}

#else

bool LinuxResolver::DNS2IP(String &ipAddress, const String &dnsName)
{
	struct hostent he;
	struct hostent *res;
	const int bufSz = 8192;
	char buf[bufSz];
	int err;

	if (gethostbyname_r(dnsName, &he, buf, bufSz, &res, &err) == 0) {
		char **pptr;
		char str[INET6_ADDRSTRLEN];
		pptr = he.h_addr_list;
		ipAddress = inet_ntop(he.h_addrtype, *pptr, str, sizeof(str));
		return true;
	}
	return false;
}

bool LinuxResolver::IP2DNS(String &dnsName, const String &ipAddress, unsigned long addr)
{
	struct hostent he;
	struct hostent *res = 0;
	int err = 0;

	const int bufSz = 8192;
	char buf[bufSz];

	int result = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &he, buf, bufSz, &res, &err);
	if ( result == 0 && err == NETDB_SUCCESS) {
		dnsName = res->h_name;
		return true;
	}
	return false;
}

#endif

<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <vector>
#include <random>
#include <memory>
#include <string>
#include <cmath>

#include <macros.hh>
#include <vec.hh>
#include <pretty_printers.hh>
#include <loss_functions.hh>
#include <dataset.hh>
#include <timer.hh>
#include <model.hh>
#include <classifier.hh>
#include <lvec.hh>
#include <task_executor.hh>

namespace opt {

template <typename Model, typename Generator>
class parsgd : public classifier::base_iterative_clf<Model, Generator> {
public:

  typedef Model model_type;
  typedef Generator generator_type;

  parsgd(const Model &model,
         size_t nrounds,
         const std::shared_ptr<Generator> &prng,
         size_t nworkers,
         bool do_locking,
         size_t t_offset = 0,
         double c0 = 1.0,
         bool verbose = false)
    : classifier::base_iterative_clf<Model, Generator>(model, nrounds, prng, verbose),
      t_offset_(t_offset),
      c0_(c0),
      nworkers_(nworkers),
      do_locking_(do_locking)
  {
    ALWAYS_ASSERT(c0_ > 0.0);
    ALWAYS_ASSERT(nworkers_ > 0);
  }

  void
  fit(const dataset& d, bool keep_histories=false)
  {
    dataset transformed(this->model_.transform(d));
    if (this->verbose_)
      std::cerr << "[INFO] fitting x_shape: "
                << transformed.get_x_shape() << std::endl;
    timer tt;
    transformed.materialize();
    if (this->verbose_) {
      std::cerr << "[INFO] materializing took " << tt.lap_ms() << " ms" << std::endl;
      std::cerr << "[INFO] max transformed norm is " << transformed.max_x_norm() << std::endl;
    }

    const auto shape = transformed.get_x_shape();
    this->training_sz_ = shape.first;
    const auto feature_counts = transformed.feature_counts();

    //if (this->verbose_) {
    //  for (size_t i = 0; i < feature_counts.size(); i++)
    //    if (!feature_counts[i])
    //      std::cerr << "[WARN] feature idx " << i << " is never used!" << std::endl;
    //}

    this->state_.reset(new standard_lvec<double>(shape.second));
    this->w_history_.clear();
    if (keep_histories)
      this->w_history_.reserve(this->nrounds_);

    // setup executors
    std::vector< std::unique_ptr<task_executor_thread<bool>> > workers;
    const size_t actual_nworkers =
      (this->training_sz_ < nworkers_) ? 1 : nworkers_;
    if (this->verbose_) {
      std::cerr << "[INFO] keep_histories: " << keep_histories << std::endl;
      std::cerr << "[INFO] actual_nworkers: " << actual_nworkers << std::endl;
      std::cerr << "[INFO] starting eta_t: "
                << c0_ / (this->model_.get_lambda() * (1 + this->t_offset_))
                << std::endl;
    }
    for (size_t i = 0; i < actual_nworkers; i++)
      workers.emplace_back(new task_executor_thread<bool>);
    const size_t nelems_per_worker =
      this->training_sz_ / actual_nworkers;
    tt.lap();
    std::vector<std::future<bool>> futures;
    timer tt1;
    for (size_t round = 0; round < this->nrounds_; round++) {
      const auto permutation = transformed.permute(*this->prng_);
      const auto it_end = permutation.end();
      const auto it_beg = permutation.begin();

      // Uncomment (and comment out above) to remove randomness each round
      // (testing purposes)
      /**
      const auto it_end = transformed.end();
      const auto it_beg = transformed.begin();
      */

      tt1.lap();
      for (size_t i = 0; i < actual_nworkers; i++)
        futures.emplace_back(
          workers[i]->enq(
            std::bind(
              do_locking_ ? &parsgd::work<true> : &parsgd::work<false>,
              this,
              i,
              round+1,
              this->training_sz_,
              std::ref(feature_counts),
              it_beg + i*nelems_per_worker,
              ((i+1)==actual_nworkers) ?
                it_end : (it_beg + (i+1)*nelems_per_worker))));
      for (auto &f : futures)
        f.wait();
      futures.clear();
      if (keep_histories) {
        state_->unsafesnapshot(this->model_.weightvec());
        this->w_history_.emplace_back(
            round + 1, tt.elapsed_usec(), this->model_.weightvec());
      }

      if (this->verbose_) {
        std::cerr << "[INFO] finished round " << (round+1) << " in "
                  << tt1.lap_ms() << " ms" << std::endl;
        state_->unsafesnapshot(this->model_.weightvec());
        std::cerr << "[INFO] current risk: "
                  << this->model_.empirical_risk(transformed) << std::endl;
      }
    }
    state_->unsafesnapshot(this->model_.weightvec());
    for (auto &w : workers)
      w->shutdown();
    ALWAYS_ASSERT( this->model_.weightvec().size() == shape.second );
  }

  inline size_t get_t_offset() const { return t_offset_; }
  inline double get_c0() const { return c0_; }
  inline size_t get_nworkers() const { return nworkers_; }
  inline bool get_do_locking() const { return do_locking_; }

  std::string name() const OVERRIDE { return "parsgd"; }

  std::map<std::string, std::string>
  mapconfig() const OVERRIDE
  {
    std::map<std::string, std::string> m =
      classifier::base_iterative_clf<Model, Generator>::mapconfig();
    m["clf_name"]       = name();
    m["clf_t_offset"]   = std::to_string(t_offset_);
    m["clf_c0"]         = std::to_string(c0_);
    m["clf_nworkers"]   = std::to_string(nworkers_);
    m["clf_do_locking"] = std::to_string(do_locking_);
    return m;
  }

private:

  template <bool DoLocking>
  static inline double
  dot(const vec_t &x, standard_lvec<double> &b)
  {
    double s = 0.0;
    const auto inner_it_end = x.end();
    for (auto inner_it = x.begin();
         inner_it != inner_it_end; ++inner_it) {
      const size_t feature_idx = inner_it.tell();
      if (DoLocking)
        s += (*inner_it) * b.lockandread(feature_idx);
      else
        s += (*inner_it) * b.unsaferead(feature_idx);
    }
    return s;
  }

  template <bool DoLocking>
  bool
  work(size_t workerid,
       size_t round,
       size_t dataset_size,
       const std::vector<size_t> &feature_counts,
       dataset::const_iterator begin,
       dataset::const_iterator end)
  {
    const double dataset_sizef = double(dataset_size);
    size_t i = 1;
    for (auto it = begin; it != end; ++it, ++i) {
      const size_t t_eff = (round-1)*dataset_size + i + t_offset_;
      const double eta_t = c0_ / (this->model_.get_lambda() * t_eff);
      const auto &x = *it.first();
      const double dloss = this->model_.get_lossfn().dloss(
          *it.second(), dot<DoLocking>(x, *state_.get()));
      const auto inner_it_end = x.end();
      for (auto inner_it = x.begin();
           inner_it != inner_it_end; ++inner_it) {
        const size_t feature_idx = inner_it.tell();
        const double w_old = state_->unsaferead(feature_idx);
        assert(feature_counts[feature_idx]);
        const double w_new =
          (1.0 - eta_t * this->model_.get_lambda() * dataset_sizef /
           double(feature_counts[feature_idx])) * w_old
          - eta_t * dloss * (*inner_it);
        if (DoLocking)
          state_->writeandunlock(feature_idx, w_new);
        else
          state_->unsafewrite(feature_idx, w_new);
      }
      //std::cerr << "[worker " << workerid << ", round " << round << ", item " << i << "]" << std::endl;
    }
    return false;
  }

  size_t t_offset_;
  double c0_;
  size_t nworkers_;
  bool do_locking_;
  std::unique_ptr<standard_lvec<double>> state_;
};

} // namespace opt
<commit_msg>don't spawn off workers for single threaded<commit_after>#pragma once

#include <cassert>
#include <vector>
#include <random>
#include <memory>
#include <string>
#include <cmath>

#include <macros.hh>
#include <vec.hh>
#include <pretty_printers.hh>
#include <loss_functions.hh>
#include <dataset.hh>
#include <timer.hh>
#include <model.hh>
#include <classifier.hh>
#include <lvec.hh>
#include <task_executor.hh>

namespace opt {

template <typename Model, typename Generator>
class parsgd : public classifier::base_iterative_clf<Model, Generator> {
public:

  typedef Model model_type;
  typedef Generator generator_type;

  parsgd(const Model &model,
         size_t nrounds,
         const std::shared_ptr<Generator> &prng,
         size_t nworkers,
         bool do_locking,
         size_t t_offset = 0,
         double c0 = 1.0,
         bool verbose = false)
    : classifier::base_iterative_clf<Model, Generator>(model, nrounds, prng, verbose),
      t_offset_(t_offset),
      c0_(c0),
      nworkers_(nworkers),
      do_locking_(do_locking)
  {
    ALWAYS_ASSERT(c0_ > 0.0);
    ALWAYS_ASSERT(nworkers_ > 0);
  }

  void
  fit(const dataset& d, bool keep_histories=false)
  {
    dataset transformed(this->model_.transform(d));
    if (this->verbose_)
      std::cerr << "[INFO] fitting x_shape: "
                << transformed.get_x_shape() << std::endl;
    timer tt;
    transformed.materialize();
    if (this->verbose_) {
      std::cerr << "[INFO] materializing took " << tt.lap_ms() << " ms" << std::endl;
      std::cerr << "[INFO] max transformed norm is " << transformed.max_x_norm() << std::endl;
    }

    const auto shape = transformed.get_x_shape();
    this->training_sz_ = shape.first;
    const auto feature_counts = transformed.feature_counts();

    //if (this->verbose_) {
    //  for (size_t i = 0; i < feature_counts.size(); i++)
    //    if (!feature_counts[i])
    //      std::cerr << "[WARN] feature idx " << i << " is never used!" << std::endl;
    //}

    this->state_.reset(new standard_lvec<double>(shape.second));
    this->w_history_.clear();
    if (keep_histories)
      this->w_history_.reserve(this->nrounds_);

    // setup executors
    std::vector< std::unique_ptr<task_executor_thread<bool>> > workers;
    const size_t actual_nworkers =
      (this->training_sz_ < nworkers_) ? 1 : nworkers_;
    if (this->verbose_) {
      std::cerr << "[INFO] keep_histories: " << keep_histories << std::endl;
      std::cerr << "[INFO] actual_nworkers: " << actual_nworkers << std::endl;
      std::cerr << "[INFO] starting eta_t: "
                << c0_ / (this->model_.get_lambda() * (1 + this->t_offset_))
                << std::endl;
    }
    if (actual_nworkers > 1)
      for (size_t i = 0; i < actual_nworkers; i++)
        workers.emplace_back(new task_executor_thread<bool>);
    const size_t nelems_per_worker =
      this->training_sz_ / actual_nworkers;
    tt.lap();
    std::vector<std::future<bool>> futures;
    timer tt1;
    for (size_t round = 0; round < this->nrounds_; round++) {
      const auto permutation = transformed.permute(*this->prng_);
      const auto it_end = permutation.end();
      const auto it_beg = permutation.begin();

      // Uncomment (and comment out above) to remove randomness each round
      // (testing purposes)
      /**
      const auto it_end = transformed.end();
      const auto it_beg = transformed.begin();
      */

      tt1.lap();
      if (actual_nworkers > 1) {
        for (size_t i = 0; i < actual_nworkers; i++)
          futures.emplace_back(
            workers[i]->enq(
              std::bind(
                do_locking_ ? &parsgd::work<true> : &parsgd::work<false>,
                this,
                i,
                round+1,
                this->training_sz_,
                std::ref(feature_counts),
                it_beg + i*nelems_per_worker,
                ((i+1)==actual_nworkers) ?
                  it_end : (it_beg + (i+1)*nelems_per_worker))));
        for (auto &f : futures)
          f.wait();
        futures.clear();
      } else {
        if (do_locking_)
          work<true>(0, round+1, this->training_sz_, feature_counts, it_beg, it_end);
        else
          work<false>(0, round+1, this->training_sz_, feature_counts, it_beg, it_end);
      }

      if (keep_histories) {
        state_->unsafesnapshot(this->model_.weightvec());
        this->w_history_.emplace_back(
            round + 1, tt.elapsed_usec(), this->model_.weightvec());
      }

      if (this->verbose_) {
        std::cerr << "[INFO] finished round " << (round+1) << " in "
                  << tt1.lap_ms() << " ms" << std::endl;
        state_->unsafesnapshot(this->model_.weightvec());
        std::cerr << "[INFO] current risk: "
                  << this->model_.empirical_risk(transformed) << std::endl;
      }
    }
    state_->unsafesnapshot(this->model_.weightvec());
    for (auto &w : workers)
      w->shutdown();
    ALWAYS_ASSERT( this->model_.weightvec().size() == shape.second );
  }

  inline size_t get_t_offset() const { return t_offset_; }
  inline double get_c0() const { return c0_; }
  inline size_t get_nworkers() const { return nworkers_; }
  inline bool get_do_locking() const { return do_locking_; }

  std::string name() const OVERRIDE { return "parsgd"; }

  std::map<std::string, std::string>
  mapconfig() const OVERRIDE
  {
    std::map<std::string, std::string> m =
      classifier::base_iterative_clf<Model, Generator>::mapconfig();
    m["clf_name"]       = name();
    m["clf_t_offset"]   = std::to_string(t_offset_);
    m["clf_c0"]         = std::to_string(c0_);
    m["clf_nworkers"]   = std::to_string(nworkers_);
    m["clf_do_locking"] = std::to_string(do_locking_);
    return m;
  }

private:

  template <bool DoLocking>
  static inline double
  dot(const vec_t &x, standard_lvec<double> &b)
  {
    double s = 0.0;
    const auto inner_it_end = x.end();
    for (auto inner_it = x.begin();
         inner_it != inner_it_end; ++inner_it) {
      const size_t feature_idx = inner_it.tell();
      if (DoLocking)
        s += (*inner_it) * b.lockandread(feature_idx);
      else
        s += (*inner_it) * b.unsaferead(feature_idx);
    }
    return s;
  }

  template <bool DoLocking>
  bool
  work(size_t workerid,
       size_t round,
       size_t dataset_size,
       const std::vector<size_t> &feature_counts,
       dataset::const_iterator begin,
       dataset::const_iterator end)
  {
    const double dataset_sizef = double(dataset_size);
    size_t i = 1;
    //std::cerr << "[worker " << workerid << ", round " << round << ", elems" << size_t(end-begin) << "]" << std::endl;
    for (auto it = begin; it != end; ++it, ++i) {
      const size_t t_eff = (round-1)*dataset_size + i + t_offset_;
      const double eta_t = c0_ / (this->model_.get_lambda() * t_eff);
      const auto &x = *it.first();
      const double dloss = this->model_.get_lossfn().dloss(
          *it.second(), dot<DoLocking>(x, *state_.get()));
      const auto inner_it_end = x.end();
      for (auto inner_it = x.begin();
           inner_it != inner_it_end; ++inner_it) {
        const size_t feature_idx = inner_it.tell();
        const double w_old = state_->unsaferead(feature_idx);
        assert(feature_counts[feature_idx]);
        const double w_new =
          (1.0 - eta_t * this->model_.get_lambda() * dataset_sizef /
           double(feature_counts[feature_idx])) * w_old
          - eta_t * dloss * (*inner_it);
        if (DoLocking)
          state_->writeandunlock(feature_idx, w_new);
        else
          state_->unsafewrite(feature_idx, w_new);
      }
      //std::cerr << "[worker " << workerid << ", round " << round << ", item " << i << "]" << std::endl;
    }
    return false;
  }

  size_t t_offset_;
  double c0_;
  size_t nworkers_;
  bool do_locking_;
  std::unique_ptr<standard_lvec<double>> state_;
};

} // namespace opt
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ODriver.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 16:22:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#ifndef _CONNECTIVITY_ODBC_ODRIVER_HXX_
#include "odbc/ODriver.hxx"
#endif
#ifndef _CONNECTIVITY_ODBC_OCONNECTION_HXX_
#include "odbc/OConnection.hxx"
#endif
#ifndef _CONNECTIVITY_ODBC_OFUNCTIONS_HXX_
#include "odbc/OFunctions.hxx"
#endif
#ifndef _CONNECTIVITY_OTOOLS_HXX_
#include "odbc/OTools.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include "connectivity/dbexception.hxx"
#endif

using namespace connectivity::odbc;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
// --------------------------------------------------------------------------------
ODBCDriver::ODBCDriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
    :ODriver_BASE(m_aMutex)
    ,m_xORB(_rxFactory)
    ,m_pDriverHandle(SQL_NULL_HANDLE)
{
}
// --------------------------------------------------------------------------------
void ODBCDriver::disposing()
{
    ::osl::MutexGuard aGuard(m_aMutex);

    for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
    {
        Reference< XComponent > xComp(i->get(), UNO_QUERY);
        if (xComp.is())
            xComp->dispose();
    }
    m_xConnections.clear();

    ODriver_BASE::disposing();
}

// static ServiceInfo
//------------------------------------------------------------------------------
rtl::OUString ODBCDriver::getImplementationName_Static(  ) throw(RuntimeException)
{
    return rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.ODBCDriver");
        // this name is referenced in the configuration and in the odbc.xml
        // Please take care when changing it.
}

typedef Sequence< ::rtl::OUString > SS;
//------------------------------------------------------------------------------
SS ODBCDriver::getSupportedServiceNames_Static(  ) throw (RuntimeException)
{
    SS aSNS( 1 );
    aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
    return aSNS;
}

//------------------------------------------------------------------
::rtl::OUString SAL_CALL ODBCDriver::getImplementationName(  ) throw(RuntimeException)
{
    return getImplementationName_Static();
}

//------------------------------------------------------------------
sal_Bool SAL_CALL ODBCDriver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
{
    SS aSupported(getSupportedServiceNames());
    const ::rtl::OUString* pSupported = aSupported.getConstArray();
    const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
    for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
        ;

    return pSupported != pEnd;
}

//------------------------------------------------------------------
SS SAL_CALL ODBCDriver::getSupportedServiceNames(  ) throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

// --------------------------------------------------------------------------------
Reference< XConnection > SAL_CALL ODBCDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
{
    if ( ! acceptsURL(url) )
        return NULL;

    if(!m_pDriverHandle)
    {
        ::rtl::OUString aPath;
        if(!EnvironmentHandle(aPath))
            throw SQLException(aPath,*this,::rtl::OUString(),1000,Any());
    }
    OConnection* pCon = new OConnection(m_pDriverHandle,this);
    Reference< XConnection > xCon = pCon;
    pCon->Construct(url,info);
    m_xConnections.push_back(WeakReferenceHelper(*pCon));

    return xCon;
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL ODBCDriver::acceptsURL( const ::rtl::OUString& url )
        throw(SQLException, RuntimeException)
{
    return (!url.compareTo(::rtl::OUString::createFromAscii("sdbc:odbc:"),10));
}
// --------------------------------------------------------------------------------
Sequence< DriverPropertyInfo > SAL_CALL ODBCDriver::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw(SQLException, RuntimeException)
{
    if ( acceptsURL(url) )
    {
        ::std::vector< DriverPropertyInfo > aDriverInfo;

        Sequence< ::rtl::OUString > aBooleanValues(2);
        aBooleanValues[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
        aBooleanValues[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) );

        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharSet"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharSet of the database."))
                ,sal_False
                ,::rtl::OUString()
                ,Sequence< ::rtl::OUString >())
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseCatalog"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Use catalog for file-based databases."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SystemDriverSettings"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Driver settings."))
                ,sal_False
                ,::rtl::OUString()
                ,Sequence< ::rtl::OUString >())
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParameterNameSubstitution"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Change named parameters with '?'."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IgnoreDriverPrivileges"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Ignore the privileges from the database driver."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsAutoRetrievingEnabled"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Retrieve generated values."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoRetrievingStatement"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Auto-increment statement."))
                ,sal_False
                ,::rtl::OUString()
                ,Sequence< ::rtl::OUString >())
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GenerateASBeforeCorrelationName"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Generate AS before table correlation names."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) )
                ,aBooleanValues)
                );
        return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
    }
    ::dbtools::throwGenericSQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid URL!")) ,*this);
    return Sequence< DriverPropertyInfo >();
}
// --------------------------------------------------------------------------------
sal_Int32 SAL_CALL ODBCDriver::getMajorVersion(  ) throw(RuntimeException)
{
    return 1;
}
// --------------------------------------------------------------------------------
sal_Int32 SAL_CALL ODBCDriver::getMinorVersion(  ) throw(RuntimeException)
{
    return 0;
}
// --------------------------------------------------------------------------------
//-----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS dba24e_SRC680 (1.16.136); FILE MERGED 2007/12/03 11:09:55 lla 1.16.136.1: #i78988# add EscapeDateTime property<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ODriver.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: vg $ $Date: 2008-01-29 08:38:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#ifndef _CONNECTIVITY_ODBC_ODRIVER_HXX_
#include "odbc/ODriver.hxx"
#endif
#ifndef _CONNECTIVITY_ODBC_OCONNECTION_HXX_
#include "odbc/OConnection.hxx"
#endif
#ifndef _CONNECTIVITY_ODBC_OFUNCTIONS_HXX_
#include "odbc/OFunctions.hxx"
#endif
#ifndef _CONNECTIVITY_OTOOLS_HXX_
#include "odbc/OTools.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include "connectivity/dbexception.hxx"
#endif

using namespace connectivity::odbc;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
// --------------------------------------------------------------------------------
ODBCDriver::ODBCDriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
    :ODriver_BASE(m_aMutex)
    ,m_xORB(_rxFactory)
    ,m_pDriverHandle(SQL_NULL_HANDLE)
{
}
// --------------------------------------------------------------------------------
void ODBCDriver::disposing()
{
    ::osl::MutexGuard aGuard(m_aMutex);

    for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
    {
        Reference< XComponent > xComp(i->get(), UNO_QUERY);
        if (xComp.is())
            xComp->dispose();
    }
    m_xConnections.clear();

    ODriver_BASE::disposing();
}

// static ServiceInfo
//------------------------------------------------------------------------------
rtl::OUString ODBCDriver::getImplementationName_Static(  ) throw(RuntimeException)
{
    return rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.ODBCDriver");
        // this name is referenced in the configuration and in the odbc.xml
        // Please take care when changing it.
}

typedef Sequence< ::rtl::OUString > SS;
//------------------------------------------------------------------------------
SS ODBCDriver::getSupportedServiceNames_Static(  ) throw (RuntimeException)
{
    SS aSNS( 1 );
    aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
    return aSNS;
}

//------------------------------------------------------------------
::rtl::OUString SAL_CALL ODBCDriver::getImplementationName(  ) throw(RuntimeException)
{
    return getImplementationName_Static();
}

//------------------------------------------------------------------
sal_Bool SAL_CALL ODBCDriver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
{
    SS aSupported(getSupportedServiceNames());
    const ::rtl::OUString* pSupported = aSupported.getConstArray();
    const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
    for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
        ;

    return pSupported != pEnd;
}

//------------------------------------------------------------------
SS SAL_CALL ODBCDriver::getSupportedServiceNames(  ) throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

// --------------------------------------------------------------------------------
Reference< XConnection > SAL_CALL ODBCDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
{
    if ( ! acceptsURL(url) )
        return NULL;

    if(!m_pDriverHandle)
    {
        ::rtl::OUString aPath;
        if(!EnvironmentHandle(aPath))
            throw SQLException(aPath,*this,::rtl::OUString(),1000,Any());
    }
    OConnection* pCon = new OConnection(m_pDriverHandle,this);
    Reference< XConnection > xCon = pCon;
    pCon->Construct(url,info);
    m_xConnections.push_back(WeakReferenceHelper(*pCon));

    return xCon;
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL ODBCDriver::acceptsURL( const ::rtl::OUString& url )
        throw(SQLException, RuntimeException)
{
    return (!url.compareTo(::rtl::OUString::createFromAscii("sdbc:odbc:"),10));
}
// --------------------------------------------------------------------------------
Sequence< DriverPropertyInfo > SAL_CALL ODBCDriver::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw(SQLException, RuntimeException)
{
    if ( acceptsURL(url) )
    {
        ::std::vector< DriverPropertyInfo > aDriverInfo;

        Sequence< ::rtl::OUString > aBooleanValues(2);
        aBooleanValues[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
        aBooleanValues[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) );

        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharSet"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharSet of the database."))
                ,sal_False
                ,::rtl::OUString()
                ,Sequence< ::rtl::OUString >())
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseCatalog"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Use catalog for file-based databases."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SystemDriverSettings"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Driver settings."))
                ,sal_False
                ,::rtl::OUString()
                ,Sequence< ::rtl::OUString >())
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParameterNameSubstitution"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Change named parameters with '?'."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IgnoreDriverPrivileges"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Ignore the privileges from the database driver."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsAutoRetrievingEnabled"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Retrieve generated values."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoRetrievingStatement"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Auto-increment statement."))
                ,sal_False
                ,::rtl::OUString()
                ,Sequence< ::rtl::OUString >())
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GenerateASBeforeCorrelationName"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Generate AS before table correlation names."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) )
                ,aBooleanValues)
                );
        aDriverInfo.push_back(DriverPropertyInfo(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EscapeDateTime"))
                ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Escape date time format."))
                ,sal_False
                ,::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) )
                ,aBooleanValues)
                );

        return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
    }
    ::dbtools::throwGenericSQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid URL!")) ,*this);
    return Sequence< DriverPropertyInfo >();
}
// --------------------------------------------------------------------------------
sal_Int32 SAL_CALL ODBCDriver::getMajorVersion(  ) throw(RuntimeException)
{
    return 1;
}
// --------------------------------------------------------------------------------
sal_Int32 SAL_CALL ODBCDriver::getMinorVersion(  ) throw(RuntimeException)
{
    return 0;
}
// --------------------------------------------------------------------------------
//-----------------------------------------------------------------------------

<|endoftext|>