From eddff2d353cd541bee6ce306b128447ccb3a7a5b Mon Sep 17 00:00:00 2001
From: pansen <pansen626@sina.com>
Date: 星期六, 15 十二月 2018 14:49:14 +0800
Subject: [PATCH] 

---
 syncDBTool/Client.cpp          |   51 
 syncDBTool/ErlangDbTool.hpp    | 1555 ++++++++++++++++
 syncDBTool/ErlangDbTool.h      |  312 +++
 syncDBTool/cnode.cpp           |  210 ++
 syncDBTool/CMakeLists.txt      |   98 +
 syncDBTool/SyncDB.hpp          |  718 +++++++
 syncDBTool/ErlangDbTool.cpp    | 2054 +++++++++++++++++++++
 syncDBTool/ShareMemoryTool.hpp |  259 ++
 syncDBTool/main.cpp            |  265 ++
 syncDBTool/main2.cpp           |  145 +
 10 files changed, 5,667 insertions(+), 0 deletions(-)

diff --git a/syncDBTool/CMakeLists.txt b/syncDBTool/CMakeLists.txt
new file mode 100755
index 0000000..5199a6f
--- /dev/null
+++ b/syncDBTool/CMakeLists.txt
@@ -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
+    )
\ No newline at end of file
diff --git a/syncDBTool/Client.cpp b/syncDBTool/Client.cpp
new file mode 100755
index 0000000..ca83cb9
--- /dev/null
+++ b/syncDBTool/Client.cpp
@@ -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;
+}
\ No newline at end of file
diff --git a/syncDBTool/ErlangDbTool.cpp b/syncDBTool/ErlangDbTool.cpp
new file mode 100755
index 0000000..a96f15d
--- /dev/null
+++ b/syncDBTool/ErlangDbTool.cpp
@@ -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;
+}
+
+// 鍜宔rlang浜や簰
+//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
+//鐩存帴鍜宻qlite3 浜や簰
+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;
+}
\ No newline at end of file
diff --git a/syncDBTool/ErlangDbTool.h b/syncDBTool/ErlangDbTool.h
new file mode 100755
index 0000000..76ce646
--- /dev/null
+++ b/syncDBTool/ErlangDbTool.h
@@ -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);
+
+    /***
+     * 妫�鏌TERM鐨勬暟鎹被鍨�
+     * @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
diff --git a/syncDBTool/ErlangDbTool.hpp b/syncDBTool/ErlangDbTool.hpp
new file mode 100755
index 0000000..66310fd
--- /dev/null
+++ b/syncDBTool/ErlangDbTool.hpp
@@ -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;
+//    }
+//
+//    /***
+//     * 妫�鏌TERM鐨勬暟鎹被鍨�
+//     * @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
diff --git a/syncDBTool/ShareMemoryTool.hpp b/syncDBTool/ShareMemoryTool.hpp
new file mode 100755
index 0000000..4e7d884
--- /dev/null
+++ b/syncDBTool/ShareMemoryTool.hpp
@@ -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>绫诲瀷鐨刟llocator
+         * @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:
+        /***
+         * 鍒涘缓鐩稿簲绫诲瀷鐨刴ap
+         */
+        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
diff --git a/syncDBTool/SyncDB.hpp b/syncDBTool/SyncDB.hpp
new file mode 100755
index 0000000..82919ca
--- /dev/null
+++ b/syncDBTool/SyncDB.hpp
@@ -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
diff --git a/syncDBTool/cnode.cpp b/syncDBTool/cnode.cpp
new file mode 100755
index 0000000..fdf007f
--- /dev/null
+++ b/syncDBTool/cnode.cpp
@@ -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
+    //鍒濆鍖杦insock鏈嶅姟
+    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;
+}
\ No newline at end of file
diff --git a/syncDBTool/main.cpp b/syncDBTool/main.cpp
new file mode 100755
index 0000000..8821f25
--- /dev/null
+++ b/syncDBTool/main.cpp
@@ -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);
+//////    閭d箞鍑芥暟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);
+    //閭d箞鍑芥暟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);
+//    //閭d箞鍑芥暟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;
+}
\ No newline at end of file
diff --git a/syncDBTool/main2.cpp b/syncDBTool/main2.cpp
new file mode 100755
index 0000000..89b29d5
--- /dev/null
+++ b/syncDBTool/main2.cpp
@@ -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);
+            //閭d箞鍑芥暟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);
+            //閭d箞鍑芥暟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;
+}

--
Gitblit v1.8.0