<commit_before>/*
 * Copyright (C) 2015-present ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <memory>
#include <functional>
#include <unordered_map>
#include "gms/inet_address.hh"
#include "locator/snitch_base.hh"
#include "dht/i_partitioner.hh"
#include "token_metadata.hh"
#include "snitch_base.hh"
#include <seastar/util/bool_class.hh>
#include "utils/maybe_yield.hh"

// forward declaration since database.hh includes this file
class keyspace;

namespace locator {

extern logging::logger rslogger;

using inet_address = gms::inet_address;
using token = dht::token;

enum class replication_strategy_type {
    simple,
    local,
    network_topology,
    everywhere_topology,
};

using can_yield = utils::can_yield;

using replication_strategy_config_options = std::map<sstring, sstring>;

using replication_map = std::unordered_map<token, inet_address_vector_replica_set>;

class effective_replication_map;

class abstract_replication_strategy {
    friend class effective_replication_map;
protected:
    replication_strategy_config_options _config_options;
    snitch_ptr& _snitch;
    replication_strategy_type _my_type;

    template <typename... Args>
    void err(const char* fmt, Args&&... args) const {
        rslogger.error(fmt, std::forward<Args>(args)...);
    }

    template <typename... Args>
    void warn(const char* fmt, Args&&... args) const {
        rslogger.warn(fmt, std::forward<Args>(args)...);
    }

    template <typename... Args>
    void debug(const char* fmt, Args&&... args) const {
        rslogger.debug(fmt, std::forward<Args>(args)...);
    }

public:
    using ptr_type = seastar::shared_ptr<abstract_replication_strategy>;

    abstract_replication_strategy(
        snitch_ptr& snitch,
        const replication_strategy_config_options& config_options,
        replication_strategy_type my_type);

    // The returned vector has size O(number of normal token owners), which is O(number of nodes in the cluster).
    // Note: it is not guaranteed that the function will actually yield. If the complexity of a particular implementation
    // is small, that implementation may not yield since by itself it won't cause a reactor stall (assuming practical
    // cluster sizes and number of tokens per node). The caller is responsible for yielding if they call this function
    // in a loop.
    virtual future<inet_address_vector_replica_set> calculate_natural_endpoints(const token& search_token, const token_metadata& tm) const  = 0;

    virtual ~abstract_replication_strategy() {}
    static ptr_type create_replication_strategy(const sstring& strategy_name, const replication_strategy_config_options& config_options);
    static void validate_replication_strategy(const sstring& ks_name,
                                              const sstring& strategy_name,
                                              const replication_strategy_config_options& config_options,
                                              const topology& topology);
    static void validate_replication_factor(sstring rf);

    static sstring to_qualified_class_name(std::string_view strategy_class_name);

    virtual inet_address_vector_replica_set get_natural_endpoints(const token& search_token, const effective_replication_map& erm) const;
    virtual void validate_options() const = 0;
    virtual std::optional<std::set<sstring>> recognized_options(const topology&) const = 0;
    virtual size_t get_replication_factor(const token_metadata& tm) const = 0;
    // Decide if the replication strategy allow removing the node being
    // replaced from the natural endpoints when a node is being replaced in the
    // cluster. LocalStrategy is the not allowed to do so because it always
    // returns the node itself as the natural_endpoints and the node will not
    // appear in the pending_endpoints.
    virtual bool allow_remove_node_being_replaced_from_natural_endpoints() const = 0;
    replication_strategy_type get_type() const noexcept { return _my_type; }
    const replication_strategy_config_options get_config_options() const noexcept { return _config_options; }

    // Use the token_metadata provided by the caller instead of _token_metadata
    // Note: must be called with initialized, non-empty token_metadata.
    future<dht::token_range_vector> get_ranges(inet_address ep, token_metadata_ptr tmptr) const;

public:
    future<std::unordered_multimap<inet_address, dht::token_range>> get_address_ranges(const token_metadata& tm) const;
    future<std::unordered_multimap<inet_address, dht::token_range>> get_address_ranges(const token_metadata& tm, inet_address endpoint) const;

    // Caller must ensure that token_metadata will not change throughout the call.
    future<std::unordered_map<dht::token_range, inet_address_vector_replica_set>> get_range_addresses(const token_metadata& tm) const;

    future<dht::token_range_vector> get_pending_address_ranges(const token_metadata_ptr tmptr, token pending_token, inet_address pending_address) const;

    future<dht::token_range_vector> get_pending_address_ranges(const token_metadata_ptr tmptr, std::unordered_set<token> pending_tokens, inet_address pending_address) const;
};

// Holds the full replication_map resulting from applying the
// effective replication strategy over the given token_metadata
// and replication_strategy_config_options.
class effective_replication_map {
public:
    struct factory_key {
        replication_strategy_type rs_type;
        long ring_version;
        replication_strategy_config_options rs_config_options;

        factory_key(replication_strategy_type rs_type_, const replication_strategy_config_options& rs_config_options_, long ring_version_)
            : rs_type(std::move(rs_type_))
            , ring_version(ring_version_)
            , rs_config_options(std::move(rs_config_options_))
        {}

        factory_key(factory_key&&) = default;
        factory_key(const factory_key&) = default;

        bool operator==(const factory_key& o) const = default;
        bool operator!=(const factory_key& o) const = default;

        sstring to_sstring() const;
    };

private:
    abstract_replication_strategy::ptr_type _rs;
    token_metadata_ptr _tmptr;
    replication_map _replication_map;
    size_t _replication_factor;

    friend class abstract_replication_strategy;
public:
    explicit effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr, replication_map replication_map, size_t replication_factor) noexcept
        : _rs(std::move(rs))
        , _tmptr(std::move(tmptr))
        , _replication_map(std::move(replication_map))
        , _replication_factor(replication_factor)
    { }
    effective_replication_map() = delete;
    effective_replication_map(effective_replication_map&&) = default;

    const token_metadata_ptr& get_token_metadata_ptr() const noexcept {
        return _tmptr;
    }

    const replication_map& get_replication_map() const noexcept {
        return _replication_map;
    }

    const size_t get_replication_factor() const noexcept {
        return _replication_factor;
    }

    future<> clear_gently() noexcept;

    future<replication_map> clone_endpoints_gently() const;

    inet_address_vector_replica_set get_natural_endpoints(const token& search_token) const;
    inet_address_vector_replica_set get_natural_endpoints_without_node_being_replaced(const token& search_token) const;

    // get_ranges() returns the list of ranges held by the given endpoint.
    // The list is sorted, and its elements are non overlapping and non wrap-around.
    // It the analogue of Origin's getAddressRanges().get(endpoint).
    // This function is not efficient, and not meant for the fast path.
    //
    // Note: must be called after token_metadata has been initialized.
    dht::token_range_vector get_ranges(inet_address ep) const;

    // get_primary_ranges() returns the list of "primary ranges" for the given
    // endpoint. "Primary ranges" are the ranges that the node is responsible
    // for storing replica primarily, which means this is the first node
    // returned calculate_natural_endpoints().
    // This function is the analogue of Origin's
    // StorageService.getPrimaryRangesForEndpoint().
    //
    // Note: must be called after token_metadata has been initialized.
    dht::token_range_vector get_primary_ranges(inet_address ep) const;

    // get_primary_ranges_within_dc() is similar to get_primary_ranges()
    // except it assigns a primary node for each range within each dc,
    // instead of one node globally.
    //
    // Note: must be called after token_metadata has been initialized.
    dht::token_range_vector get_primary_ranges_within_dc(inet_address ep) const;

    std::unordered_map<dht::token_range, inet_address_vector_replica_set>
    get_range_addresses() const;

private:
    dht::token_range_vector do_get_ranges(noncopyable_function<bool(inet_address_vector_replica_set)> should_add_range) const;

public:
    static factory_key make_factory_key(const abstract_replication_strategy::ptr_type& rs, const token_metadata_ptr& tmptr);
};

using effective_replication_map_ptr = lw_shared_ptr<const effective_replication_map>;
using mutable_effective_replication_map_ptr = lw_shared_ptr<effective_replication_map>;

inline mutable_effective_replication_map_ptr make_effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr, replication_map replication_map, size_t replication_factor) {
    return make_lw_shared<effective_replication_map>(std::move(rs), std::move(tmptr), std::move(replication_map), replication_factor);
}

// Apply the replication strategy over the current configuration and the given token_metadata.
future<mutable_effective_replication_map_ptr> calculate_effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr);

} // namespace locator

std::ostream& operator<<(std::ostream& os, locator::replication_strategy_type);
std::ostream& operator<<(std::ostream& os, const locator::effective_replication_map::factory_key& key);

template <>
struct fmt::formatter<locator::effective_replication_map::factory_key> {
    constexpr auto parse(format_parse_context& ctx) {
        return ctx.end();
    }

    template <typename FormatContext>
    auto format(const locator::effective_replication_map::factory_key& key, FormatContext& ctx) {
        std::ostringstream os;
        os << key;
        return format_to(ctx.out(), "{}", os.str());
    }
};

template<>
struct appending_hash<locator::effective_replication_map::factory_key> {
    template<typename Hasher>
    void operator()(Hasher& h, const locator::effective_replication_map::factory_key& key) const {
        feed_hash(h, key.rs_type);
        feed_hash(h, key.ring_version);
        for (const auto& [opt, val] : key.rs_config_options) {
            h.update(opt.c_str(), opt.size());
            h.update(val.c_str(), val.size());
        }
    }
};

struct factory_key_hasher : public hasher {
    XXH64_state_t _state;
    factory_key_hasher(uint64_t seed = 0) noexcept {
        XXH64_reset(&_state, seed);
    }
    void update(const char* ptr, size_t length) noexcept {
        XXH64_update(&_state, ptr, length);
    }
    size_t finalize() {
        return static_cast<size_t>(XXH64_digest(&_state));
    }
};

namespace std {

template <>
struct hash<locator::effective_replication_map::factory_key> {
    size_t operator()(const locator::effective_replication_map::factory_key& key) const {
        factory_key_hasher h;
        appending_hash<locator::effective_replication_map::factory_key>{}(h, key);
        return h.finalize();
    }
};

} // namespace std

namespace locator {

class effective_replication_map_factory {
    std::unordered_map<effective_replication_map::factory_key, effective_replication_map*> _effective_replication_maps;

    // TODO: create and erase effective_replication_map
};

}
<commit_msg>effective_replication_map: enable_lw_shared_from_this<commit_after>/*
 * Copyright (C) 2015-present ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <memory>
#include <functional>
#include <unordered_map>
#include "gms/inet_address.hh"
#include "locator/snitch_base.hh"
#include "dht/i_partitioner.hh"
#include "token_metadata.hh"
#include "snitch_base.hh"
#include <seastar/util/bool_class.hh>
#include "utils/maybe_yield.hh"

// forward declaration since database.hh includes this file
class keyspace;

namespace locator {

extern logging::logger rslogger;

using inet_address = gms::inet_address;
using token = dht::token;

enum class replication_strategy_type {
    simple,
    local,
    network_topology,
    everywhere_topology,
};

using can_yield = utils::can_yield;

using replication_strategy_config_options = std::map<sstring, sstring>;

using replication_map = std::unordered_map<token, inet_address_vector_replica_set>;

class effective_replication_map;

class abstract_replication_strategy {
    friend class effective_replication_map;
protected:
    replication_strategy_config_options _config_options;
    snitch_ptr& _snitch;
    replication_strategy_type _my_type;

    template <typename... Args>
    void err(const char* fmt, Args&&... args) const {
        rslogger.error(fmt, std::forward<Args>(args)...);
    }

    template <typename... Args>
    void warn(const char* fmt, Args&&... args) const {
        rslogger.warn(fmt, std::forward<Args>(args)...);
    }

    template <typename... Args>
    void debug(const char* fmt, Args&&... args) const {
        rslogger.debug(fmt, std::forward<Args>(args)...);
    }

public:
    using ptr_type = seastar::shared_ptr<abstract_replication_strategy>;

    abstract_replication_strategy(
        snitch_ptr& snitch,
        const replication_strategy_config_options& config_options,
        replication_strategy_type my_type);

    // The returned vector has size O(number of normal token owners), which is O(number of nodes in the cluster).
    // Note: it is not guaranteed that the function will actually yield. If the complexity of a particular implementation
    // is small, that implementation may not yield since by itself it won't cause a reactor stall (assuming practical
    // cluster sizes and number of tokens per node). The caller is responsible for yielding if they call this function
    // in a loop.
    virtual future<inet_address_vector_replica_set> calculate_natural_endpoints(const token& search_token, const token_metadata& tm) const  = 0;

    virtual ~abstract_replication_strategy() {}
    static ptr_type create_replication_strategy(const sstring& strategy_name, const replication_strategy_config_options& config_options);
    static void validate_replication_strategy(const sstring& ks_name,
                                              const sstring& strategy_name,
                                              const replication_strategy_config_options& config_options,
                                              const topology& topology);
    static void validate_replication_factor(sstring rf);

    static sstring to_qualified_class_name(std::string_view strategy_class_name);

    virtual inet_address_vector_replica_set get_natural_endpoints(const token& search_token, const effective_replication_map& erm) const;
    virtual void validate_options() const = 0;
    virtual std::optional<std::set<sstring>> recognized_options(const topology&) const = 0;
    virtual size_t get_replication_factor(const token_metadata& tm) const = 0;
    // Decide if the replication strategy allow removing the node being
    // replaced from the natural endpoints when a node is being replaced in the
    // cluster. LocalStrategy is the not allowed to do so because it always
    // returns the node itself as the natural_endpoints and the node will not
    // appear in the pending_endpoints.
    virtual bool allow_remove_node_being_replaced_from_natural_endpoints() const = 0;
    replication_strategy_type get_type() const noexcept { return _my_type; }
    const replication_strategy_config_options get_config_options() const noexcept { return _config_options; }

    // Use the token_metadata provided by the caller instead of _token_metadata
    // Note: must be called with initialized, non-empty token_metadata.
    future<dht::token_range_vector> get_ranges(inet_address ep, token_metadata_ptr tmptr) const;

public:
    future<std::unordered_multimap<inet_address, dht::token_range>> get_address_ranges(const token_metadata& tm) const;
    future<std::unordered_multimap<inet_address, dht::token_range>> get_address_ranges(const token_metadata& tm, inet_address endpoint) const;

    // Caller must ensure that token_metadata will not change throughout the call.
    future<std::unordered_map<dht::token_range, inet_address_vector_replica_set>> get_range_addresses(const token_metadata& tm) const;

    future<dht::token_range_vector> get_pending_address_ranges(const token_metadata_ptr tmptr, token pending_token, inet_address pending_address) const;

    future<dht::token_range_vector> get_pending_address_ranges(const token_metadata_ptr tmptr, std::unordered_set<token> pending_tokens, inet_address pending_address) const;
};

// Holds the full replication_map resulting from applying the
// effective replication strategy over the given token_metadata
// and replication_strategy_config_options.
class effective_replication_map : public enable_lw_shared_from_this<effective_replication_map> {
public:
    struct factory_key {
        replication_strategy_type rs_type;
        long ring_version;
        replication_strategy_config_options rs_config_options;

        factory_key(replication_strategy_type rs_type_, const replication_strategy_config_options& rs_config_options_, long ring_version_)
            : rs_type(std::move(rs_type_))
            , ring_version(ring_version_)
            , rs_config_options(std::move(rs_config_options_))
        {}

        factory_key(factory_key&&) = default;
        factory_key(const factory_key&) = default;

        bool operator==(const factory_key& o) const = default;
        bool operator!=(const factory_key& o) const = default;

        sstring to_sstring() const;
    };

private:
    abstract_replication_strategy::ptr_type _rs;
    token_metadata_ptr _tmptr;
    replication_map _replication_map;
    size_t _replication_factor;

    friend class abstract_replication_strategy;
public:
    explicit effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr, replication_map replication_map, size_t replication_factor) noexcept
        : _rs(std::move(rs))
        , _tmptr(std::move(tmptr))
        , _replication_map(std::move(replication_map))
        , _replication_factor(replication_factor)
    { }
    effective_replication_map() = delete;
    effective_replication_map(effective_replication_map&&) = default;

    const token_metadata_ptr& get_token_metadata_ptr() const noexcept {
        return _tmptr;
    }

    const replication_map& get_replication_map() const noexcept {
        return _replication_map;
    }

    const size_t get_replication_factor() const noexcept {
        return _replication_factor;
    }

    future<> clear_gently() noexcept;

    future<replication_map> clone_endpoints_gently() const;

    inet_address_vector_replica_set get_natural_endpoints(const token& search_token) const;
    inet_address_vector_replica_set get_natural_endpoints_without_node_being_replaced(const token& search_token) const;

    // get_ranges() returns the list of ranges held by the given endpoint.
    // The list is sorted, and its elements are non overlapping and non wrap-around.
    // It the analogue of Origin's getAddressRanges().get(endpoint).
    // This function is not efficient, and not meant for the fast path.
    //
    // Note: must be called after token_metadata has been initialized.
    dht::token_range_vector get_ranges(inet_address ep) const;

    // get_primary_ranges() returns the list of "primary ranges" for the given
    // endpoint. "Primary ranges" are the ranges that the node is responsible
    // for storing replica primarily, which means this is the first node
    // returned calculate_natural_endpoints().
    // This function is the analogue of Origin's
    // StorageService.getPrimaryRangesForEndpoint().
    //
    // Note: must be called after token_metadata has been initialized.
    dht::token_range_vector get_primary_ranges(inet_address ep) const;

    // get_primary_ranges_within_dc() is similar to get_primary_ranges()
    // except it assigns a primary node for each range within each dc,
    // instead of one node globally.
    //
    // Note: must be called after token_metadata has been initialized.
    dht::token_range_vector get_primary_ranges_within_dc(inet_address ep) const;

    std::unordered_map<dht::token_range, inet_address_vector_replica_set>
    get_range_addresses() const;

private:
    dht::token_range_vector do_get_ranges(noncopyable_function<bool(inet_address_vector_replica_set)> should_add_range) const;

public:
    static factory_key make_factory_key(const abstract_replication_strategy::ptr_type& rs, const token_metadata_ptr& tmptr);
};

using effective_replication_map_ptr = lw_shared_ptr<const effective_replication_map>;
using mutable_effective_replication_map_ptr = lw_shared_ptr<effective_replication_map>;

inline mutable_effective_replication_map_ptr make_effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr, replication_map replication_map, size_t replication_factor) {
    return make_lw_shared<effective_replication_map>(std::move(rs), std::move(tmptr), std::move(replication_map), replication_factor);
}

// Apply the replication strategy over the current configuration and the given token_metadata.
future<mutable_effective_replication_map_ptr> calculate_effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr);

} // namespace locator

std::ostream& operator<<(std::ostream& os, locator::replication_strategy_type);
std::ostream& operator<<(std::ostream& os, const locator::effective_replication_map::factory_key& key);

template <>
struct fmt::formatter<locator::effective_replication_map::factory_key> {
    constexpr auto parse(format_parse_context& ctx) {
        return ctx.end();
    }

    template <typename FormatContext>
    auto format(const locator::effective_replication_map::factory_key& key, FormatContext& ctx) {
        std::ostringstream os;
        os << key;
        return format_to(ctx.out(), "{}", os.str());
    }
};

template<>
struct appending_hash<locator::effective_replication_map::factory_key> {
    template<typename Hasher>
    void operator()(Hasher& h, const locator::effective_replication_map::factory_key& key) const {
        feed_hash(h, key.rs_type);
        feed_hash(h, key.ring_version);
        for (const auto& [opt, val] : key.rs_config_options) {
            h.update(opt.c_str(), opt.size());
            h.update(val.c_str(), val.size());
        }
    }
};

struct factory_key_hasher : public hasher {
    XXH64_state_t _state;
    factory_key_hasher(uint64_t seed = 0) noexcept {
        XXH64_reset(&_state, seed);
    }
    void update(const char* ptr, size_t length) noexcept {
        XXH64_update(&_state, ptr, length);
    }
    size_t finalize() {
        return static_cast<size_t>(XXH64_digest(&_state));
    }
};

namespace std {

template <>
struct hash<locator::effective_replication_map::factory_key> {
    size_t operator()(const locator::effective_replication_map::factory_key& key) const {
        factory_key_hasher h;
        appending_hash<locator::effective_replication_map::factory_key>{}(h, key);
        return h.finalize();
    }
};

} // namespace std

namespace locator {

class effective_replication_map_factory {
    std::unordered_map<effective_replication_map::factory_key, effective_replication_map*> _effective_replication_maps;

    // TODO: create and erase effective_replication_map
};

}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://sourceforge.net/projects/lxde-qt/
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *   Luis Pereira <luis.artur.pereira@gmail.com>
 *
 * The directoryMatchesSize() and thedirectorySizeDistance() functions were
 * taken from Qt5 qtbase/src/gui/image/qiconloader.cpp
 * Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

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

#include "iconthemeinfo.h"
#include <QDebug>

#include <private/qtxdg/qiconloader_p.h>

#include <QStringBuilder>

#define PREVIEW_ICON_SIZE 22

using namespace QtXdg;

/*
 * This algorithm is defined by the freedesktop spec:
 * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
 */
static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
{
    if (dir.type == QIconDirInfo::Fixed) {
        return dir.size == iconsize;

    } else if (dir.type == QIconDirInfo::Scalable) {
        return dir.size <= dir.maxSize &&
                iconsize >= dir.minSize;

    } else if (dir.type == QIconDirInfo::Threshold) {
        return iconsize >= dir.size - dir.threshold &&
                iconsize <= dir.size + dir.threshold;
    }

    Q_ASSERT(1); // Not a valid value
    return false;
}

/*
 * This algorithm is defined by the freedesktop spec:
 * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
 */
static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
{
    if (dir.type == QIconDirInfo::Fixed) {
        return qAbs(dir.size - iconsize);

    } else if (dir.type == QIconDirInfo::Scalable) {
        if (iconsize < dir.minSize)
            return dir.minSize - iconsize;
        else if (iconsize > dir.maxSize)
            return iconsize - dir.maxSize;
        else
            return 0;

    } else if (dir.type == QIconDirInfo::Threshold) {
        if (iconsize < dir.size - dir.threshold)
            return dir.minSize - iconsize;
        else if (iconsize > dir.size + dir.threshold)
            return iconsize - dir.maxSize;
        else return 0;
    }

    Q_ASSERT(1); // Not a valid value
    return INT_MAX;
}

IconThemeInfo::IconThemeInfo(const QDir &dir):
    mValid(false),
    mHidden(false)
{
    mName = dir.dirName();
    if (dir.exists(QStringLiteral("index.theme")))
        load(dir.absoluteFilePath(QStringLiteral("index.theme")));
}

void IconThemeInfo::load(const QString &fileName)
{
    mFileName = fileName;
    mValid = false;
    QSettings file(mFileName, QSettings::IniFormat);
    if (file.status() != QSettings::NoError)
        return;

    if (file.value(QStringLiteral("Icon Theme/Directories")).toStringList().join(QLatin1Char(' ')).isEmpty())
        return;

    mHidden = file.value(QStringLiteral("Icon Theme/Hidden"), false).toBool();
    mText = file.value(QStringLiteral("Icon Theme/Name")).toString();
    mComment = file.value(QStringLiteral("Icon Theme/Comment")).toString();

    mValid = true;
}

QVector<QIcon> IconThemeInfo::icons(const QStringList &iconNames) const
{
    QVector<QIcon> icons;

    const QString currentThemeName = QIconLoader::instance()->themeName();
    QIconLoader::instance()->setThemeName(mName);
    foreach (const QString &i, iconNames) {
        QThemeIconInfo info = QIconLoader::instance()->loadIcon(i);
        if (!info.entries.isEmpty()) {
            const int numEntries = info.entries.size();

            // Search for exact matches first
            bool found = false;
            for (int i = 0; i < numEntries; ++i) {
                QIconLoaderEngineEntry *entry = info.entries.at(i);
                    icons.append(QIcon(entry->filename));
                    found = true;
                    break;
                }
            if (!found) {  // No exact match. Search for an approximation
                // Find the minimum distance icon
                int minimalSize = INT_MAX;
                QIconLoaderEngineEntry *closestMatch = 0;
                for (int i = 0; i < numEntries; ++i) {
                    QIconLoaderEngineEntry *entry = info.entries.at(i);
                    int distance = directorySizeDistance(entry->dir, PREVIEW_ICON_SIZE);
                    if (distance < minimalSize) {
                        minimalSize  = distance;
                        closestMatch = entry;
                    }
                }
                icons.append(QIcon(closestMatch->filename));
            }
        } else {
            icons.append(QIcon());
        }
    }
    QIconLoader::instance()->setThemeName(currentThemeName);
    return icons;
}
<commit_msg>lxqt-config-appearance: Choose the icon with the matching size<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://sourceforge.net/projects/lxde-qt/
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *   Luis Pereira <luis.artur.pereira@gmail.com>
 *
 * The directoryMatchesSize() and thedirectorySizeDistance() functions were
 * taken from Qt5 qtbase/src/gui/image/qiconloader.cpp
 * Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

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

#include "iconthemeinfo.h"
#include <QDebug>

#include <private/qtxdg/qiconloader_p.h>

#include <QStringBuilder>

#define PREVIEW_ICON_SIZE 22

using namespace QtXdg;

/*
 * This algorithm is defined by the freedesktop spec:
 * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
 */
static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
{
    if (dir.type == QIconDirInfo::Fixed) {
        return dir.size == iconsize;

    } else if (dir.type == QIconDirInfo::Scalable) {
        return dir.size <= dir.maxSize &&
                iconsize >= dir.minSize;

    } else if (dir.type == QIconDirInfo::Threshold) {
        return iconsize >= dir.size - dir.threshold &&
                iconsize <= dir.size + dir.threshold;
    }

    Q_ASSERT(1); // Not a valid value
    return false;
}

/*
 * This algorithm is defined by the freedesktop spec:
 * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
 */
static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
{
    if (dir.type == QIconDirInfo::Fixed) {
        return qAbs(dir.size - iconsize);

    } else if (dir.type == QIconDirInfo::Scalable) {
        if (iconsize < dir.minSize)
            return dir.minSize - iconsize;
        else if (iconsize > dir.maxSize)
            return iconsize - dir.maxSize;
        else
            return 0;

    } else if (dir.type == QIconDirInfo::Threshold) {
        if (iconsize < dir.size - dir.threshold)
            return dir.minSize - iconsize;
        else if (iconsize > dir.size + dir.threshold)
            return iconsize - dir.maxSize;
        else return 0;
    }

    Q_ASSERT(1); // Not a valid value
    return INT_MAX;
}

IconThemeInfo::IconThemeInfo(const QDir &dir):
    mValid(false),
    mHidden(false)
{
    mName = dir.dirName();
    if (dir.exists(QStringLiteral("index.theme")))
        load(dir.absoluteFilePath(QStringLiteral("index.theme")));
}

void IconThemeInfo::load(const QString &fileName)
{
    mFileName = fileName;
    mValid = false;
    QSettings file(mFileName, QSettings::IniFormat);
    if (file.status() != QSettings::NoError)
        return;

    if (file.value(QStringLiteral("Icon Theme/Directories")).toStringList().join(QLatin1Char(' ')).isEmpty())
        return;

    mHidden = file.value(QStringLiteral("Icon Theme/Hidden"), false).toBool();
    mText = file.value(QStringLiteral("Icon Theme/Name")).toString();
    mComment = file.value(QStringLiteral("Icon Theme/Comment")).toString();

    mValid = true;
}

QVector<QIcon> IconThemeInfo::icons(const QStringList &iconNames) const
{
    QVector<QIcon> icons;

    const QString currentThemeName = QIconLoader::instance()->themeName();
    QIconLoader::instance()->setThemeName(mName);
    foreach (const QString &i, iconNames) {
        QThemeIconInfo info = QIconLoader::instance()->loadIcon(i);
        if (!info.entries.isEmpty()) {
            const int numEntries = info.entries.size();

            // Search for exact matches first
            bool found = false;
            for (int i = 0; i < numEntries; ++i) {
                QIconLoaderEngineEntry *entry = info.entries.at(i);
                if (directoryMatchesSize(entry->dir, PREVIEW_ICON_SIZE)) {
                    icons.append(QIcon(entry->filename));
                    found = true;
                    break;
                }
            }
            if (!found) {  // No exact match. Search for an approximation
                // Find the minimum distance icon
                int minimalSize = INT_MAX;
                QIconLoaderEngineEntry *closestMatch = 0;
                for (int i = 0; i < numEntries; ++i) {
                    QIconLoaderEngineEntry *entry = info.entries.at(i);
                    int distance = directorySizeDistance(entry->dir, PREVIEW_ICON_SIZE);
                    if (distance < minimalSize) {
                        minimalSize  = distance;
                        closestMatch = entry;
                    }
                }
                icons.append(QIcon(closestMatch->filename));
            }
        } else {
            icons.append(QIcon());
        }
    }
    QIconLoader::instance()->setThemeName(currentThemeName);
    return icons;
}
<|endoftext|>


<commit_before>#ifndef _DCC_DCC_TEST_UTILS_HXX_
#define _DCC_DCC_TEST_UTILS_HXX_

#include "dcc/DccDebug.hxx"
#include "dcc/Packet.hxx"

void PrintTo(const DCCPacket &pkt, ::std::ostream *os)
{
    *os << dcc::packet_to_string(pkt);
}

namespace dcc
{
void PrintTo(const Packet &pkt, ::std::ostream *os)
{
    *os << packet_to_string(pkt);
}
}

string PrintToString(const dcc::Packet &pkt)
{
    return dcc::packet_to_string(pkt);
}

std::vector<uint8_t> dcc_from(uint8_t d0, uint8_t d1, int d2 = -1, int d3 = -1)
{
    std::vector<uint8_t> ret;
    ret.push_back(d0);
    ret.push_back(d1);
    if (d2 >= 0)
    {
        ret.push_back(d2);
    }
    else if (d2 == -2)
    {
        ret.push_back(d0 ^ d1);
    }
    if (d3 >= 0)
    {
        ret.push_back(d3);
    }
    else if (d3 == -2)
    {
        ret.push_back(d0 ^ d1 ^ ret[2]);
    }
    return ret;
}

dcc::Packet packet_from(uint8_t hdr, std::vector<uint8_t> payload)
{
    dcc::Packet pkt;
    pkt.header_raw_data = hdr;
    pkt.dlc = payload.size();
    memcpy(pkt.payload, &payload[0], pkt.dlc);
    return pkt;
}

MATCHER_P2(PacketIs, hdr, payload,
    std::string(" is a packet of ") + PrintToString(packet_from(hdr, payload)))
{
    dcc::Packet pkt = packet_from(hdr, payload);
    return (pkt.header_raw_data == arg.header_raw_data && pkt.dlc == arg.dlc &&
        memcmp(pkt.payload, arg.payload, pkt.dlc) == 0);
}

#endif // _DCC_DCC_TEST_UTILS_HXX_
<commit_msg>Adds support for 4-byte payload packets to the test util.<commit_after>#ifndef _DCC_DCC_TEST_UTILS_HXX_
#define _DCC_DCC_TEST_UTILS_HXX_

#include "dcc/DccDebug.hxx"
#include "dcc/Packet.hxx"

void PrintTo(const DCCPacket &pkt, ::std::ostream *os)
{
    *os << dcc::packet_to_string(pkt);
}

namespace dcc
{
void PrintTo(const Packet &pkt, ::std::ostream *os)
{
    *os << packet_to_string(pkt);
}
}

string PrintToString(const dcc::Packet &pkt)
{
    return dcc::packet_to_string(pkt);
}

std::vector<uint8_t> dcc_from(uint8_t d0, uint8_t d1, int d2 = -1, int d3 = -1, int d4 = -1)
{
    std::vector<uint8_t> ret;
    ret.push_back(d0);
    ret.push_back(d1);
    if (d2 >= 0)
    {
        ret.push_back(d2);
    }
    else if (d2 == -2)
    {
        ret.push_back(d0 ^ d1);
    }
    if (d3 >= 0)
    {
        ret.push_back(d3);
    }
    else if (d3 == -2)
    {
        ret.push_back(d0 ^ d1 ^ ret[2]);
    }
    if (d4 >= 0)
    {
        ret.push_back(d4);
    }
    else if (d4 == -2)
    {
        ret.push_back(d0 ^ d1 ^ ret[2] ^ ret[3]);
    }
    return ret;
}

dcc::Packet packet_from(uint8_t hdr, std::vector<uint8_t> payload)
{
    dcc::Packet pkt;
    pkt.header_raw_data = hdr;
    pkt.dlc = payload.size();
    memcpy(pkt.payload, &payload[0], pkt.dlc);
    return pkt;
}

MATCHER_P2(PacketIs, hdr, payload,
    std::string(" is a packet of ") + PrintToString(packet_from(hdr, payload)))
{
    dcc::Packet pkt = packet_from(hdr, payload);
    return (pkt.header_raw_data == arg.header_raw_data && pkt.dlc == arg.dlc &&
        memcmp(pkt.payload, arg.payload, pkt.dlc) == 0);
}

#endif // _DCC_DCC_TEST_UTILS_HXX_
<|endoftext|>


<commit_before>#include "Lemke.h"
#include <iostream>

namespace lcpsolver {

    double RandDouble(double _low, double _high)
    {
        double temp;

        /* swap low & high around if the user makes no sense */
        if (_low > _high)
        {
            temp = _low;
            _low = _high;
            _high = temp;
        }

        /* calculate the random number & return it */
        temp = (rand() / (static_cast<double>(RAND_MAX) + 1.0))
            * (_high - _low) + _low;
        return temp;
    }

    int Lemke(const MatrixXd& _M, const VectorXd& _q, VectorXd& _z)
    {
        int n = _q.size();
        CHECK(_M.rows() == n && _M.cols() == n) << "Matrices are not compatible";

	    const double zer_tol = 1e-5;
	    const double piv_tol = 1e-8;
	    int maxiter = min(1000, 50 * n);
	    int err = 0;

	    if (_q.minCoeff() > 0)
	    {
		    LOG(INFO) << "Trivial solution exists.";
		    _z = VectorXd::Zero(n);
		    return err;
	    }

	    _z = VectorXd::Zero(2 * n);

	    int iter = 0;
	    double theta = 0;
	    double ratio = 0;
	    int leaving  = 0;
	    VectorXd Be = VectorXd::Constant(n, 1);
	    VectorXd x = _q;
	    vector<int> bas;
	    vector<int> nonbas;

	    int t = 2 * n + 1;
	    int entering = t;

	    bas.clear();
	    for (int i = 0; i < n; ++i)
	    {
		    nonbas.push_back(i);
		    bas.push_back(i + n);
	    }

	    MatrixXd B = -MatrixXd::Identity(n, n);
	    VectorXd minuxX = -x;
	    int lvindex;
	    double tval = minuxX.maxCoeff(&lvindex);
	    leaving = bas[lvindex];

	    bas[lvindex] = t;
	    VectorXd U = VectorXd::Zero(n);
	    for (int i = 0; i < n; ++i)
	    {
		    if (x[i] < 0)
			    U[i] = 1;
	    }
	    Be = -(B * U);
	    x += tval * U;
	    x[lvindex] = tval;
	    B.col(lvindex) = Be;

	    for (iter = 0; iter < maxiter; ++iter)
	    {
		    if (leaving == t)
		    {
			    break;
		    }
		    else if (leaving < n)
		    {
			    entering = n + leaving;
			    Be = VectorXd::Zero(n);
			    Be[leaving] = -1;
		    }
		    else
		    {
			    entering = leaving - n;
			    Be = _M.col(entering);
		    }
		    VectorXd d = B.fullPivLu().solve(Be);

		    vector<int> j;
		    for (int i = 0; i < n; ++i)
		    {
			    if (d[i] > piv_tol)
				    j.push_back(i);
		    }
		    if (j.empty())
		    {
			    err = 2;
			    break;
		    }
		    int jSize = static_cast<int>(j.size());
		    VectorXd minRatio(jSize);
		    for (int i = 0; i < jSize; ++i)
		    {
			    minRatio[i] = (x[j[i]] + zer_tol) / d[j[i]];
		    }
		    double theta = minRatio.minCoeff();
		    vector<int> tmpJ;
		    for (int i = 0; i < jSize; ++i)
		    {
			    if (x[j[i]] / d[j[i]] <= theta)
				    tmpJ.push_back(j[i]);
		    }
            if (tmpJ.empty())
            {
                LOG(WARNING) << "tmpJ should never be empty!!!";
                LOG(WARNING) << "dumping data:";
                LOG(WARNING) << "theta:" << theta;
                for (int i = 0; i < jSize; ++i)
                {
                    LOG(WARNING) << "x/d(" << j[i] << "): " << x[j[i]] / d[j[i]];
                }
            }
		    j = tmpJ;
		    jSize = static_cast<int>(j.size());
		    lvindex = -1;
		    for (int i = 0; i < jSize; ++i)
		    {
			    if (bas[j[i]] == t)
				    lvindex = i;
		    }
		    if (lvindex != -1)
		    {
			    lvindex = j[lvindex];
		    }
		    else
		    {
                if (jSize == 0)
                {
                    LOG(WARNING) << "JSize should not be zero!!!";
                }
			    VectorXd dj(jSize);
			    for (int i = 0; i < jSize; ++i)
			    {
				    dj[i] = d[j[i]];
			    }
			    theta = dj.maxCoeff(&lvindex);
			    vector<int> lvindexSet;
			    for (int i = 0; i < jSize; ++i)
			    {
				    if (dj[i] == theta)
					    lvindexSet.push_back(i);
			    }
                if (lvindexSet.empty())
                {
                    LOG(WARNING) << "lvindex set should never be empty!!!";
                    LOG(WARNING) << "dumping data:";
                    LOG(WARNING) << "theta:" << theta << " lvindex: " << lvindex;
                    LOG(WARNING) << dj;
                }
			    lvindex = lvindexSet[static_cast<int>((lvindexSet.size() * RandDouble(0, 1)))];
			    lvindex = j[lvindex];

		    }
		    leaving = bas[lvindex];

		    ratio = x[lvindex] / d[lvindex];
		    x = x - ratio * d;
		    x[lvindex] = ratio;
		    B.col(lvindex) = Be;
		    bas[lvindex] = entering;

	    }

	    if (iter >= maxiter && leaving != t)
		    err = 1;

	    //for (size_t i = 0; i < bas.size(); ++i)
     //           cout << "bas[i] = " << bas[i] << " ";
     //       cout << endl;

		if (err == 0)
		{
			for (size_t i = 0; i < bas.size(); ++i) {
				_z[bas[i]] = x[i];
			}

			VectorXd realZ = _z.segment(0, n);
			_z = realZ;

            if (!validate(_M, _z, _q))
            {
                _z = VectorXd::Zero(n);
                err = 3;
            }
		}
		else
		{
			_z = VectorXd::Zero(n); //solve failed, return a 0 vector
		}

	    if (err == 1)
		    LOG(ERROR) << "LCP Solver: Iterations exceeded limit";
	    else if (err == 2)
		    LOG(ERROR) << "LCP Solver: Unbounded ray";
        else if (err == 3)
            LOG(ERROR) << "LCP Solver: Solver converged with numerical issues. Validation failed.";

	    return err;
    }

    bool validate(const MatrixXd& _M, const VectorXd& _z, const VectorXd& _q)
    {
        const double threshold = 1e-4;
        int n = _z.size();

        VectorXd w = _M * _z + _q;
        for (int i = 0; i < n; ++i)
        {
            if (w(i) < -threshold || _z(i) < -threshold)
                return false;
            if (abs(w(i) * _z(i)) > threshold)
                return false;
        }
        return true;
    }

} //namespace lcpsolver
<commit_msg>lcp update<commit_after>#include "Lemke.h"
#include <iostream>

namespace lcpsolver {

    double RandDouble(double _low, double _high)
    {
        double temp;

        /* swap low & high around if the user makes no sense */
        if (_low > _high)
        {
            temp = _low;
            _low = _high;
            _high = temp;
        }

        /* calculate the random number & return it */
        temp = (rand() / (static_cast<double>(RAND_MAX) + 1.0))
            * (_high - _low) + _low;
        return temp;
    }

    int Lemke(const MatrixXd& _M, const VectorXd& _q, VectorXd& _z)
    {
        int n = _q.size();
        CHECK(_M.rows() == n && _M.cols() == n) << "Matrices are not compatible";

	    const double zer_tol = 1e-5;
	    const double piv_tol = 1e-8;
	    int maxiter = min(1000, 50 * n);
	    int err = 0;

	    if (_q.minCoeff() > 0)
	    {
		    LOG(INFO) << "Trivial solution exists.";
		    _z = VectorXd::Zero(n);
		    return err;
	    }

	    _z = VectorXd::Zero(2 * n);

	    int iter = 0;
	    double theta = 0;
	    double ratio = 0;
	    int leaving  = 0;
	    VectorXd Be = VectorXd::Constant(n, 1);
	    VectorXd x = _q;
	    vector<int> bas;
	    vector<int> nonbas;

	    int t = 2 * n + 1;
	    int entering = t;

	    bas.clear();
	    for (int i = 0; i < n; ++i)
	    {
		    nonbas.push_back(i);
		    bas.push_back(i + n);
	    }

	    MatrixXd B = -MatrixXd::Identity(n, n);
	    VectorXd minuxX = -x;
	    int lvindex;
	    double tval = minuxX.maxCoeff(&lvindex);
	    leaving = bas[lvindex];

	    bas[lvindex] = t;
	    VectorXd U = VectorXd::Zero(n);
	    for (int i = 0; i < n; ++i)
	    {
		    if (x[i] < 0)
			    U[i] = 1;
	    }
	    Be = -(B * U);
	    x += tval * U;
	    x[lvindex] = tval;
	    B.col(lvindex) = Be;

	    for (iter = 0; iter < maxiter; ++iter)
	    {
		    if (leaving == t)
		    {
			    break;
		    }
		    else if (leaving < n)
		    {
			    entering = n + leaving;
			    Be = VectorXd::Zero(n);
			    Be[leaving] = -1;
		    }
		    else
		    {
			    entering = leaving - n;
			    Be = _M.col(entering);
		    }
		    VectorXd d = B.fullPivLu().solve(Be);

		    vector<int> j;
		    for (int i = 0; i < n; ++i)
		    {
			    if (d[i] > piv_tol)
				    j.push_back(i);
		    }
		    if (j.empty())
		    {
			    err = 2;
			    break;
		    }
		    int jSize = static_cast<int>(j.size());
		    VectorXd minRatio(jSize);
		    for (int i = 0; i < jSize; ++i)
		    {
			    minRatio[i] = (x[j[i]] + zer_tol) / d[j[i]];
		    }
		    double theta = minRatio.minCoeff();
		    vector<int> tmpJ;
                    vector<double> tmpMinRatio;
		    for (int i = 0; i < jSize; ++i)
		    {
			    if (x[j[i]] / d[j[i]] <= theta)
                                {
				    tmpJ.push_back(j[i]);
                                    tmpMinRatio.push_back(minRatio[i]);
                                }
		    }
//             if (tmpJ.empty())
//             {
//                 LOG(WARNING) << "tmpJ should never be empty!!!";
//                 LOG(WARNING) << "dumping data:";
//                 LOG(WARNING) << "theta:" << theta;
//                 for (int i = 0; i < jSize; ++i)
//                 {
//                     LOG(WARNING) << "x(" << j[i] << "): " << x[j[i]] << "d: " << d[j[i]];
//                 }
//             }
		    j = tmpJ;
		    jSize = static_cast<int>(j.size());
		    lvindex = -1;
		    for (int i = 0; i < jSize; ++i)
		    {
			    if (bas[j[i]] == t)
				    lvindex = i;
		    }
		    if (lvindex != -1)
		    {
			    lvindex = j[lvindex];
		    }
		    else
		    {
                        theta = 1e30;
                        for (int i = 0; i < jSize; ++i)
                            {
                                if (tmpMinRatio[i] < theta)
                                    {
                                        theta = tmpMinRatio[i];
                                        lvindex = i;
                                    }
                            }
// 			    VectorXd dj(jSize);
// 			    for (int i = 0; i < jSize; ++i)
// 			    {
// 				    dj[i] = d[j[i]];
// 			    }
// 			    theta = dj.maxCoeff(&lvindex);
// 			    vector<int> lvindexSet;
// 			    for (int i = 0; i < jSize; ++i)
// 			    {
// 				    if (dj[i] == theta)
// 					    lvindexSet.push_back(i);
// 			    }
//			    lvindex = lvindexSet[static_cast<int>((lvindexSet.size() * RandDouble(0, 1)))];
			    lvindex = j[lvindex];

		    }
		    leaving = bas[lvindex];

		    ratio = x[lvindex] / d[lvindex];

                    for (int i = 0; i < n; ++i)
                        {
                            if (x[i] != x[i] || isinf(x[i]))
                                {
                                    err = 4;
                                    _z = VectorXd::Zero(n);
                                    LOG(ERROR) << "LCP: iteration diverged.";
                                    return err;
                                }
                        }
		    x = x - ratio * d;
		    x[lvindex] = ratio;
		    B.col(lvindex) = Be;
		    bas[lvindex] = entering;

	    }

	    if (iter >= maxiter && leaving != t)
		    err = 1;

	    //for (size_t i = 0; i < bas.size(); ++i)
     //           cout << "bas[i] = " << bas[i] << " ";
     //       cout << endl;

		if (err == 0)
		{
			for (size_t i = 0; i < bas.size(); ++i) {
				_z[bas[i]] = x[i];
			}

			VectorXd realZ = _z.segment(0, n);
			_z = realZ;

            if (!validate(_M, _z, _q))
            {
                _z = VectorXd::Zero(n);
                err = 3;
            }
		}
		else
		{
			_z = VectorXd::Zero(n); //solve failed, return a 0 vector
		}

	    if (err == 1)
		    LOG(ERROR) << "LCP Solver: Iterations exceeded limit";
	    else if (err == 2)
		    LOG(ERROR) << "LCP Solver: Unbounded ray";
        else if (err == 3)
            LOG(ERROR) << "LCP Solver: Solver converged with numerical issues. Validation failed.";

	    return err;
    }

    bool validate(const MatrixXd& _M, const VectorXd& _z, const VectorXd& _q)
    {
        const double threshold = 1e-4;
        int n = _z.size();

        VectorXd w = _M * _z + _q;
        for (int i = 0; i < n; ++i)
        {
            if (w(i) < -threshold || _z(i) < -threshold)
                return false;
            if (abs(w(i) * _z(i)) > threshold)
                return false;
        }
        return true;
    }

} //namespace lcpsolver
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 11/10/2019, 5:08:05 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{998244353LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};

class UnionFind
{
  int N;
  vector<int> par;

public:
  UnionFind() : N{0} {}
  UnionFind(int N) : N{N}, par(N, -1) {}

  bool is_same(int x, int y)
  {
    return root(x) == root(y);
  }

  bool merge(int x, int y)
  {
    x = root(x);
    y = root(y);
    if (x == y)
    {
      return false;
    }
    if (par[x] > par[y])
    {
      swap(x, y);
    }
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  int size(int x)
  {
    return -par[root(x)];
  }

  int count_parts()
  {
    int ans{0};
    for (auto i = 0; i < N; i++)
    {
      if (root(i) < 0)
      {
        ++ans;
      }
    }
    return ans;
  }

private:
  int root(int x)
  {
    if (par[x] < 0)
    {
      return x;
    }
    return par[x] = root(par[x]);
  }
};

// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "0" << endl;
  exit(0);
}

enum class State
{
  empty,
  on,
  off,
  que,
  used,
  invalid
};

vector<vector<State>> make_states(int N, vector<string> const &A)
{
  vector<vector<State>> V(N + 1, vector<State>(N + 1, State::empty));
  for (auto i = 1; i <= N; i++)
  {
    for (auto j = 1; j <= N; j++)
    {
      char c{A[i - 1][j - 1]};
      int a{abs(i - j)};
      int b{min(2 * N - i - j, i + j)};
#if DEBUG == 1
      cerr << "(" << i << ", " << j << ") = " << a << ", " << b << endl;
#endif
      assert(a != b);
      State s;
      if (c == 'o')
      {
        s = State::on;
      }
      else if (c == 'x')
      {
        s = State::off;
      }
      else
      {
        assert(c == '?');
        s = State::que;
      }
      if (V[a][b] == State::empty)
      {
        V[a][b] = V[b][a] = s;
      }
      else if (V[a][b] != s)
      {
        if ((s == State::on && V[a][b] == State::off) || (s == State::off && V[a][b] == State::on))
        {
          No();
        }
        if (V[a][b] == State::que)
        {
          V[a][b] = V[b][a] = s;
        }
      }
    }
  }
  return V;
}

mint calc_even(int N, vector<vector<State>> &V, int K);
mint calc_odd(int N, vector<vector<State>> &V, int K);

mint calc(int N, vector<vector<State>> &V, int K)
{
  int Y{N / 2};
  int X{N - Y};
  int U;
  if (K == 0)
  {
    U = X;
  }
  else
  {
    assert(K == 1);
    U = Y;
  }
  if (U % 2 == 0)
  {
    return calc_even(N, V, K);
  }
  else
  {
    return calc_odd(N, V, K);
  }
}

mint calc_even(int N, vector<vector<State>> &V, int K)
{
  int cnt{0};
  for (auto i = K; i < N; i += 2)
  {
    for (auto j = K; j < N; j += 2)
    {
      if (V[i][j] == State::que)
      {
        ++cnt;
      }
    }
  }
  cnt /= 2;
  return mint{2}.power(cnt);
}

mint calc_odd(int N, vector<vector<State>> &V, int K)
{
  int cnt{0};
  UnionFind uf(N);
  for (auto i = K; i < N; i += 2)
  {
    for (auto j = i + 2; j < N; j += 2)
    {
      if (V[i][j] == State::que && !uf.merge(i, j))
      {
        ++cnt;
      }
    }
  }
  // working on each connected components
  vector<bool> visited(N, false);
  for (auto i = K; i < N; i += 2)
  {
    if (visited[i])
    {
      continue;
    }
    for (auto j = K; j < N; j += 2)
    {
      if (uf.is_same(i, j))
      {
        visited[j] = true;
      }
    }
    int c{0};
    for (auto j = K; j < N; j += 2)
    {
      for (auto k = K; k < N; k += 2)
      {
        if (uf.is_same(i, j) && !uf.is_same(i, k) && V[j][k] == State::on)
        {
          ++c;
        }
      }
    }
    if (c % 2 == 1)
    {
      No();
    }
  }
  return mint{2}.power(cnt);
}

int main()
{
  int N;
  cin >> N;
  vector<string> A(N);
  for (auto i = 0; i < N - 1; i++)
  {
    cin >> A[i];
  }
  vector<vector<State>> V{make_states(N, A)};
  ++N;
  mint ans{1};
  ans *= calc(N, V, 0);
  ans *= calc(N, V, 1);
  cout << ans << endl;
}
<commit_msg>submit F.cpp to 'F - Mirror Frame' (nikkei2019-2-qual) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 11/10/2019, 5:08:05 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{998244353LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};

class UnionFind
{
  int N;
  vector<int> par;

public:
  UnionFind() : N{0} {}
  UnionFind(int N) : N{N}, par(N, -1) {}

  bool is_same(int x, int y)
  {
    return root(x) == root(y);
  }

  bool merge(int x, int y)
  {
    x = root(x);
    y = root(y);
    if (x == y)
    {
      return false;
    }
    if (par[x] > par[y])
    {
      swap(x, y);
    }
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  int size(int x)
  {
    return -par[root(x)];
  }

  int count_parts()
  {
    int ans{0};
    for (auto i = 0; i < N; i++)
    {
      if (root(i) < 0)
      {
        ++ans;
      }
    }
    return ans;
  }

private:
  int root(int x)
  {
    if (par[x] < 0)
    {
      return x;
    }
    return par[x] = root(par[x]);
  }
};

// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "0" << endl;
  exit(0);
}

enum class State
{
  empty,
  on,
  off,
  que,
  used,
  invalid
};

vector<vector<State>> make_states(int N, vector<string> const &A)
{
  vector<vector<State>> V(N + 1, vector<State>(N + 1, State::empty));
  for (auto i = 1; i < N; i++)
  {
    for (auto j = 1; j < N; j++)
    {
      char c{A[i - 1][j - 1]};
      int a{abs(i - j)};
      int b{min(2 * N - i - j, i + j)};
#if DEBUG == 1
      cerr << "(" << i << ", " << j << ") = " << a << ", " << b << endl;
#endif
      assert(a != b);
      State s;
      if (c == 'o')
      {
        s = State::on;
      }
      else if (c == 'x')
      {
        s = State::off;
      }
      else
      {
        assert(c == '?');
        s = State::que;
      }
      if (V[a][b] == State::empty)
      {
        V[a][b] = V[b][a] = s;
      }
      else if (V[a][b] != s)
      {
        if ((s == State::on && V[a][b] == State::off) || (s == State::off && V[a][b] == State::on))
        {
          No();
        }
        if (V[a][b] == State::que)
        {
          V[a][b] = V[b][a] = s;
        }
      }
    }
  }
  return V;
}

mint calc_even(int N, vector<vector<State>> &V, int K);
mint calc_odd(int N, vector<vector<State>> &V, int K);

mint calc(int N, vector<vector<State>> &V, int K)
{
  int Y{N / 2};
  int X{N - Y};
  int U;
  if (K == 0)
  {
    U = X;
  }
  else
  {
    assert(K == 1);
    U = Y;
  }
  if (U % 2 == 0)
  {
    return calc_even(N, V, K);
  }
  else
  {
    return calc_odd(N, V, K);
  }
}

mint calc_even(int N, vector<vector<State>> &V, int K)
{
  int cnt{0};
  for (auto i = K; i < N; i += 2)
  {
    for (auto j = K; j < N; j += 2)
    {
      if (V[i][j] == State::que)
      {
        ++cnt;
      }
    }
  }
  cnt /= 2;
  return mint{2}.power(cnt);
}

mint calc_odd(int N, vector<vector<State>> &V, int K)
{
  int cnt{0};
  UnionFind uf(N);
  for (auto i = K; i < N; i += 2)
  {
    for (auto j = i + 2; j < N; j += 2)
    {
      if (V[i][j] == State::que && !uf.merge(i, j))
      {
        ++cnt;
      }
    }
  }
  // working on each connected components
  vector<bool> visited(N, false);
  for (auto i = K; i < N; i += 2)
  {
    if (visited[i])
    {
      continue;
    }
    for (auto j = K; j < N; j += 2)
    {
      if (uf.is_same(i, j))
      {
        visited[j] = true;
      }
    }
    int c{0};
    for (auto j = K; j < N; j += 2)
    {
      for (auto k = K; k < N; k += 2)
      {
        if (uf.is_same(i, j) && !uf.is_same(i, k) && V[j][k] == State::on)
        {
          ++c;
        }
      }
    }
    if (c % 2 == 1)
    {
      No();
    }
  }
  return mint{2}.power(cnt);
}

int main()
{
  int N;
  cin >> N;
  vector<string> A(N);
  for (auto i = 0; i < N - 1; i++)
  {
    cin >> A[i];
  }
  vector<vector<State>> V{make_states(N, A)};
  ++N;
  mint ans{1};
  ans *= calc(N, V, 0);
  ans *= calc(N, V, 1);
  cout << ans << endl;
}
<|endoftext|>


<commit_before>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

// See docs in ../ops/array_ops.cc.
#include "tensorflow/core/kernels/reshape_op.h"

namespace tensorflow {

REGISTER_KERNEL_BUILDER(Name("Reshape")
                            .Device(DEVICE_CPU)
                            .HostMemory("shape")
                            .TypeConstraint<int32>("Tshape"),
                        ReshapeOp);

#define REGISTER_GPU_KERNEL(type)                               \
  REGISTER_KERNEL_BUILDER(Name("Reshape")                       \
                              .Device(DEVICE_GPU)               \
                              .HostMemory("shape")              \
                              .TypeConstraint<type>("T")        \
                              .TypeConstraint<int32>("Tshape"), \
                          ReshapeOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
#undef REGISTER_GPU_KERNEL

#ifdef TENSORFLOW_USE_SYCL
#define REGISTER_SYCL_KERNEL(type)                              \
  REGISTER_KERNEL_BUILDER(Name("Reshape")                       \
                              .Device(DEVICE_SYCL)              \
                              .HostMemory("shape")              \
                              .TypeConstraint<type>("T")        \
                              .TypeConstraint<int32>("Tshape"), \
                          ReshapeOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_SYCL_KERNEL);
#undef REGISTER_SYCL_KERNEL

REGISTER_KERNEL_BUILDER(Name("Reshape")
                            .Device(DEVICE_SYCL)
                            .HostMemory("tensor")
                            .HostMemory("shape")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T")
                            .TypeConstraint<int32>("Tshape"),
                        ReshapeOp);
#endif  // TENSORFLOW_USE_SYCL

#if GOOGLE_CUDA
// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("Reshape")
                            .Device(DEVICE_GPU)
                            .HostMemory("tensor")
                            .HostMemory("shape")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T")
                            .TypeConstraint<int32>("Tshape"),
                        ReshapeOp);
#endif

}  // namespace tensorflow
<commit_msg>[OpenCL] Cleans reshape.cc (#10347)<commit_after>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

// See docs in ../ops/array_ops.cc.
#include "tensorflow/core/kernels/reshape_op.h"

namespace tensorflow {

REGISTER_KERNEL_BUILDER(Name("Reshape")
                            .Device(DEVICE_CPU)
                            .HostMemory("shape")
                            .TypeConstraint<int32>("Tshape"),
                        ReshapeOp);

#define REGISTER_GPU_KERNEL(type)                               \
  REGISTER_KERNEL_BUILDER(Name("Reshape")                       \
                              .Device(DEVICE_GPU)               \
                              .HostMemory("shape")              \
                              .TypeConstraint<type>("T")        \
                              .TypeConstraint<int32>("Tshape"), \
                          ReshapeOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
#undef REGISTER_GPU_KERNEL

#ifdef TENSORFLOW_USE_SYCL
#define REGISTER_SYCL_KERNEL(type)                              \
  REGISTER_KERNEL_BUILDER(Name("Reshape")                       \
                              .Device(DEVICE_SYCL)              \
                              .HostMemory("shape")              \
                              .TypeConstraint<type>("T")        \
                              .TypeConstraint<int32>("Tshape"), \
                          ReshapeOp);
REGISTER_SYCL_KERNEL(float)
REGISTER_SYCL_KERNEL(double)
REGISTER_SYCL_KERNEL(uint8)
REGISTER_SYCL_KERNEL(int8)
REGISTER_SYCL_KERNEL(int64)
REGISTER_SYCL_KERNEL(uint16)

REGISTER_KERNEL_BUILDER(Name("Reshape")
                            .Device(DEVICE_SYCL)
                            .HostMemory("tensor")
                            .HostMemory("shape")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T")
                            .TypeConstraint<int32>("Tshape"),
                        ReshapeOp);
#undef REGISTER_SYCL_KERNEL
#endif  // TENSORFLOW_USE_SYCL

#if GOOGLE_CUDA
// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("Reshape")
                            .Device(DEVICE_GPU)
                            .HostMemory("tensor")
                            .HostMemory("shape")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T")
                            .TypeConstraint<int32>("Tshape"),
                        ReshapeOp);
#endif

}  // namespace tensorflow
<|endoftext|>


<commit_before>/*
 * ping_pong_sparring.cpp
 *
 *  Created on: May 8, 2016
 *      Author: zmij
 */

#include <iostream>
#include "ping_pong_impl.hpp"

#include <wire/core/connector.hpp>
#include <wire/core/adapter.hpp>
#include <wire/core/proxy.hpp>

int
main(int argc, char* argv[])
try {
    using namespace ::wire::core;

    ::wire::asio_config::io_service_ptr io_service =
            ::std::make_shared< ::wire::asio_config::io_service >();

    connector_ptr conn = connector::create_connector(io_service, argc, argv);
    adapter_ptr adptr = conn->create_adapter(
            "ping_pong", { ::wire::core::endpoint::tcp("127.0.0.1", 0) });

    adptr->activate();
    auto prx = adptr->add_object({"ping_pong"},
            ::std::make_shared< wire::test::ping_pong_server >([io_service](){ io_service->stop(); }) );
    ::std::cout << *prx << ::std::endl;

    io_service->run();
    return 0;
} catch (::std::exception const& e) {
    ::std::cerr << "Exception: " << e.what() << "\n";
    return 1;
} catch (...) {
    ::std::cerr << "Unexpected exception\n";
    return 2;
}
<commit_msg>Add a port parameter to ping-pong-sparring program<commit_after>/*
 * ping_pong_sparring.cpp
 *
 *  Created on: May 8, 2016
 *      Author: zmij
 */

#include <iostream>
#include "ping_pong_impl.hpp"

#include <wire/core/connector.hpp>
#include <wire/core/adapter.hpp>
#include <wire/core/proxy.hpp>

#include <boost/program_options.hpp>

int
main(int argc, char* argv[])
try {
    using namespace ::wire::core;
    namespace po = ::boost::program_options;
    ::std::uint16_t port_no{0};
    po::options_description desc("Test options");

    desc.add_options()
        ("help,h", "show options description")
        ("port,p",
            po::value< ::std::uint16_t >(&port_no),
            "Port to bind to")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 0;
    }
    po::notify(vm);

    ::wire::asio_config::io_service_ptr io_service =
            ::std::make_shared< ::wire::asio_config::io_service >();

    connector_ptr conn = connector::create_connector(io_service, argc, argv);
    adapter_ptr adptr = conn->create_adapter(
            "ping_pong", { ::wire::core::endpoint::tcp("127.0.0.1", port_no) });

    adptr->activate();
    auto prx = adptr->add_object({"ping_pong"},
            ::std::make_shared< wire::test::ping_pong_server >([io_service](){ io_service->stop(); }) );
    ::std::cout << *prx << ::std::endl;

    io_service->run();
    return 0;
} catch (::std::exception const& e) {
    ::std::cerr << "Exception: " << e.what() << "\n";
    return 1;
} catch (...) {
    ::std::cerr << "Unexpected exception\n";
    return 2;
}
<|endoftext|>


<commit_before>#ifndef VER_INT_H
#define VER_INT_H

#include <vector>
#include <string>
#include <algorithm>
#ifdef _MSC_VER
    #include <win32\stdint.h>
#endif
#include <stdio.h>
#include "verified_integer.hpp"

using namespace std;
using namespace tightdb;

void VerifiedInteger::verify_neighbours(size_t ndx)
{
    if (v.size() > ndx)
        TIGHTDB_ASSERT(v[ndx] == u.get(ndx));

    if (ndx > 0)
        TIGHTDB_ASSERT(v[ndx - 1] == u.get(ndx - 1));

    if (v.size() > ndx + 1)
        TIGHTDB_ASSERT(v[ndx + 1] == u.get(ndx + 1));
}

void VerifiedInteger::add(int64_t value)
{
    v.push_back(value);
    u.add(value);
    TIGHTDB_ASSERT(v.size() == u.size());
    verify_neighbours(v.size());
    TIGHTDB_ASSERT(conditional_verify());
}

void VerifiedInteger::insert(size_t ndx, int64_t value)
{
    v.insert(v.begin() + ndx, value);
    u.insert(ndx, value);
    TIGHTDB_ASSERT(v.size() == u.size());
    verify_neighbours(ndx);
    TIGHTDB_ASSERT(conditional_verify());
}

int64_t VerifiedInteger::get(size_t ndx)
{
    TIGHTDB_ASSERT(v[ndx] == u.get(ndx));
    return v[ndx];
}

int64_t VerifiedInteger::sum(size_t start, size_t end)
{
    int64_t sum = 0;

    if (start == end)
        return 0;

    if (end == size_t(-1))
        end = v.size();

    for (size_t t = start; t < end; ++t)
        sum += v[t];

    TIGHTDB_ASSERT(sum == u.sum(start, end));
    return sum;
}

int64_t VerifiedInteger::maximum(size_t start, size_t end)
{
    if (end == size_t(-1))
        end = v.size();

    if (end == start)
        return 0;

    int64_t max = v[start];

    for (size_t t = start + 1; t < end; ++t)
        if (v[t] > max)
            max = v[t];

    TIGHTDB_ASSERT(max == u.maximum(start, end));
    return max;
}

int64_t VerifiedInteger::minimum(size_t start, size_t end)
{
    if (end == size_t(-1))
        end = v.size();

    if (end == start)
        return 0;

    int64_t min = v[start];

    for (size_t t = start + 1; t < end; ++t)
        if (v[t] < min)
            min = v[t];

    TIGHTDB_ASSERT(min == u.minimum(start, end));
    return min;
}

void VerifiedInteger::set(size_t ndx, int64_t value)
{
    v[ndx] = value;
    u.set(ndx, value);
    verify_neighbours(ndx);
    TIGHTDB_ASSERT(conditional_verify());
}

void VerifiedInteger::erase(size_t ndx)
{
    v.erase(v.begin() + ndx);
    u.erase(ndx, ndx == u.size());
    TIGHTDB_ASSERT(v.size() == u.size());
    verify_neighbours(ndx);
    TIGHTDB_ASSERT(conditional_verify());
}

void VerifiedInteger::clear()
{
    v.clear();
    u.clear();
    TIGHTDB_ASSERT(v.size() == u.size());
    TIGHTDB_ASSERT(conditional_verify());
}

size_t VerifiedInteger::find_first(int64_t value)
{
    std::vector<int64_t>::iterator it = std::find(v.begin(), v.end(), value);
    size_t ndx = std::distance(v.begin(), it);
    size_t index2 = u.find_first(value);
    TIGHTDB_ASSERT(ndx == index2 || (it == v.end() && index2 == size_t(-1)));
    static_cast<void>(index2);
    return ndx;
}

size_t VerifiedInteger::size()
{
    TIGHTDB_ASSERT(v.size() == u.size());
    return v.size();
}

// todo/fixme, end ignored
void VerifiedInteger::find_all(Array &c, int64_t value, size_t start, size_t end)
{
    std::vector<int64_t>::iterator ita = v.begin() + start;
    std::vector<int64_t>::iterator itb = end == size_t(-1) ? v.end() : v.begin() + (end == size_t(-1) ? v.size() : end);;
    std::vector<size_t> result;
    while (ita != itb) {
        ita = std::find(ita, itb, value);
        size_t ndx = std::distance(v.begin(), ita);
        if (ndx < v.size()) {
            result.push_back(ndx);
            ita++;
        }
    }

    c.clear();

    u.find_all(c, value);
    if (c.size() != result.size())
        TIGHTDB_ASSERT(false);
    for (size_t t = 0; t < result.size(); ++t) {
        if (result[t] != size_t(c.get(t)))
            TIGHTDB_ASSERT(false);
    }

    return;
}

bool VerifiedInteger::Verify()
{
    TIGHTDB_ASSERT(u.size() == v.size());
    if (u.size() != v.size())
        return false;

    for (size_t t = 0; t < v.size(); ++t) {
        TIGHTDB_ASSERT(v[t] == u.get(t));
        if (v[t] != u.get(t))
            return false;
    }
    return true;
}

// makes it run amortized the same time complexity as original, even though the row count grows
bool VerifiedInteger::conditional_verify()
{
    if ((uint64_t(rand()) * uint64_t(rand()))  % (v.size() / 10 + 1) == 0) {
        return Verify();
    }
    else {
        return true;
    }
}

void VerifiedInteger::destroy()
{
    u.destroy();
}

#endif
<commit_msg>Update verified_integer.cpp<commit_after>#ifndef VER_INT_H
#define VER_INT_H

#include <vector>
#include <string>
#include <algorithm>
#ifdef _MSC_VER
    #include <win32\stdint.h>
#endif
#include <stdio.h>
#include "verified_integer.hpp"

using namespace std;
using namespace tightdb;

void VerifiedInteger::verify_neighbours(size_t ndx)
{
    if (v.size() > ndx)
        TIGHTDB_ASSERT(v[ndx] == u.get(ndx));

    if (ndx > 0)
        TIGHTDB_ASSERT(v[ndx - 1] == u.get(ndx - 1));

    if (v.size() > ndx + 1)
        TIGHTDB_ASSERT(v[ndx + 1] == u.get(ndx + 1));
}

void VerifiedInteger::add(int64_t value)
{
    v.push_back(value);
    u.add(value);
    TIGHTDB_ASSERT(v.size() == u.size());
    verify_neighbours(v.size());
    TIGHTDB_ASSERT(conditional_verify());
}

void VerifiedInteger::insert(size_t ndx, int64_t value)
{
    v.insert(v.begin() + ndx, value);
    u.insert(ndx, value);
    TIGHTDB_ASSERT(v.size() == u.size());
    verify_neighbours(ndx);
    TIGHTDB_ASSERT(conditional_verify());
}

int64_t VerifiedInteger::get(size_t ndx)
{
    TIGHTDB_ASSERT(v[ndx] == u.get(ndx));
    return v[ndx];
}

int64_t VerifiedInteger::sum(size_t start, size_t end)
{
    int64_t sum = 0;

    if (start == end)
        return 0;

    if (end == size_t(-1))
        end = v.size();

    for (size_t t = start; t < end; ++t)
        sum += v[t];

    TIGHTDB_ASSERT(sum == u.sum(start, end));
    return sum;
}

int64_t VerifiedInteger::maximum(size_t start, size_t end)
{
    if (end == size_t(-1))
        end = v.size();

    if (end == start)
        return 0;

    int64_t max = v[start];

    for (size_t t = start + 1; t < end; ++t)
        if (v[t] > max)
            max = v[t];

    TIGHTDB_ASSERT(max == u.maximum(start, end));
    return max;
}

int64_t VerifiedInteger::minimum(size_t start, size_t end)
{
    if (end == size_t(-1))
        end = v.size();

    if (end == start)
        return 0;

    int64_t min = v[start];

    for (size_t t = start + 1; t < end; ++t)
        if (v[t] < min)
            min = v[t];

    TIGHTDB_ASSERT(min == u.minimum(start, end));
    return min;
}

void VerifiedInteger::set(size_t ndx, int64_t value)
{
    v[ndx] = value;
    u.set(ndx, value);
    verify_neighbours(ndx);
    TIGHTDB_ASSERT(conditional_verify());
}

void VerifiedInteger::erase(size_t ndx)
{
    v.erase(v.begin() + ndx);
    u.erase(ndx, ndx + 1 == u.size());
    TIGHTDB_ASSERT(v.size() == u.size());
    verify_neighbours(ndx);
    TIGHTDB_ASSERT(conditional_verify());
}

void VerifiedInteger::clear()
{
    v.clear();
    u.clear();
    TIGHTDB_ASSERT(v.size() == u.size());
    TIGHTDB_ASSERT(conditional_verify());
}

size_t VerifiedInteger::find_first(int64_t value)
{
    std::vector<int64_t>::iterator it = std::find(v.begin(), v.end(), value);
    size_t ndx = std::distance(v.begin(), it);
    size_t index2 = u.find_first(value);
    TIGHTDB_ASSERT(ndx == index2 || (it == v.end() && index2 == size_t(-1)));
    static_cast<void>(index2);
    return ndx;
}

size_t VerifiedInteger::size()
{
    TIGHTDB_ASSERT(v.size() == u.size());
    return v.size();
}

// todo/fixme, end ignored
void VerifiedInteger::find_all(Array &c, int64_t value, size_t start, size_t end)
{
    std::vector<int64_t>::iterator ita = v.begin() + start;
    std::vector<int64_t>::iterator itb = end == size_t(-1) ? v.end() : v.begin() + (end == size_t(-1) ? v.size() : end);;
    std::vector<size_t> result;
    while (ita != itb) {
        ita = std::find(ita, itb, value);
        size_t ndx = std::distance(v.begin(), ita);
        if (ndx < v.size()) {
            result.push_back(ndx);
            ita++;
        }
    }

    c.clear();

    u.find_all(c, value);
    if (c.size() != result.size())
        TIGHTDB_ASSERT(false);
    for (size_t t = 0; t < result.size(); ++t) {
        if (result[t] != size_t(c.get(t)))
            TIGHTDB_ASSERT(false);
    }

    return;
}

bool VerifiedInteger::Verify()
{
    TIGHTDB_ASSERT(u.size() == v.size());
    if (u.size() != v.size())
        return false;

    for (size_t t = 0; t < v.size(); ++t) {
        TIGHTDB_ASSERT(v[t] == u.get(t));
        if (v[t] != u.get(t))
            return false;
    }
    return true;
}

// makes it run amortized the same time complexity as original, even though the row count grows
bool VerifiedInteger::conditional_verify()
{
    if ((uint64_t(rand()) * uint64_t(rand()))  % (v.size() / 10 + 1) == 0) {
        return Verify();
    }
    else {
        return true;
    }
}

void VerifiedInteger::destroy()
{
    u.destroy();
}

#endif
<|endoftext|>


<commit_before>#include <thread>
#include <iostream>
#include <vector>
#include <gtest/gtest.h>
#include "net/sender.hpp"
#include "net/receiver.hpp"

using namespace std;
using namespace net;

static mutex m;

TEST(ReceiverAndSenderTest,runTwoThreads)
{
    int s{0};
    int test[1000];
    for(auto& i : test)
        i = ++s;

    thread t1{
        [&test]{
            receiver rver{"228.0.0.4", "54321"};
            istream is{rver.join()};
            {
                unique_lock<mutex> l{m};
                clog << "Listening: " << rver.group() << '.' << rver.service() << endl;
            }
            for(auto i : test)
            {
                int ii;
                is >> ii;
                ASSERT_EQ(i,ii);
                unique_lock<mutex> l{m};
                clog << "Receiver: " << ii << endl;
            }
        }
    };

    thread t2{
        [&test]{
            sender sder{"228.0.0.4", "54321"};
            ostream os{sder.distribute()};
            for(auto i : test)
            {
                this_thread::sleep_for(1ms);
                os << i << endl;
                unique_lock<mutex> l{m};
                clog << "Sender: " << i << endl;
            }
        }
    };

    t1.join();
    t2.join();
}

TEST(ReceiverAndSenderTest,runManyThreads)
{
    int s{0};
    int test[1000];
    for(auto& i : test)
        i = ++s;

    vector<thread> threads;

    for(int i = 100; --i; i)
        threads.push_back(thread{
            [&test]{
                receiver rver{"228.0.0.4", "54321"};
                istream is{rver.join()};
                {
                    unique_lock<mutex> l{m};
                    clog << "Listening: " << rver.group() << '.' << rver.service() << endl;
                }
                for(auto i : test)
                {
                    int ii;
                    is >> ii;
                    ASSERT_EQ(i,ii);
                    unique_lock<mutex> l{m};
                    clog << "Receiver: " << ii << endl;
                }
            }
        }
        );

    threads.push_back(thread{
        [&test]{
            sender sder{"228.0.0.4", "54321"};
            ostream os{sder.distribute()};
            for(auto i : test)
            {
                this_thread::sleep_for(1ms);
                os << i << endl;
                unique_lock<mutex> l{m};
                clog << "Sender: " << i << endl;
            }
        }
    }
    );

    for(auto& thr : threads)
        thr.join();
}
<commit_msg>Update test_receiver_and_sender.cpp<commit_after>#include <thread>
#include <iostream>
#include <vector>
#include <gtest/gtest.h>
#include "net/sender.hpp"
#include "net/receiver.hpp"

using namespace std;
using namespace net;

static mutex m;

TEST(ReceiverAndSenderTest,runTwoThreads)
{
    int s{0};
    int test[1000];
    for(auto& i : test)
        i = ++s;

    thread t1{
        [&test]{
            receiver rver{"228.0.0.4", "54321"};
            istream is{rver.join()};
            {
                unique_lock<mutex> l{m};
                clog << "Listening: " << rver.group() << '.' << rver.service() << endl;
            }
            for(auto i : test)
            {
                int ii;
                is >> ii;
                ASSERT_EQ(i,ii);
                unique_lock<mutex> l{m};
                clog << "Receiver: " << ii << endl;
            }
        }
    };

    thread t2{
        [&test]{
            sender sder{"228.0.0.4", "54321"};
            ostream os{sder.distribute()};
            for(auto i : test)
            {
                this_thread::sleep_for(1ms);
                os << i << endl;
                unique_lock<mutex> l{m};
                clog << "Sender: " << i << endl;
            }
        }
    };

    t1.join();
    t2.join();
}

TEST(ReceiverAndSenderTest,runManyThreads)
{
    int s{0};
    int test[1000];
    for(auto& i : test)
        i = ++s;

    vector<thread> threads;

    for(int i = 100; --i; i > 0)
        threads.push_back(thread{
            [&test]{
                receiver rver{"228.0.0.4", "54321"};
                istream is{rver.join()};
                {
                    unique_lock<mutex> l{m};
                    clog << "Listening: " << rver.group() << '.' << rver.service() << endl;
                }
                for(auto i : test)
                {
                    int ii;
                    is >> ii;
                    ASSERT_EQ(i,ii);
                    unique_lock<mutex> l{m};
                    clog << "Receiver: " << ii << endl;
                }
            }
        }
        );

    threads.push_back(thread{
        [&test]{
            sender sder{"228.0.0.4", "54321"};
            ostream os{sder.distribute()};
            for(auto i : test)
            {
                this_thread::sleep_for(1ms);
                os << i << endl;
                unique_lock<mutex> l{m};
                clog << "Sender: " << i << endl;
            }
        }
    }
    );

    for(auto& thr : threads)
        thr.join();
}
<|endoftext|>