text:
/* 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 "meta/MetaServiceUtils.h"
#include <boost/stacktrace.hpp>
#include <thrift/lib/cpp2/protocol/CompactProtocol.h>
#include <thrift/lib/cpp2/protocol/Serializer.h>
#include "common/network/NetworkUtils.h"
#include "processors/Common.h"

namespace nebula {
namespace meta {

// Systemtable means that it does not contain any space information(id).false means that the backup
// should be skipped.
static const std::unordered_map<std::string, std::pair<std::string, bool>> systemTableMaps = {
    {"users", {"__users__", true}},
    {"hosts", {"__hosts__", false}},
    {"snapshots", {"__snapshots__", false}},
    {"configs", {"__configs__", true}},
    {"groups", {"__groups__", true}},
    {"zones", {"__zones__", true}},
    {"ft_service", {"__ft_service__", false}},
    {"sessions", {"__sessions__", true}}};

// name => {prefix, parseSpaceid}, nullptr means that the backup should be skipped.
static const std::unordered_map<
    std::string,
    std::pair<std::string, std::function<decltype(MetaServiceUtils::spaceId)>>>
    tableMaps = {
        {"spaces", {"__spaces__", MetaServiceUtils::spaceId}},
        {"parts", {"__parts__", MetaServiceUtils::parsePartKeySpaceId}},
        {"tags", {"__tags__", MetaServiceUtils::parseTagsKeySpaceID}},
        {"edges", {"__edges__", MetaServiceUtils::parseEdgesKeySpaceID}},
        {"indexes", {"__indexes__", MetaServiceUtils::parseIndexesKeySpaceID}},
        // Index tables are handled separately.
        {"index", {"__index__", nullptr}},
        {"index_status", {"__index_status__", MetaServiceUtils::parseIndexStatusKeySpaceID}},
        {"roles", {"__roles__", MetaServiceUtils::parseRoleSpace}},
        {"last_update_time", {"__last_update_time__", nullptr}},
        {"leaders", {"__leaders__", nullptr}},
        {"leader_terms", {"__leader_terms__", nullptr}},
        {"listener", {"__listener__", nullptr}},
        {"statis", {"__statis__", MetaServiceUtils::parseStatisSpace}},
        {"balance_task", {"__balance_task__", nullptr}},
        {"balance_plan", {"__balance_plan__", nullptr}},
        {"ft_index", {"__ft_index__", nullptr}}};

static const std::string kSpacesTable         = tableMaps.at("spaces").first;         // NOLINT
static const std::string kPartsTable          = tableMaps.at("parts").first;          // NOLINT
static const std::string kHostsTable          = systemTableMaps.at("hosts").first;          // NOLINT
static const std::string kTagsTable           = tableMaps.at("tags").first;           // NOLINT
static const std::string kEdgesTable          = tableMaps.at("edges").first;          // NOLINT
static const std::string kIndexesTable        = tableMaps.at("indexes").first;        // NOLINT
static const std::string kIndexTable          = tableMaps.at("index").first;          // NOLINT
static const std::string kIndexStatusTable    = tableMaps.at("index_status").first;   // NOLINT
static const std::string kUsersTable          = systemTableMaps.at("users").first;          // NOLINT
static const std::string kRolesTable          = tableMaps.at("roles").first;          // NOLINT
static const std::string kConfigsTable        = systemTableMaps.at("configs").first;        // NOLINT
static const std::string kSnapshotsTable      = systemTableMaps.at("snapshots").first;      // NOLINT
static const std::string kLastUpdateTimeTable = tableMaps.at("last_update_time").first; // NOLINT
static const std::string kLeadersTable        = tableMaps.at("leaders").first;          // NOLINT
static const std::string kLeaderTermsTable    = tableMaps.at("leader_terms").first;     // NOLINT
static const std::string kGroupsTable         = systemTableMaps.at("groups").first;           // NOLINT
static const std::string kZonesTable          = systemTableMaps.at("zones").first;            // NOLINT
static const std::string kListenerTable       = tableMaps.at("listener").first;         // NOLINT

// Used to record the number of vertices and edges in the space
// The number of vertices of each tag in the space
// The number of edges of each edgetype in the space
static const std::string kStatisTable         = tableMaps.at("statis").first;           // NOLINT
static const std::string kBalanceTaskTable    = tableMaps.at("balance_task").first;     // NOLINT
static const std::string kBalancePlanTable    = tableMaps.at("balance_plan").first;     // NOLINT

const std::string kFTIndexTable        = tableMaps.at("ft_index").first;         // NOLINT
const std::string kFTServiceTable = systemTableMaps.at("ft_service").first;      // NOLINT
const std::string kSessionsTable = systemTableMaps.at("sessions").first;         // NOLINT

const int kMaxIpAddrLen = 15;   // '255.255.255.255'

bool backupTable(kvstore::KVStore* kvstore,
                 const std::string& backupName,
                 const std::string& tableName,
                 std::vector<std::string>& files,
                 std::function<bool(const folly::StringPiece& key)> filter) {
    auto backupFilePath = kvstore->backupTable(kDefaultSpaceId, backupName, tableName, filter);
    if (!ok(backupFilePath)) {
        auto result = error(backupFilePath);
        if (result == nebula::cpp2::ErrorCode::E_BACKUP_EMPTY_TABLE) {
            return true;
        }
        return false;
    }

    files.insert(files.end(),
                 std::make_move_iterator(value(backupFilePath).begin()),
                 std::make_move_iterator(value(backupFilePath).end()));
    return true;
}

std::string MetaServiceUtils::lastUpdateTimeKey() {
    std::string key;
    key.reserve(kLastUpdateTimeTable.size());
    key.append(kLastUpdateTimeTable.data(), kLastUpdateTimeTable.size());
    return key;
}

std::string MetaServiceUtils::lastUpdateTimeVal(const int64_t timeInMilliSec) {
    std::string val;
    val.reserve(sizeof(int64_t));
    val.append(reinterpret_cast<const char*>(&timeInMilliSec), sizeof(int64_t));
    return val;
}

std::string MetaServiceUtils::spaceKey(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kSpacesTable.size() + sizeof(GraphSpaceID));
    key.append(kSpacesTable.data(), kSpacesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

std::string MetaServiceUtils::spaceVal(const cpp2::SpaceDesc& spaceDesc) {
    std::string val;
    apache::thrift::CompactSerializer::serialize(spaceDesc, &val);
    return val;
}

cpp2::SpaceDesc MetaServiceUtils::parseSpace(folly::StringPiece rawData) {
    cpp2::SpaceDesc spaceDesc;
    apache::thrift::CompactSerializer::deserialize(rawData, spaceDesc);
    return spaceDesc;
}

const std::string& MetaServiceUtils::spacePrefix() {
    return kSpacesTable;
}

GraphSpaceID MetaServiceUtils::spaceId(folly::StringPiece rawKey) {
    return *reinterpret_cast<const GraphSpaceID*>(rawKey.data() + kSpacesTable.size());
}

std::string MetaServiceUtils::spaceName(folly::StringPiece rawVal) {
    return parseSpace(rawVal).get_space_name();
}

std::string MetaServiceUtils::partKey(GraphSpaceID spaceId, PartitionID partId) {
    std::string key;
    key.reserve(kPartsTable.size() + sizeof(GraphSpaceID) + sizeof(PartitionID));
    key.append(kPartsTable.data(), kPartsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(reinterpret_cast<const char*>(&partId), sizeof(PartitionID));
    return key;
}

GraphSpaceID MetaServiceUtils::parsePartKeySpaceId(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kPartsTable.size());
}

PartitionID MetaServiceUtils::parsePartKeyPartId(folly::StringPiece key) {
    return *reinterpret_cast<const PartitionID*>(key.data() + kPartsTable.size() +
                                                 sizeof(GraphSpaceID));
}

std::string MetaServiceUtils::partVal(const std::vector<HostAddr>& hosts) {
    return partValV2(hosts);
}

// dataVer(int) + vectorSize(size_t) + vector of (strIp(string) + port(int))
std::string MetaServiceUtils::partValV2(const std::vector<HostAddr>& hosts) {
    std::string encodedVal;
    int dataVersion = 2;
    encodedVal.append(reinterpret_cast<const char*>(&dataVersion), sizeof(int))
              .append(network::NetworkUtils::toHostsStr(hosts));
    return encodedVal;
}

std::string MetaServiceUtils::partPrefix() {
    std::string prefix;
    prefix.reserve(kPartsTable.size() + sizeof(GraphSpaceID));
    prefix.append(kPartsTable.data(), kPartsTable.size());
    return prefix;
}

std::string MetaServiceUtils::partPrefix(GraphSpaceID spaceId) {
    std::string prefix;
    prefix.reserve(kPartsTable.size() + sizeof(GraphSpaceID));
    prefix.append(kPartsTable.data(), kPartsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return prefix;
}

std::vector<HostAddr> MetaServiceUtils::parsePartVal(folly::StringPiece val, int partNum) {
    static const size_t unitSizeV1 = sizeof(int64_t);
    if (unitSizeV1 * partNum == val.size()) {
        return parsePartValV1(val);
    }
    int dataVer = *reinterpret_cast<const int32_t*>(val.data());
    UNUSED(dataVer);   // currently if not ver1, it must be v2
    val.advance(sizeof(int));
    return parsePartValV2(val);
}

// partion val is ip(int) + port(int)
std::vector<HostAddr> MetaServiceUtils::parsePartValV1(folly::StringPiece val) {
    std::vector<HostAddr> hosts;
    static const size_t unitSize = sizeof(int32_t) * 2;
    auto hostsNum = val.size() / unitSize;
    hosts.reserve(hostsNum);
    VLOG(3) << "Total size:" << val.size() << ", host size:" << unitSize
            << ", host num:" << hostsNum;
    for (decltype(hostsNum) i = 0; i < hostsNum; i++) {
        HostAddr h;
        uint32_t ip = *reinterpret_cast<const int32_t*>(val.data() + i * unitSize);
        h.host = network::NetworkUtils::intToIPv4(ip);
        h.port = *reinterpret_cast<const int32_t*>(val.data() + i * unitSize + sizeof(int32_t));
        hosts.emplace_back(std::move(h));
    }
    return hosts;
}

// dataVer(int) + vectorSize(size_t) + vector of (strIpV4(string) + port(int))
std::vector<HostAddr> MetaServiceUtils::parsePartValV2(folly::StringPiece val) {
    std::vector<HostAddr> ret;
    auto hostsOrErr = network::NetworkUtils::toHosts(val.str());
    if (hostsOrErr.ok()) {
        ret = std::move(hostsOrErr.value());
    } else {
        LOG(ERROR) << "invalid input for parsePartValV2()";
    }
    return ret;
}

std::string MetaServiceUtils::hostKey(std::string addr, Port port) {
    return hostKeyV2(addr, port);
}

std::string MetaServiceUtils::hostKeyV2(std::string addr, Port port) {
    std::string key;
    HostAddr h(addr, port);
    key.append(kHostsTable.data(), kHostsTable.size())
        .append(MetaServiceUtils::serializeHostAddr(h));
    return key;
}

const std::string& MetaServiceUtils::hostPrefix() {
    return kHostsTable;
}

HostAddr MetaServiceUtils::parseHostKey(folly::StringPiece key) {
    if (key.size() == kHostsTable.size() + sizeof(int64_t)) {
        return parseHostKeyV1(key);
    }
    return parseHostKeyV2(key);
}

HostAddr MetaServiceUtils::parseHostKeyV1(folly::StringPiece key) {
    HostAddr host;
    key.advance(kHostsTable.size());
    uint32_t ip = *reinterpret_cast<const uint32_t*>(key.begin());
    host.host = network::NetworkUtils::intToIPv4(ip);
    host.port = *reinterpret_cast<const int32_t*>(key.begin() + sizeof(uint32_t));
    return host;
}

HostAddr MetaServiceUtils::parseHostKeyV2(folly::StringPiece key) {
    key.advance(kHostsTable.size());
    return MetaServiceUtils::deserializeHostAddr(key);
}

std::string MetaServiceUtils::leaderKey(std::string addr, Port port) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    return leaderKeyV2(addr, port);
}

std::string MetaServiceUtils::leaderKeyV2(std::string addr, Port port) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    std::string key;
    HostAddr h(addr, port);

    key.reserve(kLeadersTable.size() + kMaxIpAddrLen + sizeof(Port));
    key.append(kLeadersTable.data(), kLeadersTable.size())
       .append(MetaServiceUtils::serializeHostAddr(h));
    return key;
}

std::string MetaServiceUtils::leaderKey(GraphSpaceID spaceId, PartitionID partId) {
    std::string key;
    key.reserve(kLeaderTermsTable.size() + sizeof(GraphSpaceID) + sizeof(PartitionID));
    key.append(kLeaderTermsTable.data(), kLeaderTermsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(reinterpret_cast<const char*>(&partId), sizeof(PartitionID));
    return key;
}

std::string MetaServiceUtils::leaderVal(const LeaderParts& leaderParts) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    std::string value;
    value.reserve(512);
    for (const auto& spaceEntry : leaderParts) {
        GraphSpaceID spaceId = spaceEntry.first;
        value.append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
        size_t leaderCount = spaceEntry.second.size();
        value.append(reinterpret_cast<const char*>(&leaderCount), sizeof(size_t));
        for (const auto& partId : spaceEntry.second) {
            value.append(reinterpret_cast<const char*>(&partId), sizeof(PartitionID));
        }
    }
    return value;
}

// v3: dataVer(int) + lenOfHost(8) + HostAddr(varchar) + term(int64_t)
std::string MetaServiceUtils::leaderValV3(const HostAddr& h, int64_t term) {
    std::string leaderVal;
    leaderVal.reserve(256);

    int dataVersion = 3;

    auto sHost = serializeHostAddr(h);
    auto lenOfHost = sHost.size();

    leaderVal.append(reinterpret_cast<const char*>(&dataVersion), sizeof(dataVersion))
             .append(reinterpret_cast<const char*>(&lenOfHost), sizeof(lenOfHost))
             .append(sHost)
             .append(reinterpret_cast<const char*>(&term), sizeof(term));
    return leaderVal;
}

// v3: dataVer(int) + lenOfHost(8) + HostAddr(varchar) + term(int64_t)
std::tuple<HostAddr, TermID, nebula::cpp2::ErrorCode>
MetaServiceUtils::parseLeaderValV3(folly::StringPiece val) {
    std::tuple<HostAddr, TermID, nebula::cpp2::ErrorCode> ret;
    std::get<2>(ret) = nebula::cpp2::ErrorCode::SUCCEEDED;
    int dataVer = *reinterpret_cast<const int*>(val.data());
    if (dataVer != 3) {
        std::get<2>(ret) = nebula::cpp2::ErrorCode::E_INVALID_PARM;
        return ret;
    }

    CHECK_GE(val.size(), sizeof(int));
    val.advance(sizeof(int));
    auto lenOfHost = *reinterpret_cast<const size_t*>(val.data());

    val.advance(sizeof(size_t));
    CHECK_GE(val.size(), lenOfHost);
    std::get<0>(ret) = MetaServiceUtils::deserializeHostAddr(val.subpiece(0, lenOfHost));

    val.advance(lenOfHost);
    std::get<1>(ret) = *reinterpret_cast<const TermID*>(val.data());
    return ret;
}

const std::string& MetaServiceUtils::leaderPrefix() {
    return kLeaderTermsTable;
}

std::string MetaServiceUtils::leaderPrefix(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kLeaderTermsTable.size() + sizeof(GraphSpaceID));
    key.append(kLeaderTermsTable.data(), kLeaderTermsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

HostAddr MetaServiceUtils::parseLeaderKey(folly::StringPiece key) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    if (key.size() == kLeadersTable.size() + sizeof(int64_t)) {
        return parseLeaderKeyV1(key);
    }
    return parseLeaderKeyV2(key);
}

// input should be a pair of int32_t
HostAddr MetaServiceUtils::parseLeaderKeyV1(folly::StringPiece key) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    HostAddr host;
    CHECK_EQ(key.size(), kLeadersTable.size() + sizeof(int64_t));
    key.advance(kLeadersTable.size());
    auto ip = *reinterpret_cast<const uint32_t*>(key.begin());
    host.host = network::NetworkUtils::intToIPv4(ip);
    host.port = *reinterpret_cast<const uint32_t*>(key.begin() + sizeof(ip));
    return host;
}

HostAddr MetaServiceUtils::parseLeaderKeyV2(folly::StringPiece key) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    key.advance(kLeadersTable.size());
    return MetaServiceUtils::deserializeHostAddr(key);
}

std::pair<GraphSpaceID, PartitionID> MetaServiceUtils::parseLeaderKeyV3(folly::StringPiece key) {
    std::pair<GraphSpaceID, PartitionID> ret;
    ret.first = *reinterpret_cast<const GraphSpaceID*>(key.data() + kLeaderTermsTable.size());
    ret.second = *reinterpret_cast<const PartitionID*>(key.data() + kLeaderTermsTable.size() +
                                                                    sizeof(GraphSpaceID));
    return ret;
}

LeaderParts MetaServiceUtils::parseLeaderValV1(folly::StringPiece val) {
    LOG(ERROR) << "deprecated function\n" << boost::stacktrace::stacktrace();
    LeaderParts leaderParts;
    size_t size = val.size();
    // decode leader info
    size_t offset = 0;
    while (offset + sizeof(GraphSpaceID) + sizeof(size_t) < size) {
        GraphSpaceID spaceId = *reinterpret_cast<const GraphSpaceID*>(val.data() + offset);
        offset += sizeof(GraphSpaceID);
        size_t leaderCount = *reinterpret_cast<const size_t*>(val.data() + offset);
        offset += sizeof(size_t);
        std::vector<PartitionID> partIds;
        for (size_t i = 0; i < leaderCount && offset < size; i++) {
            partIds.emplace_back(*reinterpret_cast<const PartitionID*>(val.data() + offset));
            offset += sizeof(PartitionID);
        }
        leaderParts.emplace(spaceId, std::move(partIds));
    }
    return leaderParts;
}

std::string MetaServiceUtils::schemaEdgePrefix(GraphSpaceID spaceId, EdgeType edgeType) {
    std::string key;
    key.reserve(kEdgesTable.size() + sizeof(GraphSpaceID) + sizeof(edgeType));
    key.append(kEdgesTable.data(), kEdgesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(reinterpret_cast<const char*>(&edgeType), sizeof(edgeType));
    return key;
}

std::string MetaServiceUtils::schemaEdgesPrefix(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kEdgesTable.size() + sizeof(GraphSpaceID));
    key.append(kEdgesTable.data(), kEdgesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

std::string MetaServiceUtils::schemaEdgeKey(GraphSpaceID spaceId,
                                            EdgeType edgeType,
                                            SchemaVer version) {
    auto storageVer = std::numeric_limits<SchemaVer>::max() - version;
    std::string key;
    key.reserve(kEdgesTable.size() + sizeof(GraphSpaceID) + sizeof(EdgeType) + sizeof(SchemaVer));
    key.append(kEdgesTable.data(), kEdgesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(reinterpret_cast<const char*>(&edgeType), sizeof(EdgeType))
        .append(reinterpret_cast<const char*>(&storageVer), sizeof(SchemaVer));
    return key;
}

std::string MetaServiceUtils::schemaVal(const std::string& name, const cpp2::Schema& schema) {
    auto len = name.size();
    std::string val, sval;
    apache::thrift::CompactSerializer::serialize(schema, &sval);
    val.reserve(sizeof(int32_t) + name.size() + sval.size());
    val.append(reinterpret_cast<const char*>(&len), sizeof(int32_t)).append(name).append(sval);
    return val;
}

EdgeType MetaServiceUtils::parseEdgeType(folly::StringPiece key) {
    return *reinterpret_cast<const EdgeType*>(key.data() + kEdgesTable.size() +
                                              sizeof(GraphSpaceID));
}

SchemaVer MetaServiceUtils::parseEdgeVersion(folly::StringPiece key) {
    auto offset = kEdgesTable.size() + sizeof(GraphSpaceID) + sizeof(EdgeType);
    return std::numeric_limits<SchemaVer>::max() -
           *reinterpret_cast<const SchemaVer*>(key.begin() + offset);
}

GraphSpaceID MetaServiceUtils::parseEdgesKeySpaceID(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kEdgesTable.size());
}

std::string MetaServiceUtils::schemaTagKey(GraphSpaceID spaceId, TagID tagId, SchemaVer version) {
    auto storageVer = std::numeric_limits<SchemaVer>::max() - version;
    std::string key;
    key.reserve(kTagsTable.size() + sizeof(GraphSpaceID) + sizeof(TagID) + sizeof(SchemaVer));
    key.append(kTagsTable.data(), kTagsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(reinterpret_cast<const char*>(&tagId), sizeof(TagID))
        .append(reinterpret_cast<const char*>(&storageVer), sizeof(SchemaVer));
    return key;
}

TagID MetaServiceUtils::parseTagId(folly::StringPiece key) {
    return *reinterpret_cast<const TagID*>(key.data() + kTagsTable.size() + sizeof(GraphSpaceID));
}

SchemaVer MetaServiceUtils::parseTagVersion(folly::StringPiece key) {
    auto offset = kTagsTable.size() + sizeof(GraphSpaceID) + sizeof(TagID);
    return std::numeric_limits<SchemaVer>::max() -
           *reinterpret_cast<const SchemaVer*>(key.begin() + offset);
}

std::string MetaServiceUtils::schemaTagPrefix(GraphSpaceID spaceId, TagID tagId) {
    std::string key;
    key.reserve(kTagsTable.size() + sizeof(GraphSpaceID) + sizeof(TagID));
    key.append(kTagsTable.data(), kTagsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(reinterpret_cast<const char*>(&tagId), sizeof(TagID));
    return key;
}

std::string MetaServiceUtils::schemaTagsPrefix(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kTagsTable.size() + sizeof(GraphSpaceID));
    key.append(kTagsTable.data(), kTagsTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

GraphSpaceID MetaServiceUtils::parseTagsKeySpaceID(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kTagsTable.size());
}

cpp2::Schema MetaServiceUtils::parseSchema(folly::StringPiece rawData) {
    cpp2::Schema schema;
    int32_t offset = sizeof(int32_t) + *reinterpret_cast<const int32_t*>(rawData.begin());
    auto schval = rawData.subpiece(offset, rawData.size() - offset);
    apache::thrift::CompactSerializer::deserialize(schval, schema);
    return schema;
}

std::string MetaServiceUtils::indexKey(GraphSpaceID spaceID, IndexID indexID) {
    std::string key;
    key.reserve(kIndexesTable.size() + sizeof(GraphSpaceID) + sizeof(IndexID));
    key.append(kIndexesTable.data(), kIndexesTable.size())
       .append(reinterpret_cast<const char*>(&spaceID), sizeof(GraphSpaceID))
       .append(reinterpret_cast<const char*>(&indexID), sizeof(IndexID));
    return key;
}

std::string MetaServiceUtils::indexVal(const nebula::meta::cpp2::IndexItem& item) {
    std::string value;
    apache::thrift::CompactSerializer::serialize(item, &value);
    return value;
}

std::string MetaServiceUtils::indexPrefix(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kIndexesTable.size() + sizeof(GraphSpaceID));
    key.append(kIndexesTable.data(), kIndexesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

GraphSpaceID MetaServiceUtils::parseIndexesKeySpaceID(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kIndexesTable.size());
}

IndexID MetaServiceUtils::parseIndexesKeyIndexID(folly::StringPiece key) {
    return *reinterpret_cast<const IndexID*>(key.data() + kIndexesTable.size() +
                                             sizeof(GraphSpaceID));
}

nebula::meta::cpp2::IndexItem MetaServiceUtils::parseIndex(const folly::StringPiece& rawData) {
    nebula::meta::cpp2::IndexItem item;
    apache::thrift::CompactSerializer::deserialize(rawData, item);
    return item;
}

// This method should replace with JobManager when it ready.
std::string MetaServiceUtils::rebuildIndexStatus(GraphSpaceID space,
                                                 char type,
                                                 const std::string& indexName) {
    std::string key;
    key.reserve(64);
    key.append(kIndexStatusTable.data(), kIndexStatusTable.size())
        .append(reinterpret_cast<const char*>(&space), sizeof(GraphSpaceID))
        .append(1, type)
        .append(indexName);
    return key;
}

// This method should replace with JobManager when it ready.
std::string MetaServiceUtils::rebuildIndexStatusPrefix(GraphSpaceID space, char type) {
    std::string key;
    key.reserve(kIndexStatusTable.size() + sizeof(GraphSpaceID) + sizeof(char));
    key.append(kIndexStatusTable.data(), kIndexStatusTable.size())
        .append(reinterpret_cast<const char*>(&space), sizeof(GraphSpaceID))
        .append(1, type);
    return key;
}

std::string MetaServiceUtils::rebuildIndexStatusPrefix() {
    std::string key;
    key.reserve(kIndexStatusTable.size());
    key.append(kIndexStatusTable.data(), kIndexStatusTable.size());
    return key;
}

GraphSpaceID MetaServiceUtils::parseIndexStatusKeySpaceID(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kIndexStatusTable.size());
}

std::string MetaServiceUtils::indexSpaceKey(const std::string& name) {
    EntryType type = EntryType::SPACE;
    std::string key;
    key.reserve(64);
    key.append(kIndexTable.data(), kIndexTable.size())
        .append(reinterpret_cast<const char*>(&type), sizeof(type))
        .append(name);
    return key;
}

std::string MetaServiceUtils::indexTagKey(GraphSpaceID spaceId, const std::string& name) {
    EntryType type = EntryType::TAG;
    std::string key;
    key.reserve(128);
    key.append(kIndexTable.data(), kIndexTable.size())
        .append(reinterpret_cast<const char*>(&type), sizeof(type))
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(name);
    return key;
}

std::string MetaServiceUtils::indexEdgeKey(GraphSpaceID spaceId, const std::string& name) {
    EntryType type = EntryType::EDGE;
    std::string key;
    key.reserve(128);
    key.append(kIndexTable.data(), kIndexTable.size())
        .append(reinterpret_cast<const char*>(&type), sizeof(type))
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(name);
    return key;
}

GraphSpaceID MetaServiceUtils::parseIndexKeySpaceID(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kIndexTable.size() +
                                                  sizeof(EntryType));
}

std::string MetaServiceUtils::indexIndexKey(GraphSpaceID spaceID,
                                            const std::string& indexName) {
    EntryType type = EntryType::INDEX;
    std::string key;
    key.reserve(128);
    key.append(kIndexTable.data(), kIndexTable.size())
       .append(reinterpret_cast<const char*>(&type), sizeof(type))
       .append(reinterpret_cast<const char*>(&spaceID), sizeof(GraphSpaceID))
       .append(indexName);
    return key;
}

std::string MetaServiceUtils::indexGroupKey(const std::string& name) {
    EntryType type = EntryType::GROUP;
    std::string key;
    key.reserve(128);
    key.append(kIndexTable.data(), kIndexTable.size())
       .append(reinterpret_cast<const char*>(&type), sizeof(EntryType))
       .append(name);
    return key;
}

std::string MetaServiceUtils::indexZoneKey(const std::string& name) {
    EntryType type = EntryType::ZONE;
    std::string key;
    key.reserve(128);
    key.append(kIndexTable.data(), kIndexTable.size())
       .append(reinterpret_cast<const char*>(&type), sizeof(type))
       .append(name);
    return key;
}

std::string MetaServiceUtils::assembleSegmentKey(const std::string& segment,
                                                 const std::string& key) {
    std::string segmentKey;
    segmentKey.reserve(64);
    segmentKey.append(segment).append(key.data(), key.size());
    return segmentKey;
}

nebula::cpp2::ErrorCode
MetaServiceUtils::alterColumnDefs(std::vector<cpp2::ColumnDef>& cols,
                                  cpp2::SchemaProp& prop,
                                  const cpp2::ColumnDef col,
                                  const cpp2::AlterSchemaOp op,
                                  bool isEdge) {
    switch (op) {
        case cpp2::AlterSchemaOp::ADD:
            for (auto it = cols.begin(); it != cols.end(); ++it) {
                if (it->get_name() == col.get_name()) {
                    LOG(ERROR) << "Column existing: " << col.get_name();
                    return nebula::cpp2::ErrorCode::E_EXISTED;
                }
            }
            cols.emplace_back(std::move(col));
            return nebula::cpp2::ErrorCode::SUCCEEDED;
        case cpp2::AlterSchemaOp::CHANGE:
            for (auto it = cols.begin(); it != cols.end(); ++it) {
                auto colName = col.get_name();
                if (colName == it->get_name()) {
                    // If this col is ttl_col, change not allowed
                    if (prop.get_ttl_col() && (*prop.get_ttl_col() == colName)) {
                        LOG(ERROR) << "Column: " << colName << " as ttl_col, change not allowed";
                        return nebula::cpp2::ErrorCode::E_UNSUPPORTED;
                    }
                    *it = col;
                    return nebula::cpp2::ErrorCode::SUCCEEDED;
                }
            }
            LOG(ERROR) << "Column not found: " << col.get_name();
            if (isEdge) {
                return nebula::cpp2::ErrorCode::E_EDGE_PROP_NOT_FOUND;
            }
            return nebula::cpp2::ErrorCode::E_TAG_PROP_NOT_FOUND;
        case cpp2::AlterSchemaOp::DROP:
            for (auto it = cols.begin(); it != cols.end(); ++it) {
                auto colName = col.get_name();
                if (colName == it->get_name()) {
                    if (prop.get_ttl_col() && (*prop.get_ttl_col() == colName)) {
                        prop.set_ttl_duration(0);
                        prop.set_ttl_col("");
                    }
                    cols.erase(it);
                    return nebula::cpp2::ErrorCode::SUCCEEDED;
                }
            }
            LOG(ERROR) << "Column not found: " << col.get_name();
            if (isEdge) {
                return nebula::cpp2::ErrorCode::E_EDGE_PROP_NOT_FOUND;
            }
            return nebula::cpp2::ErrorCode::E_TAG_PROP_NOT_FOUND;
        default:
            LOG(ERROR) << "Alter schema operator not supported";
            return nebula::cpp2::ErrorCode::E_UNSUPPORTED;
    }
}

nebula::cpp2::ErrorCode
MetaServiceUtils::alterSchemaProp(std::vector<cpp2::ColumnDef>& cols,
                                  cpp2::SchemaProp& schemaProp,
                                  cpp2::SchemaProp alterSchemaProp,
                                  bool existIndex,
                                  bool isEdge) {
    if (existIndex && (alterSchemaProp.ttl_duration_ref().has_value() ||
                alterSchemaProp.ttl_col_ref().has_value())) {
        LOG(ERROR) << "Has index, can't change ttl";
        return nebula::cpp2::ErrorCode::E_UNSUPPORTED;
    }
    if (alterSchemaProp.ttl_duration_ref().has_value()) {
        // Graph check  <=0 to = 0
        schemaProp.set_ttl_duration(*alterSchemaProp.ttl_duration_ref());
    }
    if (alterSchemaProp.ttl_col_ref().has_value()) {
        auto ttlCol = *alterSchemaProp.ttl_col_ref();
        // Disable ttl, ttl_col is empty, ttl_duration is 0
        if (ttlCol.empty()) {
            schemaProp.set_ttl_duration(0);
            schemaProp.set_ttl_col(ttlCol);
            return nebula::cpp2::ErrorCode::SUCCEEDED;
        }

        auto existed = false;
        for (auto& col : cols) {
            if (col.get_name() == ttlCol) {
                auto colType = col.get_type().get_type();
                // Only integer and timestamp columns can be used as ttl_col
                if (colType != cpp2::PropertyType::INT64 &&
                    colType != cpp2::PropertyType::TIMESTAMP) {
                    LOG(ERROR) << "TTL column type illegal";
                    return nebula::cpp2::ErrorCode::E_UNSUPPORTED;
                }
                existed = true;
                schemaProp.set_ttl_col(ttlCol);
                break;
            }
        }

        if (!existed) {
            LOG(ERROR) << "TTL column not found: " << ttlCol;
            if (isEdge) {
                return nebula::cpp2::ErrorCode::E_EDGE_PROP_NOT_FOUND;
            }
            return nebula::cpp2::ErrorCode::E_TAG_PROP_NOT_FOUND;
        }
    }

    // Disable implicit TTL mode
    if ((schemaProp.get_ttl_duration() && (*schemaProp.get_ttl_duration() != 0)) &&
        (!schemaProp.get_ttl_col() ||
         (schemaProp.get_ttl_col() && schemaProp.get_ttl_col()->empty()))) {
        LOG(WARNING) << "Implicit ttl_col not support";
        return nebula::cpp2::ErrorCode::E_UNSUPPORTED;
    }

    if (alterSchemaProp.comment_ref().has_value()) {
        schemaProp.set_comment(*alterSchemaProp.comment_ref());
    }

    return nebula::cpp2::ErrorCode::SUCCEEDED;
}

std::string MetaServiceUtils::userKey(const std::string& account) {
    std::string key;
    key.reserve(kUsersTable.size() + account.size());
    key.append(kUsersTable.data(), kUsersTable.size()).append(account);
    return key;
}

std::string MetaServiceUtils::userVal(const std::string& val) {
    std::string key;
    auto pwdLen = val.size();
    key.reserve(sizeof(int64_t) + pwdLen);
    key.append(reinterpret_cast<const char*>(&pwdLen), sizeof(size_t)).append(val);
    return key;
}

std::string MetaServiceUtils::parseUser(folly::StringPiece key) {
    return key.subpiece(kUsersTable.size(), key.size() - kUsersTable.size()).str();
}

std::string MetaServiceUtils::parseUserPwd(folly::StringPiece val) {
    auto len = *reinterpret_cast<const size_t*>(val.data());
    return val.subpiece(sizeof(size_t), len).str();
}

std::string MetaServiceUtils::roleKey(GraphSpaceID spaceId, const std::string& account) {
    std::string key;
    key.reserve(kRolesTable.size() + sizeof(GraphSpaceID) + account.size());
    key.append(kRolesTable.data(), kRolesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
        .append(account);
    return key;
}

std::string MetaServiceUtils::roleVal(cpp2::RoleType roleType) {
    std::string val;
    val.reserve(sizeof(cpp2::RoleType));
    val.append(reinterpret_cast<const char*>(&roleType), sizeof(cpp2::RoleType));
    return val;
}

std::string MetaServiceUtils::parseRoleUser(folly::StringPiece key) {
    auto offset = kRolesTable.size() + sizeof(GraphSpaceID);
    return key.subpiece(offset, key.size() - offset).str();
}

GraphSpaceID MetaServiceUtils::parseRoleSpace(folly::StringPiece key) {
    return *reinterpret_cast<const GraphSpaceID*>(key.data() + kRolesTable.size());
}

std::string MetaServiceUtils::rolesPrefix() {
    return kRolesTable;
}

std::string MetaServiceUtils::roleSpacePrefix(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kRolesTable.size() + sizeof(GraphSpaceID));
    key.append(kRolesTable.data(), kRolesTable.size())
        .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

std::string MetaServiceUtils::parseRoleStr(folly::StringPiece key) {
    auto type = *reinterpret_cast<const cpp2::RoleType*>(&key);
    std::string role;
    switch (type) {
        case cpp2::RoleType::GOD: {
            role = "GOD";
            break;
        }
        case cpp2::RoleType::ADMIN: {
            role = "ADMIN";
            break;
        }
        case cpp2::RoleType::DBA: {
            role = "DBA";
            break;
        }
        case cpp2::RoleType::USER: {
            role = "USER";
            break;
        }
        case cpp2::RoleType::GUEST: {
            role = "GUEST";
            break;
        }
    }
    return role;
}

std::string MetaServiceUtils::configKey(const cpp2::ConfigModule& module, const std::string& name) {
    int32_t nSize = name.size();
    std::string key;
    key.reserve(128);
    key.append(kConfigsTable.data(), kConfigsTable.size())
        .append(reinterpret_cast<const char*>(&module), sizeof(cpp2::ConfigModule))
        .append(reinterpret_cast<const char*>(&nSize), sizeof(int32_t))
        .append(name);
    return key;
}

std::string MetaServiceUtils::configKeyPrefix(const cpp2::ConfigModule& module) {
    std::string key;
    key.reserve(128);
    key.append(kConfigsTable.data(), kConfigsTable.size());
    if (module != cpp2::ConfigModule::ALL) {
        key.append(reinterpret_cast<const char*>(&module), sizeof(cpp2::ConfigModule));
    }
    return key;
}

std::string MetaServiceUtils::configValue(const cpp2::ConfigMode& valueMode, const Value& value) {
    std::string val, cVal;
    apache::thrift::CompactSerializer::serialize(value, &cVal);
    val.reserve(sizeof(cpp2::ConfigMode) + cVal.size());
    val.append(reinterpret_cast<const char*>(&valueMode), sizeof(cpp2::ConfigMode)).append(cVal);
    return val;
}

ConfigName MetaServiceUtils::parseConfigKey(folly::StringPiece rawKey) {
    std::string key;
    auto offset = kConfigsTable.size();
    auto module = *reinterpret_cast<const cpp2::ConfigModule*>(rawKey.data() + offset);
    offset += sizeof(cpp2::ConfigModule);
    int32_t nSize = *reinterpret_cast<const int32_t*>(rawKey.data() + offset);
    offset += sizeof(int32_t);
    auto name = rawKey.subpiece(offset, nSize);
    return {module, name.str()};
}

cpp2::ConfigItem MetaServiceUtils::parseConfigValue(folly::StringPiece rawData) {
    int32_t offset = 0;
    cpp2::ConfigMode mode = *reinterpret_cast<const cpp2::ConfigMode*>(rawData.data() + offset);
    offset += sizeof(cpp2::ConfigMode);
    Value value;
    apache::thrift::CompactSerializer::deserialize(
        rawData.subpiece(offset, rawData.size() - offset), value);

    cpp2::ConfigItem item;
    item.set_mode(mode);
    item.set_value(value);
    return item;
}

std::string MetaServiceUtils::snapshotKey(const std::string& name) {
    std::string key;
    key.reserve(kSnapshotsTable.size() + name.size());
    key.append(kSnapshotsTable.data(), kSnapshotsTable.size()).append(name);
    return key;
}

std::string MetaServiceUtils::snapshotVal(const cpp2::SnapshotStatus& status,
                                          const std::string& hosts) {
    std::string val;
    val.reserve(sizeof(cpp2::SnapshotStatus) + sizeof(hosts));
    val.append(reinterpret_cast<const char*>(&status), sizeof(cpp2::SnapshotStatus)).append(hosts);
    return val;
}

cpp2::SnapshotStatus MetaServiceUtils::parseSnapshotStatus(folly::StringPiece rawData) {
    return *reinterpret_cast<const cpp2::SnapshotStatus*>(rawData.data());
}

std::string MetaServiceUtils::parseSnapshotHosts(folly::StringPiece rawData) {
    return rawData
        .subpiece(sizeof(cpp2::SnapshotStatus), rawData.size() - sizeof(cpp2::SnapshotStatus))
        .str();
}

std::string MetaServiceUtils::parseSnapshotName(folly::StringPiece rawData) {
    int32_t offset = kSnapshotsTable.size();
    return rawData.subpiece(offset, rawData.size() - offset).str();
}

const std::string& MetaServiceUtils::snapshotPrefix() {
    return kSnapshotsTable;
}

std::string MetaServiceUtils::serializeHostAddr(const HostAddr& host) {
    std::string ret;
    ret.reserve(sizeof(size_t) + 15 + sizeof(Port));   // 255.255.255.255
    size_t len = host.host.size();
    ret.append(reinterpret_cast<char*>(&len), sizeof(size_t))
        .append(host.host.data(), len)
        .append(reinterpret_cast<const char*>(&host.port), sizeof(Port));
    return ret;
}

HostAddr MetaServiceUtils::deserializeHostAddr(folly::StringPiece raw) {
    HostAddr addr;
    CHECK_GE(raw.size(), sizeof(size_t) + sizeof(Port));   // host may be ""
    size_t offset = 0;
    size_t len = *reinterpret_cast<const size_t*>(raw.begin() + offset);
    offset += sizeof(size_t);
    addr.host = std::string(raw.begin() + offset, len);
    offset += len;
    addr.port = *reinterpret_cast<const Port*>(raw.begin() + offset);
    return addr;
}

std::string MetaServiceUtils::genTimestampStr() {
    char ch[60];
    std::time_t t = std::time(nullptr);
    std::strftime(ch, sizeof(ch), "%Y_%m_%d_%H_%M_%S", localtime(&t));
    return ch;
}

std::function<bool(const folly::StringPiece& key)>
MetaServiceUtils::spaceFilter(const std::unordered_set<GraphSpaceID>& spaces,
                              std::function<GraphSpaceID(folly::StringPiece rawKey)> parseSpace) {
    auto sf = [spaces, parseSpace](const folly::StringPiece& key) -> bool {
        if (spaces.empty()) {
            return false;
        }

        auto id = parseSpace(key);
        auto it = spaces.find(id);
        if (it == spaces.end()) {
            return true;
        }

        return false;
    };

    return sf;
}

ErrorOr<nebula::cpp2::ErrorCode, std::vector<std::string>>
MetaServiceUtils::backupIndexTable(
    kvstore::KVStore* kvstore,
    const std::unordered_set<GraphSpaceID>& spaces,
    const std::string& backupName,
    const std::vector<std::string>* spaceName) {
    return kvstore->backupTable(
        kDefaultSpaceId,
        backupName,
        kIndexTable,
        [spaces, spaceName](const folly::StringPiece& key) -> bool {
            if (spaces.empty() || spaceName == nullptr || spaceName->empty()) {
                return false;
            }

            auto type = *reinterpret_cast<const EntryType*>(key.data() + kIndexTable.size());
            if (type == EntryType::SPACE) {
                auto sn = key.subpiece(kIndexTable.size() + sizeof(EntryType),
                                       key.size() - kIndexTable.size() - sizeof(EntryType))
                              .str();
                LOG(INFO) << "sn was " << sn;
                auto it = std::find_if(spaceName->cbegin(), spaceName->cend(), [&sn](auto& name) {
                    return sn == name;
                });

                if (it == spaceName->cend()) {
                    return true;
                }
                return false;
            }

            auto id = parseIndexKeySpaceID(key);
            auto it = spaces.find(id);
            if (it == spaces.end()) {
                return true;
            }

            return false;
        });
}

folly::Optional<std::vector<std::string>> MetaServiceUtils::backup(
    kvstore::KVStore* kvstore,
    const std::unordered_set<GraphSpaceID>& spaces,
    const std::string& backupName,
    const std::vector<std::string>* spaceNames) {
    std::vector<std::string> files;
    files.reserve(tableMaps.size() + systemTableMaps.size());

    for (const auto& table : tableMaps) {
        if (table.second.second == nullptr) {
            LOG(INFO) << table.first << " table skipped";
            continue;
        }
        if (!backupTable(kvstore,
                         backupName,
                         table.second.first,
                         files,
                         spaceFilter(spaces, table.second.second))) {
            return folly::none;
        }
        LOG(INFO) << table.first << " table backup successed";
    }

    for (const auto& table : systemTableMaps) {
        if (!table.second.second) {
            LOG(INFO) << table.first << " table skipped";
            continue;
        }
        if (!backupTable(kvstore, backupName, table.second.first, files, nullptr)) {
            return folly::none;
        }
        LOG(INFO) << table.first << " table backup successed";
    }

    // The mapping of space name and space id needs to be handled separately.
    auto ret = backupIndexTable(kvstore, spaces, backupName, spaceNames);
    if (!ok(ret)) {
        auto result = error(ret);
        if (result == nebula::cpp2::ErrorCode::E_BACKUP_EMPTY_TABLE) {
            return files;
        }
        return folly::none;
    }

    files.insert(files.end(),
                 std::make_move_iterator(value(ret).begin()),
                 std::make_move_iterator(value(ret).end()));

    return files;
}

std::string MetaServiceUtils::balanceTaskKey(BalanceID balanceId,
                                             GraphSpaceID spaceId,
                                             PartitionID partId,
                                             HostAddr src,
                                             HostAddr dst) {
    std::string str;
    str.reserve(64);
    str.append(reinterpret_cast<const char*>(kBalanceTaskTable.data()), kBalanceTaskTable.size())
       .append(reinterpret_cast<const char*>(&balanceId), sizeof(BalanceID))
       .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
       .append(reinterpret_cast<const char*>(&partId), sizeof(PartitionID))
       .append(serializeHostAddr(src))
       .append(serializeHostAddr(dst));
    return str;
}

std::string MetaServiceUtils::balanceTaskVal(BalanceTaskStatus status,
                                             BalanceTaskResult retult,
                                             int64_t startTime,
                                             int64_t endTime) {
    std::string val;
    val.reserve(32);
    val.append(reinterpret_cast<const char*>(&status), sizeof(BalanceTaskStatus))
       .append(reinterpret_cast<const char*>(&retult), sizeof(BalanceTaskResult))
       .append(reinterpret_cast<const char*>(&startTime), sizeof(int64_t))
       .append(reinterpret_cast<const char*>(&endTime), sizeof(int64_t));
    return val;
}

std::string MetaServiceUtils::balanceTaskPrefix(BalanceID balanceId) {
    std::string prefix;
    prefix.reserve(32);
    prefix.append(reinterpret_cast<const char*>(kBalanceTaskTable.data()),
                  kBalanceTaskTable.size())
          .append(reinterpret_cast<const char*>(&balanceId), sizeof(BalanceID));
    return prefix;
}

std::string MetaServiceUtils::balancePlanKey(BalanceID id) {
    CHECK_GE(id, 0);
    // make the balance id is stored in decend order
    auto encode = folly::Endian::big(std::numeric_limits<BalanceID>::max() - id);
    std::string key;
    key.reserve(sizeof(BalanceID) + kBalancePlanTable.size());
    key.append(reinterpret_cast<const char*>(kBalancePlanTable.data()), kBalancePlanTable.size())
       .append(reinterpret_cast<const char*>(&encode), sizeof(BalanceID));
    return key;
}

std::string MetaServiceUtils::balancePlanVal(BalanceStatus status) {
    std::string val;
    val.reserve(sizeof(BalanceStatus));
    val.append(reinterpret_cast<const char*>(&status), sizeof(BalanceStatus));
    return val;
}

std::string MetaServiceUtils::balancePlanPrefix() {
    return kBalancePlanTable;
}

std::tuple<BalanceID, GraphSpaceID, PartitionID, HostAddr, HostAddr>
MetaServiceUtils::parseBalanceTaskKey(const folly::StringPiece& rawKey) {
    uint32_t offset = kBalanceTaskTable.size();
    auto balanceId = *reinterpret_cast<const BalanceID*>(rawKey.begin() + offset);
    offset += sizeof(balanceId);
    auto spaceId = *reinterpret_cast<const GraphSpaceID*>(rawKey.begin() + offset);
    offset += sizeof(GraphSpaceID);
    auto partId = *reinterpret_cast<const PartitionID*>(rawKey.begin() + offset);
    offset += sizeof(PartitionID);
    auto src = MetaServiceUtils::deserializeHostAddr({rawKey, offset});
    offset += src.host.size() + sizeof(size_t) + sizeof(uint32_t);
    auto dst = MetaServiceUtils::deserializeHostAddr({rawKey, offset});
    return std::make_tuple(balanceId, spaceId, partId, src, dst);
}

std::tuple<BalanceTaskStatus, BalanceTaskResult, int64_t, int64_t>
MetaServiceUtils::parseBalanceTaskVal(const folly::StringPiece& rawVal) {
    int32_t offset = 0;
    auto status = *reinterpret_cast<const BalanceTaskStatus*>(rawVal.begin() + offset);
    offset += sizeof(BalanceTaskStatus);
    auto ret = *reinterpret_cast<const BalanceTaskResult*>(rawVal.begin() + offset);
    offset += sizeof(BalanceTaskResult);
    auto start = *reinterpret_cast<const int64_t*>(rawVal.begin() + offset);
    offset += sizeof(int64_t);
    auto end = *reinterpret_cast<const int64_t*>(rawVal.begin() + offset);
    return std::make_tuple(status, ret, start, end);
}

std::string MetaServiceUtils::groupKey(const std::string& group) {
    std::string key;
    key.reserve(kGroupsTable.size() + group.size());
    key.append(kGroupsTable.data(), kGroupsTable.size())
       .append(group);
    return key;
}

BalanceID MetaServiceUtils::parseBalanceID(const folly::StringPiece& rawKey) {
    auto decode = *reinterpret_cast<const BalanceID*>(rawKey.begin() + kBalancePlanTable.size());
    auto id = std::numeric_limits<BalanceID>::max() - folly::Endian::big(decode);
    CHECK_GE(id, 0);
    return id;
}

BalanceStatus MetaServiceUtils::parseBalanceStatus(const folly::StringPiece& rawVal) {
    return static_cast<BalanceStatus>(*rawVal.begin());
}

std::string MetaServiceUtils::groupVal(const std::vector<std::string>& zones) {
    return folly::join(",", zones);
}

const std::string& MetaServiceUtils::groupPrefix() {
    return kGroupsTable;
}

std::string MetaServiceUtils::parseGroupName(folly::StringPiece rawData) {
    return rawData.subpiece(kGroupsTable.size(), rawData.size()).toString();
}

std::vector<std::string> MetaServiceUtils::parseZoneNames(folly::StringPiece rawData) {
    std::vector<std::string> zones;
    folly::split(',', rawData.str(), zones);
    return zones;
}

std::string MetaServiceUtils::zoneKey(const std::string& zone) {
    std::string key;
    key.reserve(kZonesTable.size() + zone.size());
    key.append(kZonesTable.data(), kZonesTable.size())
       .append(zone);
    return key;
}

std::string MetaServiceUtils::zoneVal(const std::vector<HostAddr>& hosts) {
    std::string value;
    value.append(network::NetworkUtils::toHostsStr(hosts));
    return value;
}

const std::string& MetaServiceUtils::zonePrefix() {
    return kZonesTable;
}

std::string MetaServiceUtils::parseZoneName(folly::StringPiece rawData) {
    return rawData.subpiece(kZonesTable.size(), rawData.size()).toString();
}

std::vector<HostAddr> MetaServiceUtils::parseZoneHosts(folly::StringPiece rawData) {
    std::vector<HostAddr> addresses;
    auto hostsOrErr = network::NetworkUtils::toHosts(rawData.str());
    if (hostsOrErr.ok()) {
        addresses = std::move(hostsOrErr.value());
    } else {
        LOG(ERROR) << "invalid input for parseZoneHosts()";
    }
    return addresses;
}

std::string MetaServiceUtils::listenerKey(GraphSpaceID spaceId,
                                          PartitionID partId,
                                          cpp2::ListenerType type) {
    std::string key;
    key.reserve(kListenerTable.size() + sizeof(GraphSpaceID) +
                sizeof(cpp2::ListenerType) + sizeof(PartitionID));
    key.append(kListenerTable.data(), kListenerTable.size())
       .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
       .append(reinterpret_cast<const char*>(&type), sizeof(cpp2::ListenerType))
       .append(reinterpret_cast<const char*>(&partId), sizeof(PartitionID));
    return key;
}

std::string MetaServiceUtils::listenerPrefix(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kListenerTable.size() + sizeof(GraphSpaceID));
    key.append(kListenerTable.data(), kListenerTable.size())
       .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

std::string MetaServiceUtils::listenerPrefix(GraphSpaceID spaceId,
                                             cpp2::ListenerType type) {
    std::string key;
    key.reserve(kListenerTable.size() + sizeof(GraphSpaceID) + sizeof(cpp2::ListenerType));
    key.append(kListenerTable.data(), kListenerTable.size())
       .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID))
       .append(reinterpret_cast<const char*>(&type), sizeof(cpp2::ListenerType));
    return key;
}

cpp2::ListenerType MetaServiceUtils::parseListenerType(folly::StringPiece rawData) {
    auto offset = kListenerTable.size() + sizeof(GraphSpaceID);
    return *reinterpret_cast<const cpp2::ListenerType*>(rawData.data() + offset);
}

GraphSpaceID MetaServiceUtils::parseListenerSpace(folly::StringPiece rawData) {
    auto offset = kListenerTable.size();
    return *reinterpret_cast<const GraphSpaceID*>(rawData.data() + offset);
}

PartitionID MetaServiceUtils::parseListenerPart(folly::StringPiece rawData) {
    auto offset = kListenerTable.size() + sizeof(cpp2::ListenerType) + sizeof(GraphSpaceID);
    return *reinterpret_cast<const PartitionID*>(rawData.data() + offset);
}

std::string MetaServiceUtils::statisKey(GraphSpaceID spaceId) {
    std::string key;
    key.reserve(kStatisTable.size() + sizeof(GraphSpaceID));
    key.append(kStatisTable.data(), kStatisTable.size())
       .append(reinterpret_cast<const char*>(&spaceId), sizeof(GraphSpaceID));
    return key;
}

std::string MetaServiceUtils::statisVal(const cpp2::StatisItem& statisItem) {
    std::string val;
    apache::thrift::CompactSerializer::serialize(statisItem, &val);
    return val;
}

cpp2::StatisItem MetaServiceUtils::parseStatisVal(folly::StringPiece rawData) {
    cpp2::StatisItem statisItem;
    apache::thrift::CompactSerializer::deserialize(rawData, statisItem);
    return statisItem;
}

GraphSpaceID MetaServiceUtils::parseStatisSpace(folly::StringPiece rawData) {
    auto offset = kStatisTable.size();
    return *reinterpret_cast<const GraphSpaceID*>(rawData.data() + offset);
}

const std::string& MetaServiceUtils::statisKeyPrefix() {
    return kStatisTable;
}

std::string MetaServiceUtils::fulltextServiceKey() {
    std::string key;
    key.reserve(kFTServiceTable.size());
    key.append(kFTServiceTable.data(), kFTServiceTable.size());
    return key;
}

std::string MetaServiceUtils::fulltextServiceVal(cpp2::FTServiceType type,
                                                 const std::vector<cpp2::FTClient>& clients) {
    std::string val, cval;
    apache::thrift::CompactSerializer::serialize(clients, &cval);
    val.reserve(sizeof(cpp2::FTServiceType) + cval.size());
    val.append(reinterpret_cast<const char*>(&type), sizeof(cpp2::FTServiceType))
        .append(cval);
    return val;
}

std::vector<cpp2::FTClient> MetaServiceUtils::parseFTClients(folly::StringPiece rawData) {
    std::vector<cpp2::FTClient> clients;
    int32_t offset = sizeof(cpp2::FTServiceType);
    auto clientsRaw = rawData.subpiece(offset, rawData.size() - offset);
    apache::thrift::CompactSerializer::deserialize(clientsRaw, clients);
    return clients;
}

const std::string& MetaServiceUtils::sessionPrefix() {
    return kSessionsTable;
}

std::string MetaServiceUtils::sessionKey(SessionID sessionId) {
    std::string key;
    key.reserve(kSessionsTable.size() + sizeof(sessionId));
    key.append(kSessionsTable.data(), kSessionsTable.size())
       .append(reinterpret_cast<const char*>(&sessionId), sizeof(SessionID));
    return key;
}

std::string MetaServiceUtils::sessionVal(const meta::cpp2::Session &session) {
    std::string val;
    apache::thrift::CompactSerializer::serialize(session, &val);
    return val;
}

SessionID MetaServiceUtils::getSessionId(const folly::StringPiece &key) {
    return *reinterpret_cast<const SessionID*>(key.data() + kSessionsTable.size());
}

meta::cpp2::Session MetaServiceUtils::parseSessionVal(const folly::StringPiece &val) {
    meta::cpp2::Session session;
    apache::thrift::CompactSerializer::deserialize(val, session);
    return session;
}

std::string MetaServiceUtils::fulltextIndexKey(const std::string& indexName) {
    std::string key;
    key.reserve(kFTIndexTable.size() + indexName.size());
    key.append(kFTIndexTable.data(), kFTIndexTable.size())
       .append(indexName);
    return key;
}

std::string MetaServiceUtils::fulltextIndexVal(const cpp2::FTIndex& index) {
    std::string val;
    apache::thrift::CompactSerializer::serialize(index, &val);
    return val;
}

std::string MetaServiceUtils::parsefulltextIndexName(folly::StringPiece key) {
    return key.subpiece(kFTIndexTable.size(), key.size()).toString();
}

cpp2::FTIndex MetaServiceUtils::parsefulltextIndex(folly::StringPiece val) {
   cpp2::FTIndex ftIndex;
   apache::thrift::CompactSerializer::deserialize(val, ftIndex);
   return ftIndex;
}

std::string MetaServiceUtils::fulltextIndexPrefix() {
    return kFTIndexTable;
}

}  // namespace meta
}  // namespace nebula

max_stars_repo_name: Aiee/nebula-storage

max_issues_repo_name: Aiee/nebula-storage

max_forks_repo_name: Aiee/nebula-storage


text:
/*
 * Copyright (C) 2012-2015 Open Source Robotics Foundation
 *
 * 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.
 *
*/

#ifdef _WIN32
  // Ensure that Winsock2.h is included before Windows.h, which can get
  // pulled in by anybody (e.g., Boost).
  #include <Winsock2.h>
#endif

#include <boost/function.hpp>
#include "gazebo/common/Assert.hh"
#include "gazebo/common/Console.hh"

#include "gazebo/sensors/GaussianNoiseModel.hh"
#include "gazebo/sensors/Noise.hh"

using namespace gazebo;
using namespace sensors;

//////////////////////////////////////////////////
NoisePtr NoiseFactory::NewNoiseModel(sdf::ElementPtr _sdf,
    const std::string &_sensorType)
{
  GZ_ASSERT(_sdf != NULL, "noise sdf is NULL");
  GZ_ASSERT(_sdf->GetName() == "noise", "Not a noise SDF element");

  std::string typeString = _sdf->Get<std::string>("type");

  NoisePtr noise;

  // Check for 'gaussian' noise. The 'gaussian_quantized' type is kept for
  // backward compatibility.
  if (typeString == "gaussian" ||
      typeString == "gaussian_quantized")
  {
    if (_sensorType == "camera" || _sensorType == "depth" ||
      _sensorType == "multicamera")
    {
      noise.reset(new ImageGaussianNoiseModel());
    }
    else
      noise.reset(new GaussianNoiseModel());

    GZ_ASSERT(noise->GetNoiseType() == Noise::GAUSSIAN,
        "Noise type should be 'gaussian'");
  }
  else if (typeString == "none" || typeString == "custom")
  {
    // Return empty noise if 'none' or 'custom' is specified.
    // if 'custom', the type will be set once the user calls the
    // SetCustomNoiseCallback function.
    noise.reset(new Noise(Noise::NONE));
    GZ_ASSERT(noise->GetNoiseType() == Noise::NONE,
        "Noise type should be 'none'");
  }
  else
  {
    gzerr << "Unrecognized noise type" << std::endl;
    return NoisePtr();
  }
  noise->Load(_sdf);

  return noise;
}

//////////////////////////////////////////////////
Noise::Noise(NoiseType _type)
  : type(_type),
    customNoiseCallback(NULL)
{
}

//////////////////////////////////////////////////
Noise::~Noise()
{
}

//////////////////////////////////////////////////
void Noise::Load(sdf::ElementPtr _sdf)
{
  this->sdf = _sdf;
  GZ_ASSERT(this->sdf != NULL, "this->sdf is NULL");
}

//////////////////////////////////////////////////
void Noise::SetCamera(rendering::CameraPtr /*_camera*/)
{
  gzerr << "Ignoring SetCamera: Not attached to an image sensor" << std::endl;
}

//////////////////////////////////////////////////
double Noise::Apply(double _in)
{
  if (this->type == NONE)
    return _in;
  else if (this->type == CUSTOM)
  {
    if (this->customNoiseCallback)
      return this->customNoiseCallback(_in);
    else
    {
      gzerr << "Custom noise callback function not set!"
          << " Please call SetCustomNoiseCallback within a sensor plugin."
          << std::endl;
      return _in;
    }
  }
  else
    return this->ApplyImpl(_in);
}

//////////////////////////////////////////////////
double Noise::ApplyImpl(double _in)
{
  return _in;
}

//////////////////////////////////////////////////
Noise::NoiseType Noise::GetNoiseType() const
{
  return this->type;
}

//////////////////////////////////////////////////
void Noise::SetCustomNoiseCallback(boost::function<double (double)> _cb)
{
  this->type = CUSTOM;
  this->customNoiseCallback = _cb;
}

//////////////////////////////////////////////////
void Noise::Fini()
{
  this->customNoiseCallback = NULL;
}

//////////////////////////////////////////////////
void Noise::Print(std::ostream &_out) const
{
  _out << "Noise with type[" << this->type << "] "
    << "does not have an overloaded Print function. "
    << "No more information is available.";
}

ext: cc

max_stars_repo_name: harderthan/gazebo

max_issues_repo_name: harderthan/gazebo

max_forks_repo_name: harderthan/gazebo


text:
#ifndef SOLVER_PARAMS_HPP
#define SOLVER_PARAMS_HPP

#include <Eigen/Dense>

namespace ms  // mader solver
{
struct par_solver
{
  ///// Will not change between iterations
  double x_min = -std::numeric_limits<double>::max();
  double x_max = std::numeric_limits<double>::max();

  double y_min = -std::numeric_limits<double>::max();
  double y_max = std::numeric_limits<double>::max();

  double z_min = -std::numeric_limits<double>::max();
  double z_max = std::numeric_limits<double>::max();
  Eigen::Vector3d v_max;
  Eigen::Vector3d a_max;
  Eigen::Vector3d j_max;
  double dc;
  double dist_to_use_straight_guess;
  int a_star_samp_x;
  int a_star_samp_y;
  int a_star_samp_z;
  double a_star_fraction_voxel_size;
  int num_pol;
  int deg_pol;
  double weight;
  double epsilon_tol_constraints;
  double xtol_rel;
  double ftol_rel;
  std::string solver;
  std::string basis;
  double a_star_bias;
  bool allow_infeasible_guess;
  double Ra;

  double alpha_shrink;
};
}  // namespace ms

#endif

ext: hpp

max_stars_repo_name: shubham-shahh/mader

max_issues_repo_name: shubham-shahh/mader

max_forks_repo_name: shubham-shahh/mader


text:
#ifndef SERVER_HTTP_HPP
#define	SERVER_HTTP_HPP

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/functional/hash.hpp>

#include <unordered_map>
#include <thread>
#include <functional>
#include <iostream>
#include <sstream>

/* WEB SERVER IS BASED ON https://github.com/eidheim/Simple-Web-Server */

namespace SimpleWeb {
	template <class socket_type>
	class ServerBase {
	public:
		class Response : public std::ostream {
			friend class ServerBase<socket_type>;
		private:
			boost::asio::yield_context& yield;

			boost::asio::streambuf streambuf;

			socket_type &socket;

			Response(socket_type &socket, boost::asio::yield_context& yield): std::ostream(&streambuf), yield(yield), socket(socket) {}

		public:
			size_t size() { return streambuf.size(); }
			void flush() {
				boost::system::error_code ec;
				boost::asio::async_write(socket, streambuf, yield[ec]);

				if(ec) throw std::runtime_error(ec.message());
			}
		};

		class Content : public std::istream {
			friend class ServerBase<socket_type>;
		public:
			size_t size() { return streambuf.size(); }
			std::string string() { std::stringstream ss; ss << rdbuf(); return ss.str(); }
		private:
			boost::asio::streambuf &streambuf;
			Content(boost::asio::streambuf &streambuf): std::istream(&streambuf), streambuf(streambuf) {}
		};

		class Request {
			friend class ServerBase<socket_type>;

		public:
			std::string method, path, http_version;

			Content content;

			std::unordered_multimap<std::string, std::string> header;

			boost::smatch path_match;

			std::string remote_endpoint_address;
			unsigned short remote_endpoint_port;

		private:
			Request(boost::asio::io_service &io_service): content(streambuf), strand(io_service) {}

			boost::asio::streambuf streambuf;

			boost::asio::strand strand;

			void read_remote_endpoint_data(socket_type& socket) {
				try {
					remote_endpoint_address=socket.lowest_layer().remote_endpoint().address().to_string();
					remote_endpoint_port=socket.lowest_layer().remote_endpoint().port();
				}
				catch(const std::exception& e) {}
			}
		};

		class Config {
			friend class ServerBase<socket_type>;
		private:
			Config(const std::string& address, unsigned short port, size_t num_threads): address(address), port(port), num_threads(num_threads), reuse_address(true) {}
			std::string address;
			unsigned short port;
			size_t num_threads;
		public:
			bool reuse_address;
		};

		Config config;

		std::unordered_map<std::string, std::unordered_map<std::string,
			std::function<void(typename ServerBase<socket_type>::Response&, std::shared_ptr<typename ServerBase<socket_type>::Request>)> > >  resource;

		std::unordered_map<std::string,
			std::function<void(typename ServerBase<socket_type>::Response&, std::shared_ptr<typename ServerBase<socket_type>::Request>)> > default_resource;

	private:
		std::vector<std::pair<std::string, std::vector<std::pair<boost::regex,
			std::function<void(typename ServerBase<socket_type>::Response&, std::shared_ptr<typename ServerBase<socket_type>::Request>)> > > > > opt_resource;

	public:
		void start() {
			opt_resource.clear();
			for(auto& res: resource) {
				for(auto& res_method: res.second) {
					auto it=opt_resource.end();
					for(auto opt_it=opt_resource.begin();opt_it!=opt_resource.end();opt_it++) {
						if(res_method.first==opt_it->first) {
							it=opt_it;
							break;
						}
					}
					if(it==opt_resource.end()) {
						opt_resource.emplace_back();
						it=opt_resource.begin()+(opt_resource.size()-1);
						it->first=res_method.first;
					}
					it->second.emplace_back(boost::regex(res.first), res_method.second);
				}
			}

			if(io_service.stopped()) io_service.reset();

			boost::asio::ip::tcp::endpoint endpoint;

			if(config.address.size()>0) endpoint=boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(config.address), config.port);
			else endpoint=boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), config.port);

			acceptor.open(endpoint.protocol());
			acceptor.set_option(boost::asio::socket_base::reuse_address(config.reuse_address));
			acceptor.bind(endpoint);
			acceptor.listen();

			accept();

			threads.clear();
			for(size_t c=1;c<config.num_threads;c++) {
				threads.emplace_back([this](){
					io_service.run();
				});
			}

			io_service.run();

			for(auto& t: threads) {
				t.join();
			}
		}

		void stop() {
			acceptor.close();
			io_service.stop();
		}

	protected:
		boost::asio::io_service io_service;
		boost::asio::ip::tcp::acceptor acceptor;
		std::vector<std::thread> threads;

		size_t timeout_request;
		size_t timeout_content;

		ServerBase(const std::string& address, unsigned short port, size_t num_threads, size_t timeout_request, size_t timeout_send_or_receive) :
				config(address, port, num_threads), acceptor(io_service),
				timeout_request(timeout_request), timeout_content(timeout_send_or_receive) {}

		virtual void accept()=0;

		std::shared_ptr<boost::asio::deadline_timer> set_timeout_on_socket(std::shared_ptr<socket_type> socket, size_t seconds) {
			std::shared_ptr<boost::asio::deadline_timer> timer(new boost::asio::deadline_timer(io_service));
			timer->expires_from_now(boost::posix_time::seconds(seconds));
			timer->async_wait([socket](const boost::system::error_code& ec){
				if(!ec) {
					boost::system::error_code ec;
					socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
					socket->lowest_layer().close();
				}
			});
			return timer;
		}

		std::shared_ptr<boost::asio::deadline_timer> set_timeout_on_socket(std::shared_ptr<socket_type> socket, std::shared_ptr<Request> request, size_t seconds) {
			std::shared_ptr<boost::asio::deadline_timer> timer(new boost::asio::deadline_timer(io_service));
			timer->expires_from_now(boost::posix_time::seconds(seconds));
			timer->async_wait(request->strand.wrap([socket](const boost::system::error_code& ec){
				if(!ec) {
					boost::system::error_code ec;
					socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
					socket->lowest_layer().close();
				}
			}));
			return timer;
		}

		void read_request_and_content(std::shared_ptr<socket_type> socket) {
			std::shared_ptr<Request> request(new Request(io_service));
			request->read_remote_endpoint_data(*socket);

			std::shared_ptr<boost::asio::deadline_timer> timer;
			if(timeout_request>0) timer=set_timeout_on_socket(socket, timeout_request);

			boost::asio::async_read_until(*socket, request->streambuf, "\r\n\r\n",
					[this, socket, request, timer](const boost::system::error_code& ec, size_t bytes_transferred) {
				if(timeout_request>0) timer->cancel();
				if(!ec) {
					size_t num_additional_bytes=request->streambuf.size()-bytes_transferred;

					parse_request(request, request->content);

					auto it=request->header.find("Content-Length");
					if(it!=request->header.end()) {
						std::shared_ptr<boost::asio::deadline_timer> timer;
						if(timeout_content>0)
							timer=set_timeout_on_socket(socket, timeout_content);
						unsigned long long content_length;

						try {
							content_length=stoull(it->second);
						}
						catch(const std::exception &e) { return; }

						if(content_length>num_additional_bytes) {
							boost::asio::async_read(*socket, request->streambuf,
									boost::asio::transfer_exactly(content_length-num_additional_bytes),
									[this, socket, request, timer]
									(const boost::system::error_code& ec, size_t /*bytes_transferred*/) {
								if(timeout_content>0) timer->cancel();
								if(!ec) find_resource(socket, request);
							});
						}
						else {
							if(timeout_content>0) timer->cancel();
							find_resource(socket, request);
						}
					}
					else {
						find_resource(socket, request);
					}
				}
			});
		}

		void parse_request(std::shared_ptr<Request> request, std::istream& stream) const {
			std::string line;
			getline(stream, line);
			size_t method_end;

			if((method_end=line.find(' '))!=std::string::npos) {
				size_t path_end;
				if((path_end=line.find(' ', method_end+1))!=std::string::npos) {
					request->method=line.substr(0, method_end);
					request->path=line.substr(method_end+1, path_end-method_end-1);
					if((path_end+6)<line.size())
						request->http_version=line.substr(path_end+6, line.size()-(path_end+6)-1);
					else
						request->http_version="1.0";

					getline(stream, line);
					size_t param_end;
					while((param_end=line.find(':'))!=std::string::npos) {
						size_t value_start=param_end+1;

						if((value_start)<line.size()) {
							if(line[value_start]==' ') value_start++;
							if(value_start<line.size()) request->header.insert(std::make_pair(line.substr(0, param_end), line.substr(value_start, line.size()-value_start-1)));
						}

						getline(stream, line);
					}
				}
			}
		}

		void find_resource(std::shared_ptr<socket_type> socket, std::shared_ptr<Request> request) {
			for(auto& res: opt_resource) {
				if(request->method==res.first) {
					for(auto& res_path: res.second) {
						boost::smatch sm_res;
						if(boost::regex_match(request->path, sm_res, res_path.first)) {
							request->path_match=std::move(sm_res);
							write_response(socket, request, res_path.second);
							return;
						}
					}
				}
			}
			auto it_method=default_resource.find(request->method);
			if(it_method!=default_resource.end()) write_response(socket, request, it_method->second);
		}

		void write_response(std::shared_ptr<socket_type> socket, std::shared_ptr<Request> request,
				std::function<void(typename ServerBase<socket_type>::Response&, std::shared_ptr<typename ServerBase<socket_type>::Request>)>& resource_function) {
			std::shared_ptr<boost::asio::deadline_timer> timer;
			if(timeout_content>0) timer=set_timeout_on_socket(socket, request, timeout_content);

			boost::asio::spawn(request->strand, [this, &resource_function, socket, request, timer](boost::asio::yield_context yield) {
				Response response(*socket, yield);

				try {
					resource_function(response, request);
				}
				catch(const std::exception& e) {
					return;
				}

				if(response.size()>0) {
					try {
						response.flush();
					}
					catch(const std::exception &e) {
						return;
					}
				}
				if(timeout_content>0) timer->cancel();
				float http_version;
				try {
					http_version=stof(request->http_version);
				}
				catch(const std::exception &e) {
					return;
				}
				if(http_version>1.05) read_request_and_content(socket);
			});
		}
	};

	template<class socket_type>
	class Server : public ServerBase<socket_type> {};

	typedef boost::asio::ip::tcp::socket HTTP;

	template<>
	class Server<HTTP> : public ServerBase<HTTP> {
	public:
		Server(const std::string address, unsigned short port, size_t num_threads=1, size_t timeout_request=5, size_t timeout_content=300) :
				ServerBase<HTTP>::ServerBase(address, port, num_threads, timeout_request, timeout_content) {}

	private:
		void accept() {
			std::shared_ptr<HTTP> socket(new HTTP(io_service));

			acceptor.async_accept(*socket, [this, socket](const boost::system::error_code& ec){
				accept();

				if(!ec) {
					boost::asio::ip::tcp::no_delay option(true);
					socket->set_option(option);

					read_request_and_content(socket);
				}
			});
		}
	};
}
#endif

max_stars_repo_name: miraline/myscan

max_issues_repo_name: miraline/myscan

max_forks_repo_name: miraline/myscan


text:
//
// Copyright 2020 Mateusz Loskot <mateusz at loskot dot net>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/gil/color_convert.hpp>
#include <boost/gil/gray.hpp>
#include <boost/gil/rgb.hpp>
#include <boost/gil/rgba.hpp>
#include <boost/gil/cmyk.hpp>

#include <boost/mp11.hpp>
#include <boost/core/lightweight_test.hpp>

#include <type_traits>

#include "test_utility_output_stream.hpp"
#include "core/pixel/test_fixture.hpp"

namespace gil = boost::gil;
namespace mp11 = boost::mp11;

#ifdef BOOST_GIL_TEST_DEBUG
#include <boost/core/demangle.hpp>
#include <iostream>
namespace {
template <class T>
std::string name() { return boost::core::demangle(typeid(T).name()); }
}
#endif

template <typename ColorSpaces>
struct test_roundtrip_convertible
{
    template<typename Src, typename Dst>
    void operator()(mp11::mp_list<Src, Dst> const&) const
    {
#ifdef BOOST_GIL_TEST_DEBUG
        std::cout << "test_lossless_roundtrip:\n"
                  << "\tsrc: " << name<Src>() << "\n\tdst: " << name<Dst>() << std::endl;
#endif
        using pixel_src_t = gil::pixel<std::uint8_t, gil::layout<Src>>;
        using pixel_dst_t = gil::pixel<std::uint8_t, gil::layout<Dst>>;

        pixel_src_t src1{};
        pixel_dst_t dst1{};

        gil::default_color_converter_impl<Src, Dst> convert_to;
        convert_to(src1, dst1);

        gil::default_color_converter_impl<Dst, Src> convert_from;
        pixel_src_t src2{};
        convert_from(dst1, src2);

        BOOST_TEST_EQ(src1, src2);
    }
    static void run()
    {
        boost::mp11::mp_for_each
        <
            mp11::mp_product<mp11::mp_list, ColorSpaces, ColorSpaces>
        >(test_roundtrip_convertible{});
    }
};

template <typename ColorSpaces>
struct test_convertible
{
    template<typename Src, typename Dst>
    void operator()(mp11::mp_list<Src, Dst> const&) const
    {
#ifdef BOOST_GIL_TEST_DEBUG
        std::cout << "test_all:\n"
                  << "\tsrc: " << name<Src>() << "\n\tdst: " << name<Dst>() << std::endl;
#endif
        using pixel_src_t = gil::pixel<std::uint8_t, gil::layout<Src>>;
        using pixel_dst_t = gil::pixel<std::uint8_t, gil::layout<Dst>>;

        pixel_src_t src{};
        pixel_dst_t dst{};

        gil::default_color_converter_impl<Src, Dst> convert_to;
        convert_to(src, dst);
    }
    static void run()
    {
        boost::mp11::mp_for_each
        <
            mp11::mp_product<mp11::mp_list, ColorSpaces, ColorSpaces>
        >(test_convertible{});
    }
};

int main()
{
    test_convertible
    <
        mp11::mp_list<gil::cmyk_t, gil::gray_t, gil::rgb_t, gil::rgba_t>
    >::run();

    test_roundtrip_convertible
    <
        mp11::mp_list<gil::gray_t, gil::rgb_t>
    >::run();

    test_roundtrip_convertible<mp11::mp_list<gil::cmyk_t>>::run();
    test_roundtrip_convertible<mp11::mp_list<gil::gray_t>>::run();
    test_roundtrip_convertible<mp11::mp_list<gil::rgba_t>>::run();
    return ::boost::report_errors();
}

ext: cpp

max_issues_repo_name: DevanshSGit/gil


text:
//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012-2013, Image Engine Design Inc. 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  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 OWNER 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 <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include "boost/python.hpp"
#include "boost/format.hpp"

#include "GafferBindings/SignalBinding.h"
#include "GafferBindings/Serialisation.h"
#include "GafferImageBindings/FormatBinding.h"

using namespace boost::python;
using namespace IECore;
using namespace Gaffer;
using namespace GafferBindings;
using namespace GafferImage;

namespace GafferImageBindings
{

namespace FormatBindings
{

std::string formatRepr( const GafferImage::Format *format )
{
	if ( format->getDisplayWindow().isEmpty() )
	{
		return std::string( "GafferImage.Format()" );
	}
	else
	{
		Imath::Box2i box( format->getDisplayWindow() );
		return std::string(
			boost::str( boost::format(
				"GafferImage.Format( IECore.Box2i( IECore.V2i( %d, %d ), IECore.V2i( %d, %d ) ), %.3f )" )
				% box.min.x % box.min.y % box.max.x % box.max.y %format->getPixelAspect()
			)
		);
	}
}

} // namespace FormatBindings

struct UnaryFormatSlotCaller
{
	boost::signals::detail::unusable operator()( boost::python::object slot, const std::string &s )
	{
		try
		{
			slot( s );
		}
		catch( const error_already_set &e )
		{
			PyErr_PrintEx( 0 ); // clears the error status
		}
		return boost::signals::detail::unusable();
	}
};

static boost::python::str defaultFormatContextName()
{
	return boost::python::str( Format::defaultFormatContextName.string() );
}

static boost::python::list formatNamesList()
{
	std::vector<std::string> names;
	Format::formatNames( names );
	boost::python::list result;
	for( std::vector<std::string>::const_iterator it = names.begin(); it != names.end(); it++ )
	{
		result.append( *it );
	}
	return result;
}

void bindFormat()
{
	// Useful function pointers to the overloaded members
	static const Format &(*registerFormatPtr1)( const Format &, const std::string & ) (&Format::registerFormat);
	static const Format &(*registerFormatPtr2)( const Format & ) (&Format::registerFormat);
	static void (*removeFormatPtr1)( const Format & ) (&Format::removeFormat);
	static void (*removeFormatPtr2)( const std::string & ) (&Format::removeFormat);
	static void (*setDefaultFormatPtr1)( ScriptNode *scriptNode, const Format & ) (&Format::setDefaultFormat);
	static void (*setDefaultFormatPtr2)( ScriptNode *scriptNode, const std::string & ) (&Format::setDefaultFormat);

	class_<Format>( "Format", init<int, int, double>() )
		.def( init< const Imath::Box2i &, double >() )
		.def( init<>() )
		.def( "width", &Format::width )
		.def( "height", &Format::height )
		.def( "getPixelAspect", &Format::getPixelAspect )
		.def( "setPixelAspect", &Format::setPixelAspect )
		.def( "getDisplayWindow", &Format::getDisplayWindow )
		.def( "setDisplayWindow", &Format::setDisplayWindow )

		// Static bindings
		.def( "formatAddedSignal", &Format::formatAddedSignal, return_value_policy<reference_existing_object>() ).staticmethod( "formatAddedSignal" )
		.def( "formatRemovedSignal", &Format::formatRemovedSignal, return_value_policy<reference_existing_object>() ).staticmethod( "formatRemovedSignal" )
		.def( "setDefaultFormat", setDefaultFormatPtr1, return_value_policy<reference_existing_object>() )
		.def( "setDefaultFormat", setDefaultFormatPtr2, return_value_policy<reference_existing_object>() ).staticmethod( "setDefaultFormat" )
		.def( "getDefaultFormat", &Format::getDefaultFormat, return_value_policy<return_by_value>() ).staticmethod( "getDefaultFormat" )
		.def( "removeAllFormats", &Format::removeAllFormats ).staticmethod( "removeAllFormats" )
		.def( "registerFormat", registerFormatPtr1, return_value_policy<reference_existing_object>() )
		.def( "registerFormat", registerFormatPtr2, return_value_policy<reference_existing_object>() ).staticmethod( "registerFormat" )
		.def( "removeFormat", removeFormatPtr1, return_value_policy<reference_existing_object>() )
		.def( "removeFormat", removeFormatPtr2, return_value_policy<reference_existing_object>() ).staticmethod( "removeFormat" )
		.def( "formatCount", &Format::formatCount, return_value_policy<return_by_value>() ).staticmethod( "formatCount" )
		.def( "getFormat", &Format::getFormat, return_value_policy<reference_existing_object>() ).staticmethod( "getFormat" )
		.def( "formatName", &Format::formatName ).staticmethod( "formatName" )
		.def( "formatNames", &formatNamesList ).staticmethod( "formatNames" )
		.def( "__eq__", &Format::operator== )
		.def( "__repr__", &GafferImageBindings::FormatBindings::formatRepr )
		.def( "defaultFormatContextName", &defaultFormatContextName ).staticmethod( "defaultFormatContextName" )
	;

	SignalBinder<Format::UnaryFormatSignal, DefaultSignalCaller<Format::UnaryFormatSignal>, UnaryFormatSlotCaller >
	::bind( "UnaryFormatSignal" );

	Serialisation::registerSerialiser( static_cast<IECore::TypeId>(FormatTypeId), new Serialisation::Serialiser() );
}

} // namespace IECorePython

max_stars_repo_name: danieldresser/gaffer

max_issues_repo_name: danieldresser/gaffer

max_forks_repo_name: danieldresser/gaffer


text:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN

#include <math.h>

#include <boost/test/unit_test.hpp>

#include "../../XMPCore/source/XMPUtils.hpp"
#include "../source/EndianUtils.hpp"

using boost::unit_test::test_suite;

struct Fixture {
  Fixture() {
    XMPMeta::Initialize();
  }
  ~Fixture() {
    XMPMeta::Terminate();
  }
};

BOOST_GLOBAL_FIXTURE(Fixture);

BOOST_AUTO_TEST_SUITE(test_adobesdk)

BOOST_AUTO_TEST_CASE(test_composeArray)
{
  XMP_VarString fullPath;

  BOOST_CHECK_THROW(XMPUtils::ComposeArrayItemPath("", "myArray",
                                                   42, &fullPath), XMP_Error);
  BOOST_CHECK_THROW(XMPUtils::ComposeArrayItemPath("http://ns.figuiere.net/test/", "myArray",
                                                   42, &fullPath), XMP_Error);
  BOOST_CHECK_THROW(XMPUtils::ComposeArrayItemPath(kXMP_NS_DC, "",
                                                   42, &fullPath), XMP_Error);

  XMPUtils::ComposeArrayItemPath(kXMP_NS_DC, "myArray",
                                 42, &fullPath);
  BOOST_CHECK(fullPath == "myArray[42]");

  XMPUtils::ComposeArrayItemPath(kXMP_NS_DC, "myArray",
                                 kXMP_ArrayLastItem, &fullPath);
  BOOST_CHECK(fullPath == "myArray[last()]");
}

BOOST_AUTO_TEST_CASE(test_composeStructFieldPath)
{
  XMP_VarString fullPath;

  BOOST_CHECK_THROW(XMPUtils::ComposeStructFieldPath("", "struct",
                                                     kXMP_NS_XML, "field", &fullPath), XMP_Error);
  BOOST_CHECK_THROW(XMPUtils::ComposeStructFieldPath(kXMP_NS_DC, "struct",
                                                     "", "field", &fullPath), XMP_Error);
  BOOST_CHECK_THROW(XMPUtils::ComposeStructFieldPath(kXMP_NS_DC, "",
                                                     kXMP_NS_XML, "field", &fullPath), XMP_Error);
  BOOST_CHECK_THROW(XMPUtils::ComposeStructFieldPath(kXMP_NS_DC, "struct",
                                                     kXMP_NS_XML, "", &fullPath), XMP_Error);

  XMPUtils::ComposeStructFieldPath(kXMP_NS_DC, "struct",
                                   kXMP_NS_XML, "field", &fullPath);
  BOOST_CHECK(fullPath == "struct/xml:field");
}

BOOST_AUTO_TEST_CASE(test_convertToInt64)
{
  XMP_Int64 value = XMPUtils::ConvertToInt64("0x123456789012345");
  BOOST_CHECK(value == 0x123456789012345);

  value = XMPUtils::ConvertToInt64("123456");
  BOOST_CHECK(value == 123456);

  BOOST_CHECK_THROW(XMPUtils::ConvertToInt64("abcdef"), XMP_Error);
}

// endian flip of the 4 bytes array
static void flip4(uint8_t *bytes) {
  std::swap(bytes[0], bytes[3]);
  std::swap(bytes[1], bytes[2]);
}
// endian flip of the 8 bytes array
static void flip8(uint8_t *bytes) {
  std::swap(bytes[0], bytes[7]);
  std::swap(bytes[1], bytes[6]);
  std::swap(bytes[2], bytes[5]);
  std::swap(bytes[3], bytes[4]);
}

BOOST_AUTO_TEST_CASE(test_getFloat)
{
  // this to create a byte representation of the float and double.
  union float_union {
    float value;
    uint8_t bytes[sizeof(float)];
  };
  union double_union {
    double value;
    uint8_t bytes[sizeof(double)];
  };
  float_union piF;
  piF.value = M_PI;
  double_union piD;
  piD.value = M_PI;

  // copy these byte representations
  // and flip endian as needed.
  uint8_t floatLE[sizeof(float)];
  memcpy(floatLE, piF.bytes, sizeof(float));
  if (kBigEndianHost) {
    flip4(floatLE);
  }
  uint8_t floatBE[sizeof(float)];
  memcpy(floatBE, piF.bytes, sizeof(float));
  if (kLittleEndianHost) {
    flip4(floatBE);
  }
  uint8_t doubleLE[sizeof(double)];
  memcpy(doubleLE, piD.bytes, sizeof(double));
  if (kBigEndianHost) {
    flip8(doubleLE);
  }
  uint8_t doubleBE[sizeof(double)];
  memcpy(doubleBE, piD.bytes, sizeof(double));
  if (kLittleEndianHost) {
    flip8(doubleBE);
  }

  // check getting float
  float resultF = GetFloatLE(floatLE);
  BOOST_CHECK(resultF == (float)M_PI);
  resultF = GetFloatBE(floatBE);
  BOOST_CHECK(resultF == (float)M_PI);

  // check getting double
  double resultD = GetDoubleLE(doubleLE);
  BOOST_CHECK(resultD == (double)M_PI);
  resultD = GetDoubleBE(doubleBE);
  BOOST_CHECK(resultD == (double)M_PI);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: honpong/exempi

max_issues_repo_name: honpong/exempi

max_forks_repo_name: honpong/exempi


text: #include <boost/fusion/sequence/intrinsic/begin.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#pragma once

#include <cmath>
#include <limits>
#include <Eigen/Core>

namespace kt84 {

// the definition of functions alpha(r) and beta(r) implemented in each kernel |
//-----------------------------------------------------------------------------+
/*

inner product of vectors x and y:
    x * y := x^T y (scalar)
outer product of vectors x and y:
    x % y := x y^T (matrix)

notations:
    x := (x_1, ..., x_N)
    r := |x| = sqrt(x * x)

univariate RBF kernel:
    phi(r): R+ --> R;

first & second derivatives of phi:
    phi'(r) : R+ --> R
    phi"(r) : R+ --> R

examples of phi:
    phi(r) := |r|^3                             // cubic
    phi(r) := exp(-r^2/(2 * sigma^2))           // Gaussian

multivariate RBF kernel:
    f(x): R^N --> R
    f(x) := phi(r)
          = phi(|x|)

gradient:
    g(x): R^N --> R^N
    g(x) := df/dx(x)
          = phi'(r) / r * x

definition of alpha:
    alpha(r) := phi'(r) / r
    g(x) = alpha(r) * x

Hessian:
    H(x): R^N --> R^(NxN)
    H(x) := d^2f/dx^2
          = dg/dx
          = {(r * phi"(r) - phi'(r)) / r^3} * (x % x) + {phi'(r) / r} * I

definition of beta:
    beta(r) := (r * phi"(r) - phi'(r)) / r^3
    H(x) = alpha(r) * I + beta(r) * (x % x);

*/

// Gradient is always defined even for singular (r=0) cases --> can be used with Hermite RBF |
//-------------------------------------------------------------------------------------------+
struct RBFKernel_Gaussian {
    struct Param {
        double sigma;
        Param(double sigma = 1) : sigma(sigma) {}
    } param;
    double operator()       (double r) const { return std::exp(-r * r / (2 * param.sigma * param.sigma)); }
    double derivative_first (double r) const { return operator()(r) * r / (-param.sigma * param.sigma); }
    double derivative_second(double r) const { return operator()(r) * (r * r - param.sigma * param.sigma) / (param.sigma * param.sigma * param.sigma * param.sigma); }
    double alpha_singular() const { return -1 / (param.sigma * param.sigma); }
    static const bool AlphaAlwaysDefined = true;
    static const bool Decaying = true;
};

struct RBFKernel_SquaredInverse {
    struct Param {
        double epsilon;
        Param(double epsilon = 0) : epsilon(epsilon) {}
    } param;
    double operator()(double r) const {
        if (r == 0 && param.epsilon == 0)
            return std::numeric_limits<double>::infinity();         // indication of hard constraint (for MLS)
        return 1 / (r * r + param.epsilon * param.epsilon);
    }
    double derivative_first(double r) const {
        double t = operator()(r);
        return -2 * r * t * t;
    }
    double derivative_second(double r) const {
        double t = operator()(r);
        return (6 * r * r - 2 * param.epsilon * param.epsilon) * t * t * t;
    }
    double alpha_singular() const {
        return -2 / (param.epsilon * param.epsilon * param.epsilon * param.epsilon);
    }
    static const bool AlphaAlwaysDefined = true;
    static const bool Decaying = true;
};

struct RBFKernel_Wendland {
    // Wendland, H.
    // Piecewise polynomial, positive definite and compactly supported radial basis functions of minimal degree.
    // Advances in Computational Mathematics 4, 389--396, 1995.
    struct Param {
        double support;
        Param(double support = 1) : support(support) {}
    } param;
    double operator()(double r) const {
        double t = r / param.support;
        if (t > 1)
            return 0;
        return (1 - t) * (1 - t) * (1 - t) * (1 - t) * (4 * t + 1);
    }
    double derivative_first(double r) const {
        double t = r / param.support;
        if (t > 1)
            return 0;
        return -20 * t * (1 - t) * (1 - t) * (1 - t) / param.support;
    }
    double derivative_second(double r) const {
        double t = r / param.support;
        if (t > 1)
            return 0;
        return 20 * (1 - t) * (1 - t) * (4 * t - 1) / (param.support * param.support);
    }
    double alpha_singular() const { return -20 / (param.support * param.support); }
    static const bool AlphaAlwaysDefined = true;
    static const bool Decaying = true;
};

struct RBFKernel_Cubed {
    struct Param {} param;
    double operator()       (double r) const { return r * r * r; }
    double derivative_first (double r) const { return 3 * r * r; }
    double derivative_second(double r) const { return 6 * r; }
    double alpha_singular() const { return 0; }
    static const bool AlphaAlwaysDefined = true;
    static const bool Decaying = false;
};

// gradient is undefined for singular (r=0) cases --> cannot be used with HermiteRBF |
//-----------------------------------------------------------------------------------+
struct RBFKernel_Identity {
    struct Param {} param;
    double operator()       (double r) const { return r; }
    double derivative_first (double r) const { return 1; }
    double derivative_second(double r) const { return 0; }
    double alpha_singular() const { throw std::logic_error("undefined!"); }
    static const bool AlphaAlwaysDefined = false;
    static const bool Decaying = false;
};

struct RBFKernel_SquaredLog {
    struct Param {} param;
    double operator()(double r) const {
        if (r == 0)
            return 0;
        return r * r * std::log(r);
    }
    double derivative_first(double r) const {
        if (r == 0)
            return 0;
        return 2 * r * std::log(r) + r;
    }
    double derivative_second(double r) const {
        if (r == 0)
            return -std::numeric_limits<double>::infinity();        // not sure if this treatment is correct...
        return 2 * std::log(r) + 3;
    }
    double alpha_singular() const { throw std::logic_error("undefined!"); }
    static const bool AlphaAlwaysDefined = false;
    static const bool Decaying = false;
};

// general template classes |
//--------------------------+

template <class _RBFKernel_Core>
struct RBFKernel_Univariate {
    typedef _RBFKernel_Core Core;

    Core core;

    double operator()(double r) const { return core(r); }
    double derivative_first(double r) const { return core.derivative_first(r); }
    double derivative_second(double r) const { return core.derivative_second(r); }
    double alpha(double r) const { return core.derivative_first(r) / r; }
    double beta(double r) const { return (r * core.derivative_second(r) - core.derivative_first(r)) / (r * r * r); }
};

template <int _Dim, class _RBFKernel_Core>
struct RBFKernel_Bivariate {
    enum { Dim  = _Dim };

    typedef Eigen::Matrix<double, Dim, 1> Point;
    typedef Eigen::Matrix<double, 1, Dim> Gradient;
    typedef Eigen::Matrix<double, Dim, Dim> Hessian;
    typedef RBFKernel_Univariate<_RBFKernel_Core> Univariate;

    static const bool GradientAlwaysDefined = Univariate::Core::AlphaAlwaysDefined;
    static const bool Decaying              = Univariate::Core::Decaying;

    Univariate univariate;

    double operator()(const Point& p0, const Point& p1) const { return univariate((p1 - p0).norm()); }
    Gradient gradient(const Point& p_variable, const Point& p_fixed) const {
        Point p_diff = p_variable - p_fixed;
        double r = p_diff.norm();
        if (r == 0)
            return Gradient::Zero();
        return univariate.alpha(r) * p_diff.transpose();
    }
    Hessian hessian(const Point& p_variable, const Point& p_fixed) const {
        Point p_diff = p_variable - p_fixed;
        double r = p_diff.norm();
        if (r == 0)
            return univariate.core.alpha_singular() * Hessian::Identity();
        return univariate.alpha(r) * Hessian::Identity() + univariate.beta(r) * p_diff * p_diff.transpose();
    }

    // easy access to kernel parameters
    typename Univariate::Core::Param& param() { return univariate.core.param; }
    const typename Univariate::Core::Param& param() const { return univariate.core.param; }
};

}

ext: hh

max_stars_repo_name: honoriocassiano/skbar

max_issues_repo_name: honoriocassiano/skbar

max_forks_repo_name: honoriocassiano/skbar


text:
#pragma once

#include <iron/core.h>

#include <boost/container/flat_set.hpp>

namespace iron {

struct PrimeStash {

    PrimeStash() : Primes() {
      Primes.insert(2);
    }

  // For now, strictly positive. Could be genericized and pulled out of PrimeStash
  template <typename IntegerContainer_t>
  static bool isDivisibleByAnyOf(uint64_t inEvaluated, IntegerContainer_t inValues) {
    for (auto trial : inValues) {
      if (inEvaluated % trial == 0){
        return true;
      }
    }
    return false;
  }

  uint64_t lastStashed()                  const { return *Primes.crbegin(); }
  bool     canEvaluate(uint64_t inNumber) const { return lastStashed()*lastStashed() >= inNumber; }

  boost::container::flat_set<uint64_t> Primes;
};

} /* iron */

max_stars_repo_name: BradSz/iron-horse

max_issues_repo_name: BradSz/iron-horse

max_forks_repo_name: BradSz/iron-horse