@@ -119,7 +119,20 @@ struct train_kernel_gpu<Float, method::thunder, task::classification> {
     }
 };

+template <typename Float>
+struct train_kernel_gpu<Float, method::thunder, task::nu_classification> {
+    train_result<task::nu_classification> operator()(
+        const dal::backend::context_gpu& ctx,
+        const detail::descriptor_base<task::nu_classification>& params,
+        const train_input<task::nu_classification>& input) const {
+        throw unimplemented(
+            dal::detail::error_messages::nu_svm_thunder_method_is_not_implemented_for_gpu());
+    }
+};
+
 template struct train_kernel_gpu<float, method::thunder, task::classification>;
 template struct train_kernel_gpu<double, method::thunder, task::classification>;
+template struct train_kernel_gpu<float, method::thunder, task::nu_classification>;
+template struct train_kernel_gpu<double, method::thunder, task::nu_classification>;

 } // namespace oneapi::dal::svm::backend

/*******************************************************************************
* Copyright 2020-2021 Intel Corporation
*
* 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.
*******************************************************************************/

#include "oneapi/dal/algo/svm/backend/gpu/train_kernel.hpp"
#include "oneapi/dal/algo/svm/backend/model_interop.hpp"
#include "oneapi/dal/algo/svm/backend/model_conversion.hpp"
#include "oneapi/dal/algo/svm/backend/kernel_function_impl.hpp"
#include "oneapi/dal/algo/svm/backend/utils.hpp"

#include "oneapi/dal/backend/interop/common_dpc.hpp"
#include "oneapi/dal/backend/interop/error_converter.hpp"
#include "oneapi/dal/backend/interop/table_conversion.hpp"

#include "oneapi/dal/table/row_accessor.hpp"

#include <daal/src/algorithms/svm/oneapi/svm_train_thunder_kernel_oneapi.h>

namespace oneapi::dal::svm::backend {

using dal::backend::context_gpu;
using model_t = model<task::classification>;
using input_t = train_input<task::classification>;
using result_t = train_result<task::classification>;
using descriptor_t = detail::descriptor_base<task::classification>;

namespace daal_svm = daal::algorithms::svm;
namespace daal_kernel_function = daal::algorithms::kernel_function;
namespace interop = dal::backend::interop;

template <typename Float>
using daal_svm_thunder_kernel_t =
    daal_svm::training::internal::SVMTrainOneAPI<Float, daal_svm::training::thunder>;

template <typename Float>
static result_t call_daal_kernel(const context_gpu& ctx,
                                 const descriptor_t& desc,
                                 const table& data,
                                 const table& labels) {
    auto& queue = ctx.get_queue();
    interop::execution_context_guard guard(queue);

    const std::uint64_t class_count = desc.get_class_count();
    if (class_count > 2) {
        throw unimplemented(dal::detail::error_messages::svm_multiclass_not_implemented_for_gpu());
    }

    const std::int64_t row_count = data.get_row_count();
    const std::int64_t column_count = data.get_column_count();

    auto arr_label = row_accessor<const Float>{ labels }.pull(queue);

    binary_label_t<Float> unique_label;
    auto arr_new_label =
        convert_labels(queue, arr_label, { Float(-1.0), Float(1.0) }, unique_label);

    const auto daal_data = interop::convert_to_daal_table(queue, data);
    const auto daal_labels = interop::convert_to_daal_table(queue, arr_new_label, row_count, 1);

    auto kernel_impl = detail::get_kernel_function_impl(desc);
    if (!kernel_impl) {
        throw internal_error{ dal::detail::error_messages::unknown_kernel_function_type() };
    }
    const auto daal_kernel = kernel_impl->get_daal_kernel_function();

    const std::uint64_t cache_megabyte = static_cast<std::uint64_t>(desc.get_cache_size());
    constexpr std::uint64_t megabyte = 1024 * 1024;
    dal::detail::check_mul_overflow(cache_megabyte, megabyte);
    const std::uint64_t cache_byte = cache_megabyte * megabyte;

    daal_svm::training::internal::KernelParameter daal_svm_parameter;
    daal_svm_parameter.kernel = daal_kernel;
    daal_svm_parameter.C = desc.get_c();
    daal_svm_parameter.accuracyThreshold = desc.get_accuracy_threshold();
    daal_svm_parameter.tau = desc.get_tau();
    daal_svm_parameter.maxIterations =
        dal::detail::integral_cast<std::size_t>(desc.get_max_iteration_count());
    daal_svm_parameter.doShrinking = desc.get_shrinking();
    daal_svm_parameter.cacheSize = cache_byte;

    auto daal_model = daal_svm::Model::create<Float>(column_count);
    interop::status_to_exception(daal_svm_thunder_kernel_t<Float>().compute(daal_data,
                                                                            *daal_labels,
                                                                            daal_model.get(),
                                                                            daal_svm_parameter));
    auto table_support_indices =
        interop::convert_from_daal_homogen_table<Float>(daal_model->getSupportIndices());

    auto trained_model = convert_from_daal_model<task::classification, Float>(*daal_model)
                             .set_first_class_label(unique_label.first)
                             .set_second_class_label(unique_label.second);

    return result_t().set_model(trained_model).set_support_indices(table_support_indices);
}

template <typename Float>
static result_t train(const context_gpu& ctx, const descriptor_t& desc, const input_t& input) {
    return call_daal_kernel<Float>(ctx, desc, input.get_data(), input.get_labels());
}

template <typename Float>
struct train_kernel_gpu<Float, method::thunder, task::classification> {
    result_t operator()(const context_gpu& ctx,
                        const descriptor_t& desc,
                        const input_t& input) const {
        return train<Float>(ctx, desc, input);
    }
};

template struct train_kernel_gpu<float, method::thunder, task::classification>;
template struct train_kernel_gpu<double, method::thunder, task::classification>;

} // namespace oneapi::dal::svm::backend


@@ -57,15 +57,10 @@ TEST(StatisticsQosTests, StatisticsDataWriterQosTest)
  */
 TEST(StatisticsQosTests, StatisticsDataReaderQosTest)
 {
-    // TODO(jlbueno) Remove this guards after implementation. Here to prevent failures in current CI.
-#ifdef FASTDDS_STATISTICS
-    logError(STATISTICS_QOS_TEST, "This test is going to fail because API is not yet implemented.")
-
     EXPECT_TRUE(STATISTICS_DATAREADER_QOS.reliability().kind == eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS);
     EXPECT_TRUE(STATISTICS_DATAREADER_QOS.durability().kind == eprosima::fastdds::dds::TRANSIENT_LOCAL_DURABILITY_QOS);
     EXPECT_TRUE(STATISTICS_DATAREADER_QOS.history().kind == eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS);
     EXPECT_TRUE(STATISTICS_DATAREADER_QOS.history().depth == 100);
-#endif // FASTDDS_STATISTICS
 }

 } // namespace dds

// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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.

#include <gtest/gtest.h>

#include <fastdds/dds/core/policy/QosPolicies.hpp>
#include <fastdds/dds/log/Log.hpp>
#include <fastdds/statistics/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/statistics/dds/subscriber/qos/DataReaderQos.hpp>

namespace eprosima {
namespace fastdds {
namespace statistics {
namespace dds {

/*
 * This test checks that STATISTICS_DATAWRITER_QOS correctly sets the expected QoS.
 * 1. Reliability RELIABLE
 * 2. Durability TRANSIENT LOCAL
 * 3. Pull mode enabled
 * 4. Publication mode ASYNCHRONOUS
 * 5. History kind KEEP LAST
 * 6. History depth 100
 */
TEST(StatisticsQosTests, StatisticsDataWriterQosTest)
{
    // TODO(jlbueno) Remove this guards after implementation. Here to prevent failures in current CI.
#ifdef FASTDDS_STATISTICS
    logError(STATISTICS_QOS_TEST, "This test is going to fail because API is not yet implemented.")

    EXPECT_TRUE(STATISTICS_DATAWRITER_QOS.reliability().kind == eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS);
    EXPECT_TRUE(STATISTICS_DATAWRITER_QOS.durability().kind == eprosima::fastdds::dds::TRANSIENT_LOCAL_DURABILITY_QOS);
    // TODO(jlbueno) Pull mode is not yet exposed in DDS API
    EXPECT_TRUE(STATISTICS_DATAWRITER_QOS.publish_mode().kind == eprosima::fastdds::dds::ASYNCHRONOUS_PUBLISH_MODE);
    EXPECT_TRUE(STATISTICS_DATAWRITER_QOS.history().kind == eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS);
    EXPECT_TRUE(STATISTICS_DATAWRITER_QOS.history().depth == 100);
#endif // FASTDDS_STATISTICS
}

/*
 * This test checks that STATISTICS_DATAREADER_QOS correctly sets the expected QoS.
 * 1. Reliability RELIABLE
 * 2. Durability TRANSIENT LOCAL
 * 3. History kind KEEP LAST
 * 4. History depth 100
 */
TEST(StatisticsQosTests, StatisticsDataReaderQosTest)
{
    // TODO(jlbueno) Remove this guards after implementation. Here to prevent failures in current CI.
#ifdef FASTDDS_STATISTICS
    logError(STATISTICS_QOS_TEST, "This test is going to fail because API is not yet implemented.")

    EXPECT_TRUE(STATISTICS_DATAREADER_QOS.reliability().kind == eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS);
    EXPECT_TRUE(STATISTICS_DATAREADER_QOS.durability().kind == eprosima::fastdds::dds::TRANSIENT_LOCAL_DURABILITY_QOS);
    EXPECT_TRUE(STATISTICS_DATAREADER_QOS.history().kind == eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS);
    EXPECT_TRUE(STATISTICS_DATAREADER_QOS.history().depth == 100);
#endif // FASTDDS_STATISTICS
}

} // namespace dds
} // namespace statistics
} // namespace fastdds
} // namespace eprosima

int main(
        int argc,
        char** argv)
{
    eprosima::fastdds::dds::Log::SetVerbosity(eprosima::fastdds::dds::Log::Error);

    testing::InitGoogleTest(&argc, argv);
    int ret = RUN_ALL_TESTS();

    eprosima::fastdds::dds::Log::KillThread();
    return ret;
}


@@ -80,6 +80,13 @@ void ScriptingEnvironment::init_lua_state(lua_State *lua_state)
         luabind::def("print", LUA_print<std::string>),
         luabind::def("durationIsValid", durationIsValid),
         luabind::def("parseDuration", parseDuration),
+        luabind::class_<SourceContainer>("sources")
+            .def(luabind::constructor<>())
+            .def("load", &SourceContainer::loadRasterSource)
+            .def("query", &SourceContainer::getRasterDataFromSource)
+            .def("interpolate", &SourceContainer::getRasterInterpolateFromSource),
+        luabind::class_<const float>("constants")
+            .enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)],

         luabind::class_<std::vector<std::string>>("vector")
             .def("Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>(

/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "scripting_environment.hpp"

#include "extraction_helper_functions.hpp"
#include "extraction_node.hpp"
#include "extraction_way.hpp"
#include "../data_structures/external_memory_node.hpp"
#include "../util/lua_util.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include "../typedefs.h"

#include <luabind/tag_function.hpp>

#include <osmium/osm.hpp>

#include <sstream>
namespace
{
// wrapper method as luabind doesn't automatically overload funcs w/ default parameters
template <class T>
auto get_value_by_key(T const &object, const char *key) -> decltype(object.get_value_by_key(key))
{
    return object.get_value_by_key(key, "");
}

int lua_error_callback(lua_State *L) // This is so I can use my own function as an
// exception handler, pcall_log()
{
    std::string error_msg = lua_tostring(L, -1);
    std::ostringstream error_stream;
    error_stream << error_msg;
    throw osrm::exception("ERROR occured in profile script:\n" + error_stream.str());
}
}

ScriptingEnvironment::ScriptingEnvironment(const std::string &file_name) : file_name(file_name)
{
    SimpleLogger().Write() << "Using script " << file_name;
}

void ScriptingEnvironment::init_lua_state(lua_State *lua_state)
{
    typedef double (osmium::Location::*location_member_ptr_type)() const;

    luabind::open(lua_state);
    // open utility libraries string library;
    luaL_openlibs(lua_state);

    luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());

    // Add our function to the state's global scope
    luabind::module(lua_state)[
        luabind::def("print", LUA_print<std::string>),
        luabind::def("durationIsValid", durationIsValid),
        luabind::def("parseDuration", parseDuration),

        luabind::class_<std::vector<std::string>>("vector")
            .def("Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>(
                            &std::vector<std::string>::push_back)),

        luabind::class_<osmium::Location>("Location")
            .def<location_member_ptr_type>("lat", &osmium::Location::lat)
            .def<location_member_ptr_type>("lon", &osmium::Location::lon),

        luabind::class_<osmium::Node>("Node")
            // .def<node_member_ptr_type>("tags", &osmium::Node::tags)
            .def("location", &osmium::Node::location)
            .def("get_value_by_key", &osmium::Node::get_value_by_key)
            .def("get_value_by_key", &get_value_by_key<osmium::Node>)
            .def("id", &osmium::Node::id),

        luabind::class_<ExtractionNode>("ResultNode")
            .def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
            .def_readwrite("barrier", &ExtractionNode::barrier),

        luabind::class_<ExtractionWay>("ResultWay")
            // .def(luabind::constructor<>())
            .def_readwrite("forward_speed", &ExtractionWay::forward_speed)
            .def_readwrite("backward_speed", &ExtractionWay::backward_speed)
            .def_readwrite("name", &ExtractionWay::name)
            .def_readwrite("roundabout", &ExtractionWay::roundabout)
            .def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
            .def_readwrite("duration", &ExtractionWay::duration)
            .property("forward_mode", &ExtractionWay::get_forward_mode,
                      &ExtractionWay::set_forward_mode)
            .property("backward_mode", &ExtractionWay::get_backward_mode,
                      &ExtractionWay::set_backward_mode)
            .enum_("constants")[
                luabind::value("notSure", 0),
                luabind::value("oneway", 1),
                luabind::value("bidirectional", 2),
                luabind::value("opposite", 3)
            ],
        luabind::class_<osmium::Way>("Way")
            .def("get_value_by_key", &osmium::Way::get_value_by_key)
            .def("get_value_by_key", &get_value_by_key<osmium::Way>)
            .def("id", &osmium::Way::id)
    ];

    if (0 != luaL_dofile(lua_state, file_name.c_str()))
    {
        luabind::object error_msg(luabind::from_stack(lua_state, -1));
        std::ostringstream error_stream;
        error_stream << error_msg;
        throw osrm::exception("ERROR occured in profile script:\n" + error_stream.str());
    }
}

lua_State *ScriptingEnvironment::get_lua_state()
{
    std::lock_guard<std::mutex> lock(init_mutex);
    bool initialized = false;
    auto &ref = script_contexts.local(initialized);
    if (!initialized)
    {
        std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
        ref = state;
        init_lua_state(ref.get());
    }
    luabind::set_pcall_callback(&lua_error_callback);

    return ref.get();
}


@@ -7,6 +7,7 @@
 #include "base/Base.h"
 #include <gtest/gtest.h>
 #include "time/Duration.h"
+#include <time.h>

 using nebula::time::Duration;

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "base/Base.h"
#include <gtest/gtest.h>
#include "time/Duration.h"

using nebula::time::Duration;

TEST(Duration, elapsedInSeconds) {
    for (int i = 0; i < 5; i++) {
        Duration dur;
        auto start = std::chrono::steady_clock::now();
        sleep(2);
        auto diff = std::chrono::steady_clock::now() - start;
        dur.pause();

        ASSERT_EQ(std::chrono::duration_cast<std::chrono::seconds>(diff).count(),
                  dur.elapsedInSec()) << "Inaccuracy in iteration " << i;
    }
}

TEST(Duration, elapsedInMilliSeconds) {
    Duration dur;
    for (int i = 0; i < 200; i++) {
        dur.reset();
        auto start = std::chrono::steady_clock::now();
        usleep(5000);   // Sleep for 5 ms
        auto diff = std::chrono::steady_clock::now() - start;
        dur.pause();

        // Allow 1ms difference
        ASSERT_LE(std::chrono::duration_cast<std::chrono::milliseconds>(diff).count(),
                  dur.elapsedInMSec()) << "Inaccuracy in iteration " << i;
        ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() + 1,
                  dur.elapsedInMSec()) << "Inaccuracy in iteration " << i;
    }
}

int main(int argc, char** argv) {
    testing::InitGoogleTest(&argc, argv);
    folly::init(&argc, &argv, true);
    google::SetStderrLogging(google::INFO);

    return RUN_ALL_TESTS();
}


@@ -17,15 +17,19 @@ namespace nebula {
 namespace meta {

 using Status = cpp2::JobStatus;
+using AdminCmd = nebula::cpp2::AdminCmd;
+
+int32_t JobDescription::minDataVer_ = 1;
+int32_t JobDescription::currDataVer_ = 1;

 JobDescription::JobDescription(int32_t id,
-                               std::string cmd,
+                               nebula::cpp2::AdminCmd cmd,
                                std::vector<std::string> paras,
                                Status status,
                                int64_t startTime,
                                int64_t stopTime)
                                : id_(id),
-                                 cmd_(std::move(cmd)),
+                                 cmd_(cmd),
                                  paras_(std::move(paras)),
                                  status_(status),
                                  startTime_(startTime),

/* Copyright (c) 2019 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include <stdexcept>
#include <string>
#include <vector>
#include <folly/String.h>
#include <boost/stacktrace.hpp>
#include "meta/processors/jobMan/JobUtils.h"
#include "meta/processors/jobMan/JobDescription.h"

#include "kvstore/KVIterator.h"
namespace nebula {
namespace meta {

using Status = cpp2::JobStatus;

JobDescription::JobDescription(int32_t id,
                               std::string cmd,
                               std::vector<std::string> paras,
                               Status status,
                               int64_t startTime,
                               int64_t stopTime)
                               : id_(id),
                                 cmd_(std::move(cmd)),
                                 paras_(std::move(paras)),
                                 status_(status),
                                 startTime_(startTime),
                                 stopTime_(stopTime) {}

folly::Optional<JobDescription>
JobDescription::makeJobDescription(folly::StringPiece rawkey,
                                   folly::StringPiece rawval) {
    try {
        if (!isJobKey(rawkey)) {
            return folly::none;
        }
        auto key = parseKey(rawkey);
        auto tup = parseVal(rawval);

        auto cmd = std::get<0>(tup);
        auto paras = std::get<1>(tup);
        for (auto p : paras) {
            LOG(INFO) << "p = " << p;
        }
        auto status = std::get<2>(tup);
        auto startTime = std::get<3>(tup);
        auto stopTime = std::get<4>(tup);
        return JobDescription(key, cmd, paras, status, startTime, stopTime);
    } catch(std::exception& ex) {
        LOG(ERROR) << ex.what();
    }
    return folly::none;
}

std::string JobDescription::jobKey() const {
    return makeJobKey(id_);
}

std::string JobDescription::makeJobKey(int32_t iJob) {
    std::string str;
    str.reserve(32);
    str.append(reinterpret_cast<const char*>(JobUtil::jobPrefix().data()),
                                             JobUtil::jobPrefix().size());
    str.append(reinterpret_cast<const char*>(&iJob), sizeof(int32_t));
    return str;
}

int32_t JobDescription::parseKey(const folly::StringPiece& rawKey) {
    auto offset = JobUtil::jobPrefix().size();
    return *reinterpret_cast<const int32_t*>(rawKey.begin() + offset);
}

std::string JobDescription::jobVal() const {
    std::string str;
    auto cmdLen = cmd_.length();
    auto paraSize = paras_.size();
    str.reserve(256);
    str.append(reinterpret_cast<const char*>(&cmdLen), sizeof(size_t));
    str.append(reinterpret_cast<const char*>(cmd_.data()), cmd_.length());
    str.append(reinterpret_cast<const char*>(&paraSize), sizeof(size_t));
    for (auto& para : paras_) {
        auto len = para.length();
        str.append(reinterpret_cast<const char*>(&len), sizeof(len));
        str.append(reinterpret_cast<const char*>(&para[0]), len);
    }
    str.append(reinterpret_cast<const char*>(&status_), sizeof(Status));
    str.append(reinterpret_cast<const char*>(&startTime_), sizeof(int64_t));
    str.append(reinterpret_cast<const char*>(&stopTime_), sizeof(int64_t));
    return str;
}

std::tuple<std::string,
           std::vector<std::string>,
           Status,
           int64_t,
           int64_t>
JobDescription::parseVal(const folly::StringPiece& rawVal) {
    size_t offset = 0;

    std::string cmd = JobUtil::parseString(rawVal, offset);
    offset += sizeof(size_t) + cmd.length();

    std::vector<std::string> paras = JobUtil::parseStrVector(rawVal, &offset);

    auto status = JobUtil::parseFixedVal<Status>(rawVal, offset);
    offset += sizeof(Status);

    auto tStart = JobUtil::parseFixedVal<int64_t>(rawVal, offset);
    offset += sizeof(int64_t);

    auto tStop = JobUtil::parseFixedVal<int64_t>(rawVal, offset);

    return std::make_tuple(cmd, paras, status, tStart, tStop);
}

cpp2::JobDesc JobDescription::toJobDesc() {
    cpp2::JobDesc ret;
    ret.set_id(id_);
    ret.set_cmd(cmd_);
    ret.set_paras(paras_);
    ret.set_status(status_);
    ret.set_start_time(startTime_);
    ret.set_stop_time(stopTime_);
    return ret;
}

std::string JobDescription::archiveKey() {
    std::string str;
    str.reserve(32);
    str.append(reinterpret_cast<const char*>(JobUtil::archivePrefix().data()),
                                             JobUtil::archivePrefix().size());
    str.append(reinterpret_cast<const char*>(&id_), sizeof(id_));
    return str;
}

bool JobDescription::setStatus(Status newStatus) {
    if (JobStatus::laterThan(status_, newStatus)) {
        return false;
    }
    status_ = newStatus;
    if (newStatus == Status::RUNNING) {
        startTime_ = std::time(nullptr);
    }
    if (JobStatus::laterThan(newStatus, Status::RUNNING)) {
        stopTime_ = std::time(nullptr);
    }
    return true;
}

bool JobDescription::isJobKey(const folly::StringPiece& rawKey) {
    return rawKey.size() == JobUtil::jobPrefix().length() + sizeof(int32_t);
}

folly::Optional<JobDescription>
JobDescription::loadJobDescription(int32_t iJob, nebula::kvstore::KVStore* kv) {
    auto key = makeJobKey(iJob);
    std::string val;
    auto rc = kv->get(0, 0, key, &val);
    if (rc != nebula::kvstore::SUCCEEDED) {
        return folly::none;
    }
    return makeJobDescription(key, val);
}

}  // namespace meta
}  // namespace nebula


@@ -21,10 +21,9 @@ typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
 namespace RDKit {
 namespace {

-MolStandardize::TautomerTransform* getTautomer(const std::string& name,
-                                               const std::string& smarts,
-                                               const std::string& bond_str,
-                                               const std::string& charge_str) {
+std::unique_ptr<MolStandardize::TautomerTransform> getTautomer(
+    const std::string& name, const std::string& smarts,
+    const std::string& bond_str, const std::string& charge_str) {
   std::vector<Bond::BondType> bond_types =
       MolStandardize::stringToBondType(bond_str);
   std::vector<int> charges = MolStandardize::stringToCharge(charge_str);

//
//  Copyright (C) 2018-2021 Susan H. Leung and other RDKit contributors
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#include "TautomerCatalogUtils.h"
#include <RDGeneral/BadFileException.h>
#include <boost/tokenizer.hpp>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/SmilesParse/SmilesWrite.h>
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
#include <fstream>
#include <string>

namespace RDKit {
namespace {

MolStandardize::TautomerTransform* getTautomer(const std::string& name,
                                               const std::string& smarts,
                                               const std::string& bond_str,
                                               const std::string& charge_str) {
  std::vector<Bond::BondType> bond_types =
      MolStandardize::stringToBondType(bond_str);
  std::vector<int> charges = MolStandardize::stringToCharge(charge_str);

  ROMol* tautomer = SmartsToMol(smarts);
  if (!tautomer) {
    throw ValueErrorException("cannot parse tautomer SMARTS: " + smarts);
  }
  tautomer->setProp(common_properties::_Name, name);
  return new MolStandardize::TautomerTransform(tautomer, bond_types, charges);
}

MolStandardize::TautomerTransform* getTautomer(const std::string& tmpStr) {
  if (tmpStr.length() == 0 || tmpStr.substr(0, 2) == "//") {
    // empty or comment line
    return nullptr;
  }
  boost::char_separator<char> tabSep("\t");
  tokenizer tokens(tmpStr, tabSep);
  std::vector<std::string> result(tokens.begin(), tokens.end());

  // tautomer information to collect from each line
  std::string name;
  std::string smarts;
  std::string bond_str;
  std::string charge_str;

  // line must have at least two tab separated values
  if (result.size() < 2) {
    BOOST_LOG(rdWarningLog) << "Invalid line: " << tmpStr << std::endl;
    return nullptr;
  }
  // line only has name and smarts
  if (result.size() == 2) {
    name = result[0];
    smarts = result[1];
  }
  // line has name, smarts, bonds
  if (result.size() == 3) {
    name = result[0];
    smarts = result[1];
    bond_str = result[2];
  }
  // line has name, smarts, bonds, charges
  if (result.size() == 4) {
    name = result[0];
    smarts = result[1];
    bond_str = result[2];
    charge_str = result[3];
  }

  boost::erase_all(smarts, " ");
  boost::erase_all(name, " ");
  boost::erase_all(bond_str, " ");
  boost::erase_all(charge_str, " ");

  return getTautomer(name, smarts, bond_str, charge_str);
}
}  // namespace

namespace MolStandardize {

std::vector<Bond::BondType> stringToBondType(std::string bond_str) {
  std::vector<Bond::BondType> bonds;
  for (const auto& c : bond_str) {
    switch (c) {
      case '-':
        bonds.push_back(Bond::SINGLE);
        break;
      case '=':
        bonds.push_back(Bond::DOUBLE);
        break;
      case '#':
        bonds.push_back(Bond::TRIPLE);
        break;
      case ':':
        bonds.push_back(Bond::AROMATIC);
        break;
    }
  }
  return bonds;
}

std::vector<int> stringToCharge(std::string charge_str) {
  std::vector<int> charges;
  for (const auto& c : charge_str) {
    switch (c) {
      case '+':
        charges.push_back(1);
        break;
      case '0':
        charges.push_back(0);
        break;
      case '-':
        charges.push_back(-1);
        break;
      default:
        throw ValueErrorException("Charge symbol not recognised.");
    }
  }
  return charges;
}

std::vector<TautomerTransform> readTautomers(std::string fileName) {
  std::ifstream inStream(fileName.c_str());
  if ((!inStream) || (inStream.bad())) {
    std::ostringstream errout;
    errout << "Bad input file " << fileName;
    throw BadFileException(errout.str());
  }
  std::vector<TautomerTransform> tautomers = readTautomers(inStream);
  return tautomers;
}

std::vector<TautomerTransform> readTautomers(std::istream& inStream,
                                             int nToRead) {
  if (inStream.bad()) {
    throw BadFileException("Bad stream contents.");
  }
  std::vector<TautomerTransform> tautomers;
  if (nToRead > 0) {
    tautomers.reserve(nToRead);
  }
  const int MAX_LINE_LEN = 512;
  char inLine[MAX_LINE_LEN];
  std::string tmpstr;
  int nRead = 0;
  while (!inStream.eof() && !inStream.fail() &&
         (nToRead < 0 || nRead < nToRead)) {
    inStream.getline(inLine, MAX_LINE_LEN, '\n');
    tmpstr = inLine;
    // parse the tautomer on this line (if there is one)
    TautomerTransform* transform = getTautomer(tmpstr);
    if (transform) {
      tautomers.emplace_back(*transform);
      delete transform;
      nRead++;
    }
  }

  return tautomers;
}

std::vector<TautomerTransform> readTautomers(
    const std::vector<
        std::tuple<std::string, std::string, std::string, std::string>>& data) {
  std::vector<TautomerTransform> tautomers;
  for (const auto& tpl : data) {
    auto transform = getTautomer(std::get<0>(tpl), std::get<1>(tpl),
                                 std::get<2>(tpl), std::get<3>(tpl));
    if (transform) {
      tautomers.emplace_back(*transform);
    }
  }
  return tautomers;
}

}  // namespace MolStandardize
}  // namespace RDKit


@@ -108,7 +108,7 @@ int main(int argc, char *argv[]) {
     }

   } catch (exception& e) {
-    if (options::get()->has_bool("stack_trace_to_file")) {
+    if (options::get()->get_bool("stack_trace_to_file")) {
       std::ostringstream ss("stack_trace");
       const auto& rank = get_rank_in_world();
       if (rank >= 0) {

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014-2016, Lawrence Livermore National Security, LLC.
// Produced at the Lawrence Livermore National Laboratory.
// Written by the LBANN Research Team (B. Van Essen, et al.) listed in
// the CONTRIBUTORS file. <lbann-dev@llnl.gov>
//
// LLNL-CODE-697807.
// All rights reserved.
//
// This file is part of LBANN: Livermore Big Artificial Neural Network
// Toolkit. For details, see http://software.llnl.gov/LBANN or
// https://github.com/LLNL/LBANN.
//
// Licensed under the Apache License, Version 2.0 (the "Licensee"); 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.
//
// lbann_proto.cpp - prototext application
////////////////////////////////////////////////////////////////////////////////

#include "lbann/lbann.hpp"
#include "lbann/proto/proto_common.hpp"
#include "lbann/utils/protobuf_utils.hpp"
#include "lbann/data_store/generic_data_store.hpp"
#include <cstdlib>

using namespace lbann;

int main(int argc, char *argv[]) {
  int random_seed = lbann_default_random_seed;
  world_comm_ptr comm = initialize(argc, argv, random_seed);
  const bool master = comm->am_world_master();

  if (master) {
    std::cout << "\n\n==============================================================\n"
              << "STARTING lbann with this command line:\n";
    for (int j=0; j<argc; j++) {
      std::cout << argv[j] << " ";
    }
    std::cout << std::endl << std::endl;
  }

  try {
    // Initialize options db (this parses the command line)
    options *opts = options::get();
    opts->init(argc, argv);
    if (opts->has_string("h") or opts->has_string("help") or argc == 1) {
      print_help(*comm);
      return EXIT_SUCCESS;
    }

    //this must be called after call to opts->init();
    if (!opts->has_bool("disable_signal_handler")) {
      std::string file_base = (opts->has_bool("stack_trace_to_file") ?
                               "stack_trace" : "");
      stack_trace::register_signal_handler(file_base);
    }

    //to activate, must specify --st_on on cmd line
    stack_profiler::get()->activate(comm->get_rank_in_world());

    // Initalize a global I/O thread pool
    std::shared_ptr<thread_pool> io_thread_pool = construct_io_thread_pool(comm.get());

    auto pbs = protobuf_utils::load_prototext(master, argc, argv);
    lbann_data::LbannPB pb = *(pbs[0]);

    lbann_data::Model *pb_model = pb.mutable_model();

    auto model = build_model_from_prototext(argc, argv, pb,
                                            comm.get(), io_thread_pool, true);

    if (opts->has_string("create_tarball")) {
      return EXIT_SUCCESS;
    }

    if (! (opts->has_bool("exit_after_setup") && opts->get_bool("exit_after_setup"))) {

      // Train model
      model->train(pb_model->num_epochs());

      // Evaluate model on test set
      model->evaluate(execution_mode::testing);

      //has no affect unless option: --st_on was given
      stack_profiler::get()->print();

    } else {
      if (comm->am_world_master()) {
        std::cout <<
          "--------------------------------------------------------------------------------\n"
          "ALERT: model has been setup; we are now exiting due to command\n"
          "       line option: --exit_after_setup\n"
          "--------------------------------------------------------------------------------\n";
      }

      //has no affect unless option: --st_on was given
      stack_profiler::get()->print();
    }

  } catch (exception& e) {
    if (options::get()->has_bool("stack_trace_to_file")) {
      std::ostringstream ss("stack_trace");
      const auto& rank = get_rank_in_world();
      if (rank >= 0) {
        ss << "_rank" << rank;
      }
      ss << ".txt";
      std::ofstream fs(ss.str());
      e.print_report(fs);
    }
    El::ReportException(e);
    return EXIT_FAILURE;
  } catch (std::exception& e) {
    El::ReportException(e);
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}


@@ -61,7 +61,8 @@ ReceiverResource::ReceiverResource(ReceiverResource&& rValueResource)
     max_message_size_ = rValueResource.max_message_size_;
 }

-bool ReceiverResource::SupportsLocator(const Locator_t& localLocator)
+bool ReceiverResource::SupportsLocator(
+        const Locator_t& localLocator)
 {
     if (LocatorMapsToManagedChannel)
     {

// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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.

#include <fastdds/rtps/network/ReceiverResource.h>
#include <fastdds/rtps/messages/MessageReceiver.h>
#include <cassert>
#include <fastdds/dds/log/Log.hpp>

#define IDSTRING "(ID:" << std::this_thread::get_id() <<") "<<

using namespace std;
using namespace eprosima::fastdds::rtps;

namespace eprosima{
namespace fastrtps{
namespace rtps{

ReceiverResource::ReceiverResource(
			TransportInterface& transport,
			const Locator_t& locator,
			uint32_t max_recv_buffer_size)
        : Cleanup(nullptr)
        , LocatorMapsToManagedChannel(nullptr)
        , mValid(false)
        , mtx()
        , receiver(nullptr)
        , max_message_size_(max_recv_buffer_size)
{
    // Internal channel is opened and assigned to this resource.
    mValid = transport.OpenInputChannel(locator, this, max_message_size_);
    if (!mValid)
    {
        return; // Invalid resource to be discarded by the factory.
    }

    // Implementation functions are bound to the right transport parameters
    Cleanup = [&transport, locator]() { transport.CloseInputChannel(locator); };
    LocatorMapsToManagedChannel = [&transport, locator](const Locator_t& locatorToCheck) -> bool
    { return transport.DoInputLocatorsMatch(locator, locatorToCheck); };
}

ReceiverResource::ReceiverResource(ReceiverResource&& rValueResource)
{
    Cleanup.swap(rValueResource.Cleanup);
    LocatorMapsToManagedChannel.swap(rValueResource.LocatorMapsToManagedChannel);
    receiver = rValueResource.receiver;
    rValueResource.receiver = nullptr;
    mValid = rValueResource.mValid;
    rValueResource.mValid = false;
    max_message_size_ = rValueResource.max_message_size_;
}

bool ReceiverResource::SupportsLocator(const Locator_t& localLocator)
{
    if (LocatorMapsToManagedChannel)
    {
        return LocatorMapsToManagedChannel(localLocator);
    }
    return false;
}

void ReceiverResource::RegisterReceiver(MessageReceiver* rcv)
{
    std::unique_lock<std::mutex> lock(mtx);
    if (receiver == nullptr)
        receiver = rcv;
}

void ReceiverResource::UnregisterReceiver(MessageReceiver* rcv)
{
    std::unique_lock<std::mutex> lock(mtx);
    if (receiver == rcv)
        receiver = nullptr;
}

void ReceiverResource::OnDataReceived(const octet * data, const uint32_t size,
    const Locator_t & localLocator, const Locator_t & remoteLocator)
{
    (void)localLocator;

    std::unique_lock<std::mutex> lock(mtx);
    MessageReceiver* rcv = receiver;

    if (rcv != nullptr)
    {
        CDRMessage_t msg(0);
        msg.wraps = true;
        msg.buffer = const_cast<octet*>(data);
        msg.length = size;
        msg.max_size = size;
        msg.reserved_size = size;

        // TODO: Should we unlock in case UnregisterReceiver is called from callback ?
        rcv->processCDRMsg(remoteLocator, &msg);
    }

}

void ReceiverResource::disable()
{
    if (Cleanup)
    {
        Cleanup();
    }
}

ReceiverResource::~ReceiverResource()
{
}

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima


@@ -23,6 +23,8 @@ DEFINE_string(peers, "", "It is a list of IPs split by comma,"
                          "the ips number equals replica number."
                          "If empty, it means replica is 1");
 DEFINE_string(local_ip, "", "Local ip speicified for NetworkUtils::getLocalIP");
+DEFINE_int32(num_workers, 4, "Number of worker threads");
+DEFINE_int32(num_io_threads, 16, "Number of IO threads");
 DECLARE_string(part_man_type);

 DEFINE_string(pid_file, "pids/nebula-metad.pid", "File to hold the process id");

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "base/Base.h"
#include <thrift/lib/cpp2/server/ThriftServer.h>
#include "meta/MetaServiceHandler.h"
#include "meta/MetaHttpHandler.h"
#include "webservice/WebService.h"
#include "network/NetworkUtils.h"
#include "process/ProcessUtils.h"
#include "kvstore/PartManager.h"

using nebula::ProcessUtils;
using nebula::Status;

DEFINE_int32(port, 45500, "Meta daemon listening port");
DEFINE_bool(reuse_port, true, "Whether to turn on the SO_REUSEPORT option");
DEFINE_string(data_path, "", "Root data path");
DEFINE_string(peers, "", "It is a list of IPs split by comma,"
                         "the ips number equals replica number."
                         "If empty, it means replica is 1");
DEFINE_string(local_ip, "", "Local ip speicified for NetworkUtils::getLocalIP");
DECLARE_string(part_man_type);

DEFINE_string(pid_file, "pids/nebula-metad.pid", "File to hold the process id");
DEFINE_bool(daemonize, true, "Whether run as a daemon process");

static std::unique_ptr<apache::thrift::ThriftServer> gServer;

static void signalHandler(int sig);
static Status setupSignalHandler();

int main(int argc, char *argv[]) {
    folly::init(&argc, &argv, true);
    if (FLAGS_data_path.empty()) {
        LOG(ERROR) << "Meta Data Path should not empty";
        return EXIT_FAILURE;
    }

    if (FLAGS_daemonize) {
        google::SetStderrLogging(google::FATAL);
    } else {
        google::SetStderrLogging(google::INFO);
    }

    // Detect if the server has already been started
    auto pidPath = FLAGS_pid_file;
    auto status = ProcessUtils::isPidAvailable(pidPath);
    if (!status.ok()) {
        LOG(ERROR) << status;
        return EXIT_FAILURE;
    }

    if (FLAGS_daemonize) {
        status = ProcessUtils::daemonize(pidPath);
        if (!status.ok()) {
            LOG(ERROR) << status;
            return EXIT_FAILURE;
        }
    } else {
        status = ProcessUtils::makePidFile(pidPath);
        if (!status.ok()) {
            LOG(ERROR) << status;
            return EXIT_FAILURE;
        }
    }

    LOG(INFO) << "Starting Meta HTTP Service";
    nebula::WebService::registerHandler("/status", [] {
        return new nebula::meta::MetaHttpHandler();
    });
    status = nebula::WebService::start();
    if (!status.ok()) {
        LOG(ERROR) << "Failed to start web service: " << status;
        return EXIT_FAILURE;
    }

    auto result = nebula::network::NetworkUtils::getLocalIP(FLAGS_local_ip);
    if (!result.ok()) {
        LOG(ERROR) << "Get local ip failed! status:" << result.status();
        return EXIT_FAILURE;
    }
    auto hostAddrRet = nebula::network::NetworkUtils::toHostAddr(result.value(), FLAGS_port);
    if (!hostAddrRet.ok()) {
        LOG(ERROR) << "Bad local host addr, status:" << hostAddrRet.status();
        return EXIT_FAILURE;
    }
    auto& localHost = hostAddrRet.value();

    auto peersRet = nebula::network::NetworkUtils::toHosts(FLAGS_peers);
    if (!peersRet.ok()) {
        LOG(ERROR) << "Can't get peers address, status:" << peersRet.status();
        return EXIT_FAILURE;
    }
    // Setup the signal handlers
    status = setupSignalHandler();
    if (!status.ok()) {
        LOG(ERROR) << status;
        return EXIT_FAILURE;
    }

    auto partMan
        = std::make_unique<nebula::kvstore::MemPartManager>();
    // The meta server has only one space, one part.
    partMan->addPart(0, 0, std::move(peersRet.value()));

    nebula::kvstore::KVOptions options;
    options.local_ = localHost;
    options.dataPaths_ = {FLAGS_data_path};
    options.partMan_ = std::move(partMan);
    std::unique_ptr<nebula::kvstore::KVStore> kvstore(
            nebula::kvstore::KVStore::instance(std::move(options)));

    auto handler = std::make_shared<nebula::meta::MetaServiceHandler>(kvstore.get());

    nebula::operator<<(operator<<(LOG(INFO), "The meta deamon start on "), localHost);
    try {
        gServer = std::make_unique<apache::thrift::ThriftServer>();
        gServer->setInterface(std::move(handler));
        gServer->setPort(FLAGS_port);
        gServer->setReusePort(FLAGS_reuse_port);
        gServer->setIdleTimeout(std::chrono::seconds(0));  // No idle timeout on client connection
        gServer->serve();  // Will wait until the server shuts down
    } catch (const std::exception &e) {
        LOG(ERROR) << "Exception thrown: " << e.what();
        return EXIT_FAILURE;
    }

    LOG(INFO) << "The meta Daemon stopped";
}

Status setupSignalHandler() {
    ::signal(SIGPIPE, SIG_IGN);
    ::signal(SIGINT, signalHandler);
    ::signal(SIGTERM, signalHandler);
    return Status::OK();
}

void signalHandler(int sig) {
    switch (sig) {
        case SIGINT:
        case SIGTERM:
            FLOG_INFO("Signal %d(%s) received, stopping this server", sig, ::strsignal(sig));
            nebula::WebService::stop();
            gServer->stop();
            break;
        default:
            FLOG_ERROR("Signal %d(%s) received but ignored", sig, ::strsignal(sig));
    }
}


@@ -112,6 +112,26 @@ std::string NebulaKeyUtils::edgePrefix(PartitionID partId, VertexID srcId, EdgeT
     return key;
 }

+// static
+std::string NebulaKeyUtils::edgePrefix(PartitionID partId,
+                                       VertexID srcId,
+                                       EdgeType type,
+                                       EdgeRanking rank,
+                                       VertexID dstId) {
+    type |= kEdgeMaskSet;
+    int32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);
+    std::string key;
+    key.reserve(sizeof(PartitionID) + sizeof(VertexID)
+                + sizeof(EdgeType) + sizeof(VertexID)
+                + sizeof(EdgeRanking));
+    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
+            .append(reinterpret_cast<const char*>(&srcId), sizeof(VertexID))
+            .append(reinterpret_cast<const char*>(&type), sizeof(EdgeType))
+            .append(reinterpret_cast<const char*>(&rank), sizeof(EdgeRanking))
+            .append(reinterpret_cast<const char*>(&dstId), sizeof(VertexID));
+    return key;
+}
+
 // static
 std::string NebulaKeyUtils::prefix(PartitionID partId) {
     PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "base/NebulaKeyUtils.h"

namespace nebula {

// static
std::string NebulaKeyUtils::vertexKey(PartitionID partId, VertexID vId,
                                      TagID tagId, TagVersion tv) {
    tagId &= kTagMaskSet;
    int32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);

    std::string key;
    key.reserve(kVertexLen);
    key.append(reinterpret_cast<const char*>(&item), sizeof(int32_t))
       .append(reinterpret_cast<const char*>(&vId), sizeof(VertexID))
       .append(reinterpret_cast<const char*>(&tagId), sizeof(TagID))
       .append(reinterpret_cast<const char*>(&tv), sizeof(TagVersion));
    return key;
}

// static
std::string NebulaKeyUtils::edgeKey(PartitionID partId,
                                    VertexID srcId,
                                    EdgeType type,
                                    EdgeRanking rank,
                                    VertexID dstId,
                                    EdgeVersion ev) {
    type |= kEdgeMaskSet;
    int32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);

    std::string key;
    key.reserve(kEdgeLen);
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&srcId), sizeof(VertexID))
       .append(reinterpret_cast<const char*>(&type), sizeof(EdgeType))
       .append(reinterpret_cast<const char*>(&rank), sizeof(EdgeRanking))
       .append(reinterpret_cast<const char*>(&dstId), sizeof(VertexID))
       .append(reinterpret_cast<const char*>(&ev), sizeof(EdgeVersion));
    return key;
}

// static
std::string NebulaKeyUtils::systemCommitKey(PartitionID partId) {
    int32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kSystem);
    uint32_t type = static_cast<uint32_t>(NebulaSystemKeyType::kSystemCommit);
    std::string key;
    key.reserve(kSystemLen);
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&type), sizeof(NebulaSystemKeyType));
    return key;
}

// static
std::string NebulaKeyUtils::systemPartKey(PartitionID partId) {
    uint32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kSystem);
    uint32_t type = static_cast<uint32_t>(NebulaSystemKeyType::kSystemPart);
    std::string key;
    key.reserve(kSystemLen);
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&type), sizeof(NebulaSystemKeyType));
    return key;
}

// static
std::string NebulaKeyUtils::uuidKey(PartitionID partId, const folly::StringPiece& name) {
    std::string key;
    key.reserve(sizeof(PartitionID) + name.size());
    int32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kUUID);
    key.append(reinterpret_cast<const char*>(&item), sizeof(int32_t))
       .append(name.data(), name.size());
    return key;
}

// static
std::string NebulaKeyUtils::kvKey(PartitionID partId, const folly::StringPiece& name) {
    std::string key;
    key.reserve(sizeof(PartitionID) + name.size());
    int32_t item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);
    key.append(reinterpret_cast<const char*>(&item), sizeof(int32_t))
       .append(name.data(), name.size());
    return key;
}

// static
std::string NebulaKeyUtils::vertexPrefix(PartitionID partId, VertexID vId, TagID tagId) {
    tagId &= kTagMaskSet;
    PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);

    std::string key;
    key.reserve(kVertexLen);
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&vId), sizeof(VertexID))
       .append(reinterpret_cast<const char*>(&tagId), sizeof(TagID));
    return key;
}

// static
std::string NebulaKeyUtils::edgePrefix(PartitionID partId, VertexID srcId, EdgeType type) {
    type |= kEdgeMaskSet;
    PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);

    std::string key;
    key.reserve(sizeof(PartitionID) + sizeof(VertexID) + sizeof(EdgeType));
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&srcId), sizeof(VertexID))
       .append(reinterpret_cast<const char*>(&type), sizeof(EdgeType));
    return key;
}

// static
std::string NebulaKeyUtils::prefix(PartitionID partId) {
    PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);
    std::string key;
    key.reserve(sizeof(PartitionID));
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID));
    return key;
}

// static
std::string NebulaKeyUtils::vertexPrefix(PartitionID partId, VertexID vId) {
    PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);
    std::string key;
    key.reserve(sizeof(PartitionID) + sizeof(VertexID));
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&vId), sizeof(VertexID));
    return key;
}

// static
std::string NebulaKeyUtils::edgePrefix(PartitionID partId, VertexID vId) {
    PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);
    std::string key;
    key.reserve(sizeof(PartitionID) + sizeof(VertexID));
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&vId), sizeof(VertexID));
    return key;
}

// static
std::string NebulaKeyUtils::systemPrefix() {
    int8_t type = static_cast<uint32_t>(NebulaKeyType::kSystem);
    std::string key;
    key.reserve(sizeof(int8_t));
    key.append(reinterpret_cast<const char*>(&type), sizeof(int8_t));
    return key;
}

// static
std::string NebulaKeyUtils::prefix(PartitionID partId, VertexID src, EdgeType type,
                                   EdgeRanking ranking, VertexID dst) {
    type |= kEdgeMaskSet;
    PartitionID item = (partId << kPartitionOffset) | static_cast<uint32_t>(NebulaKeyType::kData);

    std::string key;
    key.reserve(sizeof(PartitionID) + sizeof(VertexID) + sizeof(EdgeType)
                + sizeof(VertexID) + sizeof(EdgeRanking));
    key.append(reinterpret_cast<const char*>(&item), sizeof(PartitionID))
       .append(reinterpret_cast<const char*>(&src), sizeof(VertexID))
       .append(reinterpret_cast<const char*>(&type), sizeof(EdgeType))
       .append(reinterpret_cast<const char*>(&ranking), sizeof(EdgeRanking))
       .append(reinterpret_cast<const char*>(&dst), sizeof(VertexID));
    return key;
}

}  // namespace nebula


@@ -137,8 +137,7 @@ TopologicalTorsionEnvGenerator<OutputType>::getEnvironments(
           code = getTopologicalTorsionCode(
               pathCodes, topologicalTorsionArguments->df_includeChirality);
         }
-
-        result.push_back(new TopologicalTorsionAtomEnv<OutputType>(code));
+        result.push_back(new TopologicalTorsionAtomEnv<OutputType>(code, path));
       }
     }
   }

//
//  Copyright (C) 2018 Boran Adas, Google Summer of Code
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#include <GraphMol/Fingerprints/TopologicalTorsionGenerator.h>
#include <GraphMol/Fingerprints/FingerprintUtil.h>
#include <GraphMol/Fingerprints/AtomPairGenerator.h>

namespace RDKit {
namespace TopologicalTorsion {

using namespace AtomPairs;

template <typename OutputType>
TopologicalTorsionArguments<OutputType>::TopologicalTorsionArguments(
    const bool includeChirality, const uint32_t torsionAtomCount,
    const bool countSimulation, const std::vector<std::uint32_t> countBounds,
    const std::uint32_t fpSize)
    : FingerprintArguments<OutputType>(countSimulation, countBounds, fpSize),
      df_includeChirality(includeChirality),
      d_torsionAtomCount(torsionAtomCount){};

template <typename OutputType>
OutputType TopologicalTorsionArguments<OutputType>::getResultSize() const {
  OutputType result = 1;
  return (result << (d_torsionAtomCount *
                     (codeSize + (df_includeChirality ? numChiralBits : 0))));
};

template <typename OutputType>
std::string TopologicalTorsionArguments<OutputType>::infoString() const {
  return "TopologicalTorsionArguments includeChirality=" +
         std::to_string(df_includeChirality) +
         " torsionAtomCount=" + std::to_string(d_torsionAtomCount);
};
template <typename OutputType>
OutputType TopologicalTorsionAtomEnv<OutputType>::getBitId(
    FingerprintArguments<OutputType> *,  // arguments
    const std::vector<std::uint32_t> *,  // atomInvariants
    const std::vector<std::uint32_t> *,  // bondInvariants
    const AdditionalOutput *,            // additionalOutput
    const bool                           // hashResults
) const {
  return d_bitId;
};

template <typename OutputType>
TopologicalTorsionAtomEnv<OutputType>::TopologicalTorsionAtomEnv(
    OutputType bitId)
    : d_bitId(bitId){};

template <typename OutputType>
std::vector<AtomEnvironment<OutputType> *>
TopologicalTorsionEnvGenerator<OutputType>::getEnvironments(
    const ROMol &mol, FingerprintArguments<OutputType> *arguments,
    const std::vector<std::uint32_t> *fromAtoms,
    const std::vector<std::uint32_t> *ignoreAtoms,
    const int,                 // confId
    const AdditionalOutput *,  // additionalOutput
    const std::vector<std::uint32_t> *atomInvariants,
    const std::vector<std::uint32_t> *,  // bondInvariants
    const bool hashResults) const {
  auto *topologicalTorsionArguments =
      dynamic_cast<TopologicalTorsionArguments<OutputType> *>(arguments);

  std::vector<AtomEnvironment<OutputType> *> result =
      std::vector<AtomEnvironment<OutputType> *>();

  boost::dynamic_bitset<> *fromAtomsBV = nullptr;
  if (fromAtoms) {
    fromAtomsBV = new boost::dynamic_bitset<>(mol.getNumAtoms());
    for (auto fAt : *fromAtoms) {
      fromAtomsBV->set(fAt);
    }
  }
  boost::dynamic_bitset<> *ignoreAtomsBV = nullptr;
  if (ignoreAtoms) {
    ignoreAtomsBV = new boost::dynamic_bitset<>(mol.getNumAtoms());
    for (auto fAt : *ignoreAtoms) {
      ignoreAtomsBV->set(fAt);
    }
  }
  boost::dynamic_bitset<> pAtoms(mol.getNumAtoms());
  PATH_LIST paths = findAllPathsOfLengthN(
      mol, topologicalTorsionArguments->d_torsionAtomCount, false);
  for (PATH_LIST::const_iterator pathIt = paths.begin(); pathIt != paths.end();
       ++pathIt) {
    bool keepIt = true;
    if (fromAtomsBV) {
      keepIt = false;
    }
    std::vector<std::uint32_t> pathCodes;
    const PATH_TYPE &path = *pathIt;
    if (fromAtomsBV) {
      if (fromAtomsBV->test(static_cast<std::uint32_t>(path.front())) ||
          fromAtomsBV->test(static_cast<std::uint32_t>(path.back()))) {
        keepIt = true;
      }
    }
    if (keepIt && ignoreAtomsBV) {
      for (int pElem : path) {
        if (ignoreAtomsBV->test(pElem)) {
          keepIt = false;
          break;
        }
      }
    }
    if (keepIt) {
      pAtoms.reset();
      for (auto pIt = path.begin(); pIt < path.end(); ++pIt) {
        // look for a cycle that doesn't start at the first atom
        // we can't effectively canonicalize these at the moment
        // (was github #811)
        if (pIt != path.begin() && *pIt != *(path.begin()) && pAtoms[*pIt]) {
          pathCodes.clear();
          break;
        }
        pAtoms.set(*pIt);
        unsigned int code = (*atomInvariants)[*pIt] % ((1 << codeSize) - 1) + 1;
        // subtract off the branching number:
        if (pIt != path.begin() && pIt + 1 != path.end()) {
          --code;
        }
        pathCodes.push_back(code);
      }
      if (pathCodes.size()) {
        OutputType code;
        if (hashResults) {
          code = getTopologicalTorsionHash(pathCodes);
        } else {
          code = getTopologicalTorsionCode(
              pathCodes, topologicalTorsionArguments->df_includeChirality);
        }

        result.push_back(new TopologicalTorsionAtomEnv<OutputType>(code));
      }
    }
  }
  delete fromAtomsBV;
  delete ignoreAtomsBV;

  return result;
};

template <typename OutputType>
std::string TopologicalTorsionEnvGenerator<OutputType>::infoString() const {
  return "TopologicalTorsionEnvGenerator";
};

template <typename OutputType>
FingerprintGenerator<OutputType> *getTopologicalTorsionGenerator(
    const bool includeChirality, const uint32_t torsionAtomCount,
    AtomInvariantsGenerator *atomInvariantsGenerator,
    const bool countSimulation, const std::vector<std::uint32_t> countBounds,
    const std::uint32_t fpSize, const bool ownsAtomInvGen) {
  auto *envGenerator = new TopologicalTorsionEnvGenerator<OutputType>();

  auto *arguments = new TopologicalTorsionArguments<OutputType>(
      includeChirality, torsionAtomCount, countSimulation, countBounds, fpSize);

  bool ownsAtomInvGenerator = ownsAtomInvGen;
  if (!atomInvariantsGenerator) {
    atomInvariantsGenerator =
        new AtomPair::AtomPairAtomInvGenerator(includeChirality, true);
    ownsAtomInvGenerator = true;
  }

  return new FingerprintGenerator<OutputType>(envGenerator, arguments,
                                              atomInvariantsGenerator, nullptr,
                                              ownsAtomInvGenerator, false);
};

// Topological torsion fingerprint does not support 32 bit output yet

template RDKIT_FINGERPRINTS_EXPORT FingerprintGenerator<std::uint64_t> *
getTopologicalTorsionGenerator(const bool includeChirality,
                               const uint32_t torsionAtomCount,
                               AtomInvariantsGenerator *atomInvariantsGenerator,
                               const bool countSimulation,
                               const std::vector<std::uint32_t> countBounds,
                               const std::uint32_t fpSize,
                               const bool ownsAtomInvGen);

}  // namespace TopologicalTorsion
}  // namespace RDKit


@@ -187,13 +187,19 @@ void init_io_random(int seed) {

   ::io_generator_seed_base = seed;
   ::io_generator_seed_inited = true;
-  /// Reset the init flag so that generator will reinitialize
-  ::io_generator_inited = false;
-
   ::fast_io_generator_seed_base = seed;
   ::fast_io_generator_seed_inited = true;
-  /// Reset the init flag so that generator will reinitialize
-  ::fast_io_generator_inited = false;
+
+  ::io_generator.resize(num_io_RNGs);
+  ::fast_io_generator.resize(num_io_RNGs);
+  ::io_generator_inited.resize(num_io_RNGs);
+  ::fast_io_generator_inited.resize(num_io_RNGs);
+  for(int i = 0; i < num_io_RNGs; i++) {
+    /// Reset the init flag so that I/O generator will reinitialize
+    ::io_generator_inited[i] = false;
+    /// Reset the init flag so that fast I/O generator will reinitialize
+    ::fast_io_generator_inited[i] = false;
+  }
 }

 }  // namespace lbann

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014-2019, Lawrence Livermore National Security, LLC.
// Produced at the Lawrence Livermore National Laboratory.
// Written by the LBANN Research Team (B. Van Essen, et al.) listed in
// the CONTRIBUTORS file. <lbann-dev@llnl.gov>
//
// LLNL-CODE-697807.
// All rights reserved.
//
// This file is part of LBANN: Livermore Big Artificial Neural Network
// Toolkit. For details, see http://software.llnl.gov/LBANN or
// https://github.com/LLNL/LBANN.
//
// Licensed under the Apache License, Version 2.0 (the "Licensee"); 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.
////////////////////////////////////////////////////////////////////////////////

#include <omp.h>
#include "lbann/utils/random_number_generators.hpp"
#include "lbann/utils/hash.hpp"
#include "lbann/utils/exception.hpp"
#include <thread>

namespace {
#ifdef __ICC
lbann::rng_gen generator;
#pragma omp threadprivate(generator)

lbann::fast_rng_gen fast_generator;
#pragma omp threadprivate(fast_generator)
#else
// Random number generator, file-visible only.
// Defined like this to work around a GCC problem with threadprivate objects:
// https://stackoverflow.com/questions/23552077/how-to-define-a-object-or-struct-as-threadprivate-in-openmp/
extern lbann::rng_gen generator;
#pragma omp threadprivate(generator)
lbann::rng_gen generator;

extern lbann::fast_rng_gen fast_generator;
#pragma omp threadprivate(fast_generator)
lbann::fast_rng_gen fast_generator;
#endif

bool generator_inited = false;
bool fast_generator_inited = false;

thread_local lbann::rng_gen data_seq_generator;
thread_local bool data_seq_generator_inited = false;
int data_seq_generator_seed_base = 0;
bool data_seq_generator_seed_inited = false;

thread_local lbann::rng_gen io_generator;
thread_local bool io_generator_inited = false;
int io_generator_seed_base = 0;
bool io_generator_seed_inited = false;

thread_local lbann::fast_rng_gen fast_io_generator;
thread_local bool fast_io_generator_inited = false;
int fast_io_generator_seed_base = 0;
bool fast_io_generator_seed_inited = false;
}

namespace lbann {

rng_gen& get_generator() {
  if (!::generator_inited) { LBANN_ERROR("RNG seed not set"); }
  return ::generator;
}

fast_rng_gen& get_fast_generator() {
  if (!::fast_generator_inited) { LBANN_ERROR("Fast RNG seed not set"); }
  return ::fast_generator;
}

rng_gen& get_data_seq_generator() {
  if (!::data_seq_generator_inited) {
    if (!::data_seq_generator_seed_inited) { LBANN_ERROR("data sequence RNG seed not set"); }
    ::data_seq_generator.seed(::data_seq_generator_seed_base);
    ::data_seq_generator_inited = true;
  }
  return ::data_seq_generator;
}

rng_gen& get_io_generator() {
  if (!::io_generator_inited) {
    if (!::io_generator_seed_inited) { LBANN_ERROR("I/O RNG seed not set"); }
    ::io_generator.seed(hash_combine(::io_generator_seed_base,
                                     std::this_thread::get_id()));
    ::io_generator_inited = true;
  }
  return ::io_generator;
}

fast_rng_gen& get_fast_io_generator() {
  if (!::fast_io_generator_inited) {
    if (!::fast_io_generator_seed_inited) { LBANN_ERROR("Fast I/O RNG seed not set"); }
    ::fast_io_generator.seed(hash_combine(::fast_io_generator_seed_base,
                                          std::this_thread::get_id()));
    ::fast_io_generator_inited = true;
  }
  return ::fast_io_generator;
}
void init_random(int seed, lbann_comm *comm) {
  generator_inited = true;
  fast_generator_inited = true;
  if (seed != -1) {
    // Seed every OpenMP thread, if present.
    // Note: Threadprivate OMP variables don't work with dynamic threads.
#ifdef _OPENMP
    #pragma omp parallel
    {
      get_generator().seed(hash_combine(seed, omp_get_thread_num()));
      get_fast_generator().seed(hash_combine(seed, omp_get_thread_num()));
    }
#else
    get_generator().seed(seed);
    get_fast_generator().seed(seed);
#endif

#ifdef LBANN_SET_EL_RNG
    // Set Elemental's RNG seed
    auto elemental_seed = hash_combine(seed, 104729); // 10000th prime
    int mpi_initialized = 0;
    MPI_Initialized(&mpi_initialized);
    if(mpi_initialized) {
      // If MPI is initialized mix in the rank to ensure that Hydrogen
      // has good RNGs.  Note that under some configurations LBANN
      // will not do this, so it is good to ensure that Hydrogen is
      // well seeded.
      elemental_seed = (comm == nullptr
                        ? hash_combine(elemental_seed, El::mpi::Rank(El::mpi::COMM_WORLD))
                        : hash_combine(elemental_seed, comm->get_rank_in_trainer()));
    }
    El::Generator().seed(elemental_seed);
#endif

  } else {
    // Seed with a random value.
    std::random_device rd;
    unsigned rand_val = rd();
#ifdef _OPENMP
    #pragma omp parallel
    {
      get_generator().seed(hash_combine(rand_val, omp_get_thread_num()));
      get_fast_generator().seed(hash_combine(rand_val, omp_get_thread_num()));
    }
#else
    get_generator().seed(rand_val);
    get_fast_generator().seed(rand_val);
#endif
#ifdef LBANN_SET_EL_RNG
    El::Generator().seed(rand_val);
#endif
  }

  init_io_random(seed);
}

void init_data_seq_random(int seed) {
  if (seed == -1) {
    // Seed with a random value.
    std::random_device rd;
    seed = rd();
  }

  ::data_seq_generator_seed_base = seed;
  ::data_seq_generator_seed_inited = true;
  /// Reset the init flag so that generator will reinitialize
  ::data_seq_generator_inited = false;
}

void init_io_random(int seed) {
  if (seed == -1) {
    // Seed with a random value.
    std::random_device rd;
    seed = rd();
  }

  ::io_generator_seed_base = seed;
  ::io_generator_seed_inited = true;
  /// Reset the init flag so that generator will reinitialize
  ::io_generator_inited = false;

  ::fast_io_generator_seed_base = seed;
  ::fast_io_generator_seed_inited = true;
  /// Reset the init flag so that generator will reinitialize
  ::fast_io_generator_inited = false;
}

}  // namespace lbann


@@ -74,11 +74,8 @@ void LXQtMountPlugin::settingsChanged()
         delete mDeviceAction;
         mDeviceAction = DeviceAction::create(actionId, this);

-        connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded,
-                mDeviceAction, &DeviceAction::onDeviceAdded);
-
-        connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved,
-                mDeviceAction, &DeviceAction::onDeviceRemoved);
+        connect(mPopup, &Popup::deviceAdded, mDeviceAction, &DeviceAction::onDeviceAdded);
+        connect(mPopup, &Popup::deviceRemoved, mDeviceAction, &DeviceAction::onDeviceRemoved);
     }

 }

/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Petr Vanek <petr@scribus.info>
 *
 * 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 "lxqtmountplugin.h"
#include "configuration.h"

#include <Solid/DeviceNotifier>

LXQtMountPlugin::LXQtMountPlugin(const ILXQtPanelPluginStartupInfo &startupInfo):
    QObject(),
    ILXQtPanelPlugin(startupInfo),
    mPopup(nullptr),
    mDeviceAction(nullptr)
{
    mButton = new Button;
    mPopup = new Popup(this);

    connect(mButton, &QToolButton::clicked, mPopup, &Popup::showHide);
    connect(mPopup, &Popup::visibilityChanged, mButton, &QToolButton::setDown);
}

LXQtMountPlugin::~LXQtMountPlugin()
{
    delete mButton;
    delete mPopup;
}

QDialog *LXQtMountPlugin::configureDialog()
{
    if (mPopup)
        mPopup->hide();

    Configuration *configWindow = new Configuration(settings());
    configWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    return configWindow;
}

void LXQtMountPlugin::realign()
{
    //nothing to do
}

void LXQtMountPlugin::settingsChanged()
{
    QString s = settings()->value(QLatin1String(CFG_KEY_ACTION)).toString();
    DeviceAction::ActionId actionId = DeviceAction::stringToActionId(s, DeviceAction::ActionMenu);

    if (mDeviceAction == nullptr || mDeviceAction->Type() != actionId)
    {
        delete mDeviceAction;
        mDeviceAction = DeviceAction::create(actionId, this);

        connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded,
                mDeviceAction, &DeviceAction::onDeviceAdded);

        connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved,
                mDeviceAction, &DeviceAction::onDeviceRemoved);
    }

}


@@ -94,7 +94,8 @@ uint16_t  Adafruit_MPR121::filteredData(uint8_t t) {
 }

 uint16_t  Adafruit_MPR121::baselineData(uint8_t t) {
-  if (t > 12) return 0;
+  if ((_sensitivity == MPR212_EXTRA_SENSITIVITY) && (t > 3)) return 0;
+  if (t > 12) return 0; // MPR212_NORMAL_SENSITIVITY
   uint16_t bl = readRegister8(MPR121_BASELINE_0 + t);
   return (bl << 2);
 }

/***************************************************
  This is a library for the MPR121 I2C 12-chan Capacitive Sensor

  Designed specifically to work with the MPR121 sensor from Adafruit
  ----> https://www.adafruit.com/products/1982

  These sensors use I2C to communicate, 2+ pins are required to
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "Adafruit_MPR121.h"

Adafruit_MPR121::Adafruit_MPR121() {
}

boolean Adafruit_MPR121::begin(uint8_t i2caddr) {
  //Wire.begin();   called in ESPEasy framework

  _i2caddr = i2caddr;

  // soft reset
  writeRegister(MPR121_SOFTRESET, 0x63);
  delay(1);
  for (uint8_t i=0; i<0x7F; i++) {
  //  Serial.print("$"); Serial.print(i, HEX);
  //  Serial.print(": 0x"); Serial.println(readRegister8(i));
  }

  writeRegister(MPR121_ECR, 0x0);

  uint8_t c = readRegister8(MPR121_CONFIG2);

  if (c != 0x24) return false;

  setThresholds(12, 6);
  writeRegister(MPR121_MHDR, 0x01);
  writeRegister(MPR121_NHDR, 0x01);
  writeRegister(MPR121_NCLR, 0x0E);
  writeRegister(MPR121_FDLR, 0x00);

  writeRegister(MPR121_MHDF, 0x01);
  writeRegister(MPR121_NHDF, 0x05);
  writeRegister(MPR121_NCLF, 0x01);
  writeRegister(MPR121_FDLF, 0x00);

  writeRegister(MPR121_NHDT, 0x00);
  writeRegister(MPR121_NCLT, 0x00);
  writeRegister(MPR121_FDLT, 0x00);

  writeRegister(MPR121_DEBOUNCE, 0);
  writeRegister(MPR121_CONFIG1, 0x10); // default, 16uA charge current
  writeRegister(MPR121_CONFIG2, 0x20); // 0.5uS encoding, 1ms period

//  writeRegister(MPR121_AUTOCONFIG0, 0x8F);

//  writeRegister(MPR121_UPLIMIT, 150);
//  writeRegister(MPR121_TARGETLIMIT, 100); // should be ~400 (100 shifted)
//  writeRegister(MPR121_LOWLIMIT, 50);
  // enable all electrodes
  writeRegister(MPR121_ECR, 0x8F);  // start with first 5 bits of baseline tracking

  return true;
}

void Adafruit_MPR121::setThreshholds(uint8_t touch, uint8_t release) {

  setThresholds(touch, release);
  }

void Adafruit_MPR121::setThresholds(uint8_t touch, uint8_t release) {
  for (uint8_t i=0; i<12; i++) {
    writeRegister(MPR121_TOUCHTH_0 + 2*i, touch);
    writeRegister(MPR121_RELEASETH_0 + 2*i, release);
  }
}

void Adafruit_MPR121::setThreshold(uint8_t t, uint8_t touch, uint8_t release) {
  if (t > 12) return;
  writeRegister(MPR121_TOUCHTH_0 + 2 * t, touch);
  writeRegister(MPR121_RELEASETH_0 + 2 * t, release);
}

uint16_t  Adafruit_MPR121::filteredData(uint8_t t) {
  if (t > 12) return 0;
  return readRegister16(MPR121_FILTDATA_0L + t*2);
}

uint16_t  Adafruit_MPR121::baselineData(uint8_t t) {
  if (t > 12) return 0;
  uint16_t bl = readRegister8(MPR121_BASELINE_0 + t);
  return (bl << 2);
}

uint16_t  Adafruit_MPR121::touched(void) {
  uint16_t t = readRegister16(MPR121_TOUCHSTATUS_L);
  return t & 0x0FFF;
}

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

uint8_t Adafruit_MPR121::readRegister8(uint8_t reg) {
    Wire.beginTransmission(_i2caddr);
    Wire.write(reg);
    Wire.endTransmission(false);
    while (Wire.requestFrom(_i2caddr, 1) != 1);
    return ( Wire.read());
}

uint16_t Adafruit_MPR121::readRegister16(uint8_t reg) {
    Wire.beginTransmission(_i2caddr);
    Wire.write(reg);
    Wire.endTransmission(false);
    while (Wire.requestFrom(_i2caddr, 2) != 2);
    uint16_t v = Wire.read();
    v |=  ((uint16_t) Wire.read()) << 8;
    return v;
}

/**************************************************************************/
/*!
    @brief  Writes 8-bits to the specified destination register
*/
/**************************************************************************/
void Adafruit_MPR121::writeRegister(uint8_t reg, uint8_t value) {
    Wire.beginTransmission(_i2caddr);
    Wire.write((uint8_t)reg);
    Wire.write((uint8_t)(value));
    Wire.endTransmission();
}


@@ -67,20 +67,20 @@ struct WaitListInfo
 	WaitList priorityWaitList;
 	WaitList waitList;

-	std::pair<WaitList::iterator, WaitList::size_type> findClient(const Player *player) {
+	std::tuple<WaitList&, WaitList::iterator, WaitList::size_type> findClient(const Player *player) {
 		std::size_t slot = 1;
 		for (auto it = priorityWaitList.begin(), end = priorityWaitList.end(); it != end; ++it, ++slot) {
 			if (it->playerGUID == player->getGUID()) {
-				return {it, slot};
+				return std::make_tuple(std::ref(priorityWaitList), it, slot);
 			}
 		}

 		for (auto it = waitList.begin(), end = waitList.end(); it != end; ++it, ++slot) {
 			if (it->playerGUID == player->getGUID()) {
-				return {it, slot};
+				return std::make_tuple(std::ref(waitList), it, slot);
 			}
 		}
-		return {waitList.end(), slot};
+		return std::make_tuple(std::ref(waitList), waitList.end(), slot);
 	}
 };

/**
 * The Forgotten Server - a free and open-source MMORPG server emulator
 * Copyright (C) 2019  Mark Samman <mark.samman@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "otpch.h"

#include "configmanager.h"
#include "game.h"
#include "waitlist.h"

extern ConfigManager g_config;
extern Game g_game;

namespace {

struct Wait
{
	constexpr Wait(std::size_t timeout, uint32_t playerGUID) :
			timeout(timeout), playerGUID(playerGUID) {}

	std::size_t timeout;
	uint32_t playerGUID;
};

using WaitList = std::list<Wait>;

void cleanupList(WaitList& list)
{
	int64_t time = OTSYS_TIME();

	auto it = list.begin(), end = list.end();
	while (it != end) {
		if ((it->timeout - time) <= 0) {
			it = list.erase(it);
		} else {
			++it;
		}
	}
}

std::size_t getTimeout(std::size_t slot)
{
	//timeout is set to 15 seconds longer than expected retry attempt
	return WaitingList::getTime(slot) + 15;
}

} // namespace

struct WaitListInfo
{
	WaitList priorityWaitList;
	WaitList waitList;

	std::pair<WaitList::iterator, WaitList::size_type> findClient(const Player *player) {
		std::size_t slot = 1;
		for (auto it = priorityWaitList.begin(), end = priorityWaitList.end(); it != end; ++it, ++slot) {
			if (it->playerGUID == player->getGUID()) {
				return {it, slot};
			}
		}

		for (auto it = waitList.begin(), end = waitList.end(); it != end; ++it, ++slot) {
			if (it->playerGUID == player->getGUID()) {
				return {it, slot};
			}
		}
		return {waitList.end(), slot};
	}
};

WaitingList& WaitingList::getInstance()
{
	static WaitingList waitingList;
	return waitingList;
}

std::size_t WaitingList::getTime(std::size_t slot)
{
	if (slot < 5) {
		return 5;
	} else if (slot < 10) {
		return 10;
	} else if (slot < 20) {
		return 20;
	} else if (slot < 50) {
		return 60;
	} else {
		return 120;
	}
}

bool WaitingList::clientLogin(const Player* player)
{
	if (player->hasFlag(PlayerFlag_CanAlwaysLogin) || player->getAccountType() >= ACCOUNT_TYPE_GAMEMASTER) {
		return true;
	}

	auto maxPlayers = static_cast<uint32_t>(g_config.getNumber(ConfigManager::MAX_PLAYERS));
	if (maxPlayers == 0 || (info->priorityWaitList.empty() && info->waitList.empty() && g_game.getPlayersOnline() < maxPlayers)) {
		return true;
	}

	cleanupList(info->priorityWaitList);
	cleanupList(info->waitList);

	WaitList::iterator it;
	WaitList::size_type slot;
	std::tie(it, slot) = info->findClient(player);
	if (it != info->waitList.end()) {
		if ((g_game.getPlayersOnline() + slot) <= maxPlayers) {
			//should be able to login now
			info->waitList.erase(it);
			return true;
		}

		//let them wait a bit longer
		it->timeout = OTSYS_TIME() + (getTimeout(slot) * 1000);
		return false;
	}

	slot = info->priorityWaitList.size();
	if (player->isPremium()) {
		info->priorityWaitList.emplace_back(OTSYS_TIME() + (getTimeout(slot + 1) * 1000), player->getGUID());
	} else {
		slot += info->waitList.size();
		info->waitList.emplace_back(OTSYS_TIME() + (getTimeout(slot + 1) * 1000), player->getGUID());
	}
	return false;
}

std::size_t WaitingList::getClientSlot(const Player* player)
{
	WaitList::iterator it;
	WaitList::size_type slot;
	std::tie(it, slot) = info->findClient(player);
	if (it == info->waitList.end()) {
		return 0;
	}
	return slot;
}

WaitingList::WaitingList() : info(new WaitListInfo) {}


@@ -10,6 +10,7 @@ import (
 	"strconv"
 	"strings"

+	"github.com/opencontainers/runc/libcontainer"
 	"github.com/urfave/cli"
 )

// +build linux

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"github.com/urfave/cli"
)

var psCommand = cli.Command{
	Name:      "ps",
	Usage:     "ps displays the processes running inside a container",
	ArgsUsage: `<container-id> [ps options]`,
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "format, f",
			Value: "table",
			Usage: `select one of: ` + formatOptions,
		},
	},
	Action: func(context *cli.Context) error {
		if err := checkArgs(context, 1, minArgs); err != nil {
			return err
		}
		container, err := getContainer(context)
		if err != nil {
			return err
		}

		pids, err := container.Processes()
		if err != nil {
			return err
		}

		switch context.String("format") {
		case "table":
		case "json":
			return json.NewEncoder(os.Stdout).Encode(pids)
		default:
			return fmt.Errorf("invalid format option")
		}

		// [1:] is to remove command name, ex:
		// context.Args(): [containet_id ps_arg1 ps_arg2 ...]
		// psArgs:         [ps_arg1 ps_arg2 ...]
		//
		psArgs := context.Args()[1:]
		if len(psArgs) == 0 {
			psArgs = []string{"-ef"}
		}

		cmd := exec.Command("ps", psArgs...)
		output, err := cmd.CombinedOutput()
		if err != nil {
			return fmt.Errorf("%s: %s", err, output)
		}

		lines := strings.Split(string(output), "\n")
		pidIndex, err := getPidIndex(lines[0])
		if err != nil {
			return err
		}

		fmt.Println(lines[0])
		for _, line := range lines[1:] {
			if len(line) == 0 {
				continue
			}
			fields := strings.Fields(line)
			p, err := strconv.Atoi(fields[pidIndex])
			if err != nil {
				return fmt.Errorf("unexpected pid '%s': %s", fields[pidIndex], err)
			}

			for _, pid := range pids {
				if pid == p {
					fmt.Println(line)
					break
				}
			}
		}
		return nil
	},
	SkipArgReorder: true,
}

func getPidIndex(title string) (int, error) {
	titles := strings.Fields(title)

	pidIndex := -1
	for i, name := range titles {
		if name == "PID" {
			return i, nil
		}
	}

	return pidIndex, fmt.Errorf("couldn't find PID field in ps output")
}


@@ -23,6 +23,7 @@ package thrift
 import (
 	"bytes"
 	"fmt"
+	"io"
 	"math/rand"
 	"reflect"
 	"testing"

// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package thrift

import (
	"bytes"
	"fmt"
	"math/rand"
	"reflect"
	"testing"
	"testing/quick"
	"time"

	"github.com/stretchr/testify/assert"
	"go.uber.org/thriftrw/protocol/binary"
	"go.uber.org/thriftrw/wire"
)

func TestDisableEnveloperEncode(t *testing.T) {
	rand := rand.New(rand.NewSource(time.Now().Unix()))

	tests := []struct {
		value wire.Value
		want  []byte
	}{
		{
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			[]byte{0x00},
		},
		{
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(42)},
			}}),
			[]byte{
				0x08, 0x00, 0x01,
				0x00, 0x00, 0x00, 0x2a,
				0x00,
			},
		},
	}

	for _, tt := range tests {
		e := wire.Envelope{Value: tt.value, Type: wire.Call}
		generate(&e.Name, rand)
		generate(&e.SeqID, rand)

		var buffer bytes.Buffer
		proto := disableEnvelopingProtocol{binary.Default, wire.Reply}
		if !assert.NoError(t, proto.EncodeEnveloped(e, &buffer)) {
			continue
		}

		assert.Equal(t, tt.want, buffer.Bytes())

		gotE, err := proto.DecodeEnveloped(bytes.NewReader(tt.want))
		if !assert.NoError(t, err) {
			continue
		}

		assert.Equal(t, wire.Reply, gotE.Type)
		assert.True(t, wire.ValuesAreEqual(tt.value, gotE.Value))
	}
}

// generate generates a random value into the given pointer.
//
// 	var i int
// 	generate(&i, rand)
//
// If the type implements the quick.Generator interface, that is used.
func generate(v interface{}, r *rand.Rand) {
	t := reflect.TypeOf(v)
	if t.Kind() != reflect.Ptr {
		panic(fmt.Sprintf("%v is not a pointer type", t))
	}

	out, ok := quick.Value(t.Elem(), r)
	if !ok {
		panic(fmt.Sprintf("could not generate a value for %v", t))
	}

	reflect.ValueOf(v).Elem().Set(out)
}


@@ -15,6 +15,14 @@ import (
 // Compile-time variable
 var existingServer = "False"

+const lockFile = "/var/lock/k3s-test.lock"
+
+type K3sServer struct {
+	cmd     *exec.Cmd
+	scanner *bufio.Scanner
+	lock    int
+}
+
 func findK3sExecutable() string {
 	// if running on an existing cluster, it maybe installed via k3s.service
 	// or run manually from dist/artifacts/k3s

package util

import (
	"bufio"
	"encoding/json"
	"os"
	"os/exec"
	"os/user"
	"strings"

	"github.com/rancher/k3s/pkg/flock"
	"github.com/sirupsen/logrus"
)

// Compile-time variable
var existingServer = "False"

func findK3sExecutable() string {
	// if running on an existing cluster, it maybe installed via k3s.service
	// or run manually from dist/artifacts/k3s
	if IsExistingServer() {
		k3sBin, err := exec.LookPath("k3s")
		if err == nil {
			return k3sBin
		}
	}
	k3sBin := "dist/artifacts/k3s"
	for {
		_, err := os.Stat(k3sBin)
		if err != nil {
			k3sBin = "../" + k3sBin
			continue
		}
		break
	}
	return k3sBin
}

// IsRoot return true if the user is root (UID 0)
func IsRoot() bool {
	currentUser, err := user.Current()
	if err != nil {
		return false
	}
	return currentUser.Uid == "0"
}

func IsExistingServer() bool {
	return existingServer == "True"
}

// K3sCmd launches the provided K3s command via exec. Command blocks until finished.
// Command output from both Stderr and Stdout is provided via string.
//   cmdEx1, err := K3sCmd("etcd-snapshot", "ls")
//   cmdEx2, err := K3sCmd("kubectl", "get", "pods", "-A")
func K3sCmd(cmdName string, cmdArgs ...string) (string, error) {
	k3sBin := findK3sExecutable()
	// Only run sudo if not root
	var cmd *exec.Cmd
	if IsRoot() {
		k3sCmd := append([]string{cmdName}, cmdArgs...)
		cmd = exec.Command(k3sBin, k3sCmd...)
	} else {
		k3sCmd := append([]string{k3sBin, cmdName}, cmdArgs...)
		cmd = exec.Command("sudo", k3sCmd...)
	}
	byteOut, err := cmd.CombinedOutput()
	return string(byteOut), err
}

func contains(source []string, target string) bool {
	for _, s := range source {
		if s == target {
			return true
		}
	}
	return false
}

// ServerArgsPresent checks if the given arguments are found in the running k3s server
func ServerArgsPresent(neededArgs []string) bool {
	currentArgs := K3sServerArgs()
	for _, arg := range neededArgs {
		if !contains(currentArgs, arg) {
			return false
		}
	}
	return true
}

// K3sServerArgs returns the list of arguments that the k3s server launched with
func K3sServerArgs() []string {
	results, err := K3sCmd("kubectl", "get", "nodes", "-o", `jsonpath='{.items[0].metadata.annotations.k3s\.io/node-args}'`)
	if err != nil {
		return nil
	}
	res := strings.ReplaceAll(results, "'", "")
	var args []string
	if err := json.Unmarshal([]byte(res), &args); err != nil {
		logrus.Error(err)
		return nil
	}
	return args
}

func FindStringInCmdAsync(scanner *bufio.Scanner, target string) bool {
	for scanner.Scan() {
		if strings.Contains(scanner.Text(), target) {
			return true
		}
	}
	return false
}

type K3sServer struct {
	cmd     *exec.Cmd
	scanner *bufio.Scanner
	lock    int
}

// K3sStartServer acquires an exclusive lock on a temporary file, then launches a k3s cluster
// with the provided arguments. Subsequent/parallel calls to this function will block until
// the original lock is cleared using K3sKillServer
func K3sStartServer(cmdArgs ...string) (*K3sServer, error) {
	logrus.Info("waiting to get server lock")
	k3sLock, err := flock.Acquire("/var/lock/k3s-test.lock")
	if err != nil {
		return nil, err
	}

	k3sBin := findK3sExecutable()
	var cmd *exec.Cmd
	if IsRoot() {
		k3sCmd := append([]string{"server"}, cmdArgs...)
		cmd = exec.Command(k3sBin, k3sCmd...)
	} else {
		k3sCmd := append([]string{k3sBin, "server"}, cmdArgs...)
		cmd = exec.Command("sudo", k3sCmd...)
	}
	cmdOut, _ := cmd.StderrPipe()
	cmd.Stderr = os.Stderr
	err = cmd.Start()
	return &K3sServer{cmd, bufio.NewScanner(cmdOut), k3sLock}, err
}

// K3sKillServer terminates the running K3s server and unlocks the file for
// other tests
func K3sKillServer(server *K3sServer) error {
	if IsRoot() {
		if err := server.cmd.Process.Kill(); err != nil {
			return err
		}
	} else {
		// Since k3s was launched as sudo, we can't just kill the process
		killCmd := exec.Command("sudo", "pkill", "k3s")
		if err := killCmd.Run(); err != nil {
			return err
		}
	}
	return flock.Release(server.lock)
}


@@ -72,7 +72,8 @@ func Example_withTLS() {
 		log.Fatalf("failed to create gRPC client TLS credentials: %v", err)
 	}

-	exp, err := otlp.NewExporter(otlp.WithTLSCredentials(creds))
+	exp, err := otlp.NewExporter(otlp.EmptyConfiguration,
+		otlp.NewConnectionConfig(otlp.WithTLSCredentials(creds)))
 	if err != nil {
 		log.Fatalf("failed to create the collector exporter: %v", err)
 	}

// Copyright The OpenTelemetry Authors
//
// 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.

package otlp_test

import (
	"context"
	"fmt"
	"log"
	"time"

	"google.golang.org/grpc/credentials"

	"go.opentelemetry.io/otel/api/global"
	"go.opentelemetry.io/otel/exporters/otlp"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func Example_insecure() {
	exp, err := otlp.NewExporter(otlp.WithInsecure())
	if err != nil {
		log.Fatalf("Failed to create the collector exporter: %v", err)
	}
	defer func() {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		if err := exp.Shutdown(ctx); err != nil {
			global.Handle(err)
		}
	}()

	tp := sdktrace.NewProvider(
		sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
		sdktrace.WithBatcher(
			exp,
			// add following two options to ensure flush
			sdktrace.WithBatchTimeout(5),
			sdktrace.WithMaxExportBatchSize(10),
		),
	)
	global.SetTracerProvider(tp)

	tracer := global.Tracer("test-tracer")

	// Then use the OpenTelemetry tracing library, like we normally would.
	ctx, span := tracer.Start(context.Background(), "CollectorExporter-Example")
	defer span.End()

	for i := 0; i < 10; i++ {
		_, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i))
		<-time.After(6 * time.Millisecond)
		iSpan.End()
	}
}

func Example_withTLS() {
	// Please take at look at https://pkg.go.dev/google.golang.org/grpc/credentials#TransportCredentials
	// for ways on how to initialize gRPC TransportCredentials.
	creds, err := credentials.NewClientTLSFromFile("my-cert.pem", "")
	if err != nil {
		log.Fatalf("failed to create gRPC client TLS credentials: %v", err)
	}

	exp, err := otlp.NewExporter(otlp.WithTLSCredentials(creds))
	if err != nil {
		log.Fatalf("failed to create the collector exporter: %v", err)
	}
	defer func() {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		if err := exp.Shutdown(ctx); err != nil {
			global.Handle(err)
		}
	}()

	tp := sdktrace.NewProvider(
		sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
		sdktrace.WithBatcher(
			exp,
			// add following two options to ensure flush
			sdktrace.WithBatchTimeout(5),
			sdktrace.WithMaxExportBatchSize(10),
		),
	)
	global.SetTracerProvider(tp)

	tracer := global.Tracer("test-tracer")

	// Then use the OpenTelemetry tracing library, like we normally would.
	ctx, span := tracer.Start(context.Background(), "Securely-Talking-To-Collector-Span")
	defer span.End()

	for i := 0; i < 10; i++ {
		_, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i))
		<-time.After(6 * time.Millisecond)
		iSpan.End()
	}
}