派生自 development/c++

pansen
2018-12-15 eddff2d353cd541bee6ce306b128447ccb3a7a5b
10个文件已添加
5667 ■■■■■ 已修改文件
syncDBTool/CMakeLists.txt 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/Client.cpp 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/ErlangDbTool.cpp 2054 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/ErlangDbTool.h 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/ErlangDbTool.hpp 1555 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/ShareMemoryTool.hpp 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/SyncDB.hpp 718 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/cnode.cpp 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/main.cpp 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/main2.cpp 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
syncDBTool/CMakeLists.txt
New file
@@ -0,0 +1,98 @@
cmake_minimum_required(VERSION 3.5)
project(syncDBTool)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE debug)
#add_compile_options(-fPIC -fpermissive)
add_definitions(-DGLOG)
add_definitions(-DDEBUG_INFO -DDEBUG_ERR)
include_directories(
    /home/ps/boost_1_68_0
    /usr/include/
    ../../Qt/BasicPlatForm/
    ../../Qt/BasicPlatForm/libs/libuuid/include
    ../../Qt/BasicPlatForm/libs/jsoncpp/include
    ../../Qt/BasicPlatForm/libs/glog/include
)
link_directories(
    /usr/lib/erlang/lib/erl_interface-3.8.2/lib/
    ../../Qt/BasicPlatForm/libs/libuuid/lib
    ../../Qt/BasicPlatForm/libs/jsoncpp/lib
    ../../Qt/BasicPlatForm/libs/glog/lib
)
add_executable(syncDBTool
    main2.cpp
#    main.cpp
    ShareMemoryTool.hpp
    ErlangDbTool.cpp
    )
target_link_libraries(
    syncDBTool
    ei
    erl_interface_st
    ei_st
    erl_interface
    uuid
    rt
    glog
    jsoncpp
    pthread
)
add_executable(syncDBClient main2.cpp ShareMemoryTool.hpp
    ErlangDbTool.cpp testCallBack.cpp testCallBack.h)
target_link_libraries(
    syncDBClient
    glog
    ei
    erl_interface_st
    ei_st
    erl_interface
    rt
    jsoncpp
    pthread
)
add_executable(TestCilent
    Client.cpp ShareMemoryTool.hpp
    ErlangDbTool.cpp)
target_link_libraries(TestCilent
    pthread
    glog
    rt
    )
add_executable(cNodeTest
    cnode.cpp ShareMemoryTool.hpp cnode.cpp)
target_link_libraries(cNodeTest
    ei
    erl_interface_st
    ei_st
    glog
    erl_interface
    pthread
    rt
    )
add_executable(callbacktest
    testCallBack.cpp)
target_link_libraries(callbacktest
    ei
    erl_interface_st
    ei_st
    glog
    erl_interface
    pthread
    rt
    )
syncDBTool/Client.cpp
New file
@@ -0,0 +1,51 @@
//
// Created by ps on 8/9/18.
//
#include "ShareMemoryTool.hpp"
int main() {
//    char cc = '1';
//    for (int i = 0; i < 100; i++) {
//        cc++;
//        printf("%c \n", cc);
//    }
    try {
//        BISTL::shared_memory_object
        // init
//        BISTL::managed_shared_memory segment(BISTL::open_only, "aaa8" );
        BISTL::BiMapFeaData biMapFeaData("test");
//        const BISTL::void_allocator alloc_inst (segment.get_segment_manager());
//        BISTL::bi_map_Feature_Info * mymap =
//            segment.construct<BISTL::bi_map_Feature_Info>("MyMap")(std::less<BISTL::char_string>(),alloc_inst);
//        BISTL::bi_map_Feature_Info *mymap =
//            segment.find_or_construct<BISTL::bi_map_Feature_Info>("aaa8")(std::less<BISTL::char_string>(), alloc_inst);
        auto mymap = biMapFeaData.getMap();
        auto size = mymap->size();
        for (auto it = mymap->begin(); it != mymap->end(); it++) {
//            printf("%s \n", it->second.id.c_str());
//            printf("%d \n", it->second.id);
            std::cout << "id      " << it->second.m_id << std::endl;
            std::cout << "feature " << it->second.m_feature << std::endl;
//            it->second.id;
        }
        printf("\n");
//        BISTL::shared_memory_object::remove("SharedMemory");
    }
    catch (const std::exception &e) {
        printf("Exception:%s\n", e.what());
        BISTL::shared_memory_object::remove("test");
    }
    getchar();
    BISTL::shared_memory_object::remove("test");
    return 0;
}
syncDBTool/ErlangDbTool.cpp
New file
@@ -0,0 +1,2054 @@
//
// Created by ps on 18-11-29.
//
#include "ErlangDbTool.h"
#include <QtSql/QSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>
#include <QtCore/QString>
#include <QtCore/QDebug>
#include <QtCore/QVariantList>
using ErlangTool::map_DevDataCache;
using ErlangTool::map_TabDataCache;
using ErlangTool::map_BwDataCache;
using ErlangTool::map_FaceDataCache;
static QSqlDatabase g_syncDbFile = QSqlDatabase::addDatabase("QSQLITE", "SyncDBSqliteFile");
static bool ErlangTool::dir_file_exists(std::string dir, bool mkdir_flag) {
    int state = access(dir.c_str(), R_OK | W_OK); // 头文件 #include <unistd.h>
    if (state == 0) {
        //#todo
        INFO("file exist");
        return true;
    } else if (mkdir_flag) {
        dir = "mkdir -p " + dir;
        system(dir.c_str()); // 调用linux系统命令创建文件
        //#todo
        return true;
    } else {
        return false;
    }
}
static bool ErlangTool::pingNode(const std::string &nodeName, const std::string &cookie) {
    int fd = -1;
    int ret = -1;
//    erl_init(NULL, 0);
//    struct in_addr addr;
//    addr.s_addr = inet_addr("127.0.0.1");
//    std::string str_node("cnode");
//    str_node.append(to_string((int) getpid()));
//    std::string t_nodeName(str_node);
//    t_nodeName.append("@127.0.0.1");
//    INFO("str_node << " << str_node << " ;t_nodeName " << t_nodeName);
//    if (erl_connect_xinit(str_node.c_str(), str_node.c_str(), t_nodeName.c_str(), &addr, cookie.c_str(), 0) == -1) {
//        ERR("erl_connect_xinit error");
//        erl_err_quit("erl_connect_xinit");
//        return false;
//    }
    fd = erl_connect(const_cast<char *>(nodeName.c_str()));
    if (0 > fd) {
        erl_close_connection(fd);
        ERR("erl_connect error  " << nodeName);
//            erl_err_quit("erl_connect");
        return false;
    }
    erl_close_connection(fd);
    return true;
}
static int ErlangTool::checkETERMType(ETERM *elemen) {
    if (elemen == NULL) {
        return -1;
    }
    switch (ERL_TYPE(elemen)) {
        case ERL_UNDEF:
            return ERL_UNDEF;
        case ERL_INTEGER:
            INFO("value is a int: " << ERL_INT_VALUE(elemen));
            return ERL_INTEGER;
        case ERL_U_INTEGER:
            break;
        case ERL_ATOM: {
//                int atomSize = ERL_ATOM_SIZE(elemen);
//                char *atomValue = ERL_ATOM_PTR(elemen);
//                printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
            return ERL_ATOM;
        }
        case ERL_PID:
            break;
        case ERL_PORT:
            break;
        case ERL_REF:
            break;
        case ERL_LIST:
//                printf("value is a list:%s\n", erl_iolist_to_string(elemen));
            return ERL_LIST;
        case ERL_NIL:
            return ERL_EMPTY_LIST;
        case ERL_TUPLE:
            INFO("value is a tupe: " << ERL_ATOM_PTR(erl_element(1, elemen)));
            return ERL_TUPLE;
        case ERL_BINARY:
            break;
        case ERL_FLOAT:
            break;
        case ERL_VARIABLE:
            break;
        case ERL_SMALL_BIG:
            break;
        case ERL_U_SMALL_BIG:
            break;
        case ERL_FUNCTION:
            break;
        case ERL_BIG:
            break;
        case ERL_LONGLONG:
            break;
        case ERL_U_LONGLONG:
            break;
        default:
            ERR("[Client] got a value but now checked\n\r");
            //#todo morechuli
    }
    return -1;
}
static void ErlangTool::erlangFreeEterm(int count, ...) {
    va_list args;
    va_start(args, count);
    for (int i = 0; i < count; ++i) {
        auto test = va_arg(args, ETERM*);
        erl_free_compound(test);
//            if (test != NULL)
//                erl_free_compound(test);
//            else{
//
//            }
    }
}
ErlangTool::ErlangDbTool::ErlangDbTool() : m_fd(-1) {
}
ErlangTool::ErlangDbTool::ErlangDbTool(const std::string &nodeName, const std::string &cookie, const std::string &pName)
    : m_fd(-1), m_path(""), m_nodeName(nodeName), m_cookie(cookie), m_pName(pName) {
    initCNode();
}
ErlangTool::ErlangDbTool::ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
                                       const std::string &pName)
    : m_fd(-1), m_path(path), m_nodeName(nodeName), m_cookie(cookie), m_pName(pName) {
    initCNode();
}
ErlangTool::ErlangDbTool::ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
                                       const std::string &clusterID, const std::string &clusterName) :
    m_fd(-1), m_path(path), m_nodeName(nodeName), m_cookie(cookie), m_clusterID(clusterID), m_clusterName(clusterName) {
}
ErlangTool::ErlangDbTool::ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
                                       const std::string &clusterID, const std::string &clusterName,
                                       const std::string &pName) :
    m_fd(-1), m_path(path), m_nodeName(nodeName), m_cookie(cookie), m_clusterID(clusterID), m_clusterName(clusterName),
    m_pName(pName) {
    initCNode();
}
ErlangTool::ErlangDbTool::~ErlangDbTool() {
    g_syncDbFile.close();
    erl_close_connection(m_fd);
}
void ErlangTool::ErlangDbTool::initCNode() {
    //--------------init db-------------------
    std::string str_SyncDbFile = "/opt/erlang/";
    str_SyncDbFile.append(m_nodeName.substr(0, m_nodeName.find("@"))).append(".db");
    g_syncDbFile.setDatabaseName(str_SyncDbFile.c_str());
    g_syncDbFile.open();
    erl_init(NULL, 0);
    struct in_addr addr;
    //#todo
    addr.s_addr = inet_addr("127.0.0.1");
    m_pName.append(to_string((int) getpid()));
    std::string t_cNodeName(m_pName);
    t_cNodeName.append("@127.0.0.1");
    m_cNodeName.swap(t_cNodeName);
    //m_pName
    if (erl_connect_xinit(const_cast<char *>(m_pName.c_str()), const_cast<char *>(m_pName.c_str()),
                          const_cast<char *>(m_cNodeName.c_str()), &addr,
                          const_cast<char *>(m_cookie.c_str()), 0) == -1) {
        ERR("erl_connect_xinit error" << m_pName << " " << m_cNodeName << " " << m_cookie);
        erl_err_quit("erl_connect_xinit");
    } else {
        INFO("erl_connect_xinit ok " << m_pName << " " << m_cNodeName << " " << m_cookie);
    }
}
int ErlangTool::ErlangDbTool::initErlang() {
    if (m_nodeName == "") {
        ERR("m_nodeName is null ");
        return 3;
    }
    m_ret = pingNode(m_nodeName, m_cookie);
    if (!m_ret) {
        if (dir_file_exists(m_path, true)) {
            std::string cmd = std::string("cd " + m_path + " && erl -name " + m_nodeName + " -setcookie  "
                                          + m_cookie + " -mnesia dir '\"" + m_path +
                                          "\"' -detached -noshell");// >>log
            std::cout << cmd << std::endl;
            system(cmd.c_str());
            std::cout << m_ret << std::endl;
            m_ret = waitNode();
            resetConn();
            return m_ret;
        } else {
            ERR("create file faile ");
            return 0;
        }
    } else {
        INFO("node is running");
        return 2;
    }
}
std::string ErlangTool::ErlangDbTool::getConfigJsonString() {
    Json::Value t_json;
    Json::FastWriter writer;
    t_json["\"path\""] = "\"" + m_path + "\"";
    t_json["\"nodeName\""] = "\"" + m_nodeName + "\"";
    t_json["\"cookie\""] = "\"" + m_cookie + "\"";
    t_json["\"clusterID\""] = "\"" + m_clusterID + "\"";
    t_json["\"clusterName\""] = "\"" + m_clusterName + "\"";
    std::string str_json = writer.write(t_json);
    return str_json.substr(0, str_json.length() - 1);
}
bool ErlangTool::ErlangDbTool::startNodeDb(std::string FatherNodeName, std::string DeviceId, std::string DevAdd) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (m_ret) {
//                DeviceName = DeviceName.empty() ? m_nodeName : DeviceName;
    } else {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return false;
    }
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
    ETERM *arrlist[5];
    arrlist[0] = erl_mk_atom(m_nodeName.c_str());
    arrlist[1] = erl_mk_atom(FatherNodeName.c_str());
    arrlist[2] = erl_mk_atom(DeviceId.c_str());
    arrlist[3] = erl_mk_atom(m_clusterID.c_str());
    arrlist[4] = erl_mk_string(m_clusterName.c_str());
    ETERM *list = erl_mk_list(arrlist, 5);
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
//            erl_rpc(m_fd, "syncDB", "startNode", list);
    int ret = -1;
    ret = erl_rpc_to(m_fd, "syncDB", "startNode", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, 9000000000, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *key, *value;
            ETERM *tuplep[6];
            tuplep[0] = erl_element(2, emsg.msg);
            key = erl_element(1, tuplep[0]);
            value = erl_element(2, tuplep[0]);
//                printf("key:%s\n", ERL_ATOM_PTR(key));
            switch (checkETERMType(value)) {
                case ERL_ATOM: {
                    int atomSize = ERL_ATOM_SIZE(value);
                    char *atomValue = ERL_ATOM_PTR(value);
                    t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                        printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                    break;
                }
                default:
                    ERR("error add case todo \n\r");
            }
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        erlangFreeEterm(7, emsg.to, emsg.msg, emsg.from, list, key, value, tuplep[0]);
//                        erl_eterm_release();
                return true;
            } //if end
            else {
                INFO(" t_results size is " << t_results.size());
                for (auto &item : t_results) {
                    INFO("item is " << item.first << "  " << item.second);
                }
            }
        }//ret == ERL_MSG end
        else {
            ERR(" ret is " << ret);
        }
    } //ret == ERL_TICK
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    return false;
}
bool ErlangTool::ErlangDbTool::removeNode() {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
        return false;
    }
    int ret = -1;
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
//            ETERM *arrlist[1];
//            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
    ETERM *list = erl_mk_empty_list();// (arrlist, 0);
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
    ret = erl_rpc_to(m_fd, "syncDB", "removeNode", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *key, *value;
            ETERM *tuplep[6];
            tuplep[0] = erl_element(2, emsg.msg);
            key = erl_element(1, tuplep[0]);
            value = erl_element(2, tuplep[0]);
//                printf("key:%s\n", ERL_ATOM_PTR(key));
            switch (checkETERMType(value)) {
                case ERL_ATOM: {
                    int atomSize = ERL_ATOM_SIZE(value);
                    char *atomValue = ERL_ATOM_PTR(value);
                    t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                        printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                    break;
                }
                default:
                    printf("error add case todo \n\r");
            }
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                //删除本地文件
                if (!m_path.empty()) {
                    std::string cmd = std::string("rm -rf ").append(m_path);
                    //#todo
                    system(cmd.c_str());
                }
                erlangFreeEterm(7, emsg.to, emsg.msg, emsg.from, list, key, value, tuplep[0]);
                erl_eterm_release();
                return true;
            } //if end
        } //ret == ERL_MSG end
    } //ret == ERL_TICK
    erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    return false;
}
bool ErlangTool::ErlangDbTool::modifyCluName(std::string CluId, std::string CluName) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
        return false;
    }
    ErlMessage emsg;             /* Incoming message */
    int ret = -1;
    ETERM *arrlist[2];
    arrlist[0] = erl_mk_atom(CluId.c_str());
    arrlist[1] = erl_mk_string(CluName.c_str());
    ETERM *list = erl_mk_list(arrlist, 2);
    ret = erl_rpc_to(m_fd, "syncDB", "modifyCluName", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[1000], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            printf("arr_ret[0]:%d\n", erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
                        int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
                        printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
                        break;
                    }
                    default:
                        printf("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            erl_eterm_release();
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            }
        }
    }
    erl_free_array(arrlist, 2);
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    erl_eterm_release();
    return false;
}
ErlangTool::map_DevDataCache ErlangTool::ErlangDbTool::findAllNode() {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return map_DevDataCache();
    }
    map_DevDataCache devDataCache;
    int ret = -1;
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
//            ETERM *arrlist[0];
//            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
    ETERM *list = erl_mk_empty_list();//erl_mk_list(arrlist, 0);
    ret = erl_rpc_to(m_fd, "syncDB", "findAllNode", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            ETERM *key, *value;
            ETERM *tuplep[20];
            ETERM *arr_ret[2], *list_ret[1000];
            ETERM *tail_list, *tail_tuple;
            arr_ret[0] = erl_element(2, emsg.msg);
            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
                int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
                list_ret[0] = erl_hd(arr_ret[0]);
                tail_list = erl_tl(arr_ret[0]);
                for (int i = 0; i < erlLength; i++) {
                    if (i > 0) {
                        list_ret[i] = erl_hd(tail_list);
                        tail_list = erl_tl(tail_list);
                    }
                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
                        SyncDB::Device_Info device_info;
                        int erlLength1 = erl_length(list_ret[i]);
//                            printf("list_ret[%d]:%d\n", i, erlLength1);
                        tuplep[0] = erl_hd(list_ret[i]);
                        tail_tuple = erl_tl(list_ret[i]);
                        for (int j = 0; j < erlLength1; j++) {
                            if (j > 0) {
                                tuplep[j] = erl_hd(tail_tuple);
                                tail_tuple = erl_tl(tail_tuple);
                            }
                            key = erl_element(1, tuplep[j]);
                            value = erl_element(2, tuplep[j]);
//                                printf("key:%s\n", erl_iolist_to_string(key));
                            switch (checkETERMType(value)) {
                                case ERL_ATOM: {
                                    device_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
                                    break;
                                }
                                case ERL_INTEGER: {
                                    device_info.setValue(erl_iolist_to_string(key),
                                                         std::to_string(ERL_INT_VALUE(value)));
                                    break;
                                }
                                case ERL_LIST: {
                                    device_info.setValue(erl_iolist_to_string(key),
                                                         erl_iolist_to_string(value));
                                    break;
                                }
                                default:
                                    ERR("error add case todo" << checkETERMType(value) << " key is "
                                                              << checkETERMType(key));
                            }
                            erlangFreeEterm(3, key, value, tuplep[j]);
                        }
//                            printf("\none list end\n\n\n\n");
                        // #todo this is have a bug
//                                device_info.create_by = "";
                        devDataCache.insert(std::make_pair(device_info.uuid, device_info));
                        erlangFreeEterm(1, tail_tuple);
                    } else {
                        ERR("type error " << checkETERMType(list_ret[i]));
                    }
                    erlangFreeEterm(1, list_ret[i]);
                }
                erlangFreeEterm(5, emsg.to, emsg.msg, emsg.from, tail_list, arr_ret[0]);
                erl_eterm_release();
                return devDataCache;
            } else {
                ERR(" error " << checkETERMType(arr_ret[0]));
            }
        }
    } else {
        ERR("ret != ERL_TICK");
    } //ret == ERL_TICK end
    erlangFreeEterm(3, emsg.to, emsg.msg, emsg.from);
    erl_eterm_release();
    return map_DevDataCache();
}
bool ErlangTool::ErlangDbTool::createDatabase(std::string TableType, std::string TableName, bool SyncType,
                                              std::string BwType, std::string StartTime, std::string EndTime) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
        return false;
    }
    std::string NewTableName = ((!SyncType) && TableName.find("lt_")) ? std::string("lt_").append(TableName)
                                                                      : TableName;
    ErlMessage emsg;             /* Incoming message */
    int ret = -1;
    ETERM *arrlist[6];
    arrlist[0] = erl_mk_atom(TableType.c_str());
    arrlist[1] = erl_mk_string(NewTableName.c_str());
    auto str = std::to_string(SyncType);
    arrlist[2] = erl_mk_atom(str.c_str());
    arrlist[3] = erl_mk_atom(BwType.c_str());
    arrlist[4] = erl_mk_atom(StartTime.c_str());
    arrlist[5] = erl_mk_atom(EndTime.c_str());
    ETERM *list = erl_mk_list(arrlist, 6);
    ret = erl_rpc_to(m_fd, "syncDB", "createDatabase", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[1000], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            printf("arr_ret[0]:%d\n", erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
//                            int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
//                            printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
                        break;
                    }
                    default:
                        printf("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            erl_eterm_release();
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            }
        }
    }
    erl_free_array(arrlist, 6);
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    erl_eterm_release();
    return false;
}
bool ErlangTool::ErlangDbTool::updateDatabase(std::string UUID, std::string TableType, std::string TableName,
                                              bool SyncType, std::string BwType, std::string StartTime,
                                              std::string EndTime) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
        return false;
    }
    std::string NewTableName = ((!SyncType) && TableName.find("lt_")) ? std::string("lt_").append(TableName)
                                                                      : TableName;
    ErlMessage emsg;             /* Incoming message */
    int ret = -1;
    ETERM *arrlist[7];
    arrlist[0] = erl_mk_atom(UUID.c_str());
    arrlist[1] = erl_mk_atom(TableType.c_str());
    arrlist[2] = erl_mk_string(NewTableName.c_str());
    auto str = std::to_string(SyncType);
    arrlist[3] = erl_mk_atom(str.c_str());
    arrlist[4] = erl_mk_atom(BwType.c_str());
    arrlist[5] = erl_mk_atom(StartTime.c_str());
    arrlist[6] = erl_mk_atom(EndTime.c_str());
    ETERM *list = erl_mk_list(arrlist, 7);
    ret = erl_rpc_to(m_fd, "syncDB", "updateDatabase", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[1000], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            printf("arr_ret[0]:%d\n", erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
//                            int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
//                            printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
                        break;
                    }
                    default:
                        printf("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            erl_eterm_release();
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            }
        }
    }
    erl_free_array(arrlist, 7);
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    erl_eterm_release();
    return false;
}
bool ErlangTool::ErlangDbTool::deleteDatabase(std::string TableType, std::string TableName, bool SyncType) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return false;
    }
    std::string NewTableName = ((!SyncType) && TableName.find("lt_")) ? std::string("lt_").append(TableName)
                                                                      : TableName;
    ErlMessage emsg;             /* Incoming message */
    int ret = -1;
    ETERM *arrlist[2];
    arrlist[0] = erl_mk_atom(TableType.c_str());
    arrlist[1] = erl_mk_string(NewTableName.c_str());
    ETERM *list = erl_mk_list(arrlist, 2);
    ret = erl_rpc_to(m_fd, "syncDB", "deleteDatabase", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[10], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            printf("arr_ret[0]:%d\n", erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
                        int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
                        printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                        break;
                    }
                    default:
                        printf("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            }
        }
    }
    erl_free_array(arrlist, 2);
    erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    return false;
}
// 和erlang交互
//ErlangTool::map_TabDataCache ErlangTool::ErlangDbTool::findAllDatabase() {
//    LockG lock(m_mutex);
////            m_mutex.lock();
//    m_ret = resetConn();
//    map_TabDataCache tabDataCache;
//    if (!m_ret) {
//        //#todo error message
//        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//        return tabDataCache;
//    }
//    int ret = -1;
//    ErlMessage emsg;    /* Incoming message */
//    //hanshu canshu
////            ETERM *arrlist[0];
////            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
//    ETERM *list = erl_mk_empty_list();//erl_mk_list(arrlist, 0);
//
//    std::cout << __FILE__ << __FUNCTION__ << __LINE__ << "  " << m_fd << std::endl;
//    ret = erl_rpc_to(m_fd, "syncDB", "findAllDatabase", list);
//    if (ret == ERL_TICK) {
//        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
//        //erl_close_connection(m_fd);
////                m_mutex.unlock();
//        if (ret == ERL_MSG) {
//            ETERM *key, *value;
//            ETERM *tuplep[20];
//            ETERM *arr_ret[2], *list_ret[1000];
//            ETERM *tail_list, *tail_tuple;
//            arr_ret[0] = erl_element(2, emsg.msg);
//            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                int erlLength = erl_length(arr_ret[0]);
//                list_ret[0] = erl_hd(arr_ret[0]);
//                tail_list = erl_tl(arr_ret[0]);
//                for (int i = 0; i < erlLength; i++) {
//                    if (i > 0) {
//                        list_ret[i] = erl_hd(tail_list);
//                        tail_list = erl_tl(tail_list);
//                    }
//                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                        SyncDB::Table_Info table_info;
//                        int erlLength1 = erl_length(list_ret[i]);
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        tail_tuple = erl_tl(list_ret[i]);
//
//                        for (int j = 0; j < erlLength1; j++) {
//                            if (j > 0) {
//                                tuplep[j] = erl_hd(tail_tuple);
//                                tail_tuple = erl_tl(tail_tuple);
//                            }
//                            key = erl_element(1, tuplep[j]);
//                            value = erl_element(2, tuplep[j]);
//                            switch (checkETERMType(value)) {
//                                case ERL_ATOM: {
//                                    table_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                    break;
//                                }
//                                case ERL_INTEGER: {
//                                    table_info.setValue(erl_iolist_to_string(key),
//                                                        std::to_string(ERL_INT_VALUE(value)));
//                                    break;
//                                }
//                                case ERL_LIST: {
//                                    table_info.setValue(erl_iolist_to_string(key),
//                                                        erl_iolist_to_string(value));
//                                    break;
//                                }
//                                default:
//                                    printf("error add case todo %d\n\r", checkETERMType(value));
//                            }
////                                    erlangFreeEterm(3, key, value, tuplep[j]);
//                        }
////                                erlangFreeEterm(2, tail_tuple, list_ret[i]);
//
//                        // #todo this is have a bug
////                                table_info.create_by = "";
//                        tabDataCache.insert(std::make_pair(table_info.tableName, table_info));
//                    } else {
//                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
//                                  << checkETERMType(arr_ret[0])
//                                  << "  "
//                                  << std::endl;
//                    }
//                }
////                        erlangFreeEterm(2, tail_list, arr_ret[0]);
//                return tabDataCache; //ok
//            } else {
//                ERR(" error " << checkETERMType(arr_ret[0]));
//            }
//        }
//    }
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//    return tabDataCache; //not ok
//}
//#todo
//直接和sqlite3 交互
ErlangTool::map_TabDataCache ErlangTool::ErlangDbTool::findAllDatabase() {
    map_TabDataCache tabDataCache;
    QString sql = QString::fromStdString(
        "SELECT  uuid,tableName,tableType,bwType,startTime,endTime FROM sys_o_tables where del_flag=0;");
    QSqlQuery query(g_syncDbFile);
    query.prepare(sql);
    if (!query.exec()) {
        qDebug() << "getTableNameList" << __FILE__ << __LINE__ << query.lastError();
    } else {
        while (query.next()) {
            SyncDB::Table_Info t_table_info;
            t_table_info.uuid = query.value(0).toString().toStdString();
            t_table_info.tableName = query.value(1).toString().toStdString();
            t_table_info.tableType = query.value(2).toString().toStdString();
            t_table_info.bwType = query.value(3).toString().toStdString();
            t_table_info.startTime = query.value(4).toString().toStdString();
            t_table_info.endTime = query.value(5).toString().toStdString();
            tabDataCache.insert(std::make_pair(t_table_info.uuid, t_table_info));
        }
    }
    return tabDataCache; //not ok
}
/***
 * @deprecated
 * @return
 */
ErlangTool::map_BwDataCache ErlangTool::ErlangDbTool::findAllTypeInfo() {
    return map_BwDataCache();
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
        return map_BwDataCache();
    }
    map_BwDataCache bwDataCache;
    int ret = -1;
    ErlMessage emsg;    /* Incoming message */
    ETERM *list = erl_mk_empty_list();//erl_mk_list(arrlist, 0);
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
    ret = erl_rpc_to(m_fd, "syncDB", "findAllTypeInfo", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            ETERM *key, *value;
            ETERM *tuplep[20];
            ETERM *arr_ret[2], *list_ret[1000];
            ETERM *tail_list, *tail_tuple;
            arr_ret[0] = erl_element(2, emsg.msg);
            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
                int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
                list_ret[0] = erl_hd(arr_ret[0]);
                tail_list = erl_tl(arr_ret[0]);
                for (int i = 0; i < erlLength; i++) {
                    if (i > 0) {
                        list_ret[i] = erl_hd(tail_list);
                        tail_list = erl_tl(tail_list);
                    }
                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
                        SyncDB::Bw_Info bw_info;
                        int erlLength1 = erl_length(list_ret[i]);
//                            printf("list_ret[%d]:%d\n", i, erlLength1);
                        tuplep[0] = erl_hd(list_ret[i]);
                        tail_tuple = erl_tl(list_ret[i]);
                        for (int j = 0; j < erlLength1; j++) {
                            if (j > 0) {
                                tuplep[j] = erl_hd(tail_tuple);
                                tail_tuple = erl_tl(tail_tuple);
                            }
                            key = erl_element(1, tuplep[j]);
                            value = erl_element(2, tuplep[j]);
//                                printf("key:%s\n", erl_iolist_to_string(key));
                            switch (checkETERMType(value)) {
                                case ERL_ATOM: {
                                    bw_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
                                    break;
                                }
                                case ERL_INTEGER: {
                                    bw_info.setValue(erl_iolist_to_string(key),
                                                     std::to_string(ERL_INT_VALUE(value)));
                                    break;
                                }
                                case ERL_LIST: {
                                    bw_info.setValue(erl_iolist_to_string(key),
                                                     erl_iolist_to_string(value));
                                    break;
                                }
                                default:
                                    printf("error add case todo %d\n\r", checkETERMType(value));
                            }
//                                    erlangFreeEterm(3, key, value, tuplep[j]);
                        }
//                                erlangFreeEterm(2, tail_tuple, list_ret[i]);
//                            printf("\none list end\n\n\n\n");
                        // #todo this is have a bug
//                            bw_info.create_by = "";
                        bwDataCache.insert(std::make_pair(bw_info.tableName, bw_info));
                    } else {
                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
                                  << checkETERMType(arr_ret[0])
                                  << "  "
                                  << std::endl;
                    }
                }
//                        erlangFreeEterm(2, tail_list, arr_ret[0]);
                return bwDataCache;//ok
            } else {
                ERR(" error " << checkETERMType(arr_ret[0]));
            }
        }
    }
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    return map_BwDataCache();
}
bool ErlangTool::ErlangDbTool::addPerson(std::string &UUID, std::string TableName, std::string Feature,
                                         std::string ImgUrl, std::string IdCard, std::string PersonName,
                                         std::string Age, std::string Sex, std::string PhoneNum) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd << " ");
        return false;
    }
    int ret;
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
    ETERM *arrlist[9];
    arrlist[0] = erl_mk_string(TableName.c_str());
    arrlist[1] = erl_mk_string(PersonName.c_str());
    arrlist[2] = erl_mk_string(Age.c_str());
    arrlist[3] = erl_mk_string(Sex.c_str());
    arrlist[4] = erl_mk_string(IdCard.c_str());
    arrlist[5] = erl_mk_string(PhoneNum.c_str());
    arrlist[6] = erl_mk_string(ImgUrl.c_str());
    arrlist[7] = erl_mk_string(UUID.c_str());
    arrlist[8] = erl_mk_string(Feature.c_str());
    std::string TmpUUid;
    ETERM *list = erl_mk_list(arrlist, 9);
    ret = erl_rpc_to(m_fd, "syncDB", "addPersonData", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
//        UUID.clear();
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            ETERM *value;
            value = erl_element(2, emsg.msg);
            switch (checkETERMType(value)) {
                case ERL_LIST: {
                    TmpUUid = std::string(erl_iolist_to_string(value));
                    break;
                }
                case ERL_ATOM: {
                    TmpUUid = std::string(ERL_ATOM_PTR(value));
                    break;
                }
                default:
                    printf("error add case todo \n\r");
            }
            erl_free_term(value);
            if (TmpUUid.size() > 0) {
                UUID = TmpUUid;
                erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[8]);
                erl_free_array(arrlist, 8);
                erl_eterm_release();
                return true;
            }
        }
    }
    erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[8]);
    erl_free_array(arrlist, 8);
    erl_eterm_release();
    UUID = "";
    return false;
}
ErlangTool::vec_AddDataCache
ErlangTool::ErlangDbTool::addPersons(std::string TableUuid, std::vector<SyncDB::AddPersonInfo> &tmpPer) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    ErlangTool::vec_AddDataCache t_vec_addDataCache;
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd << " ");
        return t_vec_addDataCache;
    }
    int ret;
    ErlMessage emsg;    /* Incoming message */
    ETERM *person_list[10];
    int loop = 0;
    for (auto &item :tmpPer) {
        ETERM *arrlist[4];
        arrlist[0] = erl_mk_atom(item.personid.c_str());
        arrlist[1] = erl_mk_atom(item.idcard.c_str());
        arrlist[2] = erl_mk_atom(item.personPic.c_str());
        arrlist[3] = erl_mk_string(item.feature.c_str());
        person_list[loop++] = erl_mk_tuple(arrlist, 4);
    }
    //hanshu canshu
    ETERM *arrvaluelist[2];
    arrvaluelist[0] = erl_mk_string(TableUuid.c_str());
    arrvaluelist[1] = erl_mk_list(person_list, loop);
    ETERM *list = erl_mk_list(arrvaluelist, 2);
    ret = erl_rpc_to(m_fd, "syncDB", "addPersonDatas", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            ETERM *key, *value;
            ETERM *tuplep[20];
            ETERM *arr_ret[2], *list_ret[5000];
            ETERM *tail_list, *tail_tuple;
            arr_ret[0] = erl_element(2, emsg.msg);
            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
                int erlLength = erl_length(arr_ret[0]);
//                        printf("arr_ret[0]:%d\n", erlLength);
                list_ret[0] = erl_hd(arr_ret[0]);
                tail_list = erl_tl(arr_ret[0]);
                for (int i = 0; i < erlLength; i++) {
//                            DBG(i);
                    if (i > 0) {
                        list_ret[i] = erl_hd(tail_list);
                        tail_list = erl_tl(tail_list);
                    }
                    if (tail_list == NULL)
                        break;
                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
                        SyncDB::AddPersRet addPersRet;
                        int erlLength1 = erl_length(list_ret[i]);
//                                printf("list_ret[%d]:%d\n", i, erlLength1);
                        tuplep[0] = erl_hd(list_ret[i]);
                        tail_tuple = erl_tl(list_ret[i]);
                        for (int j = 0; j < erlLength1; j++) {
                            if (j > 0) {
                                tuplep[j] = erl_hd(tail_tuple);
                                tail_tuple = erl_tl(tail_tuple);
                            }
                            key = erl_element(1, tuplep[j]);
                            value = erl_element(2, tuplep[j]);
//                                    printf("key:%s\n", erl_iolist_to_string(key));
                            switch (checkETERMType(value)) {
                                case ERL_ATOM: {
                                    addPersRet.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
                                    break;
                                }
                                case ERL_LIST: {
                                    addPersRet.setValue(erl_iolist_to_string(key),
                                                        erl_iolist_to_string(value));
                                    break;
                                }
                                default:
                                    printf("error add case todo %d\n\r", checkETERMType(value));
                            }
//                                    erlangFreeEterm(2, key, value);
                        }
//                                printf("\none list end\n\n\n\n");
                        t_vec_addDataCache.push_back(addPersRet);
                    } else {
                        ERR(" type error " << checkETERMType(list_ret[i]));
                    }
                }
                erlangFreeEterm(4, emsg.msg, emsg.from, emsg.to, list);
                erl_eterm_release();
//                        sleep()
                return t_vec_addDataCache;
            } else {
                ERR(" error " << checkETERMType(arr_ret[0]));
            }
        } else {
            ERR("send Message is error");
        }
    }
    erlangFreeEterm(4, emsg.msg, emsg.from, emsg.to, list);
    erl_free_array(arrvaluelist, 2);
    erl_eterm_release();
    return t_vec_addDataCache;
}
bool ErlangTool::ErlangDbTool::delPerson(std::string UUID, std::string TableName) {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd << " ");
        return false;
    }
    int ret;
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
    ETERM *arrlist[2];
//    arrlist[0] = erl_mk_atom(TableName.c_str());
//    arrlist[1] = erl_mk_atom(UUID.c_str());
    arrlist[0] = erl_mk_string(TableName.c_str());
    arrlist[1] = erl_mk_string(UUID.c_str());
    ETERM *list = erl_mk_list(arrlist, 2);
    ret = erl_rpc_to(m_fd, "syncDB", "deletePersonData", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[10], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            printf("arr_ret[0]:%d\n", erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
                        int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                                printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
                        break;
                    }
                    default:
                        printf("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            }
        }
    }
    erlangFreeEterm(4, emsg.msg, emsg.from, emsg.to, list);
    erl_free_array(arrlist, 2);
    erl_eterm_release();
    return false;
}
//ErlangTool::map_FaceDataCache ErlangTool::ErlangDbTool::loadFaceFeaData(std::string TableName) {
//    std::lock_guard<std::mutex> lock(m_mutex);
////            m_mutex.lock();
//    m_ret = resetConn();
//    if (!m_ret) {
//        //#todo error message
//        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//        return map_FaceDataCache();
//    }
//    map_FaceDataCache dataCache;
//    int ret;
//    ErlMessage emsg;    /* Incoming message */
//    //hanshu canshu
//    ETERM *arrlist[1];
//    arrlist[0] = erl_mk_string(TableName.c_str());
//
//    ETERM *list = erl_mk_list(arrlist, 1);
//    ret = erl_rpc_to(m_fd, "syncDB", "loadFaceFeaData", list);
//
//    if (ret == ERL_TICK) {
//        ret = erl_rpc_from(m_fd, TIMEOUT * 100000, &emsg);
//        //erl_close_connection(m_fd);
////                m_mutex.unlock();
//        if (ret == ERL_MSG) {
//            ETERM *key, *value;
//            ETERM *tuplep[20];
//            ETERM *arr_ret[2], *list_ret[5000];
//            ETERM *tail_list, *tail_tuple;
//            arr_ret[0] = erl_element(2, emsg.msg);
//            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                int erlLength = erl_length(arr_ret[0]);
////                        printf("arr_ret[0]:%d\n", erlLength);
//                list_ret[0] = erl_hd(arr_ret[0]);
//                tail_list = erl_tl(arr_ret[0]);
//                for (int i = 0; i < erlLength; i++) {
////                            DBG(i);
//                    if (i > 0) {
//                        list_ret[i] = erl_hd(tail_list);
//                        tail_list = erl_tl(tail_list);
//                    }
//                    if (tail_list == NULL)
//                        break;
//                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                        SyncDB::Feature_Info feature_info;
//                        int erlLength1 = erl_length(list_ret[i]);
////                                printf("list_ret[%d]:%d\n", i, erlLength1);
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        tail_tuple = erl_tl(list_ret[i]);
//                        for (int j = 0; j < erlLength1; j++) {
//                            if (j > 0) {
//                                tuplep[j] = erl_hd(tail_tuple);
//                                tail_tuple = erl_tl(tail_tuple);
//                            }
//                            key = erl_element(1, tuplep[j]);
//                            value = erl_element(2, tuplep[j]);
////                                    printf("key:%s\n", erl_iolist_to_string(key));
//
//                            switch (checkETERMType(value)) {
//                                case ERL_ATOM: {
//                                    feature_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                    break;
//                                }
//                                case ERL_LIST: {
//                                    feature_info.setValue(erl_iolist_to_string(key),
//                                                          erl_iolist_to_string(value));
//                                    break;
//                                }
//                                default:
//                                    printf("error add case todo %d\n\r", checkETERMType(value));
//                            }
//
////                                    erlangFreeEterm(2, key, value);
//                        }
////                                printf("\none list end\n\n\n\n");
//                        dataCache.insert(std::move(std::make_pair(feature_info.id, feature_info)));
////                                break;
////                                erlangFreeEterm(1, list_ret[i]);
//                    } else {
//                        ERR(" type error " << checkETERMType(list_ret[i]));
//                    }
//                }
//                erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//                erl_eterm_release();
////                        sleep()
//                return dataCache;
//            } else {
//                ERR(" error " << checkETERMType(arr_ret[0]));
//            }
//        } else {
//            ERR(" error " << ret << "  ");
//        }
//
//    }
//    erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//    erl_eterm_release();
//    return map_FaceDataCache();
//};
//ErlangTool::map_FaceDataCache ErlangTool::ErlangDbTool::loadFaceFeaData2(std::string TableName) {
//    std::lock_guard<std::mutex> lock(m_mutex);
////            m_mutex.lock();
//    m_ret = resetConn();
//    if (!m_ret) {
//        //#todo error message
//        ERR(" error " << m_ret << "  " << m_fd);
//        return map_FaceDataCache();
//    }
//    map_FaceDataCache dataCache;
//    int ret;
//    ErlMessage emsg;    /* Incoming message */
//    //hanshu canshu
//    ETERM *arrlist[1];
////    arrlist[0] = erl_mk_atom(TableName.c_str());
//    arrlist[0] = erl_mk_string(TableName.c_str());
//
//    ETERM *list = erl_mk_list(arrlist, 1);
//    ret = erl_rpc_to(m_fd, "syncDB", "loadFaceFeaData2", list);
//
//    if (ret == ERL_TICK) {
//        ret = erl_rpc_from(m_fd, TIMEOUT * 100000, &emsg);
//        //erl_close_connection(m_fd);
////                m_mutex.unlock();
//        if (ret == ERL_MSG) {
//            ETERM *key, *value;
//            ETERM *tuplep[20];
//            ETERM *arr_ret[2], *list_ret[5000];
//            ETERM *tail_list, *tail_tuple;
//            arr_ret[0] = erl_element(2, emsg.msg);
//            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                int erlLength = erl_length(arr_ret[0]);
////                        printf("arr_ret[0]:%d\n", erlLength);
//                list_ret[0] = erl_hd(arr_ret[0]);
//                tail_list = erl_tl(arr_ret[0]);
//                for (int i = 0; i < erlLength; i++) {
////                            DBG(i);
//                    if (i > 0) {
//                        list_ret[i] = erl_hd(tail_list);
//                        tail_list = erl_tl(tail_list);
//                    }
//                    if (tail_list == NULL)
//                        break;
//                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                        SyncDB::Feature_Info feature_info;
////                                feature_info.id = "test";
////                                feature_info.create_by = "";
////                                feature_info.feature ="";
////                                feature_info.update_time = "";
////                                feature_info.create_time = "";
//
//                        int erlLength1 = erl_length(list_ret[i]);
////                                printf("list_ret[%d]:%d\n", i, erlLength1);
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        tail_tuple = erl_tl(list_ret[i]);
//
//                        for (int j = 0; j < erlLength1; j++) {
//                            if (j > 0) {
//                                tuplep[j] = erl_hd(tail_tuple);
//                                tail_tuple = erl_tl(tail_tuple);
//                            }
//                            key = erl_element(1, tuplep[j]);
//                            value = erl_element(2, tuplep[j]);
////                                    printf("key:%s\n", erl_iolist_to_string(key));
//
//                            switch (checkETERMType(value)) {
//                                case ERL_ATOM: {
//                                    feature_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                    break;
//                                }
//                                case ERL_LIST: {
//                                    feature_info.setValue(erl_iolist_to_string(key),
//                                                          erl_iolist_to_string(value));
//                                    break;
//                                }
//                                default:
//                                    printf("error add case todo %d\n\r", checkETERMType(value));
//                            }
//
////                                    erlangFreeEterm(2, key, value);
//                        }
////                                printf("\none list end\n\n\n\n");
//                        dataCache.insert(std::move(std::make_pair(feature_info.id, feature_info)));
////                                break;
////                                erlangFreeEterm(1, list_ret[i]);
//                    } else {
//                        ERR(" type error " << checkETERMType(list_ret[i]));
//                    }
//                }
////                erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
////                erl_eterm_release();
////                        sleep()
//                return dataCache;
//            } else {
//                ERR(" error " << checkETERMType(arr_ret[0]));
//            }
//        } else {
//            ERR(" error " << ret << "  ");
//        }
//
//    }
//    erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//    erl_eterm_release();
//    return map_FaceDataCache();
//};
ErlangTool::map_FaceDataCache ErlangTool::ErlangDbTool::loadFaceFeaData(std::string TableName) {
    map_FaceDataCache dataCache;
    std::string str_tableUuid;
    auto tableInfoMap = findAllDatabase();
    for (auto &item : tableInfoMap) {
        if (item.second.tableName == TableName) {
            str_tableUuid = item.second.uuid;
            break;
        }
    }
    if (str_tableUuid.size() > 0) {
        QString sql = QString::fromStdString(
            "Select a.uuid as id ,a.faceUrl as img,a.feature,b.idCard as idcard from '" + str_tableUuid +
            "_fea' as a ,'" + str_tableUuid + "' as b  where a.uuid = b.uuid and ( a.del_flag=0 AND b.del_flag=0);");
        QSqlQuery query(g_syncDbFile);
        query.prepare(sql);
        if (!query.exec()) {
            qDebug() << "getTableNameList" << __FILE__ << __LINE__ << query.lastError();
        } else {
            while (query.next()) {
                SyncDB::Feature_Info t_feature_info;
                t_feature_info.id = query.value(0).toString().toStdString();
                t_feature_info.img = query.value(1).toString().toStdString();
                t_feature_info.feature = query.value(2).toString().toStdString();
                t_feature_info.idcard = query.value(3).toString().toStdString();
                dataCache.insert(std::make_pair(t_feature_info.id, t_feature_info));
            }
            return dataCache;
        }
    }
    return map_FaceDataCache();
};
ErlangTool::map_FaceDataCache ErlangTool::ErlangDbTool::loadFaceFeaData2(std::string TableName) {
    map_FaceDataCache dataCache;
    std::string str_tableUuid;
    auto tableInfoMap = findAllDatabase();
    for (auto &item : tableInfoMap) {
        if (item.second.tableName == TableName) {
            str_tableUuid = item.second.uuid;
            break;
        }
    }
    if (str_tableUuid.size() > 0) {
        QString sql = QString::fromStdString(
            "Select b.uuid as id,b.faceUrl as img,a.idCard as idcard from '" + str_tableUuid + "' as a, '" +
            str_tableUuid + "_fea' As b  where a.uuid = b.uuid and ( a.del_flag=0 AND b.del_flag=0);");
        QSqlQuery query(g_syncDbFile);
        query.prepare(sql);
        if (!query.exec()) {
            qDebug() << "getTableNameList" << __FILE__ << __LINE__ << query.lastError();
        } else {
            while (query.next()) {
                SyncDB::Feature_Info t_feature_info;
                t_feature_info.id = query.value(0).toString().toStdString();
                t_feature_info.img = query.value(1).toString().toStdString();
                t_feature_info.idcard = query.value(2).toString().toStdString();
                dataCache.insert(std::make_pair(t_feature_info.id, t_feature_info));
            }
            return dataCache;
        }
    }
    return map_FaceDataCache();
};
bool ErlangTool::ErlangDbTool::resetConn() {
    //#todo
    if (m_pName.size() <= 0) {
        srand(time(0));
        m_loop = rand() % 1000;
        int ret = -1;
        erl_init(NULL, 0);
//            m_loop %= 10;
//            m_loop++;
        ret = erl_connect_init(m_loop, const_cast<char *>(m_cookie.c_str()), 0);
        DBG("node name is   " << m_loop);
        if (-1 == ret) {
//            erl_err_quit("erl_connect_init");
            return false;
        }
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
        erl_close_connection(m_fd);
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
        m_fd = erl_connect(const_cast<char *>(m_nodeName.c_str()));
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
        if (0 > m_fd) {
//            erl_err_quit("erl_connect");
            return false;
        }
        return true;
    } else {
         erl_close_connection(m_fd);
        m_fd = erl_connect(const_cast<char *>(m_nodeName.c_str()));
        if (0 > m_fd) {
//            erl_err_quit("erl_connect");
//            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << " error " << fd << std::endl;
            ERR("m_fd is   " << m_fd << " m_nodeName is" << m_nodeName);
            return false;
        }
//        std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << fd << std::endl;
        INFO("m_fd is   " << m_fd << " m_nodeName is" << m_nodeName);
        return true;
    }
}
bool ErlangTool::ErlangDbTool::waitNode() {
    std::cout << "start waitNode" << std::endl;
    int loop = 0;
    while (!m_ret && loop <= 4000) {
        m_ret = ErlangTool::pingNode(m_nodeName, m_cookie);
        if (m_ret) {
//                    std::cout << "startNodeDb" << std::endl;
        } else {
//                    std::cout << "init failer" << std::endl;
            usleep(100000);
            loop++;
        }
    }
    std::cout << "start waitNode" << std::endl;
    return m_ret;
}
void ErlangTool::ErlangDbTool::test(pthread_cond_t *t_pthcon, pthread_mutex_t *t_pthmut) {
    bool ret = setCNodeName();
    {
        std::thread th1([&] {
            int res;
            pthread_cond_t *t_pthCon = t_pthcon;
            pthread_mutex_t *t_pthMut = t_pthmut;
            int listen;                              /* Listen socket */
            int fd;                                  /* fd to Erlang node */
            ErlConnect conn;                         /* Connection data */
            int loop = 1;                            /* Loop flag */
            int got;                                 /* Result of receive */
            unsigned char buf[BUFSIZE];              /* Buffer for incoming message */
            ErlMessage emsg;                         /* Incoming message */
            ETERM *fromp, *tuplep, *fnp, *argp, *resp;
            int port;                                /* Listen port number */
            port = PORT;
            /* Make a listen socket */
            if ((listen = my_listen(port)) <= 0) {
                ERR("my_listen is error");
                erl_err_quit("my_listen");
            }
            if (erl_publish(port) == -1) {
                ERR("erl_publish is error");
                erl_err_quit("erl_publish");
            }
            if ((fd = erl_accept(listen, &conn)) == ERL_ERROR) {
                ERR("erl_accept is error");
                erl_err_quit("erl_accept");
            }
            INFO("Connected to " << conn.nodename);
            while (loop) {
//        std::cout << "hello world" << std::endl;
                got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
                if (got == ERL_TICK) {
                    /* ignore */
                } else if (got == ERL_ERROR) {
                    if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
                        erl_err_quit("erl_accept");
                    INFO("Connected to " << conn.nodename);
                } else {
                    if (emsg.type == ERL_REG_SEND) {
                        fromp = erl_element(2, emsg.msg);
                        tuplep = erl_element(3, emsg.msg);
                        fnp = erl_element(1, tuplep);
                        argp = erl_element(2, tuplep);
                        if (strncmp(ERL_ATOM_PTR(fnp), "update", 6) == 0) {
                            INFO("message is  " << ERL_ATOM_PTR(fnp));
                            std::string str1(ERL_ATOM_PTR(fnp));
//                            CBF(str1);
                            DBG("erlangCallBackFunc");
                            pthread_cond_signal(t_pthCon);
                            pthread_mutex_unlock(t_pthMut);
                            //call back func
                        } else {
                            ERR("message not is  update");
                        }
//                        resp = erl_format("{c1, {res,~i}}", res);
//                        erl_send(fd, fromp, resp);
                        erl_free_term(emsg.from);
                        erl_free_term(emsg.msg);
                        erl_free_term(fromp);
                        erl_free_term(tuplep);
                        erl_free_term(fnp);
                        erl_free_term(argp);
                        erl_free_term(resp);
                        erl_close_connection(fd);
                        if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
                            erl_err_quit("erl_accept");
                        INFO("Connected to " << conn.nodename);
                    }
                }
            }
        });
        th1.detach();
    }
}
bool ErlangTool::ErlangDbTool::setCNodeName() {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return false;
    }
    ErlMessage emsg;             /* Incoming message */
    int ret = -1;
    ETERM *arrlist[1];
    arrlist[0] = erl_mk_atom(m_cNodeName.c_str());
//    arrlist[0] = erl_mk_atom("c1@127.0.0.1");
    ETERM *list = erl_mk_list(arrlist, 1);
    ret = erl_rpc_to(m_fd, "syncDB", "setCNode", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[1000], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            INFO("arr_ret[0]:  " << erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
                        int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
                        INFO("value is a atom: atomSize: " << atomSize << " , atomValue:" << atomValue << " \n\r");
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
                        break;
                    }
                    default:
                        ERR("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            erl_eterm_release();
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            } else {
                ERR("res is err ");
            }
        } else {
            ERR("recv mess error : ret != ERL_MSG");
        }
    } else {
        ERR("send mess error : ret != ERL_TICK");
    }
    erl_free_array(arrlist, 1);
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    erl_eterm_release();
    return false;
}
bool ErlangTool::ErlangDbTool::sendMessage() {
    LockG lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return false;
    }
    ErlMessage emsg;             /* Incoming message */
    int ret = -1;
    ETERM *list = erl_mk_empty_list();
    ret = erl_rpc_to(m_fd, "syncDB", "sendMessage", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            std::map<std::string, std::string> t_results;
            ETERM *tail_list;
            ETERM *list_ret[1000], *arr_ret[2];
            ETERM *key, *value;
            ETERM *tuplep[6];
            arr_ret[0] = erl_element(2, emsg.msg);
            int erlLength = erl_length(arr_ret[0]);
            INFO("arr_ret[0]:  " << erlLength);
            list_ret[0] = erl_hd(arr_ret[0]);
            tail_list = erl_tl(arr_ret[0]);
            for (int i = 0; i < erlLength; i++) {
                if (i > 0) {
                    list_ret[i] = erl_hd(tail_list);
                    tail_list = erl_tl(tail_list);
                }
//                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
                tuplep[0] = erl_hd(list_ret[i]);
                key = erl_element(1, list_ret[i]);
                value = erl_element(2, list_ret[i]);
//                    printf("key:%s\n", ERL_ATOM_PTR(key));
                switch (checkETERMType(value)) {
                    case ERL_ATOM: {
                        int atomSize = ERL_ATOM_SIZE(value);
                        char *atomValue = ERL_ATOM_PTR(value);
                        INFO("value is a atom: atomSize: " << atomSize << " , atomValue:" << atomValue << " \n\r");
                        t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
                        break;
                    }
                    default:
                        ERR("error add case todo \n\r");
                }
                erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
            }
            erlangFreeEterm(2, tail_list, arr_ret[0]);
            erl_eterm_release();
            auto it = t_results.find("atomic");
            if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
                return true;
            } else {
                ERR("res is err ");
            }
        } else {
            ERR("recv mess error : ret != ERL_MSG");
        }
    } else {
        ERR("send mess error : ret != ERL_TICK");
    }
//    erl_free_array(arrlist, 1);
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
    erl_eterm_release();
    return false;
}
ErlangTool::vec_PerExistRet ErlangTool::ErlangDbTool::personIsExistOnClu(std::string personUid) {
    ErlangTool::vec_PerExistRet t_vec_perExistRet;
    std::lock_guard<std::mutex> lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return t_vec_perExistRet;
    }
    int ret;
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
    ETERM *arrlist[1];
    arrlist[0] = erl_mk_string(personUid.c_str());
    ETERM *list = erl_mk_list(arrlist, 1);
    ret = erl_rpc_to(m_fd, "syncDB", "singlePersonIsExists", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT * 100000, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            ETERM *key, *value;
            ETERM *tuplep[20];
            ETERM *arr_ret[2], *list_ret[5000];
            ETERM *tail_list, *tail_tuple;
            arr_ret[0] = erl_element(2, emsg.msg);
            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
                int erlLength = erl_length(arr_ret[0]);
//                        printf("arr_ret[0]:%d\n", erlLength);
                list_ret[0] = erl_hd(arr_ret[0]);
                tail_list = erl_tl(arr_ret[0]);
                for (int i = 0; i < erlLength; i++) {
//                            DBG(i);
                    if (i > 0) {
                        list_ret[i] = erl_hd(tail_list);
                        tail_list = erl_tl(tail_list);
                    }
                    if (tail_list == NULL)
                        break;
                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
                        SyncDB::PerExistRet perExistRet;
                        int erlLength1 = erl_length(list_ret[i]);
//                                printf("list_ret[%d]:%d\n", i, erlLength1);
                        tuplep[0] = erl_hd(list_ret[i]);
                        tail_tuple = erl_tl(list_ret[i]);
                        for (int j = 0; j < erlLength1; j++) {
                            if (j > 0) {
                                tuplep[j] = erl_hd(tail_tuple);
                                tail_tuple = erl_tl(tail_tuple);
                            }
                            key = erl_element(1, tuplep[j]);
                            value = erl_element(2, tuplep[j]);
//                                    printf("key:%s\n", erl_iolist_to_string(key));
                            switch (checkETERMType(value)) {
                                case ERL_ATOM: {
                                    perExistRet.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
                                    break;
                                }
                                case ERL_LIST: {
                                    perExistRet.setValue(erl_iolist_to_string(key),
                                                         erl_iolist_to_string(value));
                                    break;
                                }
                                default:
                                    printf("error add case todo %d\n\r", checkETERMType(value));
                            }
                        }
                        t_vec_perExistRet.push_back(perExistRet);
                    } else {
                        ERR(" type error " << checkETERMType(list_ret[i]));
                    }
                }
                erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
                erl_eterm_release();
                return t_vec_perExistRet;
            } else {
                ERR(" error " << checkETERMType(arr_ret[0]));
            }
        } else {
            ERR(" error " << ret << "  ");
        }
    }
    erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
    erl_eterm_release();
    return t_vec_perExistRet;
}
ErlangTool::vec_UpdPersRet
ErlangTool::ErlangDbTool::singlePersonUpdate(std::string NewPerId, std::string OldId, std::string Idcard,
                                             std::string PerPicUrl, std::string PerFea) {
    ErlangTool::vec_UpdPersRet t_vec_UpdPersRet;
    std::lock_guard<std::mutex> lock(m_mutex);
//            m_mutex.lock();
    m_ret = resetConn();
    if (!m_ret) {
        //#todo error message
        ERR(" error " << m_ret << "  " << m_fd);
        return t_vec_UpdPersRet;
    }
    int ret;
    ErlMessage emsg;    /* Incoming message */
    //hanshu canshu
    ETERM *arrlist[5];
    arrlist[0] = erl_mk_atom(NewPerId.c_str());
    arrlist[1] = erl_mk_atom(OldId.c_str());
    arrlist[2] = erl_mk_atom(Idcard.c_str());
    arrlist[3] = erl_mk_atom(PerPicUrl.c_str());
    arrlist[4] = erl_mk_string(PerFea.c_str());
    ETERM *list = erl_mk_list(arrlist, 5);
    ret = erl_rpc_to(m_fd, "syncDB", "singlePersonUpdate", list);
    if (ret == ERL_TICK) {
        ret = erl_rpc_from(m_fd, TIMEOUT * 100000, &emsg);
        //erl_close_connection(m_fd);
//                m_mutex.unlock();
        if (ret == ERL_MSG) {
            ETERM *key, *value;
            ETERM *tuplep[20];
            ETERM *arr_ret[2], *list_ret[5000];
            ETERM *tail_list, *tail_tuple;
            arr_ret[0] = erl_element(2, emsg.msg);
            if (checkETERMType(arr_ret[0]) == ERL_LIST) {
                int erlLength = erl_length(arr_ret[0]);
//                        printf("arr_ret[0]:%d\n", erlLength);
                list_ret[0] = erl_hd(arr_ret[0]);
                tail_list = erl_tl(arr_ret[0]);
                for (int i = 0; i < erlLength; i++) {
//                            DBG(i);
                    if (i > 0) {
                        list_ret[i] = erl_hd(tail_list);
                        tail_list = erl_tl(tail_list);
                    }
                    if (tail_list == NULL)
                        break;
                    if (checkETERMType(list_ret[i]) == ERL_LIST) {
                        SyncDB::UpdPersRet updPersRet;
                        int erlLength1 = erl_length(list_ret[i]);
//                                printf("list_ret[%d]:%d\n", i, erlLength1);
                        tuplep[0] = erl_hd(list_ret[i]);
                        tail_tuple = erl_tl(list_ret[i]);
                        for (int j = 0; j < erlLength1; j++) {
                            if (j > 0) {
                                tuplep[j] = erl_hd(tail_tuple);
                                tail_tuple = erl_tl(tail_tuple);
                            }
                            key = erl_element(1, tuplep[j]);
                            value = erl_element(2, tuplep[j]);
//                                    printf("key:%s\n", erl_iolist_to_string(key));
                            switch (checkETERMType(value)) {
                                case ERL_ATOM: {
                                    updPersRet.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
                                    break;
                                }
                                case ERL_LIST: {
                                    updPersRet.setValue(erl_iolist_to_string(key),
                                                        erl_iolist_to_string(value));
                                    break;
                                }
                                default:
                                    printf("error add case todo %d\n\r", checkETERMType(value));
                            }
                        }
                        t_vec_UpdPersRet.push_back(updPersRet);
                    } else {
                        ERR(" type error " << checkETERMType(list_ret[i]));
                    }
                }
                erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
                erl_eterm_release();
                return t_vec_UpdPersRet;
            } else {
                ERR(" error " << checkETERMType(arr_ret[0]));
            }
        } else {
            ERR(" error " << ret << "  ");
        }
    }
    erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
    erl_eterm_release();
    return t_vec_UpdPersRet;
}
static int ErlangTool::my_listen(int port) {
    int listen_fd;
    struct sockaddr_in addr;
    int on = 1;
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return (-1);
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    memset((void *) &addr, 0, (size_t) sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(listen_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
        return (-1);
    listen(listen_fd, 5);
    return listen_fd;
}
syncDBTool/ErlangDbTool.h
New file
@@ -0,0 +1,312 @@
//
// Created by ps on 18-11-29.
//
#ifndef SYNCDBTOOL_ERLANGDBTOOL_H
#define SYNCDBTOOL_ERLANGDBTOOL_H
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <zconf.h>
#include <thread>
#include <map>
#include <vector>
#include <mutex>
#include <stdio.h>
#include <stdarg.h>
#include <jsoncpp/json/json.h>
#include <arpa/inet.h>
#include "erl_interface.h"
#include "ei.h"
#include "SyncDB.hpp"
#define TIMEOUT (5000)
#define BUFSIZE 1000
#define PORT 13001
//typedef void (*CBF)(std::string);
extern void erlangCallBackFunc(std::string);
//#TODO 多线程优化
namespace ErlangTool {
    static int m_loop = 0;
    //map<uuid,人脸特征信息>
    typedef std::map<std::string, SyncDB::Feature_Info> map_FaceDataCache;
    //map<uuid,设备信息>
    typedef std::map<std::string, SyncDB::Device_Info> map_DevDataCache;
    //map<表名,底库表信息>
    typedef std::map<std::string, SyncDB::Table_Info> map_TabDataCache;
    //map<表名,黑白名单类型>
    typedef std::map<std::string, SyncDB::Bw_Info> map_BwDataCache;
    typedef std::vector<SyncDB::AddPersRet> vec_AddDataCache;
    typedef std::vector<SyncDB::PerExistRet> vec_PerExistRet;
    typedef std::vector<SyncDB::UpdPersRet> vec_UpdPersRet;
    //c++11 互斥锁
    // LockG(Parma);
    typedef std::lock_guard<std::mutex> LockG;
    /***
     * 判断文件夹路径是否存在,不存在则创建
     * @param dir 文件路径
     * @param mkdir_flag 是否创建创建文件夹
     * @return 是否成功
     */
    static bool dir_file_exists(std::string dir, bool mkdir_flag = true);
    /***
     * 测试节点是否启动
     * @param nodeName 节点名称
     * @param cookie   节点cookie
     * @return 启动状态
     */
    static bool pingNode(const std::string &nodeName, const std::string &cookie);
    /***
     * 检查ETERM的数据类型
     * @param elemen
     * @return 返回数据类型
     */
    static int checkETERMType(ETERM *elemen);
    static void erlangFreeEterm(int count, ...);
    /***
     * Erlang交互工具
     * #todo map保存到内存?
     */
    class ErlangDbTool {
    public:
        explicit ErlangDbTool();
        /***
         * 初始化节点(zhizuo chaxun shiyong)
         * @param nodeName 节点名称
         * @param cookie 集群cookie
         */
        ErlangDbTool(const std::string &nodeName, const std::string &cookie, const std::string &pName);
        /***
         * 初始化节点
         * @param path 节点数据库保存路径
         * @param nodeName 节点名称
         * @param cookie 集群cookie
         */
        ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
                     const std::string &pName);
        //clusterID clusterName
        /***
         * 初始化节点
         * @param path 节点数据库保存路径
         * @param nodeName 节点名称
         * @param cookie 集群cookie
         * @param clusterID 集群id
         * @param clusterName 集群名称
         */
        ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
                     const std::string &clusterID, const std::string &clusterName);
        //clusterID clusterName
        /***
         * 初始化节点
         * @param path 节点数据库保存路径
         * @param nodeName 节点名称
         * @param cookie 集群cookie
         * @param clusterID 集群id
         * @param clusterName 集群名称
         * @param pName c节点标识名
         */
        ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
                     const std::string &clusterID, const std::string &clusterName, const std::string &pName);
        virtual ~ErlangDbTool();
    private:
        void initCNode();
    public:
        //#todo setCNodeName
        bool setCNodeName();
        bool sendMessage();
        //#todo sendMessage
        void test(pthread_cond_t *, pthread_mutex_t *);
        /***
         * 启动erlang节点
         * @return 启动状态
         */
        int initErlang();
        std::string getConfigJsonString();
        /***
         * 启动节点数据库
         * 新节点自动创建数据库
         * @param FatherNodeName 第一个节点无需传入此参数,其他节点需要传入引导节点的名称
         * @param DeviceName 设备名称
         * @param DevAdd 设备地址
         * @return
         */
        bool startNodeDb(std::string FatherNodeName, std::string DeviceId = "", std::string DevAdd = "DevAddress");
        /***
         * 删除节点数据库,同时删除本地文件
         * @return 返回状态
         */
        bool removeNode();
        bool modifyCluName(std::string CluId, std::string CluName);
        /***
         * 查找在线节点信息
         * #TODO 有一个小bug
         * device_info.create_by会被重置
         * @return 节点集合信息
         */
        map_DevDataCache findAllNode();
        /***
         * 创建底库表
         * @param TableType car||person
         * @param TableName
         * @param SyncType true 1||false 0
         * @param BwType   "Black"1||"White"0
         * @return 创建状态
         */
        bool createDatabase(std::string TableType, std::string TableName, bool SyncType, std::string BwType,
                            std::string StartTime = "", std::string EndTime = "");
        /***
         * 更新底库表
         * @param TableType car||person
         * @param TableName
         * @param SyncType true 1||false 0
         * @param BwType   "white"0||"black"1
         * @return 创建状态
         */
        bool updateDatabase(std::string UUID, std::string TableType, std::string TableName, bool SyncType,
                            std::string BwType, std::string StartTime = "", std::string EndTime = "");
        /***
         * 删除数据表
         * @param TableType car||person
         * @param TableName biaoming
         * @param SyncType true 1||false 0
         * @return
         */
        bool deleteDatabase(std::string TableType, std::string TableName, bool SyncType);
        /***
         * 查询所有数据表
         * @return
         */
        map_TabDataCache findAllDatabase();
        /***
         * 查询所有表的黑白名单类型
         * @return
         */
        map_BwDataCache findAllTypeInfo();
        /***
         * 增加人员
         * @param UUID  out
         * @param TableName
         * @param Feature
         * @param PersonName
         * @param Age
         * @param Sex
         * @param IdCard
         * @param PhoneNum
         * @return
         */
        bool addPerson(std::string &UUID, std::string TableName, std::string Feature, std::string ImgUrl = " ",
                       std::string IdCard = " ", std::string PersonName = " ", std::string Age = " ",
                       std::string Sex = " ", std::string PhoneNum = " ");
        vec_AddDataCache addPersons(std::string TableUuid, std::vector<SyncDB::AddPersonInfo> &tmpPer);
        /***
         * 删除人员
         * @param UUID
         * @param TableName
         * @return
         */
        bool delPerson(std::string UUID, std::string TableName);
        /***
         * 根据表名加载人脸特征
         * @param TableName
         * @return
         */
        map_FaceDataCache loadFaceFeaData(std::string TableName);
        /***
         * 根据表名加载人脸特征2
         * @param TableName
         * @return
         */
        map_FaceDataCache loadFaceFeaData2(std::string TableName);
        vec_PerExistRet personIsExistOnClu(std::string personUid);
        vec_UpdPersRet singlePersonUpdate(std::string NewPerId, std::string OldId, std::string Idcard,
                                          std::string PerPicUrl, std::string PerFea);
//    private:
        /***
         * 重新连接节点
         * @return 连接状态
         */
        bool resetConn();
        /***
         * 等待节点启动,阻塞
         * @return
         */
        bool waitNode();
    public:
    private:
        //存储路径
        std::string m_path;
        std::string m_nodeName;
        std::string m_cNodeName;
        std::string m_pName;
        std::string m_cookie;
        std::string m_clusterID;
        std::string m_clusterName;
        bool m_ret;
        int m_fd;
        std::mutex m_mutex;
    };
    static int my_listen(int port);
}
#endif //SYNCDBTOOL_ERLANGDBTOOL_H
syncDBTool/ErlangDbTool.hpp
New file
@@ -0,0 +1,1555 @@
////
//// Created by ps on 8/6/18.
////
//
//#ifndef UNTITLED_ERLANGTOOL_HPP
//#define UNTITLED_ERLANGTOOL_HPP
//
//#include <iostream>
//#include <cstring>
//#include <unistd.h>
//
//#include <map>
//#include <vector>
//#include <mutex>
//
//#include <stdio.h>
//#include <stdarg.h>
//#include <jsoncpp/json/json.h>
//#include <arpa/inet.h>
//
//#include "erl_interface.h"
//#include "ei.h"
//
//#include "SyncDB.hpp"
//
//#define TIMEOUT (5000)
//
////#TODO 多线程优化
//namespace ErlangTool {
//
//    static int m_loop = 0;
//    //map<uuid,人脸特征信息>
//    typedef std::map<std::string, SyncDB::Feature_Info> map_FaceDataCache;
//    //map<uuid,设备信息>
//    typedef std::map<std::string, SyncDB::Device_Info> map_DevDataCache;
//    //map<表名,底库表信息>
//    typedef std::map<std::string, SyncDB::Table_Info> map_TabDataCache;
//    //map<表名,黑白名单类型>
//    typedef std::map<std::string, SyncDB::Bw_Info> map_BwDataCache;
//
//    //c++11 互斥锁
//    // LockG(Parma);
//    typedef std::lock_guard<std::mutex> LockG;
//
//    /***
//     * 判断文件夹路径是否存在,不存在则创建
//     * @param dir 文件路径
//     * @param mkdir_flag 是否创建创建文件夹
//     * @return 是否成功
//     */
//    static bool dir_file_exists(std::string dir, bool mkdir_flag = true) {
//        int state = access(dir.c_str(), R_OK | W_OK); // 头文件 #include <unistd.h>
//        if (state == 0) {
//            //#todo
//            INFO("file exist");
//            return true;
//        } else if (mkdir_flag) {
//            dir = "mkdir -p " + dir;
//            system(dir.c_str()); // 调用linux系统命令创建文件
//            //#todo
//            return true;
//        } else {
//            return false;
//        }
//    }
//
//    /***
//     * 测试节点是否启动
//     * @param nodeName 节点名称
//     * @param cookie   节点cookie
//     * @return 启动状态
//     */
//    static bool pingNode(const std::string &nodeName, const std::string &cookie) {
//        int fd = -1;
//        int ret = -1;
//        erl_init(NULL, 0);
//        struct in_addr addr;
//        addr.s_addr = inet_addr("127.0.0.1");
//        if (erl_connect_xinit("idril", "cnode", "cnode@127.0.0.1", &addr, cookie.c_str(), 0) == -1) {
//            ERR("");
//            erl_err_quit("erl_connect_xinit");
//            return false;
//        }
//
//        fd = erl_connect(const_cast<char *>(nodeName.c_str()));
//        if (0 > fd) {
////            erl_err_quit("erl_connect");
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << " error " << fd << std::endl;
//            return false;
//        }
////        std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << fd << std::endl;
//        erl_close_connection(fd);
//        return true;
//    }
//
//    /***
//     * 检查ETERM的数据类型
//     * @param elemen
//     * @return 返回数据类型
//     */
//    static int checkETERMType(ETERM *elemen) {
//        if (elemen == NULL) {
//            return -1;
//        }
//        switch (ERL_TYPE(elemen)) {
//            case ERL_UNDEF:
//                return ERL_UNDEF;
//            case ERL_INTEGER:
//                INFO("value is a int: " << ERL_INT_VALUE(elemen));
//                return ERL_INTEGER;
//            case ERL_U_INTEGER:
//                break;
//            case ERL_ATOM: {
////                int atomSize = ERL_ATOM_SIZE(elemen);
////                char *atomValue = ERL_ATOM_PTR(elemen);
////                printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                return ERL_ATOM;
//            }
//            case ERL_PID:
//                break;
//            case ERL_PORT:
//                break;
//            case ERL_REF:
//                break;
//            case ERL_LIST:
////                printf("value is a list:%s\n", erl_iolist_to_string(elemen));
//                return ERL_LIST;
//            case ERL_NIL:
//                return ERL_EMPTY_LIST;
//            case ERL_TUPLE:
//                INFO("value is a tupe: " << ERL_ATOM_PTR(erl_element(1, elemen)));
//                return ERL_TUPLE;
//            case ERL_BINARY:
//                break;
//            case ERL_FLOAT:
//                break;
//            case ERL_VARIABLE:
//                break;
//            case ERL_SMALL_BIG:
//                break;
//            case ERL_U_SMALL_BIG:
//                break;
//            case ERL_FUNCTION:
//                break;
//            case ERL_BIG:
//                break;
//            case ERL_LONGLONG:
//                break;
//            case ERL_U_LONGLONG:
//                break;
//            default:
//                ERR("[Client] got a value but now checked\n\r");
//                //#todo morechuli
//        }
//        return -1;
//    }
//
//    static void erlangFreeEterm(int count, ...) {
//        va_list args;
//        va_start(args, count);
//        for (int i = 0; i < count; ++i) {
//            auto test = va_arg(args, ETERM*);
//            erl_free_compound(test);
////            if (test != NULL)
////                erl_free_compound(test);
////            else{
////
////            }
//        }
//    }
//
//
//    /***
//     * Erlang交互工具
//     * #todo map保存到内存?
//     */
//    class ErlangDbTool {
//    public:
//        ErlangDbTool() : m_fd(-1) {
//
//        }
//
//        /***
//         * 初始化节点(zhizuo chaxun shiyong)
//         * @param nodeName 节点名称
//         * @param cookie 集群cookie
//         */
//        ErlangDbTool(const std::string &nodeName, const std::string &cookie, const std::string &pName) :
//            m_fd(-1), m_path(""), m_nodeName(nodeName), m_cookie(cookie), m_pName(pName) {
//            initCNode();
//        }
//
//        /***
//         * 初始化节点
//         * @param path 节点数据库保存路径
//         * @param nodeName 节点名称
//         * @param cookie 集群cookie
//         */
//        ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
//                     const std::string &pName) : m_fd(-1), m_path(path), m_nodeName(nodeName), m_cookie(cookie),
//                                                 m_pName(pName) {
//            initCNode();
//        }
//
//        //clusterID clusterName
//        /***
//         * 初始化节点
//         * @param path 节点数据库保存路径
//         * @param nodeName 节点名称
//         * @param cookie 集群cookie
//         * @param clusterID 集群id
//         * @param clusterName 集群名称
//         */
//        ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
//                     const std::string &clusterID, const std::string &clusterName) :
//            m_fd(-1), m_path(path), m_nodeName(nodeName), m_cookie(cookie), m_clusterID(clusterID),
//            m_clusterName(clusterName) {
//
//        }
//
//        //clusterID clusterName
//        /***
//         * 初始化节点
//         * @param path 节点数据库保存路径
//         * @param nodeName 节点名称
//         * @param cookie 集群cookie
//         * @param clusterID 集群id
//         * @param clusterName 集群名称
//         * @param pName c节点标识名
//         */
//        ErlangDbTool(const std::string &path, const std::string &nodeName, const std::string &cookie,
//                     const std::string &clusterID, const std::string &clusterName, const std::string &pName) :
//            m_fd(-1), m_path(path), m_nodeName(nodeName), m_cookie(cookie), m_clusterID(clusterID),
//            m_clusterName(clusterName), m_pName(pName) {
//            initCNode();
//        }
//
//    private:
//
//        void initCNode() {
//            erl_init(NULL, 0);
//            struct in_addr addr;
//            //#todo
//            addr.s_addr = inet_addr("127.0.0.1");
//            std::string t_cNodeName(m_pName);
//            t_cNodeName.append("@127.0.0.1");
//            //m_pName
//            if (erl_connect_xinit("idril", const_cast<char *>(m_pName.c_str()), const_cast<char *>(t_cNodeName.c_str()),
//                                  &addr, const_cast<char *>(m_cookie.c_str()), 0) == -1) {
//                ERR("erl_connect_xinit error" << m_pName << " " << t_cNodeName << " " << m_cookie);
//                erl_err_quit("erl_connect_xinit");
//            } else {
//                ERR("erl_connect_xinit ok" << m_pName << " " << t_cNodeName << " " << m_cookie);
//            }
//        }
//
//    public:
//
//        virtual ~ErlangDbTool() {
//            erl_close_connection(m_fd);
//        }
//
//        //#todo setCNodeName
//
//        //#todo sendMessage
//
//        /***
//         * 启动erlang节点
//         * @return 启动状态
//         */
//        int initErlang() {
//            if (m_nodeName == "") {
//                ERR("m_nodeName is null ");
//                return 3;
//            }
//            m_ret = pingNode(m_nodeName, m_cookie);
//            if (!m_ret) {
//                if (dir_file_exists(m_path, true)) {
//                    std::string cmd = std::string("cd " + m_path + " && erl -name " + m_nodeName + " -setcookie  "
//                                                  + m_cookie + " -mnesia dir '\"" + m_path +
//                                                  "\"' -detached -noshell");// >>log
//                    std::cout << cmd << std::endl;
//                    system(cmd.c_str());
//                    std::cout << m_ret << std::endl;
//                    m_ret = waitNode();
//                    return m_ret;
//                } else {
//                    ERR("create file faile ");
//                    return 0;
//                }
//            } else {
//                INFO("node is running");
//                return 2;
//            }
//        }
//
//        std::string getConfigJsonString() {
//            Json::Value t_json;
//            Json::FastWriter writer;
//
//            t_json["\"path\""] = "\"" + m_path + "\"";
//            t_json["\"nodeName\""] = "\"" + m_nodeName + "\"";
//            t_json["\"cookie\""] = "\"" + m_cookie + "\"";
//            t_json["\"clusterID\""] = "\"" + m_clusterID + "\"";
//            t_json["\"clusterName\""] = "\"" + m_clusterName + "\"";
//
//            std::string str_json = writer.write(t_json);
//
//            return str_json.substr(0, str_json.length() - 1);
//        }
//
//        /***
//         * 启动节点数据库
//         * 新节点自动创建数据库
//         * @param FatherNodeName 第一个节点无需传入此参数,其他节点需要传入引导节点的名称
//         * @param DeviceName 设备名称
//         * @param DevAdd 设备地址
//         * @return
//         */
//        bool startNodeDb(std::string FatherNodeName, std::string DeviceId = "", std::string DevAdd = "DevAddress") {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (m_ret) {
////                DeviceName = DeviceName.empty() ? m_nodeName : DeviceName;
//            } else {
//                //#todo error message
//                ERR(" error " << m_ret << "  " << m_fd);
//                return false;
//            }
//
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
//            ETERM *arrlist[5];
//            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
//            arrlist[1] = erl_mk_atom(FatherNodeName.c_str());
//            arrlist[2] = erl_mk_atom(DeviceId.c_str());
//            arrlist[3] = erl_mk_atom(m_clusterID.c_str());
//            arrlist[4] = erl_mk_atom(m_clusterName.c_str());
//            ETERM *list = erl_mk_list(arrlist, 5);
//
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
////            erl_rpc(m_fd, "syncDB", "startNode", list);
//            int ret = -1;
//            ret = erl_rpc_to(m_fd, "syncDB", "startNode", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, 9000000000, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//
//                    tuplep[0] = erl_element(2, emsg.msg);
//                    key = erl_element(1, tuplep[0]);
//                    value = erl_element(2, tuplep[0]);
////                printf("key:%s\n", ERL_ATOM_PTR(key));
//                    switch (checkETERMType(value)) {
//                        case ERL_ATOM: {
//                            int atomSize = ERL_ATOM_SIZE(value);
//                            char *atomValue = ERL_ATOM_PTR(value);
//                            t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
////                        printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                            break;
//                        }
//                        default:
//                            ERR("error add case todo \n\r");
//                    }
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
////                        erlangFreeEterm(7, emsg.to, emsg.msg, emsg.from, list, key, value, tuplep[0]);
////                        erl_eterm_release();
//                        return true;
//                    } //if end
//                    else {
//                        INFO(" t_results size is " << t_results.size());
//                        for (auto &item : t_results) {
//                            INFO("item is " << item.first << "  " << item.second);
//                        }
//                    }
//                }//ret == ERL_MSG end
//                else {
//                    ERR(" ret is " << ret);
//
//                }
//            } //ret == ERL_TICK
//
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            return false;
//        }
//
//        /***
//         * 删除节点数据库,同时删除本地文件
//         * @return 返回状态
//         */
//        bool removeNode() {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return false;
//            }
//            int ret = -1;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
////            ETERM *arrlist[1];
////            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
//            ETERM *list = erl_mk_empty_list();// (arrlist, 0);
//
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
//            ret = erl_rpc_to(m_fd, "syncDB", "removeNode", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//
//                    tuplep[0] = erl_element(2, emsg.msg);
//                    key = erl_element(1, tuplep[0]);
//                    value = erl_element(2, tuplep[0]);
////                printf("key:%s\n", ERL_ATOM_PTR(key));
//                    switch (checkETERMType(value)) {
//                        case ERL_ATOM: {
//                            int atomSize = ERL_ATOM_SIZE(value);
//                            char *atomValue = ERL_ATOM_PTR(value);
//                            t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
////                        printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                            break;
//                        }
//                        default:
//                            printf("error add case todo \n\r");
//                    }
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        //删除本地文件
//                        std::string cmd = std::string("rm -rf ").append(m_path);
//                        //#todo
//                        system(cmd.c_str());
//                        erlangFreeEterm(7, emsg.to, emsg.msg, emsg.from, list, key, value, tuplep[0]);
//                        erl_eterm_release();
//                        return true;
//                    } //if end
//                } //ret == ERL_MSG end
//            } //ret == ERL_TICK
//
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            return false;
//        }
//
//
//        bool modifyCluName(std::string CluId, std::string CluName) {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return false;
//            }
//            ErlMessage emsg;             /* Incoming message */
//            int ret = -1;
//            ETERM *arrlist[2];
//            arrlist[0] = erl_mk_atom(CluId.c_str());
//            arrlist[1] = erl_mk_atom(CluName.c_str());
//            ETERM *list = erl_mk_list(arrlist, 2);
//
//            ret = erl_rpc_to(m_fd, "syncDB", "modifyCluName", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//
//                    ETERM *tail_list;
//                    ETERM *list_ret[1000], *arr_ret[2];
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
//                    list_ret[0] = erl_hd(arr_ret[0]);
//                    tail_list = erl_tl(arr_ret[0]);
//                    for (int i = 0; i < erlLength; i++) {
//                        if (i > 0) {
//                            list_ret[i] = erl_hd(tail_list);
//                            tail_list = erl_tl(tail_list);
//                        }
////                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        key = erl_element(1, list_ret[i]);
//                        value = erl_element(2, list_ret[i]);
////                    printf("key:%s\n", ERL_ATOM_PTR(key));
//
//                        switch (checkETERMType(value)) {
//                            case ERL_ATOM: {
//                                int atomSize = ERL_ATOM_SIZE(value);
//                                char *atomValue = ERL_ATOM_PTR(value);
//                                printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                                t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                                break;
//                            }
//                            default:
//                                printf("error add case todo \n\r");
//                        }
//                        erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
//
//                    }
//                    erlangFreeEterm(2, tail_list, arr_ret[0]);
//                    erl_eterm_release();
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        return true;
//                    }
//                }
//            }
//            erl_free_array(arrlist, 2);
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            erl_eterm_release();
//            return false;
//        }
//
//
//        /***
//         * 查找在线节点信息
//         * #TODO 有一个小bug
//         * device_info.create_by会被重置
//         * @return 节点集合信息
//         */
//        map_DevDataCache findAllNode() {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//
//                return map_DevDataCache();
//            }
//            map_DevDataCache devDataCache;
//            int ret = -1;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
////            ETERM *arrlist[0];
////            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
//            ETERM *list = erl_mk_empty_list();//erl_mk_list(arrlist, 0);
//
//            ret = erl_rpc_to(m_fd, "syncDB", "findAllNode", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    ETERM *key, *value;
//                    ETERM *tuplep[20];
//                    ETERM *arr_ret[2], *list_ret[1000];
//                    ETERM *tail_list, *tail_tuple;
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                        int erlLength = erl_length(arr_ret[0]);
////                    printf("arr_ret[0]:%d\n", erlLength);
//                        list_ret[0] = erl_hd(arr_ret[0]);
//                        tail_list = erl_tl(arr_ret[0]);
//                        for (int i = 0; i < erlLength; i++) {
//                            if (i > 0) {
//                                list_ret[i] = erl_hd(tail_list);
//                                tail_list = erl_tl(tail_list);
//                            }
//                            if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                                SyncDB::Device_Info device_info;
//                                int erlLength1 = erl_length(list_ret[i]);
////                            printf("list_ret[%d]:%d\n", i, erlLength1);
//                                tuplep[0] = erl_hd(list_ret[i]);
//                                tail_tuple = erl_tl(list_ret[i]);
//
//                                for (int j = 0; j < erlLength1; j++) {
//                                    if (j > 0) {
//                                        tuplep[j] = erl_hd(tail_tuple);
//                                        tail_tuple = erl_tl(tail_tuple);
//                                    }
//                                    key = erl_element(1, tuplep[j]);
//                                    value = erl_element(2, tuplep[j]);
////                                printf("key:%s\n", erl_iolist_to_string(key));
//                                    switch (checkETERMType(value)) {
//                                        case ERL_ATOM: {
//                                            device_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                            break;
//                                        }
//                                        case ERL_INTEGER: {
//                                            device_info.setValue(erl_iolist_to_string(key),
//                                                                 std::to_string(ERL_INT_VALUE(value)));
//                                            break;
//                                        }
//                                        case ERL_LIST: {
//                                            device_info.setValue(erl_iolist_to_string(key),
//                                                                 erl_iolist_to_string(value));
//                                            break;
//                                        }
//                                        default:
//                                            printf("error add case todo %d\n\r", checkETERMType(value));
//                                    }
//                                    erlangFreeEterm(3, key, value, tuplep[j]);
//                                }
////                            printf("\none list end\n\n\n\n");
//                                // #todo this is have a bug
////                                device_info.create_by = "";
//                                devDataCache.insert(std::make_pair(device_info.uuid, device_info));
//                                erlangFreeEterm(1, tail_tuple);
//                            } else {
//                                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
//                                          << checkETERMType(arr_ret[0])
//                                          << "  "
//                                          << std::endl;
//                            }
//                            erlangFreeEterm(1, list_ret[i]);
//                        }
//
//                        erlangFreeEterm(6, emsg.to, emsg.msg, emsg.from, list, tail_list, arr_ret[0]);
//                        erl_eterm_release();
//                        return devDataCache;
//                    } else {
//                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << checkETERMType(arr_ret[0])
//                                  << "  "
//                                  << std::endl;
//                    }
//                }
//            } //ret == ERL_TICK end
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            erl_eterm_release();
//            return map_DevDataCache();
//        }
//
//        /***
//         * 创建底库表
//         * @param TableType car||person
//         * @param TableName
//         * @param SyncType true 1||false 0
//         * @param BwType   "Black"1||"White"0
//         * @return 创建状态
//         */
//        bool createDatabase(std::string TableType, std::string TableName, bool SyncType, std::string BwType,
//                            std::string StartTime = "", std::string EndTime = "") {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return false;
//            }
//            std::string NewTableName = ((!SyncType) && TableName.find("lt_")) ? std::string("lt_").append(TableName)
//                                                                              : TableName;
//
//            ErlMessage emsg;             /* Incoming message */
//            int ret = -1;
//            ETERM *arrlist[6];
//            arrlist[0] = erl_mk_atom(TableType.c_str());
//            arrlist[1] = erl_mk_atom(NewTableName.c_str());
//            auto str = std::to_string(SyncType);
//            arrlist[2] = erl_mk_atom(str.c_str());
//            arrlist[3] = erl_mk_atom(BwType.c_str());
//            arrlist[4] = erl_mk_atom(StartTime.c_str());
//            arrlist[5] = erl_mk_atom(EndTime.c_str());
//            ETERM *list = erl_mk_list(arrlist, 6);
//
//            ret = erl_rpc_to(m_fd, "syncDB", "createDatabase", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//
//                    ETERM *tail_list;
//                    ETERM *list_ret[1000], *arr_ret[2];
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
//                    list_ret[0] = erl_hd(arr_ret[0]);
//                    tail_list = erl_tl(arr_ret[0]);
//                    for (int i = 0; i < erlLength; i++) {
//                        if (i > 0) {
//                            list_ret[i] = erl_hd(tail_list);
//                            tail_list = erl_tl(tail_list);
//                        }
////                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        key = erl_element(1, list_ret[i]);
//                        value = erl_element(2, list_ret[i]);
////                    printf("key:%s\n", ERL_ATOM_PTR(key));
//
//                        switch (checkETERMType(value)) {
//                            case ERL_ATOM: {
////                            int atomSize = ERL_ATOM_SIZE(value);
//                                char *atomValue = ERL_ATOM_PTR(value);
////                            printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                                t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                                break;
//                            }
//                            default:
//                                printf("error add case todo \n\r");
//                        }
//                        erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
//
//                    }
//                    erlangFreeEterm(2, tail_list, arr_ret[0]);
//                    erl_eterm_release();
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        return true;
//                    }
//                }
//            }
//            erl_free_array(arrlist, 6);
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            erl_eterm_release();
//            return false;
//        }
//
//        /***
//         * 更新底库表
//         * @param TableType car||person
//         * @param TableName
//         * @param SyncType true 1||false 0
//         * @param BwType   "white"0||"black"1
//         * @return 创建状态
//         */
//        bool updateDatabase(std::string UUID, std::string TableType, std::string TableName, bool SyncType,
//                            std::string BwType, std::string StartTime = "", std::string EndTime = "") {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return false;
//            }
//            std::string NewTableName = ((!SyncType) && TableName.find("lt_")) ? std::string("lt_").append(TableName)
//                                                                              : TableName;
//
//            ErlMessage emsg;             /* Incoming message */
//            int ret = -1;
//            ETERM *arrlist[7];
//            arrlist[0] = erl_mk_atom(UUID.c_str());
//            arrlist[1] = erl_mk_atom(TableType.c_str());
//            arrlist[2] = erl_mk_atom(NewTableName.c_str());
//            auto str = std::to_string(SyncType);
//            arrlist[3] = erl_mk_atom(str.c_str());
//            arrlist[4] = erl_mk_atom(BwType.c_str());
//            arrlist[5] = erl_mk_atom(StartTime.c_str());
//            arrlist[6] = erl_mk_atom(EndTime.c_str());
//            ETERM *list = erl_mk_list(arrlist, 7);
//
//            ret = erl_rpc_to(m_fd, "syncDB", "updateDatabase", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//
//                    ETERM *tail_list;
//                    ETERM *list_ret[1000], *arr_ret[2];
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
//                    list_ret[0] = erl_hd(arr_ret[0]);
//                    tail_list = erl_tl(arr_ret[0]);
//                    for (int i = 0; i < erlLength; i++) {
//                        if (i > 0) {
//                            list_ret[i] = erl_hd(tail_list);
//                            tail_list = erl_tl(tail_list);
//                        }
////                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        key = erl_element(1, list_ret[i]);
//                        value = erl_element(2, list_ret[i]);
////                    printf("key:%s\n", ERL_ATOM_PTR(key));
//
//                        switch (checkETERMType(value)) {
//                            case ERL_ATOM: {
////                            int atomSize = ERL_ATOM_SIZE(value);
//                                char *atomValue = ERL_ATOM_PTR(value);
////                            printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                                t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                                break;
//                            }
//                            default:
//                                printf("error add case todo \n\r");
//                        }
//                        erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
//                    }
//                    erlangFreeEterm(2, tail_list, arr_ret[0]);
//                    erl_eterm_release();
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        return true;
//                    }
//                }
//            }
//            erl_free_array(arrlist, 7);
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            erl_eterm_release();
//            return false;
//        }
//
//        /***
//         * 删除数据表
//         * @param TableType car||person
//         * @param TableName biaoming
//         * @param SyncType true 1||false 0
//         * @return
//         */
//        bool deleteDatabase(std::string TableType, std::string TableName, bool SyncType) {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                ERR(" error " << m_ret << "  " << m_fd);
//                return false;
//            }
//            std::string NewTableName = ((!SyncType) && TableName.find("lt_")) ? std::string("lt_").append(TableName)
//                                                                              : TableName;
//
//            ErlMessage emsg;             /* Incoming message */
//            int ret = -1;
//
//            ETERM *arrlist[2];
//            arrlist[0] = erl_mk_atom(TableType.c_str());
//            arrlist[1] = erl_mk_atom(NewTableName.c_str());
//            ETERM *list = erl_mk_list(arrlist, 2);
//
//            ret = erl_rpc_to(m_fd, "syncDB", "deleteDatabase", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//                    ETERM *tail_list;
//                    ETERM *list_ret[10], *arr_ret[2];
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
//                    list_ret[0] = erl_hd(arr_ret[0]);
//                    tail_list = erl_tl(arr_ret[0]);
//                    for (int i = 0; i < erlLength; i++) {
//                        if (i > 0) {
//                            list_ret[i] = erl_hd(tail_list);
//                            tail_list = erl_tl(tail_list);
//                        }
////                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        key = erl_element(1, list_ret[i]);
//                        value = erl_element(2, list_ret[i]);
////                    printf("key:%s\n", ERL_ATOM_PTR(key));
//                        switch (checkETERMType(value)) {
//                            case ERL_ATOM: {
//                                int atomSize = ERL_ATOM_SIZE(value);
//                                char *atomValue = ERL_ATOM_PTR(value);
//                                t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
//                                printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                                break;
//                            }
//                            default:
//                                printf("error add case todo \n\r");
//                        }
//                        erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
//                    }
//                    erlangFreeEterm(2, tail_list, arr_ret[0]);
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        return true;
//                    }
//                }
//            }
//            erl_free_array(arrlist, 2);
//            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            return false;
//        }
//
//        /***
//         * 查询所有数据表
//         * @return
//         */
//        map_TabDataCache findAllDatabase() {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            map_TabDataCache tabDataCache;
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return tabDataCache;
//            }
//            int ret = -1;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
////            ETERM *arrlist[0];
////            arrlist[0] = erl_mk_atom(m_nodeName.c_str());
//            ETERM *list = erl_mk_empty_list();//erl_mk_list(arrlist, 0);
//
//            std::cout << __FILE__ << __FUNCTION__ << __LINE__ << "  " << m_fd << std::endl;
//            ret = erl_rpc_to(m_fd, "syncDB", "findAllDatabase", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    ETERM *key, *value;
//                    ETERM *tuplep[20];
//                    ETERM *arr_ret[2], *list_ret[1000];
//                    ETERM *tail_list, *tail_tuple;
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                        int erlLength = erl_length(arr_ret[0]);
//                        list_ret[0] = erl_hd(arr_ret[0]);
//                        tail_list = erl_tl(arr_ret[0]);
//                        for (int i = 0; i < erlLength; i++) {
//                            if (i > 0) {
//                                list_ret[i] = erl_hd(tail_list);
//                                tail_list = erl_tl(tail_list);
//                            }
//                            if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                                SyncDB::Table_Info table_info;
//                                int erlLength1 = erl_length(list_ret[i]);
//                                tuplep[0] = erl_hd(list_ret[i]);
//                                tail_tuple = erl_tl(list_ret[i]);
//
//                                for (int j = 0; j < erlLength1; j++) {
//                                    if (j > 0) {
//                                        tuplep[j] = erl_hd(tail_tuple);
//                                        tail_tuple = erl_tl(tail_tuple);
//                                    }
//                                    key = erl_element(1, tuplep[j]);
//                                    value = erl_element(2, tuplep[j]);
//                                    switch (checkETERMType(value)) {
//                                        case ERL_ATOM: {
//                                            table_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                            break;
//                                        }
//                                        case ERL_INTEGER: {
//                                            table_info.setValue(erl_iolist_to_string(key),
//                                                                std::to_string(ERL_INT_VALUE(value)));
//                                            break;
//                                        }
//                                        case ERL_LIST: {
//                                            table_info.setValue(erl_iolist_to_string(key),
//                                                                erl_iolist_to_string(value));
//                                            break;
//                                        }
//                                        default:
//                                            printf("error add case todo %d\n\r", checkETERMType(value));
//                                    }
////                                    erlangFreeEterm(3, key, value, tuplep[j]);
//                                }
////                                erlangFreeEterm(2, tail_tuple, list_ret[i]);
//
//                                // #todo this is have a bug
////                                table_info.create_by = "";
//                                tabDataCache.insert(std::make_pair(table_info.tableName, table_info));
//                            } else {
//                                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
//                                          << checkETERMType(arr_ret[0])
//                                          << "  "
//                                          << std::endl;
//                            }
//                        }
////                        erlangFreeEterm(2, tail_list, arr_ret[0]);
//                        return tabDataCache; //ok
//                    } else {
//                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << checkETERMType(arr_ret[0])
//                                  << "  "
//                                  << std::endl;
//                    }
//                }
//            }
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            return tabDataCache; //not ok
//        }
//
//        /***
//         * 查询所有表的黑白名单类型
//         * @return
//         */
//        map_BwDataCache findAllTypeInfo() {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return map_BwDataCache();
//            }
//            map_BwDataCache bwDataCache;
//            int ret = -1;
//            ErlMessage emsg;    /* Incoming message */
//            ETERM *list = erl_mk_empty_list();//erl_mk_list(arrlist, 0);
//
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
//            ret = erl_rpc_to(m_fd, "syncDB", "findAllTypeInfo", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    ETERM *key, *value;
//                    ETERM *tuplep[20];
//                    ETERM *arr_ret[2], *list_ret[1000];
//                    ETERM *tail_list, *tail_tuple;
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                        int erlLength = erl_length(arr_ret[0]);
////                    printf("arr_ret[0]:%d\n", erlLength);
//                        list_ret[0] = erl_hd(arr_ret[0]);
//                        tail_list = erl_tl(arr_ret[0]);
//                        for (int i = 0; i < erlLength; i++) {
//                            if (i > 0) {
//                                list_ret[i] = erl_hd(tail_list);
//                                tail_list = erl_tl(tail_list);
//                            }
//                            if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                                SyncDB::Bw_Info bw_info;
//                                int erlLength1 = erl_length(list_ret[i]);
////                            printf("list_ret[%d]:%d\n", i, erlLength1);
//                                tuplep[0] = erl_hd(list_ret[i]);
//                                tail_tuple = erl_tl(list_ret[i]);
//
//                                for (int j = 0; j < erlLength1; j++) {
//                                    if (j > 0) {
//                                        tuplep[j] = erl_hd(tail_tuple);
//                                        tail_tuple = erl_tl(tail_tuple);
//                                    }
//                                    key = erl_element(1, tuplep[j]);
//                                    value = erl_element(2, tuplep[j]);
////                                printf("key:%s\n", erl_iolist_to_string(key));
//                                    switch (checkETERMType(value)) {
//                                        case ERL_ATOM: {
//                                            bw_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                            break;
//                                        }
//                                        case ERL_INTEGER: {
//                                            bw_info.setValue(erl_iolist_to_string(key),
//                                                             std::to_string(ERL_INT_VALUE(value)));
//                                            break;
//                                        }
//                                        case ERL_LIST: {
//                                            bw_info.setValue(erl_iolist_to_string(key),
//                                                             erl_iolist_to_string(value));
//                                            break;
//                                        }
//                                        default:
//                                            printf("error add case todo %d\n\r", checkETERMType(value));
//                                    }
////                                    erlangFreeEterm(3, key, value, tuplep[j]);
//                                }
////                                erlangFreeEterm(2, tail_tuple, list_ret[i]);
////                            printf("\none list end\n\n\n\n");
//                                // #todo this is have a bug
////                            bw_info.create_by = "";
//                                bwDataCache.insert(std::make_pair(bw_info.tableName, bw_info));
//                            } else {
//                                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
//                                          << checkETERMType(arr_ret[0])
//                                          << "  "
//                                          << std::endl;
//                            }
//                        }
////                        erlangFreeEterm(2, tail_list, arr_ret[0]);
//                        return bwDataCache;//ok
//                    } else {
//                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << checkETERMType(arr_ret[0])
//                                  << "  "
//                                  << std::endl;
//                    }
//                }
//            }
////            erlangFreeEterm(4, emsg.to, emsg.msg, emsg.from, list);
//            return map_BwDataCache();
//        }
//
//        /***
//         * 增加人员
//         * @param UUID  out
//         * @param TableName
//         * @param Feature
//         * @param PersonName
//         * @param Age
//         * @param Sex
//         * @param IdCard
//         * @param PhoneNum
//         * @return
//         */
//        bool addPerson(std::string &UUID, std::string TableName, std::string Feature, std::string ImgUrl = " ",
//                       std::string IdCard = " ", std::string PersonName = " ", std::string Age = " ",
//                       std::string Sex = " ", std::string PhoneNum = " ") {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << " "
//                          << Feature << std::endl;
//                return false;
//            }
//            int ret;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
//            ETERM *arrlist[9];
//            arrlist[0] = erl_mk_atom(TableName.c_str());
//            arrlist[1] = erl_mk_atom(PersonName.c_str());
//            arrlist[2] = erl_mk_atom(Age.c_str());
//            arrlist[3] = erl_mk_atom(Sex.c_str());
//            arrlist[4] = erl_mk_atom(IdCard.c_str());
//            arrlist[5] = erl_mk_atom(PhoneNum.c_str());
//            arrlist[6] = erl_mk_atom(ImgUrl.c_str());
//            arrlist[7] = erl_mk_atom(UUID.c_str());
//            arrlist[8] = erl_mk_string(Feature.c_str());
//
//            ETERM *list = erl_mk_list(arrlist, 9);
//            ret = erl_rpc_to(m_fd, "syncDB", "addPersonData", list);
//            if (ret == ERL_TICK) {
//
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    ETERM *value;
//                    value = erl_element(2, emsg.msg);
//                    switch (checkETERMType(value)) {
//                        case ERL_LIST: {
//                            UUID = std::string(erl_iolist_to_string(value));
//                            break;
//                        }
//                        case ERL_ATOM: {
//                            UUID = std::string(ERL_ATOM_PTR(value));
//                            break;
//                        }
//                        default:
//                            printf("error add case todo \n\r");
//                    }
//                    erl_free_term(value);
//                    if (UUID.size() > 0) {
//                        erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[8]);
//                        erl_free_array(arrlist, 8);
//                        erl_eterm_release();
//                        return true;
//                    }
//                }
//            }
//            erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[8]);
//            erl_free_array(arrlist, 8);
//            erl_eterm_release();
//            return false;
//        }
//
//        /***
//         * 删除人员
//         * @param UUID
//         * @param TableName
//         * @return
//         */
//        bool delPerson(std::string UUID, std::string TableName) {
//            LockG lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << " "
//                          << std::endl;
//                return false;
//            }
//            int ret;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
//            ETERM *arrlist[2];
//            arrlist[0] = erl_mk_atom(TableName.c_str());
//            arrlist[1] = erl_mk_atom(UUID.c_str());
//
//            ETERM *list = erl_mk_list(arrlist, 2);
//            ret = erl_rpc_to(m_fd, "syncDB", "deletePersonData", list);
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    std::map<std::string, std::string> t_results;
//                    ETERM *tail_list;
//                    ETERM *list_ret[10], *arr_ret[2];
//                    ETERM *key, *value;
//                    ETERM *tuplep[6];
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    int erlLength = erl_length(arr_ret[0]);
//                    printf("arr_ret[0]:%d\n", erlLength);
//                    list_ret[0] = erl_hd(arr_ret[0]);
//                    tail_list = erl_tl(arr_ret[0]);
//                    for (int i = 0; i < erlLength; i++) {
//                        if (i > 0) {
//                            list_ret[i] = erl_hd(tail_list);
//                            tail_list = erl_tl(tail_list);
//                        }
////                    printf("list_ret[%d]:%d\n", i, erl_length(list_ret[i]));
//                        tuplep[0] = erl_hd(list_ret[i]);
//                        key = erl_element(1, list_ret[i]);
//                        value = erl_element(2, list_ret[i]);
////                    printf("key:%s\n", ERL_ATOM_PTR(key));
//                        switch (checkETERMType(value)) {
//                            case ERL_ATOM: {
//                                int atomSize = ERL_ATOM_SIZE(value);
//                                char *atomValue = ERL_ATOM_PTR(value);
//                                t_results.insert(std::make_pair(ERL_ATOM_PTR(key), atomValue));
////                                printf("value is a atom: atomSize:%d, atomValue:%s \n\r", atomSize, atomValue);
//                                break;
//                            }
//                            default:
//                                printf("error add case todo \n\r");
//                        }
//                        erlangFreeEterm(4, key, value, tuplep[0], list_ret[i]);
//                    }
//                    erlangFreeEterm(2, tail_list, arr_ret[0]);
//                    auto it = t_results.find("atomic");
//                    if (t_results.size() > 0 && t_results.end() != it && it->second == "ok") {
//                        return true;
//                    }
//                }
//            }
//            erlangFreeEterm(4, emsg.msg, emsg.from, emsg.to, list);
//            erl_free_array(arrlist, 2);
//            erl_eterm_release();
//            return false;
//        }
//
//
//        /***
//         * 根据表名加载人脸特征
//         * @param TableName
//         * @return
//         */
//        map_FaceDataCache loadFaceFeaData(std::string TableName) {
//            std::lock_guard<std::mutex> lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return map_FaceDataCache();
//            }
//            map_FaceDataCache dataCache;
//            int ret;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
//            ETERM *arrlist[1];
//            arrlist[0] = erl_mk_atom(TableName.c_str());
//
//            ETERM *list = erl_mk_list(arrlist, 1);
//            ret = erl_rpc_to(m_fd, "syncDB", "loadFaceFeaData", list);
//
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT * 100000, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    ETERM *key, *value;
//                    ETERM *tuplep[20];
//                    ETERM *arr_ret[2], *list_ret[5000];
//                    ETERM *tail_list, *tail_tuple;
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                        int erlLength = erl_length(arr_ret[0]);
////                        printf("arr_ret[0]:%d\n", erlLength);
//                        list_ret[0] = erl_hd(arr_ret[0]);
//                        tail_list = erl_tl(arr_ret[0]);
//                        for (int i = 0; i < erlLength; i++) {
////                            DBG(i);
//                            if (i > 0) {
//                                list_ret[i] = erl_hd(tail_list);
//                                tail_list = erl_tl(tail_list);
//                            }
//                            if (tail_list == NULL)
//                                break;
//                            if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                                SyncDB::Feature_Info feature_info;
////                                feature_info.id = "test";
////                                feature_info.create_by = "";
////                                feature_info.feature ="";
////                                feature_info.update_time = "";
////                                feature_info.create_time = "";
//
//                                int erlLength1 = erl_length(list_ret[i]);
////                                printf("list_ret[%d]:%d\n", i, erlLength1);
//                                tuplep[0] = erl_hd(list_ret[i]);
//                                tail_tuple = erl_tl(list_ret[i]);
//
//                                for (int j = 0; j < erlLength1; j++) {
//                                    if (j > 0) {
//                                        tuplep[j] = erl_hd(tail_tuple);
//                                        tail_tuple = erl_tl(tail_tuple);
//                                    }
//                                    key = erl_element(1, tuplep[j]);
//                                    value = erl_element(2, tuplep[j]);
////                                    printf("key:%s\n", erl_iolist_to_string(key));
//
//                                    switch (checkETERMType(value)) {
//                                        case ERL_ATOM: {
//                                            feature_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                            break;
//                                        }
//                                        case ERL_LIST: {
//                                            feature_info.setValue(erl_iolist_to_string(key),
//                                                                  erl_iolist_to_string(value));
//                                            break;
//                                        }
//                                        default:
//                                            printf("error add case todo %d\n\r", checkETERMType(value));
//                                    }
//
////                                    erlangFreeEterm(2, key, value);
//                                }
////                                printf("\none list end\n\n\n\n");
//                                dataCache.insert(std::move(std::make_pair(feature_info.id, feature_info)));
////                                break;
////                                erlangFreeEterm(1, list_ret[i]);
//                            } else {
//                                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
//                                          << checkETERMType(list_ret[i])
//                                          << "  "
//                                          << std::endl;
//                            }
//                        }
//                        erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//                        erl_eterm_release();
////                        sleep()
//                        return dataCache;
//                    } else {
//                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << checkETERMType(arr_ret[0])
//                                  << "  "
//                                  << std::endl;
//                    }
//                } else {
//                    std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << ret << "  " << std::endl;
//                }
//
//            }
//            erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//            erl_eterm_release();
//            return map_FaceDataCache();
//        };
//
//
//        /***
//         * 根据表名加载人脸特征2
//         * @param TableName
//         * @return
//         */
//        map_FaceDataCache loadFaceFeaData2(std::string TableName) {
//            std::lock_guard<std::mutex> lock(m_mutex);
////            m_mutex.lock();
//            m_ret = resetConn();
//            if (!m_ret) {
//                //#todo error message
//                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << m_ret << "  " << m_fd << std::endl;
//                return map_FaceDataCache();
//            }
//            map_FaceDataCache dataCache;
//            int ret;
//            ErlMessage emsg;    /* Incoming message */
//            //hanshu canshu
//            ETERM *arrlist[1];
//            arrlist[0] = erl_mk_atom(TableName.c_str());
//
//            ETERM *list = erl_mk_list(arrlist, 1);
//            ret = erl_rpc_to(m_fd, "syncDB", "loadFaceFeaData2", list);
//
//            if (ret == ERL_TICK) {
//                ret = erl_rpc_from(m_fd, TIMEOUT * 100000, &emsg);
////                m_mutex.unlock();
//                if (ret == ERL_MSG) {
//                    ETERM *key, *value;
//                    ETERM *tuplep[20];
//                    ETERM *arr_ret[2], *list_ret[5000];
//                    ETERM *tail_list, *tail_tuple;
//                    arr_ret[0] = erl_element(2, emsg.msg);
//                    if (checkETERMType(arr_ret[0]) == ERL_LIST) {
//                        int erlLength = erl_length(arr_ret[0]);
////                        printf("arr_ret[0]:%d\n", erlLength);
//                        list_ret[0] = erl_hd(arr_ret[0]);
//                        tail_list = erl_tl(arr_ret[0]);
//                        for (int i = 0; i < erlLength; i++) {
////                            DBG(i);
//                            if (i > 0) {
//                                list_ret[i] = erl_hd(tail_list);
//                                tail_list = erl_tl(tail_list);
//                            }
//                            if (tail_list == NULL)
//                                break;
//                            if (checkETERMType(list_ret[i]) == ERL_LIST) {
//                                SyncDB::Feature_Info feature_info;
////                                feature_info.id = "test";
////                                feature_info.create_by = "";
////                                feature_info.feature ="";
////                                feature_info.update_time = "";
////                                feature_info.create_time = "";
//
//                                int erlLength1 = erl_length(list_ret[i]);
////                                printf("list_ret[%d]:%d\n", i, erlLength1);
//                                tuplep[0] = erl_hd(list_ret[i]);
//                                tail_tuple = erl_tl(list_ret[i]);
//
//                                for (int j = 0; j < erlLength1; j++) {
//                                    if (j > 0) {
//                                        tuplep[j] = erl_hd(tail_tuple);
//                                        tail_tuple = erl_tl(tail_tuple);
//                                    }
//                                    key = erl_element(1, tuplep[j]);
//                                    value = erl_element(2, tuplep[j]);
////                                    printf("key:%s\n", erl_iolist_to_string(key));
//
//                                    switch (checkETERMType(value)) {
//                                        case ERL_ATOM: {
//                                            feature_info.setValue(erl_iolist_to_string(key), ERL_ATOM_PTR(value));
//                                            break;
//                                        }
//                                        case ERL_LIST: {
//                                            feature_info.setValue(erl_iolist_to_string(key),
//                                                                  erl_iolist_to_string(value));
//                                            break;
//                                        }
//                                        default:
//                                            printf("error add case todo %d\n\r", checkETERMType(value));
//                                    }
//
////                                    erlangFreeEterm(2, key, value);
//                                }
////                                printf("\none list end\n\n\n\n");
//                                dataCache.insert(std::move(std::make_pair(feature_info.id, feature_info)));
////                                break;
////                                erlangFreeEterm(1, list_ret[i]);
//                            } else {
//                                std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " type error "
//                                          << checkETERMType(list_ret[i])
//                                          << "  "
//                                          << std::endl;
//                            }
//                        }
//                        erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//                        erl_eterm_release();
////                        sleep()
//                        return dataCache;
//                    } else {
//                        std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << checkETERMType(arr_ret[0])
//                                  << "  "
//                                  << std::endl;
//                    }
//                } else {
//                    std::cout << __FILE__ << __FUNCTION__ << __LINE__ << " error " << ret << "  " << std::endl;
//                }
//
//            }
//            erlangFreeEterm(5, emsg.msg, emsg.from, emsg.to, list, arrlist[0]);
//            erl_eterm_release();
//            return map_FaceDataCache();
//        };
//
////    private:
//        /***
//         * 重新连接节点
//         * @return 连接状态
//         */
//        bool resetConn() {
//            //#todo
//            if (m_pName.size() <= 0) {
//                srand(time(0));
//                m_loop = rand() % 1000;
//
//                int ret = -1;
//                erl_init(NULL, 0);
////            m_loop %= 10;
////            m_loop++;
//                ret = erl_connect_init(m_loop, const_cast<char *>(m_cookie.c_str()), 0);
//                DBG("node name is   " << m_loop);
//                if (-1 == ret) {
////            erl_err_quit("erl_connect_init");
//                    return false;
//                }
//
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
//                erl_close_connection(m_fd);
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
//                m_fd = erl_connect(const_cast<char *>(m_nodeName.c_str()));
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << m_fd << std::endl;
//                if (0 > m_fd) {
////            erl_err_quit("erl_connect");
//                    return false;
//                }
//                return true;
//            } else {
//                erl_close_connection(m_fd);
//                m_fd = erl_connect(const_cast<char *>(m_nodeName.c_str()));
//                if (0 > m_fd) {
////            erl_err_quit("erl_connect");
////            std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << " error " << fd << std::endl;
////                    ERR("node name is   " << m_loop);
//                    return false;
//                }
////        std::cout << __FILE__ << __FUNCTION__ <<__LINE__ << "  " << fd << std::endl;
//                return true;
//            }
//        }
//
//        /***
//         * 等待节点启动,阻塞
//         * @return
//         */
//        bool waitNode() {
//            std::cout << "start waitNode" << std::endl;
//            int loop = 0;
//            while (!m_ret && loop <= 4000) {
//                m_ret = ErlangTool::pingNode(m_nodeName, m_cookie);
//                if (m_ret) {
////                    std::cout << "startNodeDb" << std::endl;
//                } else {
////                    std::cout << "init failer" << std::endl;
//                    usleep(1000);
//                    loop++;
//                }
//            }
//            std::cout << "start waitNode" << std::endl;
//            return m_ret;
//        }
//
//    public:
//
//    private:
//        //存储路径
//        std::string m_path;
//        std::string m_nodeName;
//        std::string m_pName;
//        std::string m_cookie;
//
//        std::string m_clusterID;
//        std::string m_clusterName;
//
//        bool m_ret;
//        int m_fd;
//
//        std::mutex m_mutex;
//    };
//
//}
//
//#endif //UNTITLED_ERLANGTOOL_HPP
syncDBTool/ShareMemoryTool.hpp
New file
@@ -0,0 +1,259 @@
//
// Created by ps on 8/9/18.
//
#ifndef SYNCDBTOOL_SHAREMEMORYTOOL_HPP
#define SYNCDBTOOL_SHAREMEMORYTOOL_HPP
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <mutex>
#include <iostream>
//#include "SyncDB.hpp"
namespace BISTL {
    using boost::interprocess::managed_shared_memory;
    using boost::interprocess::shared_memory_object;
    using boost::interprocess::create_only;
    using boost::interprocess::open_only;
    using boost::interprocess::open_read_only;
    using boost::interprocess::open_or_create;
    using boost::interprocess::open_copy_on_write;
    using boost::interprocess::allocator;
    //DataType
    using boost::interprocess::basic_string;
    using boost::interprocess::vector;
    using boost::interprocess::map;
    typedef managed_shared_memory::segment_manager segment_manager_t;
    typedef allocator<void, segment_manager_t> void_allocator;
    //vector<int>
    typedef allocator<int, segment_manager_t> int_allocator;
    typedef vector<int, int_allocator> int_vector;
    //vector<vector<int>>
    typedef allocator<int_vector, segment_manager_t> int_vector_allocator;
    typedef vector<int_vector, int_vector_allocator> int_vector_vector;
    //std::string
    typedef allocator<char, segment_manager_t> char_allocator;
    typedef basic_string<char, std::char_traits<char>, char_allocator> char_string;
    typedef std::lock_guard<std::mutex> LockG;
    /***
     * 创建共享内存
     * @param shm_Name 名称
     * @param size 大小
     * @param type 类型
     * @return managed_shared_memory
     */
    static managed_shared_memory
    createSHM(std::string &message, std::string shm_Name, std::size_t size = 4096, int type = 1) {
        try {
            switch (type) {
                case 1:
                    return managed_shared_memory(create_only, shm_Name.c_str(), size * 1024);
                case 2:
                    return managed_shared_memory(open_only, shm_Name.c_str());
                case 3:
                    return managed_shared_memory(open_read_only, shm_Name.c_str());
                case 4:
                    return managed_shared_memory(open_or_create, shm_Name.c_str(), size * 1024);
                case 5:
                    return managed_shared_memory(open_copy_on_write, shm_Name.c_str());
                default:
                    //ERR
                    message = "type is error ";
//                    return managed_shared_memory(create_only, shm_Name.c_str(), size);
            }
        } catch (std::exception ex) {
            message = ex.what();
        }
//        return ;
    }
    //shanchu shm
    /***
     * 删除共享内存
     * @param shm_Name 名称
     * @return 状态
     */
    static bool removeSHM(std::string shm_Name) {
        return shared_memory_object::remove(shm_Name.c_str());
    }
    struct Feature_Info {
    public:
        Feature_Info(const char *id, const char *feature, const char *create_by,
                     const char *create_time, const char *update_time,
                     const void_allocator &void_alloc) :
            m_id(id, void_alloc), m_feature(feature, void_alloc), m_create_by(create_by, void_alloc),
            m_create_time(create_time, void_alloc), m_update_time(update_time, void_alloc) {}
        ~Feature_Info() {}
        char_string m_id;
        char_string m_feature;
        char_string m_create_by;
        char_string m_create_time;
        char_string m_update_time;
    };
    //vector<Feature_Info>
    typedef allocator<Feature_Info, segment_manager_t> Feature_Info_allocator;
    typedef vector<Feature_Info, Feature_Info_allocator> Feature_Info_vector;
    //map<string,Feature_Info>
    typedef char_string KeyType;
    typedef Feature_Info MappedType;
    typedef std::pair<const KeyType, MappedType> ValueType;
    typedef allocator<ValueType, segment_manager_t> ShmemAllocator;
    typedef map<KeyType, MappedType, std::less<char_string>, ShmemAllocator> bi_map_Feature_Info;
    //无用
    template<class T>
    class BiMapData {
    public:
        BiMapData(std::string shm_Name, std::size_t size)
            : m_shm_Name(shm_Name), m_size(size * 1024), m_segment(open_or_create, m_shm_Name.c_str(), m_size),
              m_alloc_inst(m_segment.get_segment_manager()), mymap(nullptr) {
            createMap();
        }
        BiMapData(std::string shm_Name)
            : m_shm_Name(shm_Name), m_size(10 * 1024), m_segment(open_only, m_shm_Name.c_str()),
              m_alloc_inst(m_segment.get_segment_manager()), mymap(nullptr) {
        }
        virtual ~BiMapData() {
        }
        const BISTL::void_allocator *getVoid_allocator() {
            return &m_alloc_inst;
        }
        const T *getMap() {
            return mymap;
        }
    private:
        void createMap() {
            mymap = m_segment.find_or_construct<T>(m_shm_Name.c_str())(
                std::less<char_string>(), m_alloc_inst);
        }
    private:
        std::string m_shm_Name;
        std::size_t m_size;
        managed_shared_memory m_segment;
        void_allocator m_alloc_inst;
        T *mymap;
        std::mutex m_mutex;
    };
    class BiMapFeaData {
    public:
        /***
         * 打开或创建共享内存
         * @param shm_Name 名称
         * @param size 大小
         */
        BiMapFeaData(std::string shm_Name, std::size_t size)
            : m_shm_Name(shm_Name), m_size(size * 1024), m_segment(open_or_create, m_shm_Name.c_str(), m_size),
              m_alloc_inst(m_segment.get_segment_manager()), mymap(nullptr) {
            createMap_Feature_Info();
            std::cout << m_segment.get_free_memory() << std::endl;
            std::cout << m_shm_Name.c_str() << std::endl;
        }
        /***
         * 打开共享内存
         * @param shm_Name 名称
         */
        BiMapFeaData(std::string shm_Name)
            : m_shm_Name(shm_Name), m_size(10 * 1024), m_segment(open_only, m_shm_Name.c_str()),
              m_alloc_inst(m_segment.get_segment_manager()), mymap(nullptr) {
            createMap_Feature_Info();
            std::cout << m_segment.get_free_memory() << std::endl;
            std::cout << m_shm_Name.c_str() << std::endl;
        }
        virtual ~BiMapFeaData() {
        }
        /***
         * 获取一个能够转换为任何allocator<T, segment_manager_t>类型的allocator
         * @return
         */
        const BISTL::void_allocator *getVoid_allocator() {
            return &m_alloc_inst;
        }
        /***
         * 返回map地址
         * @return
         */
        const BISTL::bi_map_Feature_Info *getMap() {
            return mymap;
        }
        /***
         * 封装value的初始化操作
         * @param id
         * @param feature
         * @param create_by
         * @param create_time
         * @param update_time
         * @return
         */
        bool saveKeyOrValue(std::string id, std::string feature, std::string create_by, std::string create_time,
                            std::string update_time) {
            Feature_Info v(id.c_str(), feature.c_str(), create_by.c_str(),
                           create_time.c_str(), update_time.c_str(), m_alloc_inst);
            char_string key_object(id.c_str(), m_alloc_inst);
            LockG lock(m_mutex);
            auto item = mymap->insert(ValueType(key_object, v));
            return item.second;
        }
    private:
        /***
         * 创建相应类型的map
         */
        void createMap_Feature_Info() {
            mymap = m_segment.find_or_construct<bi_map_Feature_Info>(m_shm_Name.c_str())(
                std::less<char_string>(), m_alloc_inst);
        }
    private:
        std::string m_shm_Name;
        std::size_t m_size;
        managed_shared_memory m_segment;
        void_allocator m_alloc_inst;
        bi_map_Feature_Info *mymap;
        std::mutex m_mutex;
    };
}
#endif //SYNCDBTOOL_SHAREMEMORYTOOL_HPP
syncDBTool/SyncDB.hpp
New file
@@ -0,0 +1,718 @@
//
// Created by ps on 8/9/18.
//
#ifndef UNTITLED_SYNCDB_HPP
#define UNTITLED_SYNCDB_HPP
#include <iostream>
#include <map>
#include <basic/debug/Debug.h>
namespace SyncDB {
    // Value-Defintions of the different String values
    enum Feature_InfoStringValue {
        evNotDefined,
        id,
        feature,
        create_by,
        create_time,
        update_time,
        img,
        idcard,
        evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, Feature_InfoStringValue> Map_Fea_InfoString2Values;
    static Map_Fea_InfoString2Values map_Fea_InfoString2Values;
    static void Initialize() {
        map_Fea_InfoString2Values["id"] = Feature_InfoStringValue::id;
        map_Fea_InfoString2Values["feature"] = Feature_InfoStringValue::feature;
        map_Fea_InfoString2Values["create_by"] = Feature_InfoStringValue::create_by;
        map_Fea_InfoString2Values["create_time"] = Feature_InfoStringValue::create_time;
        map_Fea_InfoString2Values["update_time"] = Feature_InfoStringValue::update_time;
        map_Fea_InfoString2Values["img"] = Feature_InfoStringValue::img;
        map_Fea_InfoString2Values["idcard"] = Feature_InfoStringValue::idcard;
        map_Fea_InfoString2Values["end"] = evEnd;
    }
    // Intialization
    static bool ret = (Initialize(), true);
    struct Feature_Info {
    public:
        Feature_Info() {
//            Initialize();
        }
//        ~Feature_Info() {
//            for (auto &item:map_Fea_InfoString2Values) {
//                map_Fea_InfoString2Values.erase(item.first);
//            }
//        }
        bool setValue(std::string key, std::string value) {
            try {
                switch (map_Fea_InfoString2Values[key]) {
                    case Feature_InfoStringValue::evNotDefined:
                        //#todo error info
                        return false;
                    case Feature_InfoStringValue::id:
                        id = value;
                        break;
                    case Feature_InfoStringValue::feature:
                        feature = value;
                        break;
                    case Feature_InfoStringValue::create_by:
                        create_by = value;
                        break;
                    case Feature_InfoStringValue::create_time:
                        create_time = value;
                        break;
                    case Feature_InfoStringValue::update_time:
                        update_time = value;
                        break;
                    case Feature_InfoStringValue::img:
                        img = value;
                        break;
                    case Feature_InfoStringValue::idcard:
                        idcard = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_Fea_InfoString2Values.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string id;
        std::string feature;
        std::string create_by;
        std::string create_time;
        std::string update_time;
        std::string img;
        std::string idcard;
//        value is a atom: atomSize:19, atomValue:test@192.168.50.216
//        value is a list:2018-08-08 20:17:11
//        value is a atom: atomSize:36, atomValue:ce386825-76f4-42bc-a0e1-cd9484cb7a8c
//        value is a list:6eda59e2-d884-5ffb-89d9-84dcffda2ad6
//        value is a list:2018-08-08 20:17:11
    private:
    };
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//---------------------------DEVICE_INFO--------------------------------------
//----------------------------------------------------------------------------
//    key:create_by  string :za@192.168.50.216
//    key:create_time  string :2018-08-12 16:56:08
//    key:del_flag   bool :0
//    key:dev_address  string :DevAddress
//    key:device_name  string :
//    key:father_node  string :
//    key:node_id      string :za@192.168.50.216
//    key:node_online  bool: 1
//    key:update_time  string :2018-08-12 16:56:08
//    key:uuid         string :19633f6f-acd9-5482-a0c8-74a44a576edf
// Value-Defintions of the different String values
    enum Device_InfoStringValue {
        dev_evNotDefined,
        dev_create_by,
        dev_create_time,
        dev_del_flag,
        dev_cluster_id,
        dev_cluster_name,
        dev_device_id,
        dev_node_id,
        dev_node_online,
        dev_update_time,
        dev_uuid,
        dev_evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, Device_InfoStringValue> Map_Dev_InfoString2Values;
    static Map_Dev_InfoString2Values map_Dev_InfoString2Values;
    static void DevInitialize() {
        //#todo
        map_Dev_InfoString2Values["create_by"] = Device_InfoStringValue::dev_create_by;
        map_Dev_InfoString2Values["create_time"] = Device_InfoStringValue::dev_create_time;
        map_Dev_InfoString2Values["del_flag"] = Device_InfoStringValue::dev_del_flag;
        map_Dev_InfoString2Values["cluster_id"] = Device_InfoStringValue::dev_cluster_id;
        map_Dev_InfoString2Values["cluster_name"] = Device_InfoStringValue::dev_cluster_name;
        map_Dev_InfoString2Values["device_id"] = Device_InfoStringValue::dev_device_id;
        map_Dev_InfoString2Values["node_id"] = Device_InfoStringValue::dev_node_id;
        map_Dev_InfoString2Values["update_time"] = Device_InfoStringValue::dev_update_time;
        map_Dev_InfoString2Values["uuid"] = Device_InfoStringValue::dev_uuid;
        map_Dev_InfoString2Values["end"] = Device_InfoStringValue::dev_evEnd;
    }
    // Intialization
    static bool devRet = (DevInitialize(), true);
    struct Device_Info {
    public:
        Device_Info() :
            create_by(""), create_time(""), del_flag(""), device_id(""), cluster_id(""), cluster_name(""), node_id(""),
            update_time(""),
            uuid("") {
//            Initialize();
        }
        ~Device_Info() {
//            for (auto &item:map_Fea_InfoString2Values) {
//                map_Fea_InfoString2Values.erase(item.first);
//            }
        }
        bool setValue(std::string key, std::string value) {
            try {
                //#todo
                int type = map_Dev_InfoString2Values[key];
                switch (type) {
                    case Device_InfoStringValue::dev_evNotDefined:
                        //#todo error info
                        return false;
                    case Device_InfoStringValue::dev_create_by:
                        create_by = value;
                        break;
                    case Device_InfoStringValue::dev_create_time:
                        create_time = value;
                        break;
                    case Device_InfoStringValue::dev_del_flag:
                        del_flag = value;
                        break;
                    case Device_InfoStringValue::dev_cluster_id:
                        cluster_id = value;
                        break;
                    case Device_InfoStringValue::dev_cluster_name:
                        cluster_name = value;
                        break;
                    case Device_InfoStringValue::dev_device_id:
                        device_id = value;
                        break;
                    case Device_InfoStringValue::dev_node_id:
                        node_id = value;
                        break;
                    case Device_InfoStringValue::dev_update_time:
                        update_time = value;
                        break;
                    case Device_InfoStringValue::dev_uuid:
                        uuid = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_Fea_InfoString2Values.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string create_by;
        std::string create_time;
        std::string del_flag;
        std::string device_id;
        std::string cluster_id;
        std::string cluster_name;
        std::string node_id;
        std::string update_time;
        std::string uuid;
    private:
    };
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//---------------------------Table_INFO--------------------------------------
//----------------------------------------------------------------------------
//{"create_by",'za@192.168.50.216'},
//{"create_time","2018-08-13 10:14:39"},
//{"del_flag","0"},
//{"tableDesc",test},
//{"tableName",aaa1},
//{"tableType",person},
//{"update_time","2018-08-13 10:14:39"},
//{"uuid","b1c19f77-623b-5294-9b65-9a766af1f77d"}
// Value-Defintions of the different String values
    enum Table_InfoStringValue {
        tab_evNotDefined,
        tab_create_by,
        tab_create_time,
        tab_del_flag,
        tab_tableDesc,
        tab_tableName,
        tab_tableType,
        tab_bwType,
        tab_update_time,
        tab_uuid,
        tab_startTime,
        tab_endTime,
        tab_evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, Table_InfoStringValue> Map_Tab_InfoString2Values;
    static Map_Tab_InfoString2Values map_Tab_InfoString2Values;
    static void TabInitialize() {
        map_Tab_InfoString2Values["create_by"] = Table_InfoStringValue::tab_create_by;
        map_Tab_InfoString2Values["create_time"] = Table_InfoStringValue::tab_create_time;
        map_Tab_InfoString2Values["del_flag"] = Table_InfoStringValue::tab_del_flag;
        map_Tab_InfoString2Values["tableDesc"] = Table_InfoStringValue::tab_tableDesc;
        map_Tab_InfoString2Values["tableName"] = Table_InfoStringValue::tab_tableName;
        map_Tab_InfoString2Values["tableType"] = Table_InfoStringValue::tab_tableType;
        map_Tab_InfoString2Values["bwType"] = Table_InfoStringValue::tab_bwType;
        map_Tab_InfoString2Values["update_time"] = Table_InfoStringValue::tab_update_time;
        map_Tab_InfoString2Values["uuid"] = Table_InfoStringValue::tab_uuid;
        map_Tab_InfoString2Values["startTime"] = Table_InfoStringValue::tab_startTime;
        map_Tab_InfoString2Values["endTime"] = Table_InfoStringValue::tab_endTime;
        map_Tab_InfoString2Values["end"] = Table_InfoStringValue::tab_evEnd;
    }
    // Intialization
    static bool tabRet = (TabInitialize(), true);
    struct Table_Info {
    public:
        Table_Info() :
            create_by(""), create_time(""), del_flag(""), tableDesc(""), tableName(""), tableType(""),
            update_time(""), uuid(""), bwType(""), startTime(""), endTime("") {
//            Initialize();
        }
        ~Table_Info() {
//            for (auto &item:map_Fea_InfoString2Values) {
//                map_Fea_InfoString2Values.erase(item.first);
//            }
        }
        bool setValue(std::string key, std::string value) {
            try {
                //#todo
                int type = map_Tab_InfoString2Values[key];
                switch (type) {
                    case Table_InfoStringValue::tab_evNotDefined:
                        //#todo error info
                        return false;
                    case Table_InfoStringValue::tab_create_by:
                        create_by = value;
                        break;
                    case Table_InfoStringValue::tab_create_time:
                        create_time = value;
                        break;
                    case Table_InfoStringValue::tab_del_flag:
                        del_flag = value;
                        break;
                    case Table_InfoStringValue::tab_tableDesc:
                        tableDesc = value;
                        break;
                    case Table_InfoStringValue::tab_tableName:
                        tableName = value;
                        break;
                    case Table_InfoStringValue::tab_tableType:
                        tableType = value;
                        break;
                    case Table_InfoStringValue::tab_bwType:
                        bwType = value;
                        break;
                    case Table_InfoStringValue::tab_uuid:
                        uuid = value;
                        break;
                    case Table_InfoStringValue::tab_update_time:
                        update_time = value;
                        break;
                    case Table_InfoStringValue::tab_startTime:
                        startTime = value;
                        break;
                    case Table_InfoStringValue::tab_endTime:
                        endTime = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_Fea_InfoString2Values.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string create_by;
        std::string create_time;
        std::string del_flag;
        std::string tableDesc;
        std::string tableName;
        std::string tableType;
        std::string update_time;
        std::string uuid;
        std::string bwType;
        std::string startTime;
        std::string endTime;
    private:
    };
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//---------------------------Bw_INFO--------------------------------------
//----------------------------------------------------------------------------
//{"bwType",'0'},
//{"create_by",'za@192.168.50.216'},
//{"create_time","2018-08-13 10:14:39"},
//{"tableName",aaa1},
//{"update_time","2018-08-13 10:14:39"},
//{"uuid","e0eb30e9-f595-5651-8895-6f07f3851fcf"}
// Value-Defintions of the different String values
    enum Bw_InfoStringValue {
        bw_evNotDefined,
        bw_bwType,
        bw_create_by,
        bw_create_time,
        bw_tableName,
        bw_update_time,
        bw_uuid,
        bw_evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, Bw_InfoStringValue> Map_Bw_InfoString2Values;
    static Map_Bw_InfoString2Values map_Bw_InfoString2Values;
    static void BwInitialize() {
        map_Bw_InfoString2Values["bwType"] = bw_bwType;
        map_Bw_InfoString2Values["create_by"] = bw_create_by;
        map_Bw_InfoString2Values["create_time"] = bw_create_time;
        map_Bw_InfoString2Values["tableName"] = bw_tableName;
        map_Bw_InfoString2Values["update_time"] = bw_update_time;
        map_Bw_InfoString2Values["uuid"] = bw_uuid;
        map_Bw_InfoString2Values["end"] = bw_evEnd;
    }
    // Intialization
    static bool bwRet = (BwInitialize(), true);
    struct Bw_Info {
    public:
        Bw_Info() :
            bwType(""), create_by(""), create_time(""), tableName(""), update_time(""),
            uuid("") {
//            Initialize();
        }
        ~Bw_Info() {
//            for (auto &item:map_Fea_InfoString2Values) {
//                map_Fea_InfoString2Values.erase(item.first);
//            }
        }
        bool setValue(std::string key, std::string value) {
            try {
                //#todo
                int type = map_Bw_InfoString2Values[key];
                switch (type) {
                    case bw_evNotDefined:
                        //#todo error info
                        return false;
                    case bw_bwType:
                        bwType = value;
                        break;
                    case bw_create_by:
                        create_by = value;
                        break;
                    case bw_create_time:
                        create_time = value;
                        break;
                    case bw_tableName:
                        tableName = value;
                        break;
                    case bw_uuid:
                        uuid = value;
                        break;
                    case bw_update_time:
                        update_time = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_Fea_InfoString2Values.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string create_by;
        std::string create_time;
        std::string bwType;
        std::string tableName;
        std::string update_time;
        std::string uuid;
    private:
    };
    struct AddPersonInfo {
        std::string personid;
        std::string idcard;
        std::string personPic;
        std::string feature;
    };
    enum AddPersRetStringValue {
        ap_evNotDefined,
        ap_PersonId,
        ap_Result,
        ap_msg,
        ap_evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, AddPersRetStringValue> Map_AddPersRetString2Values;
    static Map_AddPersRetString2Values map_AddPersRetString2Values;
    static void AddRetInitialize() {
        map_AddPersRetString2Values["PersonId"] = ap_PersonId;
        map_AddPersRetString2Values["Result"] = ap_Result;
        map_AddPersRetString2Values["msg"] = ap_msg;
        map_AddPersRetString2Values["end"] = ap_evEnd;
    }
    // Intialization
    static bool addPerRet = (AddRetInitialize(), true);
    struct AddPersRet {
    public:
        AddPersRet() :
            PersonId(""), Result(""), msg("") {
//            Initialize();
        }
        ~AddPersRet() {
        }
        bool setValue(std::string key, std::string value) {
            try {
                //#todo
                int type = map_AddPersRetString2Values[key];
                switch (type) {
                    case ap_evNotDefined:
                        //#todo error info
                        return false;
                    case ap_PersonId:
                        PersonId = value;
                        break;
                    case ap_Result:
                        Result = value;
                        break;
                    case ap_msg:
                        msg = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_AddPersRetString2Values.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string PersonId;
        std::string Result;
        std::string msg;
    private:
    };
    enum PerExistRetStringValue {
        pe_evNotDefined,
        pe_tableName,
        pe_tableUuid,
        pe_uuid,
        pe_evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, PerExistRetStringValue> Map_PerExistRetString2Values;
    static Map_PerExistRetString2Values map_PerExistRetString2Values;
    static void PerExistRetInitialize() {
        map_PerExistRetString2Values["tableName"] = pe_tableName;
        map_PerExistRetString2Values["tableUuid"] = pe_tableUuid;
        map_PerExistRetString2Values["uuid"] = pe_uuid;
        map_PerExistRetString2Values["end"] = pe_evEnd;
    }
    // Intialization
    static bool perExistsRet = (PerExistRetInitialize(), true);
    struct PerExistRet {
    public:
        PerExistRet() :
            tableName(""), uuid(""), tableUuid("") {
//            Initialize();
        }
        ~PerExistRet() {
        }
        bool setValue(std::string key, std::string value) {
            try {
                //#todo
                int type = map_PerExistRetString2Values[key];
                switch (type) {
                    case pe_evNotDefined:
                        //#todo error info
                        return false;
                    case pe_tableName:
                        tableName = value;
                        break;
                    case pe_tableUuid:
                        tableUuid = value;
                        break;
                    case pe_uuid:
                        uuid = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_PerExistRetString2Values.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string tableName;
        std::string tableUuid;
        std::string uuid;
    private:
    };
    enum UpdPersRetStringValue {
        up_evNotDefined,
        up_tableName,
        up_tableUuid,
        up_result,
        up_oldId,
        up_evEnd
    };
    // Map to associate the strings with the enum values
    typedef std::map<std::string, UpdPersRetStringValue> Map_UpdPersRetStringValue;
    static Map_UpdPersRetStringValue map_UpdPersRetStringValue;
    static void UpdPersRetInitialize() {
        map_UpdPersRetStringValue["tableName"] = up_tableName;
        map_UpdPersRetStringValue["tableUuid"] = up_tableUuid;
        map_UpdPersRetStringValue["result"] = up_result;
        map_UpdPersRetStringValue["oldId"] = up_oldId;
        map_UpdPersRetStringValue["end"] = up_evEnd;
    }
    // Intialization
    static bool updPerRet = (UpdPersRetInitialize(), true);
    struct UpdPersRet {
    public:
        UpdPersRet() :
            tableName(""), result(""), oldId(""), tableUuid("") {
//            Initialize();
        }
        ~UpdPersRet() {
        }
        bool setValue(std::string key, std::string value) {
            try {
                //#todo
                int type = map_UpdPersRetStringValue[key];
                switch (type) {
                    case up_evNotDefined:
                        //#todo error info
                        return false;
                    case up_tableName:
                        tableName = value;
                        break;
                    case up_tableUuid:
                        tableUuid = value;
                        break;
                    case up_result:
                        result = value;
                        break;
                    case up_oldId:
                        oldId = value;
                        break;
                    default:
                        ERR(key << " is an invalid string. s_mapStringValues now contains "
                                << map_UpdPersRetStringValue.size() << " entries.");
                        return false;
                }
                return true;
            } catch (std::exception ex) {
                return false;
            }
        }
    public:
    public:
        std::string tableName;
        std::string tableUuid;
        std::string result;
        std::string oldId;
    private:
    };
}
#endif //UNTITLED_SYNCDB_HPP
syncDBTool/cnode.cpp
New file
@@ -0,0 +1,210 @@
//
// Created by ps on 18-11-27.
//
#include <stdio.h>
#include <sys/types.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
#include <zconf.h>
#include <thread>
#ifdef _WIN32
#   define __WIN32__
#   include <WinSock2.h>
#   pragma comment(lib, "ws2_32.lib")
#   pragma comment(lib, "ei_md.lib")
#   pragma comment(lib, "erl_interface_md.lib")
#   pragma comment(linker, "/NODEFAULTLIB:MSVCRTD.LIB")
#endif
#include "erl_interface.h"
#include "ei.h"
#define BUFSIZE 1000
#define PORT 13001
int foo(int x) {
    return x + 1;
}
int bar(int y) {
    return y * 2;
}
int my_listen(int port);
int main(int argc, char **argv) {
    struct in_addr addr;                     /* 32-bit IP number of host */
    int port;                                /* Listen port number */
    int listen;                              /* Listen socket */
    int fd;                                  /* fd to Erlang node */
    ErlConnect conn;                         /* Connection data */
    int loop = 1;                            /* Loop flag */
    int got;                                 /* Result of receive */
    unsigned char buf[BUFSIZE];              /* Buffer for incoming message */
    ErlMessage emsg;                         /* Incoming message */
    ETERM *fromp, *tuplep, *fnp, *argp, *resp;
    int res;
#ifdef _WIN32
    //初始化winsock服务
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);
#endif
    port = PORT;
    erl_init(NULL, 0);
    addr.s_addr = inet_addr("127.0.0.1");
    if (erl_connect_xinit("test", "c1", "c1@127.0.0.1",
                          &addr, "1234", 0) == -1)
        erl_err_quit("erl_connect_xinit");
    if (erl_connect_xinit("test2", "c2", "c2@127.0.0.1",
                          &addr, "1234", 0) == -1)
        erl_err_quit("erl_connect_xinit2");
    std::thread th1([&] {
        /* Make a listen socket */
        if ((listen = my_listen(port)) <= 0)
            erl_err_quit("my_listen");
        if (erl_publish(port) == -1)
            erl_err_quit("erl_publish");
        if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
            erl_err_quit("erl_accept");
        fprintf(stderr, "Connected to %s,,,%d\n\r", conn.nodename, fd);
        while (loop) {
//        std::cout << "hello world" << std::endl;
            got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
            if (got == ERL_TICK) {
                /* ignore */
            } else if (got == ERL_ERROR) {
                if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
                    erl_err_quit("erl_accept");
                fprintf(stderr, "Connected to %s,,,%d\n\r", conn.nodename, fd);
            } else {
                if (emsg.type == ERL_REG_SEND) {
                    fromp = erl_element(2, emsg.msg);
                    tuplep = erl_element(3, emsg.msg);
                    fnp = erl_element(1, tuplep);
                    argp = erl_element(2, tuplep);
                    if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
                        res = foo(ERL_INT_VALUE(argp));
                        std::cout << "foo is  " << res << std::endl;
                    } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
                        res = bar(ERL_INT_VALUE(argp));
                        std::cout << "bar is  " << res << std::endl;
                    }
                    std::cout << "message is  " << ERL_ATOM_PTR(fnp) << std::endl;
                    resp = erl_format("{c1, {res,~i}}", res);
                    erl_send(fd, fromp, resp);
                    erl_free_term(emsg.from);
                    erl_free_term(emsg.msg);
                    erl_free_term(fromp);
                    erl_free_term(tuplep);
                    erl_free_term(fnp);
                    erl_free_term(argp);
                    erl_free_term(resp);
                }
            }
        }
    });
//    std::thread th2([&] {
//
//        /* Make a listen socket */
//        if ((listen = my_listen(8011)) <= 0)
//            erl_err_quit("my_listen 2");
//
//        if (erl_publish(8011) == -1)
//            erl_err_quit("erl_publish 2");
//
//        if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
//            erl_err_quit("erl_accept 2");
//        fprintf(stderr, "Connected to %s\n\r", conn.nodename);
//
//        while (loop) {
////        std::cout << "hello world" << std::endl;
//            got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
//            if (got == ERL_TICK) {
//                /* ignore */
//            } else if (got == ERL_ERROR) {
//                usleep(100);
////            loop = 0;
//            } else {
//
//                if (emsg.type == ERL_REG_SEND) {
//                    fromp = erl_element(2, emsg.msg);
//                    tuplep = erl_element(3, emsg.msg);
//                    fnp = erl_element(1, tuplep);
//                    argp = erl_element(2, tuplep);
//
//                    if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
//                        res = foo(ERL_INT_VALUE(argp));
//                        std::cout << "foo is  " << res << std::endl;
//                    } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
//                        res = bar(ERL_INT_VALUE(argp));
//                        std::cout << "bar is  " << res << std::endl;
//                    }
//
//                    std::cout << "message is  " << ERL_ATOM_PTR(fnp) << std::endl;
//
//                    resp = erl_format("{c1, {res,~i}}", res);
//                    erl_send(fd, fromp, resp);
//
//                    erl_free_term(emsg.from);
//                    erl_free_term(emsg.msg);
//                    erl_free_term(fromp);
//                    erl_free_term(tuplep);
//                    erl_free_term(fnp);
//                    erl_free_term(argp);
//                    erl_free_term(resp);
//                }
//            }
//
//        }
//    });
    th1.detach();
//    th2.detach();
    getchar();
}
int my_listen(int port) {
    int listen_fd;
    struct sockaddr_in addr;
    int on = 1;
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return (-1);
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    memset((void *) &addr, 0, (size_t) sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(listen_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
        return (-1);
    listen(listen_fd, 5);
    return listen_fd;
}
syncDBTool/main.cpp
New file
@@ -0,0 +1,265 @@
#include <iostream>
#include <unistd.h>
#include <sys/time.h>
#include <uuid/uuid.h>
#include <vector>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include "ErlangDbTool.h"
#include "ShareMemoryTool.hpp"
using namespace std;
//#erl -name b@192.168.1.164 -setcookie abc -mnesia dir '"/home/firefly/erlang"' -detached -noshell
int main(int argc, char **argv) {
    ENABLEGLOG(GET_STR_CONFIG("logPath").c_str());
    std::cout << "Hello, World!" << std::endl;
    std::string path = "/opt/erlang/main/";
    std::string nodeName = "main@192.168.1.124";
    std::string cookie = "abc";
    ErlangTool::ErlangDbTool *erlangDbTool;
    auto erlNode = appConfig.getStringProperty("erlNode");
    auto erlCookie = appConfig.getStringProperty("erlCookie");
    auto erlPath = appConfig.getStringProperty("erlPath");
    auto erlFatherNode = appConfig.getStringProperty("erlFatherNode");
    if (erlNode.size() > 0 && erlCookie.size() > 0) {
        string str_tmp = "DataWebserver";
        erlangDbTool = new ErlangTool::ErlangDbTool(erlPath, erlNode, erlCookie, str_tmp);
        if (erlangDbTool->initErlang() == 1) {
            erlangDbTool->startNodeDb(erlFatherNode);
        } else {
            DBG("not is startNodeDb");
        }
    }
//    ErlangTool::ErlangDbTool erlangDbTool(path, nodeName, cookie);
//
//
//
//    bool ret = erlangDbTool->initErlang();
    /**
     * chushihua jiedian jiaru jiqun
     */
//    erlangDbTool->startNodeDb(" ", " ");
//    erlangDbTool->startNodeDb("za@192.168.50.216", " ");
//---------end--------------
//    erlangDbTool->removeNode();
//    auto devCache = erlangDbTool->findAllNode();
//    INFO(devCache.size());
//    for (auto &item:devCache) {
//        DBG(item.first);
//    }
//erlangDbTool->test();
    /***
     * chuanjian shuju ku
     */
//    ret = erlangDbTool->createDatabase("person", "aaa1", true, "0");
//    ret = erlangDbTool->createDatabase("person", "aaa2", true, "1");
//    ret = erlangDbTool->createDatabase("car", "bbb1", false, "0");
//    ret = erlangDbTool->createDatabase("car", "aaa4", true, "0");
//    erlangDbTool->createDatabase("car","sycarYa32",false,"0");
//    erlangDbTool->createDatabase("car","syperYa1",true,"1");
//    erlangDbTool->createDatabase("person","syperYa2",false,"0");
//---------end--------------
//    auto dbCache = erlangDbTool->findAllDatabase();
//    auto bwCache = erlangDbTool->findAllTypeInfo();
//
//    for (auto &item : dbCache) {
//        INFO(item.first << "  " << item.second.uuid);
//    }
//    return 0;
    /***
     * add Feature
     */
//    for (int i = 0; i < 100; i++) {
//
//        uuid_t uu;
//        char str[36];
//        uuid_generate(uu);
//        uuid_unparse(uu, str);
//
//        string uuid;
//        string str2(str);
////    str2.append(str);
//        str2.append(str2).append(str2).append(str2).append(str2).append(str2);
//        auto size = str2.size();
//
//
//
////        struct timeval t1, t2;
////        gettimeofday(&t1, NULL);
//
//        ret = erlangDbTool->addPerson(uuid, "aaa1", move(str2));
////        cout << i << "  ret  " << ret << " size " << size << "  uuid " << uuid << endl;
//
////        gettimeofday(&t2, NULL);
//////    那么函数f运行所花的时间为
////        auto deltaT = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec;
////        std::cout << __FILE__ << __LINE__ << " deltaT " << deltaT << std::endl;
//
//    }
//---------end--------------
//    return 0;
    std::vector<SyncDB::AddPersonInfo> tmpPer;
    SyncDB::AddPersonInfo addPersonInfo;
    addPersonInfo.feature = "testFea22";
    addPersonInfo.personPic = "testPic33";
    addPersonInfo.idcard = "testidcard44";
    for (int i = 0; i < 3; ++i) {
        addPersonInfo.personid = std::to_string(i * 2);
        tmpPer.push_back(addPersonInfo);
    }
//    auto resaddPersons = erlangDbTool->addPersons("077b251e-8698-5852-be8c-8c2d8334a162", tmpPer);
    auto resUpdPersRet = erlangDbTool->singlePersonUpdate("12", "11", "testUpCardid", "testUpPic", "testUpFea");
//    auto resPerEit = erlangDbTool->personIsExistOnClu("1");
    /***
     * jiazai renlian
     */
    struct timeval t1, t2;
    gettimeofday(&t1, NULL);
    /***
     * load fea
     */
    auto cache = erlangDbTool->loadFaceFeaData2("测试中文12553");
    for (auto &item : cache) {
        DBG(item.first);
    }
    gettimeofday(&t2, NULL);
    //那么函数f运行所花的时间为
    auto deltaT = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec;
    std::cout << __FILE__ << __LINE__ << " deltaT " << deltaT << "us size is  " << cache.size() << std::endl;
//    auto size = sizeof(cache[0]) * cache.size();
//
//    try {
//
//        BISTL::shared_memory_object::remove("aaa8");
//
//        BISTL::BiMapFeaData biMapFeaData("aaa8", size);
//
//        for (auto &item :cache) {
//            biMapFeaData.saveKeyOrValue(item.second.id.c_str(), item.second.feature.c_str(),
//                                        item.second.create_by.c_str(),
//                                        item.second.create_time.c_str(), item.second.update_time.c_str());
//        }
//
//        auto mymap = biMapFeaData.getMap();
//        for (auto it = mymap->begin(); it != mymap->end(); it++) {
//            std::cout << "feature " << it->second.m_feature << std::endl;
//        }
//        printf("\n");
//
//    }
//    catch (const std::exception &e) {
//        printf("Exception:%s\n", e.what());
//        BISTL::shared_memory_object::remove("aaa8");
//    }
//    printf("getchar\n");
    getchar();
//--------end-----------
//   erlangDbTool->deleteDatabase("person","aaa9", true);
//    struct timeval t1, t2;
//    gettimeofday(&t1, NULL);
//    gettimeofday(&t2, NULL);
//    //那么函数f运行所花的时间为
//    auto deltaT = (t2.tv_sec-t1.tv_sec) * 1000000 + t2.tv_usec-t1.tv_usec;
//    std::cout << __FILE__ << __LINE__ << " deltaT " << deltaT << std::endl;
    return 0;
}
int main3() {
//    char cc = '1';
//    for (int i = 0; i < 100; i++) {
//        cc++;
//        printf("%c \n", cc);
//    }
    uuid_t uu;
    char str[36];
    uuid_generate(uu);
    uuid_unparse(uu, str);
    string uuid;
    string str2(str);
//    str2.append(str);
    str2.append(str2).append(str2).append(str2).append(str2).append(str2).append(str2).append(str2).append(str2).append(
        str2).append(str2).append(str2).append(str2).append(str2).append(str2);
    auto size = str2.size();
    try {
        BISTL::shared_memory_object::remove("SharedMemory");
        // init
        BISTL::managed_shared_memory segment(BISTL::create_only, "SharedMemory", 65536);
        const BISTL::void_allocator alloc_inst(segment.get_segment_manager());
        BISTL::bi_map_Feature_Info *mymap =
            segment.construct<BISTL::bi_map_Feature_Info>("MyMap")(std::less<BISTL::char_string>(), alloc_inst);
        for (int i = 0; i < 100; ++i) {
            char tmp[16] = "";
            sprintf(tmp, "test%d", i);
            BISTL::char_string key_object(tmp, alloc_inst);
            BISTL::Feature_Info v(tmp, "feature", "create_by", "create_time", "update_time", alloc_inst);
//            v.id = key_object;
//            v.feature = key_object;
            BISTL::ValueType value(key_object, v);
            mymap->insert(value);
        }
        for (BISTL::bi_map_Feature_Info::iterator it = mymap->begin(); it != mymap->end(); it++) {
            std::cout << it->second.m_id << std::endl;
            std::cout << it->second.m_feature << std::endl;
//            it->second.id;
        }
        printf("\n");
//        BISTL::shared_memory_object::remove("SharedMemory");
    }
    catch (const std::exception &e) {
        printf("Exception:%s\n", e.what());
        BISTL::shared_memory_object::remove("SharedMemory");
    }
    printf("getchar\n");
    getchar();
    return 0;
}
syncDBTool/main2.cpp
New file
@@ -0,0 +1,145 @@
#include <iostream>
#include <unistd.h>
#include <sys/time.h>
#include <vector>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <jsoncpp/json/json.h>
#include <thread>
#include "ErlangDbTool.h"
#include "ShareMemoryTool.hpp"
using namespace std;
//#erl -name b@192.168.1.164 -setcookie abc -mnesia dir '"/home/firefly/erlang"' -detached -noshell
int main(int argc, char **argv) {
    ENABLEGLOG(GET_STR_CONFIG("logPath").c_str());
    std::cout << "Hello, World!" << std::endl;
//    string str_json(argv[1]);
//0096ee77-1f50-48e2-a08a-42536a754970@192.168.1.124
//    string str_json = "{\"path\":\"/opt/erlang/0096ee77-1f50-48e2-a08a-42536a754970/\","
//                      "\"nodeName\":\"0096ee77-1f50-48e2-a08a-42536a754970@192.168.1.124\",\"cookie\":\"1234\","
//                      "\"tableName\":\"test\"}";
    string str_json = "{\"personList\":[{\"idcard\":\"www\",\"name\":\"www\",\"personId\":\"1532\",\"feature\":\"13dasd\"},"
                      "{\"idcard\":\"133310998877665544\",\"name\":\"测试教师-三班班主任\",\"personId\":\"1533\","
                      "\"feature\":\"13dasd\"}],\"uuid\":\"16011ab6-c966-5114-afa5-569c91f866c3\"}";
    Json::Value t_json;
    Json::Reader reader;
    if (!reader.parse(str_json, t_json)) {
        return -1;
    }
    string TableUuid = t_json["uuid"].asString();
    auto perlists = t_json["personList"];
    int lsize = perlists.size();
    for (int i = 0; i < lsize; ++i) {
//        perlists[0]
    }
    for (auto &item : perlists) {
        item["idcard"].asString();
        item["personId"].asString();
        item["feature"].asString();
        int i = 0;
    }
    return 0;
    std::string path = t_json["path"].asString();//"/opt/erlang/za/";
    std::string nodeName = t_json["nodeName"].asString();//"za@192.168.188.128";
    std::string cookie = t_json["cookie"].asString();//"abc";
    std::string tableName = t_json["tableName"].asString();
    ErlangTool::ErlangDbTool erlangDbTool(nodeName, cookie, "test");
//    bool ret = erlangDbTool.initErlang();
    ErlangTool::map_FaceDataCache cache;
    std::thread thread1([&] {
        while (1) {
            /***
             * jiazai renlian
             */
            struct timeval t1, t2;
            gettimeofday(&t1, NULL);
            /***
             * load fea
             */
            cache = erlangDbTool.loadFaceFeaData(tableName);
            gettimeofday(&t2, NULL);
            //那么函数f运行所花的时间为
            auto deltaT = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec;
            std::cout << __FILE__ << __LINE__ << " deltaT " << deltaT << "us  size is " << cache.size() << std::endl;
        }
    });
    std::thread thread2([&] {
        while (1) {
            /***
             * jiazai renlian
             */
            struct timeval t1, t2;
            gettimeofday(&t1, NULL);
            /***
             * load fea
             */
            auto cache2 = erlangDbTool.findAllNode();
            gettimeofday(&t2, NULL);
            //那么函数f运行所花的时间为
            auto deltaT = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec;
            std::cout << __FILE__ << __LINE__ << " deltaT " << deltaT << "us  size is " << cache2.size() << std::endl;
        }
    });
    auto size = sizeof(cache[0]) * cache.size();
    try {
        BISTL::shared_memory_object::remove(tableName.c_str());
        BISTL::BiMapFeaData biMapFeaData(tableName, size);
        for (auto &item :cache) {
            biMapFeaData.saveKeyOrValue(item.second.id.c_str(), item.second.feature.c_str(),
                                        item.second.create_by.c_str(),
                                        item.second.create_time.c_str(), item.second.update_time.c_str());
        }
//        auto mymap = biMapFeaData.getMap();
//        for (auto it = mymap->begin(); it != mymap->end(); it++) {
//            std::cout << "feature " << it->second.m_feature << std::endl;
//        }
        printf("\n");
    }
    catch (const std::exception &e) {
        printf("Exception:%s\n", e.what());
        BISTL::shared_memory_object::remove(tableName.c_str());
    }
    printf("getchar\n");
    getchar();
    return 0;
}