<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "clustering/administration/tables/table_config.hpp"

#include "clustering/administration/datum_adapter.hpp"
#include "clustering/administration/tables/elect_director.hpp"
#include "clustering/administration/tables/lookup.hpp"
#include "http/http.hpp"   /* for percent_escaped_string() [RSI(reql_admin) remove] */

counted_t<const ql::datum_t> convert_table_config_shard_to_datum(
        const table_config_t::shard_t &shard) {
    ql::datum_object_builder_t builder;

    if (shard.split_point) {
        builder.overwrite("split_point", make_counted<const ql::datum_t>(
            percent_escaped_string(key_to_unescaped_str(*shard.split_point))
            ));
    }

    builder.overwrite("replicas", convert_set_to_datum<name_string_t>(
            &convert_name_to_datum,
            shard.replica_names));

    builder.overwrite("directors", convert_vector_to_datum<name_string_t>(
            &convert_name_to_datum,
            shard.director_names));

    return std::move(builder).to_counted();
}

bool convert_table_config_shard_from_datum(
        counted_t<const ql::datum_t> datum,
        table_config_t::shard_t *shard_out,
        std::string *error_out) {
    converter_from_datum_object_t converter;
    if (!converter.init(datum, error_out)) {
        return false;
    }

    counted_t<const ql::datum_t> split_point_datum;
    converter.get_optional("split_point", &split_point_datum);
    if (split_point_datum.has()) {
        if (split_point_datum->get_type() != ql::datum_t::R_STR) {
            *error_out = "In `split_point`: Expected a string, got " +
                split_point_datum->print();
            return false;
        }
        std::string str;
        if (!percent_unescape_string(split_point_datum->as_str().to_std(), &str)) {
            *error_out = "Split point should be a percent-encoded string.";
            return false;
        }
        store_key_t split_point_value(str);
        shard_out->split_point = boost::optional<store_key_t>(split_point_value);
    } else {
        shard_out->split_point = boost::optional<store_key_t>();
    }

    counted_t<const ql::datum_t> replica_names_datum;
    if (!converter.get("replicas", &replica_names_datum, error_out)) {
        return false;
    }
    if (replica_names_datum->get_type() != ql::datum_t::R_ARRAY) {
        *error_out = "In `replicas`: Expected an array, got " +
            replica_names_datum->print();
        return false;
    }
    if (!convert_set_from_datum<name_string_t>(
            [] (counted_t<const ql::datum_t> datum2, name_string_t *val2_out,
                    std::string *error2_out) {
                return convert_name_from_datum(datum2, "server name", val2_out,
                    error2_out);
            },
            false,   /* raise an error if a server appears twice */
            replica_names_datum, &shard_out->replica_names, error_out)) {
        *error_out = "In `replicas`: " + *error_out;
        return false;
    }
    if (shard_out->replica_names.empty()) {
        *error_out = "You must specify at least one replica for each shard.";
        return false;
    }

    counted_t<const ql::datum_t> director_names_datum;
    if (!converter.get("directors", &director_names_datum, error_out)) {
        return false;
    }
    if (!convert_vector_from_datum<name_string_t>(
            [] (counted_t<const ql::datum_t> datum2, name_string_t *val2_out,
                    std::string *error2_out) {
                return convert_name_from_datum(datum2, "server name", val2_out,
                    error2_out);
            },
            director_names_datum,
            &shard_out->director_names, error_out)) {
        *error_out = "In `directors`: " + *error_out;
        return false;
    }
    if (shard_out->director_names.empty()) {
        *error_out = "You must specify at least one director for each shard.";
        return false;
    }

    if (!converter.check_no_extra_keys(error_out)) {
        return false;
    }

    std::set<name_string_t> director_names_seen;
    for (const name_string_t &director : shard_out->director_names) {
        if (shard_out->replica_names.count(director) != 1) {
            *error_out = strprintf("Server `%s` appears in `directors` but not in "
                "`replicas`.", director.c_str());
            return false;
        }
        if (director_names_seen.count(director) != 0) {
            *error_out = strprintf("In `directors`: Server `%s` appears multiple times.",
                director.c_str());
            return false;
        }
        director_names_seen.insert(director);
    }

    return true;
}

/* This is separate from `convert_table_config_and_name_to_datum` because it needs to be
publicly exposed so it can be used to create the return value of `table.reconfigure()`.
*/
counted_t<const ql::datum_t> convert_table_config_to_datum(
        const table_config_t &config) {
    ql::datum_object_builder_t builder;
    builder.overwrite("shards",
        convert_vector_to_datum<table_config_t::shard_t>(
            &convert_table_config_shard_to_datum,
            config.shards));
    return std::move(builder).to_counted();
}

counted_t<const ql::datum_t> convert_table_config_and_name_to_datum(
        const table_config_t &config,
        name_string_t db_name,
        name_string_t table_name,
        namespace_id_t uuid) {
    counted_t<const ql::datum_t> start = convert_table_config_to_datum(config);
    ql::datum_object_builder_t builder(start->as_object());
    builder.overwrite("name", convert_db_and_table_to_datum(db_name, table_name));
    builder.overwrite("uuid", convert_uuid_to_datum(uuid));
    return std::move(builder).to_counted();
}

bool convert_table_config_and_name_from_datum(
        counted_t<const ql::datum_t> datum,
        name_string_t *db_name_out,
        name_string_t *table_name_out,
        namespace_id_t *uuid_out,
        table_config_t *config_out,
        std::string *error_out) {
    /* In practice, the input will always be an object and the `name` field will always
    be valid, because `artificial_table_t` will check those thing before passing the
    row to `table_config_artificial_table_backend_t`. But we check them anyway for
    consistency. */
    converter_from_datum_object_t converter;
    if (!converter.init(datum, error_out)) {
        return false;
    }

    counted_t<const ql::datum_t> name_datum;
    if (!converter.get("name", &name_datum, error_out)) {
        return false;
    }
    name_string_t db_name_value, table_name_value;
    if (!convert_db_and_table_from_datum(name_datum, db_name_out, table_name_out,
            error_out)) {
        *error_out = "In `name`: " + *error_out;
        return false;
    }

    counted_t<const ql::datum_t> uuid_datum;
    if (!converter.get("uuid", &uuid_datum, error_out)) {
        return false;
    }
    if (!convert_uuid_from_datum(uuid_datum, uuid_out, error_out)) {
        *error_out = "In `uuid`: " + *error_out;
        return false;
    }

    counted_t<const ql::datum_t> shards_datum;
    if (!converter.get("shards", &shards_datum, error_out)) {
        return false;
    }
    if (!convert_vector_from_datum<table_config_t::shard_t>(
            &convert_table_config_shard_from_datum, shards_datum,
            &config_out->shards, error_out)) {
        *error_out = "In `shards`: " + *error_out;
        return false;
    }

    if (!converter.check_no_extra_keys(error_out)) {
        return false;
    }

    store_key_t prev_split_point = store_key_t::min();
    for (size_t i = 0; i < config_out->shards.size() - 1; i++) {
        if (!config_out->shards[i].split_point) {
            *error_out = "Every shard except the last must have a split point.";
            return false;
        }
        store_key_t split_point = *config_out->shards[i].split_point;
        if (split_point < prev_split_point) {
            *error_out = "Shard split points must be monotonically increasing.";
            return false;
        }
        if (split_point == prev_split_point) {
            *error_out = "Shards must not be empty; i.e. split points must be distinct.";
            return false;
        }
    }
    if (config_out->shards.back().split_point) {
        *error_out = "The last shard must not have a split point.";
        return false;
    }

    return true;
}

std::string table_config_artificial_table_backend_t::get_primary_key_name() {
    return "name";
}

bool table_config_artificial_table_backend_t::read_all_primary_keys(
        UNUSED signal_t *interruptor,
        std::vector<counted_t<const ql::datum_t> > *keys_out,
        std::string *error_out) {
    on_thread_t thread_switcher(home_thread());
    keys_out->clear();
    cow_ptr_t<namespaces_semilattice_metadata_t> md = table_sl_view->get();
    for (auto it = md->namespaces.begin();
              it != md->namespaces.end();
            ++it) {
        if (it->second.is_deleted()) {
            continue;
        }
        if (it->second.get_ref().database.in_conflict() ||
                it->second.get_ref().name.in_conflict()) {
            /* TODO: Handle conflict differently */
            *error_out = "Metadata is in conflict";
            return false;
        }
        database_id_t db_id = it->second.get_ref().database.get_ref();
        auto jt = database_sl_view->get().databases.find(db_id);
        guarantee(jt != database_sl_view->get().databases.end());
        /* RSI(reql_admin): This can actually happen. We should handle this case. */
        guarantee(!jt->second.is_deleted());
        if (jt->second.get_ref().name.in_conflict()) {
            *error_out = "Metadata is in conflict";
            return false;
        }
        name_string_t db_name = jt->second.get_ref().name.get_ref();
        name_string_t table_name = it->second.get_ref().name.get_ref();
        /* TODO: How to handle table name collisions? */
        keys_out->push_back(convert_db_and_table_to_datum(db_name, table_name));
    }
    return true;
}

bool table_config_artificial_table_backend_t::read_row(
        counted_t<const ql::datum_t> primary_key,
        UNUSED signal_t *interruptor,
        counted_t<const ql::datum_t> *row_out,
        std::string *error_out) {
    on_thread_t thread_switcher(home_thread());
    cow_ptr_t<namespaces_semilattice_metadata_t> md = table_sl_view->get();
    name_string_t db_name, table_name;
    std::string dummy_error;
    namespace_id_t table_id;
    if (!convert_db_and_table_from_datum(primary_key, &db_name, &table_name,
                                               &dummy_error)) {
        /* If the primary key was not a valid table name, then it must refer to a
        nonexistent row.
        TODO: Would it be more user-friendly to error instead? */
        table_id = nil_uuid();
    } else {
        table_id = lookup_table_with_database(db_name, table_name,
            database_sl_view->get(), md);
    }
    if (table_id == nil_uuid()) {
        *row_out = counted_t<const ql::datum_t>();
        return true;
    }

    auto it = md->namespaces.find(table_id);
    if (it->second.get_ref().replication_info.in_conflict()) {
        *error_out = "Metadata is in conflict.";
        return false;
    }
    table_config_t config =
        it->second.get_ref().replication_info.get_ref().config;
    *row_out = convert_table_config_and_name_to_datum(
        config, db_name, table_name, it->first);
    return true;
}

bool table_config_artificial_table_backend_t::write_row(
        counted_t<const ql::datum_t> primary_key,
        counted_t<const ql::datum_t> new_value,
        UNUSED signal_t *interruptor,
        std::string *error_out) {
    if (!new_value.has()) {
        *error_out = "It's illegal to delete from the `rethinkdb.table_config` table. "
            "To delete a table, use `r.table_drop()`.";
        return false;
    }
    on_thread_t thread_switcher(home_thread());
    cow_ptr_t<namespaces_semilattice_metadata_t> md = table_sl_view->get();
    name_string_t db_name, table_name;
    std::string dummy_error;
    namespace_id_t table_id;
    if (!convert_db_and_table_from_datum(primary_key, &db_name, &table_name,
                                         &dummy_error)) {
        table_id = nil_uuid();
    } else {
        table_id = lookup_table_with_database(db_name, table_name,
            database_sl_view->get(), md);
    }
    if (table_id == nil_uuid()) {
        *error_out = "It's illegal to insert into the `rethinkdb.table_config` "
            "table. To create a table, use `r.table_create()`.";
        return false;
    }
    cow_ptr_t<namespaces_semilattice_metadata_t>::change_t md_change(&md);
    auto it = md_change.get()->namespaces.find(table_id);
    table_replication_info_t replication_info;
    name_string_t new_db_name, new_table_name;
    namespace_id_t new_table_id;
    if (!convert_table_config_and_name_from_datum(new_value,
            &new_db_name, &new_table_name, &new_table_id,
            &replication_info.config, error_out)) {
        *error_out = "The change you're trying to make to "
            "`rethinkdb.table_config` has the wrong format. " + *error_out;
        return false;
    }
    guarantee(new_db_name == db_name && new_table_name == table_name,
        "artificial_table_t should ensure that primary key doesn't change");
    if (new_table_id != table_id) {
        *error_out = "It's illegal to change a table's `uuid` field.";
        return false;
    }
    replication_info.chosen_directors =
        table_elect_directors(replication_info.config, name_client);
    it->second.get_mutable()->replication_info =
        it->second.get_ref().replication_info.make_resolving_version(
            replication_info, my_machine_id);
    table_sl_view->join(md);
    return true;
}

<commit_msg>Clarify RSI comment<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "clustering/administration/tables/table_config.hpp"

#include "clustering/administration/datum_adapter.hpp"
#include "clustering/administration/tables/elect_director.hpp"
#include "clustering/administration/tables/lookup.hpp"
/* RSI(reql_admin): After #2895 is fixed, don't include "http/http.hpp" */
#include "http/http.hpp"   /* for percent_escaped_string() */

counted_t<const ql::datum_t> convert_table_config_shard_to_datum(
        const table_config_t::shard_t &shard) {
    ql::datum_object_builder_t builder;

    if (shard.split_point) {
        builder.overwrite("split_point", make_counted<const ql::datum_t>(
            percent_escaped_string(key_to_unescaped_str(*shard.split_point))
            ));
    }

    builder.overwrite("replicas", convert_set_to_datum<name_string_t>(
            &convert_name_to_datum,
            shard.replica_names));

    builder.overwrite("directors", convert_vector_to_datum<name_string_t>(
            &convert_name_to_datum,
            shard.director_names));

    return std::move(builder).to_counted();
}

bool convert_table_config_shard_from_datum(
        counted_t<const ql::datum_t> datum,
        table_config_t::shard_t *shard_out,
        std::string *error_out) {
    converter_from_datum_object_t converter;
    if (!converter.init(datum, error_out)) {
        return false;
    }

    counted_t<const ql::datum_t> split_point_datum;
    converter.get_optional("split_point", &split_point_datum);
    if (split_point_datum.has()) {
        if (split_point_datum->get_type() != ql::datum_t::R_STR) {
            *error_out = "In `split_point`: Expected a string, got " +
                split_point_datum->print();
            return false;
        }
        std::string str;
        if (!percent_unescape_string(split_point_datum->as_str().to_std(), &str)) {
            *error_out = "Split point should be a percent-encoded string.";
            return false;
        }
        store_key_t split_point_value(str);
        shard_out->split_point = boost::optional<store_key_t>(split_point_value);
    } else {
        shard_out->split_point = boost::optional<store_key_t>();
    }

    counted_t<const ql::datum_t> replica_names_datum;
    if (!converter.get("replicas", &replica_names_datum, error_out)) {
        return false;
    }
    if (replica_names_datum->get_type() != ql::datum_t::R_ARRAY) {
        *error_out = "In `replicas`: Expected an array, got " +
            replica_names_datum->print();
        return false;
    }
    if (!convert_set_from_datum<name_string_t>(
            [] (counted_t<const ql::datum_t> datum2, name_string_t *val2_out,
                    std::string *error2_out) {
                return convert_name_from_datum(datum2, "server name", val2_out,
                    error2_out);
            },
            false,   /* raise an error if a server appears twice */
            replica_names_datum, &shard_out->replica_names, error_out)) {
        *error_out = "In `replicas`: " + *error_out;
        return false;
    }
    if (shard_out->replica_names.empty()) {
        *error_out = "You must specify at least one replica for each shard.";
        return false;
    }

    counted_t<const ql::datum_t> director_names_datum;
    if (!converter.get("directors", &director_names_datum, error_out)) {
        return false;
    }
    if (!convert_vector_from_datum<name_string_t>(
            [] (counted_t<const ql::datum_t> datum2, name_string_t *val2_out,
                    std::string *error2_out) {
                return convert_name_from_datum(datum2, "server name", val2_out,
                    error2_out);
            },
            director_names_datum,
            &shard_out->director_names, error_out)) {
        *error_out = "In `directors`: " + *error_out;
        return false;
    }
    if (shard_out->director_names.empty()) {
        *error_out = "You must specify at least one director for each shard.";
        return false;
    }

    if (!converter.check_no_extra_keys(error_out)) {
        return false;
    }

    std::set<name_string_t> director_names_seen;
    for (const name_string_t &director : shard_out->director_names) {
        if (shard_out->replica_names.count(director) != 1) {
            *error_out = strprintf("Server `%s` appears in `directors` but not in "
                "`replicas`.", director.c_str());
            return false;
        }
        if (director_names_seen.count(director) != 0) {
            *error_out = strprintf("In `directors`: Server `%s` appears multiple times.",
                director.c_str());
            return false;
        }
        director_names_seen.insert(director);
    }

    return true;
}

/* This is separate from `convert_table_config_and_name_to_datum` because it needs to be
publicly exposed so it can be used to create the return value of `table.reconfigure()`.
*/
counted_t<const ql::datum_t> convert_table_config_to_datum(
        const table_config_t &config) {
    ql::datum_object_builder_t builder;
    builder.overwrite("shards",
        convert_vector_to_datum<table_config_t::shard_t>(
            &convert_table_config_shard_to_datum,
            config.shards));
    return std::move(builder).to_counted();
}

counted_t<const ql::datum_t> convert_table_config_and_name_to_datum(
        const table_config_t &config,
        name_string_t db_name,
        name_string_t table_name,
        namespace_id_t uuid) {
    counted_t<const ql::datum_t> start = convert_table_config_to_datum(config);
    ql::datum_object_builder_t builder(start->as_object());
    builder.overwrite("name", convert_db_and_table_to_datum(db_name, table_name));
    builder.overwrite("uuid", convert_uuid_to_datum(uuid));
    return std::move(builder).to_counted();
}

bool convert_table_config_and_name_from_datum(
        counted_t<const ql::datum_t> datum,
        name_string_t *db_name_out,
        name_string_t *table_name_out,
        namespace_id_t *uuid_out,
        table_config_t *config_out,
        std::string *error_out) {
    /* In practice, the input will always be an object and the `name` field will always
    be valid, because `artificial_table_t` will check those thing before passing the
    row to `table_config_artificial_table_backend_t`. But we check them anyway for
    consistency. */
    converter_from_datum_object_t converter;
    if (!converter.init(datum, error_out)) {
        return false;
    }

    counted_t<const ql::datum_t> name_datum;
    if (!converter.get("name", &name_datum, error_out)) {
        return false;
    }
    name_string_t db_name_value, table_name_value;
    if (!convert_db_and_table_from_datum(name_datum, db_name_out, table_name_out,
            error_out)) {
        *error_out = "In `name`: " + *error_out;
        return false;
    }

    counted_t<const ql::datum_t> uuid_datum;
    if (!converter.get("uuid", &uuid_datum, error_out)) {
        return false;
    }
    if (!convert_uuid_from_datum(uuid_datum, uuid_out, error_out)) {
        *error_out = "In `uuid`: " + *error_out;
        return false;
    }

    counted_t<const ql::datum_t> shards_datum;
    if (!converter.get("shards", &shards_datum, error_out)) {
        return false;
    }
    if (!convert_vector_from_datum<table_config_t::shard_t>(
            &convert_table_config_shard_from_datum, shards_datum,
            &config_out->shards, error_out)) {
        *error_out = "In `shards`: " + *error_out;
        return false;
    }

    if (!converter.check_no_extra_keys(error_out)) {
        return false;
    }

    store_key_t prev_split_point = store_key_t::min();
    for (size_t i = 0; i < config_out->shards.size() - 1; i++) {
        if (!config_out->shards[i].split_point) {
            *error_out = "Every shard except the last must have a split point.";
            return false;
        }
        store_key_t split_point = *config_out->shards[i].split_point;
        if (split_point < prev_split_point) {
            *error_out = "Shard split points must be monotonically increasing.";
            return false;
        }
        if (split_point == prev_split_point) {
            *error_out = "Shards must not be empty; i.e. split points must be distinct.";
            return false;
        }
    }
    if (config_out->shards.back().split_point) {
        *error_out = "The last shard must not have a split point.";
        return false;
    }

    return true;
}

std::string table_config_artificial_table_backend_t::get_primary_key_name() {
    return "name";
}

bool table_config_artificial_table_backend_t::read_all_primary_keys(
        UNUSED signal_t *interruptor,
        std::vector<counted_t<const ql::datum_t> > *keys_out,
        std::string *error_out) {
    on_thread_t thread_switcher(home_thread());
    keys_out->clear();
    cow_ptr_t<namespaces_semilattice_metadata_t> md = table_sl_view->get();
    for (auto it = md->namespaces.begin();
              it != md->namespaces.end();
            ++it) {
        if (it->second.is_deleted()) {
            continue;
        }
        if (it->second.get_ref().database.in_conflict() ||
                it->second.get_ref().name.in_conflict()) {
            /* TODO: Handle conflict differently */
            *error_out = "Metadata is in conflict";
            return false;
        }
        database_id_t db_id = it->second.get_ref().database.get_ref();
        auto jt = database_sl_view->get().databases.find(db_id);
        guarantee(jt != database_sl_view->get().databases.end());
        /* RSI(reql_admin): This can actually happen. We should handle this case. */
        guarantee(!jt->second.is_deleted());
        if (jt->second.get_ref().name.in_conflict()) {
            *error_out = "Metadata is in conflict";
            return false;
        }
        name_string_t db_name = jt->second.get_ref().name.get_ref();
        name_string_t table_name = it->second.get_ref().name.get_ref();
        /* TODO: How to handle table name collisions? */
        keys_out->push_back(convert_db_and_table_to_datum(db_name, table_name));
    }
    return true;
}

bool table_config_artificial_table_backend_t::read_row(
        counted_t<const ql::datum_t> primary_key,
        UNUSED signal_t *interruptor,
        counted_t<const ql::datum_t> *row_out,
        std::string *error_out) {
    on_thread_t thread_switcher(home_thread());
    cow_ptr_t<namespaces_semilattice_metadata_t> md = table_sl_view->get();
    name_string_t db_name, table_name;
    std::string dummy_error;
    namespace_id_t table_id;
    if (!convert_db_and_table_from_datum(primary_key, &db_name, &table_name,
                                               &dummy_error)) {
        /* If the primary key was not a valid table name, then it must refer to a
        nonexistent row.
        TODO: Would it be more user-friendly to error instead? */
        table_id = nil_uuid();
    } else {
        table_id = lookup_table_with_database(db_name, table_name,
            database_sl_view->get(), md);
    }
    if (table_id == nil_uuid()) {
        *row_out = counted_t<const ql::datum_t>();
        return true;
    }

    auto it = md->namespaces.find(table_id);
    if (it->second.get_ref().replication_info.in_conflict()) {
        *error_out = "Metadata is in conflict.";
        return false;
    }
    table_config_t config =
        it->second.get_ref().replication_info.get_ref().config;
    *row_out = convert_table_config_and_name_to_datum(
        config, db_name, table_name, it->first);
    return true;
}

bool table_config_artificial_table_backend_t::write_row(
        counted_t<const ql::datum_t> primary_key,
        counted_t<const ql::datum_t> new_value,
        UNUSED signal_t *interruptor,
        std::string *error_out) {
    if (!new_value.has()) {
        *error_out = "It's illegal to delete from the `rethinkdb.table_config` table. "
            "To delete a table, use `r.table_drop()`.";
        return false;
    }
    on_thread_t thread_switcher(home_thread());
    cow_ptr_t<namespaces_semilattice_metadata_t> md = table_sl_view->get();
    name_string_t db_name, table_name;
    std::string dummy_error;
    namespace_id_t table_id;
    if (!convert_db_and_table_from_datum(primary_key, &db_name, &table_name,
                                         &dummy_error)) {
        table_id = nil_uuid();
    } else {
        table_id = lookup_table_with_database(db_name, table_name,
            database_sl_view->get(), md);
    }
    if (table_id == nil_uuid()) {
        *error_out = "It's illegal to insert into the `rethinkdb.table_config` "
            "table. To create a table, use `r.table_create()`.";
        return false;
    }
    cow_ptr_t<namespaces_semilattice_metadata_t>::change_t md_change(&md);
    auto it = md_change.get()->namespaces.find(table_id);
    table_replication_info_t replication_info;
    name_string_t new_db_name, new_table_name;
    namespace_id_t new_table_id;
    if (!convert_table_config_and_name_from_datum(new_value,
            &new_db_name, &new_table_name, &new_table_id,
            &replication_info.config, error_out)) {
        *error_out = "The change you're trying to make to "
            "`rethinkdb.table_config` has the wrong format. " + *error_out;
        return false;
    }
    guarantee(new_db_name == db_name && new_table_name == table_name,
        "artificial_table_t should ensure that primary key doesn't change");
    if (new_table_id != table_id) {
        *error_out = "It's illegal to change a table's `uuid` field.";
        return false;
    }
    replication_info.chosen_directors =
        table_elect_directors(replication_info.config, name_client);
    it->second.get_mutable()->replication_info =
        it->second.get_ref().replication_info.make_resolving_version(
            replication_info, my_machine_id);
    table_sl_view->join(md);
    return true;
}

<|endoftext|>


<commit_before>/**
 * Note: This file contains implementations for different header files.
 */
#include <cstring>
#include <czmq.h>
#include "Graph/Serialize.hpp"

char* serializeExtAttrId(const std::string& entityId, const std::string& key, size_t* calculatedLength) {
    return serializeExtAttrId(entityId.data(), entityId.size(), key.data(), key.size(), calculatedLength);
}

char* serializeBasicAttributes(const std::string& key, const std::string& value, size_t* actualSize) {
    size_t keySize = key.size();
    size_t valueSize = value.size();
    *actualSize = keySize + valueSize + 2;
    char* res = new char[*actualSize];
    char* curPos = res;
    //Write key
    memcpy(curPos, key.c_str(), keySize);
    curPos += keySize;
    *curPos = 0x1F;
    curPos++;
    //Write value
    memcpy(curPos, value.c_str(), valueSize);
    curPos += valueSize;
    *curPos = 0x1E;
    curPos++;
    return res;
}

char* serializeExtAttrId(const char* entityId,
                         size_t entityIdLength,
                         const char* key,
                         size_t keyLength,
                         size_t* calculatedLength
                        ) {
    *calculatedLength = entityIdLength + keyLength + 1;
    char* buf = new char[*calculatedLength];
    memcpy(buf, entityId, entityIdLength);
    buf[entityIdLength] = '\x1D';
    memcpy(buf + entityIdLength + 1, key, keyLength);
    return buf;
}

void serializeEdgeId(const std::string& sourceNodeId,
                     const std::string& targetNodeId,
                     const std::string& edgeType,
                     size_t* calculatedLength,
                     char** forwardTarget,
                     char** backwardTarget) {
    serializeEdgeId(
        sourceNodeId.data(),
        sourceNodeId.size(),
        targetNodeId.data(),
        targetNodeId.size(),
        edgeType.data(),
        edgeType.size(),
        calculatedLength,
        forwardTarget,
        backwardTarget
    );
}

size_t calculateEdgeIdSize(size_t activeNodeSize, size_t passiveNodeSize, size_t typeLength) {
    return activeNodeSize + passiveNodeSize + typeLength + 2;
}

void serializeEdgeId(const char* sourceNodeId,
                   size_t sourceNodeIdLength,
                   const char* targetNodeId,
                   size_t targetNodeIdLength,
                   const char* type,
                   size_t typeLength,
                   char* forward,
                   char* backward
                  ) {
    //--Serialize--
    //Type
    memcpy(forward, type, typeLength);
    memcpy(backward, type, typeLength);
    //Type separator
    forward[typeLength] = '\x1F';
    backward[typeLength] = '\x1F';
    //Primary node
    memcpy(forward + typeLength + 1, sourceNodeId, sourceNodeIdLength);
    memcpy(backward + typeLength + 1, targetNodeId, targetNodeIdLength);
    //Node separator
    size_t forwardPos = typeLength + 1 + sourceNodeIdLength;
    size_t backwardPos = typeLength + 1 + targetNodeIdLength;
    forward[forwardPos] = '\x0E';
    backward[backwardPos] = '\x0F';
    //Secondary node
    memcpy(forward + forwardPos + 1, targetNodeId, targetNodeIdLength);
    memcpy(backward + backwardPos + 1, sourceNodeId, sourceNodeIdLength);
}

void serializeEdgeId(const char* sourceNodeId,
                   size_t sourceNodeIdLength,
                   const char* targetNodeId,
                   size_t targetNodeIdLength,
                   const char* type,
                   size_t typeLength,
                   size_t* calculatedLength,
                   char** forwardTarget,
                   char** backwardTarget
                  ) {
    *calculatedLength = calculateEdgeIdSize(sourceNodeIdLength, targetNodeIdLength, typeLength);
    char* forward = new char[*calculatedLength];
    char* backward = new char[*calculatedLength];
    *forwardTarget = forward;
    *backwardTarget = backward;
    //Call the function that generates the IDs in the existing buffers
    serializeEdgeId(sourceNodeId,
                   sourceNodeIdLength,
                   targetNodeId,
                   targetNodeIdLength,
                   type,
                   typeLength,
                   forward,
                   backward);
}

void sendEdge(void* socket,
              const std::string& sourceNodeId,
              const std::string& targetNodeId,
              const std::string& edgeType,
              const char* basicAttributes,
              size_t basicAttributeLength,
              bool last) {
    size_t edgeKeyLength = calculateEdgeIdSize(sourceNodeId.size(), targetNodeId.size(), edgeType.size());
    //Create msgs with the appropriate sizes...
    zmq_msg_t activeKeyMsg;
    zmq_msg_t passiveKeyMsg;
    zmq_msg_init_size(&activeKeyMsg, edgeKeyLength);
    zmq_msg_init_size(&passiveKeyMsg, edgeKeyLength);
    // ...and serialize directly to their buffers
    serializeEdgeId(sourceNodeId.data(),
                   sourceNodeId.size(),
                   targetNodeId.data(),
                   targetNodeId.size(),
                   edgeType.data(),
                   edgeType.size(),
                   (char*)zmq_msg_data(&activeKeyMsg),
                   (char*)zmq_msg_data(&passiveKeyMsg));
    std::string str((char*)zmq_msg_data(&activeKeyMsg), edgeKeyLength);
    printf(str.c_str());
    //Send the data
    zmq_msg_send(&activeKeyMsg, socket, ZMQ_SNDMORE);
    zmq_send(socket, (void*)basicAttributes, basicAttributeLength, ZMQ_SNDMORE);
    zmq_msg_send(&passiveKeyMsg, socket, ZMQ_SNDMORE);
    zmq_send(socket, (void*)basicAttributes, basicAttributeLength, (last ? 0 : ZMQ_SNDMORE));
}<commit_msg>Remove debug stuff<commit_after>/**
 * Note: This file contains implementations for different header files.
 */
#include <cstring>
#include <czmq.h>
#include "Graph/Serialize.hpp"

char* serializeExtAttrId(const std::string& entityId, const std::string& key, size_t* calculatedLength) {
    return serializeExtAttrId(entityId.data(), entityId.size(), key.data(), key.size(), calculatedLength);
}

char* serializeBasicAttributes(const std::string& key, const std::string& value, size_t* actualSize) {
    size_t keySize = key.size();
    size_t valueSize = value.size();
    *actualSize = keySize + valueSize + 2;
    char* res = new char[*actualSize];
    char* curPos = res;
    //Write key
    memcpy(curPos, key.c_str(), keySize);
    curPos += keySize;
    *curPos = 0x1F;
    curPos++;
    //Write value
    memcpy(curPos, value.c_str(), valueSize);
    curPos += valueSize;
    *curPos = 0x1E;
    curPos++;
    return res;
}

char* serializeExtAttrId(const char* entityId,
                         size_t entityIdLength,
                         const char* key,
                         size_t keyLength,
                         size_t* calculatedLength
                        ) {
    *calculatedLength = entityIdLength + keyLength + 1;
    char* buf = new char[*calculatedLength];
    memcpy(buf, entityId, entityIdLength);
    buf[entityIdLength] = '\x1D';
    memcpy(buf + entityIdLength + 1, key, keyLength);
    return buf;
}

void serializeEdgeId(const std::string& sourceNodeId,
                     const std::string& targetNodeId,
                     const std::string& edgeType,
                     size_t* calculatedLength,
                     char** forwardTarget,
                     char** backwardTarget) {
    serializeEdgeId(
        sourceNodeId.data(),
        sourceNodeId.size(),
        targetNodeId.data(),
        targetNodeId.size(),
        edgeType.data(),
        edgeType.size(),
        calculatedLength,
        forwardTarget,
        backwardTarget
    );
}

size_t calculateEdgeIdSize(size_t activeNodeSize, size_t passiveNodeSize, size_t typeLength) {
    return activeNodeSize + passiveNodeSize + typeLength + 2;
}

void serializeEdgeId(const char* sourceNodeId,
                   size_t sourceNodeIdLength,
                   const char* targetNodeId,
                   size_t targetNodeIdLength,
                   const char* type,
                   size_t typeLength,
                   char* forward,
                   char* backward
                  ) {
    //--Serialize--
    //Type
    memcpy(forward, type, typeLength);
    memcpy(backward, type, typeLength);
    //Type separator
    forward[typeLength] = '\x1F';
    backward[typeLength] = '\x1F';
    //Primary node
    memcpy(forward + typeLength + 1, sourceNodeId, sourceNodeIdLength);
    memcpy(backward + typeLength + 1, targetNodeId, targetNodeIdLength);
    //Node separator
    size_t forwardPos = typeLength + 1 + sourceNodeIdLength;
    size_t backwardPos = typeLength + 1 + targetNodeIdLength;
    forward[forwardPos] = '\x0E';
    backward[backwardPos] = '\x0F';
    //Secondary node
    memcpy(forward + forwardPos + 1, targetNodeId, targetNodeIdLength);
    memcpy(backward + backwardPos + 1, sourceNodeId, sourceNodeIdLength);
}

void serializeEdgeId(const char* sourceNodeId,
                   size_t sourceNodeIdLength,
                   const char* targetNodeId,
                   size_t targetNodeIdLength,
                   const char* type,
                   size_t typeLength,
                   size_t* calculatedLength,
                   char** forwardTarget,
                   char** backwardTarget
                  ) {
    *calculatedLength = calculateEdgeIdSize(sourceNodeIdLength, targetNodeIdLength, typeLength);
    char* forward = new char[*calculatedLength];
    char* backward = new char[*calculatedLength];
    *forwardTarget = forward;
    *backwardTarget = backward;
    //Call the function that generates the IDs in the existing buffers
    serializeEdgeId(sourceNodeId,
                   sourceNodeIdLength,
                   targetNodeId,
                   targetNodeIdLength,
                   type,
                   typeLength,
                   forward,
                   backward);
}

void sendEdge(void* socket,
              const std::string& sourceNodeId,
              const std::string& targetNodeId,
              const std::string& edgeType,
              const char* basicAttributes,
              size_t basicAttributeLength,
              bool last) {
    size_t edgeKeyLength = calculateEdgeIdSize(sourceNodeId.size(), targetNodeId.size(), edgeType.size());
    //Create msgs with the appropriate sizes...
    zmq_msg_t activeKeyMsg;
    zmq_msg_t passiveKeyMsg;
    zmq_msg_init_size(&activeKeyMsg, edgeKeyLength);
    zmq_msg_init_size(&passiveKeyMsg, edgeKeyLength);
    // ...and serialize directly to their buffers
    serializeEdgeId(sourceNodeId.data(),
                   sourceNodeId.size(),
                   targetNodeId.data(),
                   targetNodeId.size(),
                   edgeType.data(),
                   edgeType.size(),
                   (char*)zmq_msg_data(&activeKeyMsg),
                   (char*)zmq_msg_data(&passiveKeyMsg));
    //Send the data
    zmq_msg_send(&activeKeyMsg, socket, ZMQ_SNDMORE);
    zmq_send(socket, (void*)basicAttributes, basicAttributeLength, ZMQ_SNDMORE);
    zmq_msg_send(&passiveKeyMsg, socket, ZMQ_SNDMORE);
    zmq_send(socket, (void*)basicAttributes, basicAttributeLength, (last ? 0 : ZMQ_SNDMORE));
}<|endoftext|>


<commit_before>#include <muduo/base/Logging.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/SocketsOps.h>
#include <muduo/net/TcpClient.h>

#include <boost/bind.hpp>

#include <utility>

#include <stdio.h>
#include <unistd.h>

using namespace muduo;
using namespace muduo::net;

class TimeClient : boost::noncopyable
{
 public:
  TimeClient(EventLoop* loop, const InetAddress& listenAddr)
    : loop_(loop),
      client_(loop, listenAddr, "TimeClient")
  {
    client_.setConnectionCallback(
        boost::bind(&TimeClient::onConnection, this, _1));
    client_.setMessageCallback(
        boost::bind(&TimeClient::onMessage, this, _1, _2, _3));
    // client_.enableRetry();
  }

  void connect()
  {
    client_.connect();
  }

 private:
  void onConnection(const TcpConnectionPtr& conn)
  {
    LOG_INFO << conn->localAddress().toHostPort() << " -> "
        << conn->peerAddress().toHostPort() << " is "
        << (conn->connected() ? "UP" : "DOWN");

    if (!conn->connected())
      loop_->quit();
  }

  void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime)
  {
    if (buf->readableBytes() >= sizeof(int32_t))
    {
      const void* data = buf->peek();
      int32_t time = *static_cast<const int32_t*>(data);
      buf->retrieve(sizeof(int32_t));
      time_t servertime = sockets::networkToHost32(time);
      Timestamp t(servertime * Timestamp::kMicroSecondsPerSecond);
      LOG_INFO << "Server time = " << servertime << ", " << t.toFormattedString();
    }
    else
    {
      LOG_INFO << conn->name() << " no enough data " << buf->readableBytes()
       << " at " << receiveTime.toFormattedString();
    }
  }

  EventLoop* loop_;
  TcpClient client_;
};

int main(int argc, char* argv[])
{
  LOG_INFO << "pid = " << getpid();
  if (argc > 1)
  {
    EventLoop loop;
    InetAddress serverAddr(argv[1], 2037);

    TimeClient timeClient(&loop, serverAddr);
    timeClient.connect();
    loop.loop();
  }
  else
  {
    printf("Usage: %s host_ip\n", argv[0]);
  }
}

<commit_msg>Rename 'listenAddr' to 'serverAddr' in examples/timeclient/timeclient.cc<commit_after>#include <muduo/base/Logging.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/SocketsOps.h>
#include <muduo/net/TcpClient.h>

#include <boost/bind.hpp>

#include <utility>

#include <stdio.h>
#include <unistd.h>

using namespace muduo;
using namespace muduo::net;

class TimeClient : boost::noncopyable
{
 public:
  TimeClient(EventLoop* loop, const InetAddress& serverAddr)
    : loop_(loop),
      client_(loop, serverAddr, "TimeClient")
  {
    client_.setConnectionCallback(
        boost::bind(&TimeClient::onConnection, this, _1));
    client_.setMessageCallback(
        boost::bind(&TimeClient::onMessage, this, _1, _2, _3));
    // client_.enableRetry();
  }

  void connect()
  {
    client_.connect();
  }

 private:
  void onConnection(const TcpConnectionPtr& conn)
  {
    LOG_INFO << conn->localAddress().toHostPort() << " -> "
        << conn->peerAddress().toHostPort() << " is "
        << (conn->connected() ? "UP" : "DOWN");

    if (!conn->connected())
      loop_->quit();
  }

  void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime)
  {
    if (buf->readableBytes() >= sizeof(int32_t))
    {
      const void* data = buf->peek();
      int32_t time = *static_cast<const int32_t*>(data);
      buf->retrieve(sizeof(int32_t));
      time_t servertime = sockets::networkToHost32(time);
      Timestamp t(servertime * Timestamp::kMicroSecondsPerSecond);
      LOG_INFO << "Server time = " << servertime << ", " << t.toFormattedString();
    }
    else
    {
      LOG_INFO << conn->name() << " no enough data " << buf->readableBytes()
               << " at " << receiveTime.toFormattedString();
    }
  }

  EventLoop* loop_;
  TcpClient client_;
};

int main(int argc, char* argv[])
{
  LOG_INFO << "pid = " << getpid();
  if (argc > 1)
  {
    EventLoop loop;
    InetAddress serverAddr(argv[1], 2037);

    TimeClient timeClient(&loop, serverAddr);
    timeClient.connect();
    loop.loop();
  }
  else
  {
    printf("Usage: %s host_ip\n", argv[0]);
  }
}

<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName         :    NFVector3.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2016-09-27
//    @Module           :    NFVector3
//
// -------------------------------------------------------------------------

#ifndef NF_VETOR3_H
#define NF_VETOR3_H

#include <iostream>
#include <string>

class NFLine;
class NFBox;
class NFPlane;
class NFVector2;

class NFVector3
{
private:
	float x, y, z;
	void InitData()
	{
		x = 0.0f;
		y = 0.0f;
		z = 0.0f;
	}

public:
	// construction
	NFVector3()
	{
		InitData();
	}

	NFVector3(float x, float y, float z)
	{
		this->x = x;
		this->y = y;
		this->z = z;
	}

	NFVector3(const NFVector2& v, float z)
	{
		this->x = v.X();
		this->y = v.Y();
		this->z = z;
	}

	NFVector3(float coordinate[3])
	{
		this->x = coordinate[0];
		this->y = coordinate[1];
		this->z = coordinate[2];
	}

	NFVector3(double coordinate[3])
	{
		this->x = coordinate[0];
		this->y = coordinate[1];
		this->z = coordinate[2];
	}

	NFVector3(const NFVector3& v)
	{
		this->x = v.x;
		this->y = v.y;
		this->z = v.z;
	}

	//----------------------------------------------------------------------------
	bool operator<(const NFVector3& v) const
	{
		return this->Length() < v.Length() ;
	}

	bool operator>(const NFVector3& v) const
	{
		return this->Length() > v.Length();
	}

	NFVector3& operator= (const NFVector3& v)
	{
		this->x = v.x;
		this->y = v.x;
		this->z = v.z;

		return *this;
	}

	bool operator== (const NFVector3& v) const
	{
		return std::abs(this->x - v.x) < 0.001f && std::abs(this->y - v.y) < 0.001f && std::abs(this->z - v.z) < 0.001f;
	}

	bool operator!= (const NFVector3& v) const
	{
		return std::abs(this->x - v.x) >= 0.001f && std::abs(this->y - v.y) >= 0.001f && std::abs(this->z - v.z) >= 0.001f;
	}

	//----------------------------------------------------------------------------
    // Arithmetic Operations
	NFVector3 operator+ (const NFVector3& v) const
	{
		NFVector3 xV;

		xV.x = this->x + v.x;
		xV.y = this->y + v.y;
		xV.z = this->z + v.z;
		return xV;
	}

	NFVector3 operator- (const NFVector3& v) const
	{
		NFVector3 xV;

		xV.x = this->x - v.x;
		xV.y = this->y - v.y;
		xV.z = this->z - v.z;
		return xV;
	}

	NFVector3 operator- () const
	{
		return NFVector3(-x, -y, -z);
	}

	NFVector3 operator* (float s) const
	{
		return NFVector3(x * s, y * s, z * s);
	}

	NFVector3 operator/ (float s) const
	{
		if (std::abs(s) > 0.001f)
		{
			return NFVector3(x / s, y / s, z / s);
		}

		return Zero();
	}

	//----------------------------------------------------------------------------
    // Arithmetic Updates
	NFVector3& operator+= (const NFVector3& v)
	{
		x += v.x;
		y += v.y;
		z += v.z;
		return *this;
	}

	NFVector3& operator-= (const NFVector3& v)
	{
		x -= v.x;
		y -= v.y;
		z -= v.z;
		return *this;
	}

	NFVector3& operator*= (float s)
	{
		x *= s;
		y *= s;
		z *= s;
		return *this;
	}

	NFVector3 operator/= (float s)
	{
		//if (std::abs(s) > 0.001f)
		{
			return NFVector3(x / s, y / s, z / s);
		}

		//return Zero();
	}

	//----------------------------------------------------------------------------
	float X() const
	{
		return this->x;
	}

	float Y() const
	{
		return this->y;
	}

	float Z() const
	{
		return this->z;
	}

	void SetX(float x)
	{
		this->x = x;
	}

	void SetY(float y)
	{
		this->y = y;
	}

	void SetZ(float z)
	{
		this->z = z;
	}

	//----------------------------------------------------------------------------
	bool IsZero() const
	{
		return std::abs(x) < 0.001f && std::abs(y) < 0.001f && std::abs(z) < 0.001f;
	}
	//----------------------------------------------------------------------------
	inline float SquaredMagnitude() const
	{
		return x*x + y*y + z*z;
	}

	//----------------------------------------------------------------------------
	inline float SquaredLength() const
	{
		return SquaredMagnitude();
	}

	//----------------------------------------------------------------------------
	inline float Magnitude() const
	{
		return sqrtf(x*x + y*y + z*z);
	}

	//----------------------------------------------------------------------------
	inline float Length() const
	{
		return Magnitude();
	}

	//----------------------------------------------------------------------------
	inline NFVector3 Direction() const
	{
		if (this->IsZero())
		{
			return Zero();
		}

		float lenSquared = SquaredMagnitude();
		float invSqrt = 1.0f / sqrtf(lenSquared);
		return NFVector3(x * invSqrt, y * invSqrt, z * invSqrt);
	}

	//----------------------------------------------------------------------------
    inline NFVector3 Normalized() const
    {
        return Direction();
    }

	//----------------------------------------------------------------------------
	float Distance(const NFVector3& v) const
	{
		NFVector3 vX = *this - v;
		return vX.Length();
	}

	//----------------------------------------------------------------------------
	bool FromString(const std::string& value)
	{
		std::vector<std::string> values;
		Split(value, values, ",");
		if (values.size() != 3)
		{
			return false;
		}
		x = lexical_cast<float>(values.at(0));
		y = lexical_cast<float>(values.at(1));
		z = lexical_cast<float>(values.at(2));

		return true;
	}

	//----------------------------------------------------------------------------
	std::string ToString() const
	{
		return lexical_cast<std::string>(x) + "," + lexical_cast<std::string>(y) + "," + lexical_cast<std::string>(z);
	}

    // Special values.
    inline static const NFVector3& Zero()
    {
        static NFVector3 v(0, 0, 0);
        return v;
    }
    inline static const NFVector3& One()
    {
        static NFVector3 v(1, 1, 1);
        return v;
    }
    inline static const NFVector3& UnitX()
    {
        static NFVector3 v(1, 0, 0);
        return v;
    }
    inline static const NFVector3& UnitY()
    {
        static NFVector3 v(0, 1, 0);
        return v;
    }
	inline static const NFVector3& UnitZ()
	{
		static NFVector3 v(0, 0, 1);
		return v;
	}

	NFVector2 xx() const
	{
		return NFVector2(this->x, this->x);
	}

	NFVector2 yx() const
	{
		return NFVector2(this->y, this->x);
	}

	NFVector2 zx() const
	{
		return NFVector2(this->z, this->x);
	}

	NFVector2 xy() const
	{
		return NFVector2(this->x, this->y);
	}

	NFVector2 yy() const
	{
		return NFVector2(this->y, this->y);
	}

	NFVector2 zy() const
	{
		return NFVector2(this->z, this->y);
	}

	NFVector2 xz() const
	{
		return NFVector2(this->x, this->z);
	}

	NFVector2 yz() const
	{
		return NFVector2(this->y, this->z);
	}

	NFVector2 zz() const
	{
		return NFVector2(this->z, this->z);
	}

	bool Split(const std::string& str, std::vector<std::string>& result, std::string delim)
	{
		if (str.empty())
		{
			return false;
		}

		std::string tmp;
		size_t pos_begin = str.find_first_not_of(delim);
		size_t pos = 0;
		while (pos_begin != std::string::npos)
		{
			pos = str.find(delim, pos_begin);
			if (pos != std::string::npos)
			{
				tmp = str.substr(pos_begin, pos - pos_begin);
				pos_begin = pos + delim.length();
			}
			else
			{
				tmp = str.substr(pos_begin);
				pos_begin = pos;
			}

			if (!tmp.empty())
			{
				result.push_back(tmp);
				tmp.clear();
			}
		}
		return true;
	}
};

#endif<commit_msg>* fix NFVector3<commit_after>// -------------------------------------------------------------------------
//    @FileName         :    NFVector3.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2016-09-27
//    @Module           :    NFVector3
//
// -------------------------------------------------------------------------

#ifndef NF_VETOR3_H
#define NF_VETOR3_H

#include <iostream>
#include <string>

class NFLine;
class NFBox;
class NFPlane;
class NFVector2;

class NFVector3
{
private:
	float x, y, z;
	void InitData()
	{
		x = 0.0f;
		y = 0.0f;
		z = 0.0f;
	}

public:
	// construction
	NFVector3()
	{
		InitData();
	}

	NFVector3(float x, float y, float z)
	{
		this->x = x;
		this->y = y;
		this->z = z;
	}

	NFVector3(const NFVector2& v, float z)
	{
		this->x = v.X();
		this->y = v.Y();
		this->z = z;
	}

	NFVector3(float coordinate[3])
	{
		this->x = coordinate[0];
		this->y = coordinate[1];
		this->z = coordinate[2];
	}

	NFVector3(double coordinate[3])
	{
		this->x = coordinate[0];
		this->y = coordinate[1];
		this->z = coordinate[2];
	}

	NFVector3(const NFVector3& v)
	{
		this->x = v.x;
		this->y = v.y;
		this->z = v.z;
	}

	//----------------------------------------------------------------------------
	bool operator<(const NFVector3& v) const
	{
		return this->Length() < v.Length() ;
	}

	bool operator>(const NFVector3& v) const
	{
		return this->Length() > v.Length();
	}

	NFVector3& operator= (const NFVector3& v)
	{
		this->x = v.x;
		this->y = v.y;
		this->z = v.z;

		return *this;
	}

	bool operator== (const NFVector3& v) const
	{
		return std::abs(this->x - v.x) < 0.001f && std::abs(this->y - v.y) < 0.001f && std::abs(this->z - v.z) < 0.001f;
	}

	bool operator!= (const NFVector3& v) const
	{
		return std::abs(this->x - v.x) >= 0.001f && std::abs(this->y - v.y) >= 0.001f && std::abs(this->z - v.z) >= 0.001f;
	}

	//----------------------------------------------------------------------------
    // Arithmetic Operations
	NFVector3 operator+ (const NFVector3& v) const
	{
		NFVector3 xV;

		xV.x = this->x + v.x;
		xV.y = this->y + v.y;
		xV.z = this->z + v.z;
		return xV;
	}

	NFVector3 operator- (const NFVector3& v) const
	{
		NFVector3 xV;

		xV.x = this->x - v.x;
		xV.y = this->y - v.y;
		xV.z = this->z - v.z;
		return xV;
	}

	NFVector3 operator- () const
	{
		return NFVector3(-x, -y, -z);
	}

	NFVector3 operator* (float s) const
	{
		return NFVector3(x * s, y * s, z * s);
	}

	NFVector3 operator/ (float s) const
	{
		if (std::abs(s) > 0.001f)
		{
			return NFVector3(x / s, y / s, z / s);
		}

		return Zero();
	}

	//----------------------------------------------------------------------------
    // Arithmetic Updates
	NFVector3& operator+= (const NFVector3& v)
	{
		x += v.x;
		y += v.y;
		z += v.z;
		return *this;
	}

	NFVector3& operator-= (const NFVector3& v)
	{
		x -= v.x;
		y -= v.y;
		z -= v.z;
		return *this;
	}

	NFVector3& operator*= (float s)
	{
		x *= s;
		y *= s;
		z *= s;
		return *this;
	}

	NFVector3 operator/= (float s)
	{
		//if (std::abs(s) > 0.001f)
		{
			return NFVector3(x / s, y / s, z / s);
		}

		//return Zero();
	}

	//----------------------------------------------------------------------------
	float X() const
	{
		return this->x;
	}

	float Y() const
	{
		return this->y;
	}

	float Z() const
	{
		return this->z;
	}

	void SetX(float x)
	{
		this->x = x;
	}

	void SetY(float y)
	{
		this->y = y;
	}

	void SetZ(float z)
	{
		this->z = z;
	}

	//----------------------------------------------------------------------------
	bool IsZero() const
	{
		return std::abs(x) < 0.001f && std::abs(y) < 0.001f && std::abs(z) < 0.001f;
	}
	//----------------------------------------------------------------------------
	inline float SquaredMagnitude() const
	{
		return x*x + y*y + z*z;
	}

	//----------------------------------------------------------------------------
	inline float SquaredLength() const
	{
		return SquaredMagnitude();
	}

	//----------------------------------------------------------------------------
	inline float Magnitude() const
	{
		return sqrtf(x*x + y*y + z*z);
	}

	//----------------------------------------------------------------------------
	inline float Length() const
	{
		return Magnitude();
	}

	//----------------------------------------------------------------------------
	inline NFVector3 Direction() const
	{
		if (this->IsZero())
		{
			return Zero();
		}

		float lenSquared = SquaredMagnitude();
		float invSqrt = 1.0f / sqrtf(lenSquared);
		return NFVector3(x * invSqrt, y * invSqrt, z * invSqrt);
	}

	//----------------------------------------------------------------------------
    inline NFVector3 Normalized() const
    {
        return Direction();
    }

	//----------------------------------------------------------------------------
	float Distance(const NFVector3& v) const
	{
		NFVector3 vX = *this - v;
		return vX.Length();
	}

	//----------------------------------------------------------------------------
	bool FromString(const std::string& value)
	{
		std::vector<std::string> values;
		Split(value, values, ",");
		if (values.size() != 3)
		{
			return false;
		}
		x = lexical_cast<float>(values.at(0));
		y = lexical_cast<float>(values.at(1));
		z = lexical_cast<float>(values.at(2));

		return true;
	}

	//----------------------------------------------------------------------------
	std::string ToString() const
	{
		return lexical_cast<std::string>(x) + "," + lexical_cast<std::string>(y) + "," + lexical_cast<std::string>(z);
	}

    // Special values.
    inline static const NFVector3& Zero()
    {
        static NFVector3 v(0, 0, 0);
        return v;
    }
    inline static const NFVector3& One()
    {
        static NFVector3 v(1, 1, 1);
        return v;
    }
    inline static const NFVector3& UnitX()
    {
        static NFVector3 v(1, 0, 0);
        return v;
    }
    inline static const NFVector3& UnitY()
    {
        static NFVector3 v(0, 1, 0);
        return v;
    }
	inline static const NFVector3& UnitZ()
	{
		static NFVector3 v(0, 0, 1);
		return v;
	}

	NFVector2 xx() const
	{
		return NFVector2(this->x, this->x);
	}

	NFVector2 yx() const
	{
		return NFVector2(this->y, this->x);
	}

	NFVector2 zx() const
	{
		return NFVector2(this->z, this->x);
	}

	NFVector2 xy() const
	{
		return NFVector2(this->x, this->y);
	}

	NFVector2 yy() const
	{
		return NFVector2(this->y, this->y);
	}

	NFVector2 zy() const
	{
		return NFVector2(this->z, this->y);
	}

	NFVector2 xz() const
	{
		return NFVector2(this->x, this->z);
	}

	NFVector2 yz() const
	{
		return NFVector2(this->y, this->z);
	}

	NFVector2 zz() const
	{
		return NFVector2(this->z, this->z);
	}

	bool Split(const std::string& str, std::vector<std::string>& result, std::string delim)
	{
		if (str.empty())
		{
			return false;
		}

		std::string tmp;
		size_t pos_begin = str.find_first_not_of(delim);
		size_t pos = 0;
		while (pos_begin != std::string::npos)
		{
			pos = str.find(delim, pos_begin);
			if (pos != std::string::npos)
			{
				tmp = str.substr(pos_begin, pos - pos_begin);
				pos_begin = pos + delim.length();
			}
			else
			{
				tmp = str.substr(pos_begin);
				pos_begin = pos;
			}

			if (!tmp.empty())
			{
				result.push_back(tmp);
				tmp.clear();
			}
		}
		return true;
	}
};

#endif<|endoftext|>


<commit_before>#include "SocketSession.h"
#include "fxtimer.h"
#include "fxdb.h"
#include "fxmeta.h"
#include "PlayerSession.h"
#include "ServerSession.h"
#include "GameServer.h"

#include <signal.h>
#include "gflags/gflags.h"

unsigned int g_dwPort = 20000;
bool g_bRun = true;

DEFINE_uint32(server_id, 30001, "server id");
DEFINE_string(server_ip, "127.0.0.1", "server ip");
DEFINE_uint32(server_port, 31001, "server port");
DEFINE_uint32(player_port, 31002, "player port");
DEFINE_string(center_ip, "127.0.0.1", "center ip");
DEFINE_uint32(center_port, 40000, "center port");
DEFINE_string(redis_ip, "127.0.0.1", "redis ip");
DEFINE_string(redis_pw, "1", "redis password");
DEFINE_uint32(redis_port, 16379, "redis port");

void EndFun(int n)
{
	if (n == SIGINT || n == SIGTERM)
	{
		g_bRun = false;
	}
	else
	{
		printf("unknown signal : %d !!!!!!!!!!!!!!!!!!!!!!!\n", n);
	}
}

#ifndef WIN32
void SigChld(int signo)
{
	pid_t pid;
	int stat;
	pid = wait(&stat);
	printf("child %d exit\n", pid);
	return;
}
#endif // !WIN32

int main(int argc, char **argv)
{
	//----------------------order can't change begin-----------------------//
	gflags::SetUsageMessage("WebGameManager");
	gflags::ParseCommandLineFlags(&argc, &argv, false);
	signal(SIGINT, EndFun);
	signal(SIGTERM, EndFun);
#ifndef WIN32
	signal(SIGCHLD, &SigChld);
#endif // !WIN32

	// must define before goto
	IFxNet* pNet = NULL;

	if (!GetTimeHandler()->Init())
	{
		g_bRun = false;
		goto STOP;
	}
	GetTimeHandler()->Run();

	if (!GameServer::CreateInstance())
	{
		g_bRun = false;
		goto STOP;
	}

	pNet = FxNetGetModule();
	if (!pNet)
	{
		g_bRun = false;
		goto STOP;
	}
	//----------------------order can't change end-----------------------//

	if (!GameServer::Instance()->Init(FLAGS_server_id, FLAGS_server_ip, FLAGS_center_ip, FLAGS_center_port, FLAGS_server_port, FLAGS_player_port))
	{
		g_bRun = false;
		goto STOP;
	}
	while (g_bRun)
	{
		GetTimeHandler()->Run();
		pNet->Run(0xffffffff);
		FxSleep(1);
	}

	GameServer::Instance()->Stop();

	FxSleep(10);
	pNet->Release();
STOP:
	printf("error!!!!!!!!\n");false;}
<commit_msg>linux头文件<commit_after>#include "SocketSession.h"
#include "fxtimer.h"
#include "fxdb.h"
#include "fxmeta.h"
#include "PlayerSession.h"
#include "ServerSession.h"
#include "GameServer.h"

#include <signal.h>
#include "gflags/gflags.h"

#ifndef WIN32
#include <sys/wait.h>
#endif

unsigned int g_dwPort = 20000;
bool g_bRun = true;

DEFINE_uint32(server_id, 30001, "server id");
DEFINE_string(server_ip, "127.0.0.1", "server ip");
DEFINE_uint32(server_port, 31001, "server port");
DEFINE_uint32(player_port, 31002, "player port");
DEFINE_string(center_ip, "127.0.0.1", "center ip");
DEFINE_uint32(center_port, 40000, "center port");
DEFINE_string(redis_ip, "127.0.0.1", "redis ip");
DEFINE_string(redis_pw, "1", "redis password");
DEFINE_uint32(redis_port, 16379, "redis port");

void EndFun(int n)
{
	if (n == SIGINT || n == SIGTERM)
	{
		g_bRun = false;
	}
	else
	{
		printf("unknown signal : %d !!!!!!!!!!!!!!!!!!!!!!!\n", n);
	}
}

#ifndef WIN32
void SigChld(int signo)
{
	pid_t pid;
	int stat;
	pid = wait(&stat);
	printf("child %d exit\n", pid);
	return;
}
#endif // !WIN32

int main(int argc, char **argv)
{
	//----------------------order can't change begin-----------------------//
	gflags::SetUsageMessage("WebGameManager");
	gflags::ParseCommandLineFlags(&argc, &argv, false);
	signal(SIGINT, EndFun);
	signal(SIGTERM, EndFun);
#ifndef WIN32
	signal(SIGCHLD, &SigChld);
#endif // !WIN32

	// must define before goto
	IFxNet* pNet = NULL;

	if (!GetTimeHandler()->Init())
	{
		g_bRun = false;
		goto STOP;
	}
	GetTimeHandler()->Run();

	if (!GameServer::CreateInstance())
	{
		g_bRun = false;
		goto STOP;
	}

	pNet = FxNetGetModule();
	if (!pNet)
	{
		g_bRun = false;
		goto STOP;
	}
	//----------------------order can't change end-----------------------//

	if (!GameServer::Instance()->Init(FLAGS_server_id, FLAGS_server_ip, FLAGS_center_ip, FLAGS_center_port, FLAGS_server_port, FLAGS_player_port))
	{
		g_bRun = false;
		goto STOP;
	}
	while (g_bRun)
	{
		GetTimeHandler()->Run();
		pNet->Run(0xffffffff);
		FxSleep(1);
	}

	GameServer::Instance()->Stop();

	FxSleep(10);
	pNet->Release();
STOP:
	printf("error!!!!!!!!\n");false;}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//									     //
// This class provides access to ZDC digits in raw data.		     //
//									     //
// It loops over all ZDC digits in the raw data given by the AliRawReader.   //
// The Next method goes to the next digit. If there are no digits left	     //
// it returns kFALSE.							     //
// Getters provide information about the current digit. 		     //
//									     //
///////////////////////////////////////////////////////////////////////////////

#include "AliZDCRawStream.h"
#include "AliRawReader.h"
#include "AliLog.h"

ClassImp(AliZDCRawStream)

//_____________________________________________________________________________
AliZDCRawStream::AliZDCRawStream(AliRawReader* rawReader) :
  fRawReader(rawReader),
  fRawADC(0),
  fADCModule(0),
  fADCValue(-1),
  fADCGain(0),
  fIsADCDataWord(kFALSE)
{
  // Create an object to read ZDC raw digits

  fRawReader->Select("ZDC");
}

//_____________________________________________________________________________
AliZDCRawStream::AliZDCRawStream(const AliZDCRawStream& stream) :
  TObject(stream)
{
  // Copy constructor
  fRawADC = stream.GetADCRaw();
  for(Int_t j=0; j<2; j++) fSector[j] = stream.GetSector(j);
  fADCModule = stream.GetADCModule();
  fADCValue = stream.GetADCValue();
  fADCGain = stream.GetADCGain();
  fIsADCDataWord = stream.IsADCDataWord();

}

//_____________________________________________________________________________
AliZDCRawStream& AliZDCRawStream::operator = (const AliZDCRawStream&
					      /* stream */)
{
  // Assignment operator
  Fatal("operator =", "assignment operator not implemented");
  return *this;
}

//_____________________________________________________________________________
AliZDCRawStream::~AliZDCRawStream()
{
// Destructor

}

//_____________________________________________________________________________
Bool_t AliZDCRawStream::Next()
{
  // Read the next raw digit
  // Returns kFALSE if there is no digit left

  if(!fRawReader->ReadNextInt((UInt_t&) fRawADC)) return kFALSE;
  fIsADCDataWord = kFALSE;

  //
  // --- DARC header
  if((fRawADC == 0xe52b6300) || (fRawADC == 0xe52c0300) ||  (fRawADC == 0xffffffff) ||
     (fRawADC == 0xdeadface) || (fRawADC == 0xdeadbeef)){
    //printf("    This is a DARC header!!!\n");
  }
  // --- End of data
  else if(fRawADC == 0xcafefade){
    //printf("    End of data!\n");
  }
  // --- ADC buffer
  else{
    if((fRawADC & 0x6000000) == 0x6000000){ // Not valid datum
      //printf("    AliZDCRawStream -> Not valid datum in ADC module!!! %d\n",fADCModule);
    }
    else if((fRawADC & 0x4000000) == 0x4000000){ // ADC EOB
      //printf("    AliZDCRawStream -> ADC %d End Of Block - Event no. %d\n\n",fADCModule, (fRawADC & 0xffffff));
      fSector[0] = fSector[1] = 99;
    }
    else if((fRawADC & 0x2000000) == 0x2000000){ // ADC Header
      printf("  fRawADC %x\n",fRawADC);
      // Reading the GEO address to determine ADC module
      fADCModule = (fRawADC & 0xf8000000) >> 27;
      fADCModule ++;
      //printf("    AliZDCRawStream -> HEADER: ADC mod. %d contains %d data words \n",fADCModule,((fRawADC & 0x3f00) >> 8));
    }
    else{ // ADC data word
      fIsADCDataWord = kTRUE;
      //printf(" \t \t ADC Data Word");
      //
      if(!(fRawADC & 0x1000) && !(fRawADC & 0x2000)){ // Valid ADC data
        fADCGain = (fRawADC & 0x10000) >> 16;
        fADCValue = (fRawADC & 0xfff);
        //
        Int_t vADCChannel = (fRawADC & 0x1e0000) >> 17;
        if(fADCModule==1 || fADCModule==3){  //1st & 3rd ADC modules
          if(vADCChannel >= 0 && vADCChannel <= 4){
            fSector[0] = 1; // ZN1
            fSector[1] = vADCChannel;
          }
          else if(vADCChannel >= 8 && vADCChannel <= 12){
            fSector[0] = 2; // ZP1
            fSector[1] = vADCChannel-8;
          }
          else if(vADCChannel == 5 || vADCChannel == 13){
            fSector[0] = 3; // ZEM 1,2
            fSector[1] = ((vADCChannel-5)/8)+1;
          }
        }
        else if(fADCModule==2 || fADCModule==4){  //2nd & 4rth ADC modules
          if(vADCChannel >= 0 && vADCChannel <= 4){
            fSector[0] = 4; // ZN2
          fSector[1] = vADCChannel;
          }
          else if(vADCChannel >= 8 && vADCChannel <= 12){
            fSector[0] = 5; // ZP2
            fSector[1] = vADCChannel-8;
          }
          else if(vADCChannel == 5 || vADCChannel == 13){
            fSector[0] = (vADCChannel-5)*3/8+1; // PM Ref 1,2
            fSector[1] = 5;
          }
        }
        else{
          AliWarning("    AliZDCRawStream -> No valid ADC module\n");
          fRawReader->AddMajorErrorLog(kInvalidADCModule);
        }
        //printf("  ADC %d ch %d range %d -> det %d quad %d value %x\n",
        //   fADCModule, vADCChannel, fADCGain, fSector[0], fSector[1], fADCValue);//Chiara debugging

      }// Valid ADC data
      else if(fRawADC & 0x1000){
        //printf("  ADC %d ch %d range %d  overflow\n",fADCModule, (fRawADC & 0x1e0000) >> 17, fADCGain); // Overflow
      }
      else if(fRawADC & 0x2000){
        //printf("  ADC %d ch %d range %d  underflow\n",fADCModule, (fRawADC & 0x1e0000) >> 17, fADCGain); // Underflow
      }
    }// ADC word
  }//Not DARC Header

  return kTRUE;
}
<commit_msg>Print commented<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//									     //
// This class provides access to ZDC digits in raw data.		     //
//									     //
// It loops over all ZDC digits in the raw data given by the AliRawReader.   //
// The Next method goes to the next digit. If there are no digits left	     //
// it returns kFALSE.							     //
// Getters provide information about the current digit. 		     //
//									     //
///////////////////////////////////////////////////////////////////////////////

#include "AliZDCRawStream.h"
#include "AliRawReader.h"
#include "AliLog.h"

ClassImp(AliZDCRawStream)

//_____________________________________________________________________________
AliZDCRawStream::AliZDCRawStream(AliRawReader* rawReader) :
  fRawReader(rawReader),
  fRawADC(0),
  fADCModule(0),
  fADCValue(-1),
  fADCGain(0),
  fIsADCDataWord(kFALSE)
{
  // Create an object to read ZDC raw digits

  fRawReader->Select("ZDC");
}

//_____________________________________________________________________________
AliZDCRawStream::AliZDCRawStream(const AliZDCRawStream& stream) :
  TObject(stream)
{
  // Copy constructor
  fRawADC = stream.GetADCRaw();
  for(Int_t j=0; j<2; j++) fSector[j] = stream.GetSector(j);
  fADCModule = stream.GetADCModule();
  fADCValue = stream.GetADCValue();
  fADCGain = stream.GetADCGain();
  fIsADCDataWord = stream.IsADCDataWord();

}

//_____________________________________________________________________________
AliZDCRawStream& AliZDCRawStream::operator = (const AliZDCRawStream&
					      /* stream */)
{
  // Assignment operator
  Fatal("operator =", "assignment operator not implemented");
  return *this;
}

//_____________________________________________________________________________
AliZDCRawStream::~AliZDCRawStream()
{
// Destructor

}

//_____________________________________________________________________________
Bool_t AliZDCRawStream::Next()
{
  // Read the next raw digit
  // Returns kFALSE if there is no digit left

  if(!fRawReader->ReadNextInt((UInt_t&) fRawADC)) return kFALSE;
  fIsADCDataWord = kFALSE;

  //
  // --- DARC header
  if((fRawADC == 0xe52b6300) || (fRawADC == 0xe52c0300) ||  (fRawADC == 0xffffffff) ||
     (fRawADC == 0xdeadface) || (fRawADC == 0xdeadbeef)){
    //printf("    This is a DARC header!!!\n");
  }
  // --- End of data
  else if(fRawADC == 0xcafefade){
    //printf("    End of data!\n");
  }
  // --- ADC buffer
  else{
    if((fRawADC & 0x6000000) == 0x6000000){ // Not valid datum
      //printf("    AliZDCRawStream -> Not valid datum in ADC module!!! %d\n",fADCModule);
    }
    else if((fRawADC & 0x4000000) == 0x4000000){ // ADC EOB
      //printf("    AliZDCRawStream -> ADC %d End Of Block - Event no. %d\n\n",fADCModule, (fRawADC & 0xffffff));
      fSector[0] = fSector[1] = 99;
    }
    else if((fRawADC & 0x2000000) == 0x2000000){ // ADC Header
      //printf("  fRawADC %x\n",fRawADC);
      // Reading the GEO address to determine ADC module
      fADCModule = (fRawADC & 0xf8000000) >> 27;
      fADCModule ++;
      //printf("    AliZDCRawStream -> HEADER: ADC mod. %d contains %d data words \n",fADCModule,((fRawADC & 0x3f00) >> 8));
    }
    else{ // ADC data word
      fIsADCDataWord = kTRUE;
      //printf(" \t \t ADC Data Word");
      //
      if(!(fRawADC & 0x1000) && !(fRawADC & 0x2000)){ // Valid ADC data
        fADCGain = (fRawADC & 0x10000) >> 16;
        fADCValue = (fRawADC & 0xfff);
        //
        Int_t vADCChannel = (fRawADC & 0x1e0000) >> 17;
        if(fADCModule==1 || fADCModule==3){  //1st & 3rd ADC modules
          if(vADCChannel >= 0 && vADCChannel <= 4){
            fSector[0] = 1; // ZN1
            fSector[1] = vADCChannel;
          }
          else if(vADCChannel >= 8 && vADCChannel <= 12){
            fSector[0] = 2; // ZP1
            fSector[1] = vADCChannel-8;
          }
          else if(vADCChannel == 5 || vADCChannel == 13){
            fSector[0] = 3; // ZEM 1,2
            fSector[1] = ((vADCChannel-5)/8)+1;
          }
        }
        else if(fADCModule==2 || fADCModule==4){  //2nd & 4rth ADC modules
          if(vADCChannel >= 0 && vADCChannel <= 4){
            fSector[0] = 4; // ZN2
          fSector[1] = vADCChannel;
          }
          else if(vADCChannel >= 8 && vADCChannel <= 12){
            fSector[0] = 5; // ZP2
            fSector[1] = vADCChannel-8;
          }
          else if(vADCChannel == 5 || vADCChannel == 13){
            fSector[0] = (vADCChannel-5)*3/8+1; // PM Ref 1,2
            fSector[1] = 5;
          }
        }
        else{
          AliWarning("    AliZDCRawStream -> No valid ADC module\n");
          fRawReader->AddMajorErrorLog(kInvalidADCModule);
        }
        //printf("  ADC %d ch %d range %d -> det %d quad %d value %x\n",
        //   fADCModule, vADCChannel, fADCGain, fSector[0], fSector[1], fADCValue);//Chiara debugging

      }// Valid ADC data
      else if(fRawADC & 0x1000){
        //printf("  ADC %d ch %d range %d  overflow\n",fADCModule, (fRawADC & 0x1e0000) >> 17, fADCGain); // Overflow
      }
      else if(fRawADC & 0x2000){
        //printf("  ADC %d ch %d range %d  underflow\n",fADCModule, (fRawADC & 0x1e0000) >> 17, fADCGain); // Underflow
      }
    }// ADC word
  }//Not DARC Header

  return kTRUE;
}
<|endoftext|>