From ec3b048867bed0009dd818b69a21983768fca8ff Mon Sep 17 00:00:00 2001
From: pansen <pansen626@sina.com>
Date: 星期六, 26 一月 2019 16:00:31 +0800
Subject: [PATCH] init

---
 CasiaFaceWrapper/CasiaFaceWrapperN.h   |   48 
 Cleint.cpp                             |  438 +++++++
 main.cpp                               |   37 
 CasiaFaceWrapper/CasiaFaceWrapperN.cpp |  145 ++
 LoadFeaTool/demoTime.cpp               |  118 +
 LoadFeaTool/Client.cpp                 |  112 +
 FaceDBCompareServer.cpp                |  217 +++
 FaceFeatureSearchServerI.cpp           |  422 +++++++
 CMakeLists.txt                         |  142 ++
 README.md                              |    3 
 FaceFeatureSearchServerI.h             |   85 +
 FaceDBCompareServer.h                  |   63 +
 rpc/FaceSearchServer.cpp               |  515 ++++++++
 LoadFeaTool/CMakeLists.txt             |   76 +
 LoadFeaTool/main.cpp                   |  100 +
 rpc/FaceSearchServer.ice               |   24 
 AlarmServer.hpp                        |  199 +++
 rpc/gen.sh                             |    3 
 CasiaFaceWrapper/FaceData.hpp          |  136 ++
 rpc/FaceSearchServer.h                 |  678 +++++++++++
 20 files changed, 3,558 insertions(+), 3 deletions(-)

diff --git a/AlarmServer.hpp b/AlarmServer.hpp
new file mode 100644
index 0000000..2de5947
--- /dev/null
+++ b/AlarmServer.hpp
@@ -0,0 +1,199 @@
+//
+// Created by ps on 2/26/18.
+//
+
+#ifndef COMPARETEST_COMPARESERVER_H
+#define COMPARETEST_COMPARESERVER_H
+
+#include <thread>
+#include <set>
+
+#include <basic/debug/Debug.h>
+#include <basic/util/thread/RWLock.hpp>
+#include <basic/util/thread/MultiThread.h>
+#include <basic/util/BASE64/Base64.h>
+
+struct AlarmData {
+    int num;
+    std::string tableName;
+    std::vector<unsigned char> feature;
+    float threshold;
+};
+
+struct FeatureData {
+    long face_id;
+    std::string uuid;
+    //feature
+    std::vector<std::vector<unsigned char>> features;
+    std::string faceUrl;
+    std::string idcard;
+    std::string enabled;
+};
+
+static std::vector<std::string> AlarmServerPropertyAnalyseByComma(std::string str_list) {
+    std::vector<std::string> result;
+    char *property_list = const_cast<char *>(str_list.c_str());
+    const char *c_Analyse = ",";
+    char *t_property;
+
+#ifdef linux
+    char *t_save = NULL;
+    t_property = strtok_r(property_list, c_Analyse, &t_save);
+#else
+    t_property = strtok(property_list,c_Analyse);
+#endif
+
+    while (t_property) {
+        std::string str_pro(t_property);
+        result.push_back(str_pro);
+#ifdef linux
+        t_property = strtok_r(t_save, c_Analyse, &t_save);
+#else
+        t_property = strtok(NULL,c_Analyse);
+#endif
+
+    }
+    return result;
+}
+
+#define ParalleFunc std::function<void(std::string&,FeatureData&)>
+enum ParallelForThreardSize {
+    CPU_Number = 1
+};
+
+class AlarmServer {
+
+public:
+    AlarmServer() : m_dbSet(false), m_dbReady(false) {
+
+    }
+
+    ~AlarmServer() {
+        for (auto item : dataMap) {
+            delete &(item.second);
+//            item.second = NULL;
+        }
+        dataMap.clear();
+        dataAddBuffer.clear();
+        dataRemoveBuffer.clear();
+    }
+
+    void initDB(std::string str_config) {
+        std::thread thd(loadDBCahce, this, str_config);
+        thd.detach();
+    }
+
+    void removeData(std::string key) {
+        std::lock_guard<std::mutex> guard(dataRemoveBufferMtx);
+        dataRemoveBuffer.insert(key);
+        dataRemoveBufferUpdated = true;
+    }
+
+    void addData(std::string key, FeatureData &value) {
+        std::lock_guard<std::mutex> guard(dataAddBufferMtx);
+        dataAddBuffer[key] = value;
+        dataAddBufferUpdated = true;
+    }
+
+    bool getDBReady() {
+        return m_dbReady;
+    }
+
+    //m_dbReady is false return,true go on
+    //use parallelFor
+    virtual bool compare(std::thread::id key, AlarmData *, int topN, float score) = 0;
+
+private:
+    //init data,this is thread body
+    static void loadDBCahce(AlarmServer *compareServer, std::string str_config) {
+        std::lock_guard<std::mutex> guard(compareServer->dataRemoveBufferMtx);
+        std::lock_guard<std::mutex> guard2(compareServer->dataAddBufferMtx);
+        std::lock_guard<std::mutex> dataGuard(compareServer->dataMtx);
+
+        compareServer->dataRemoveBuffer.clear();
+        compareServer->dataAddBuffer.clear();
+
+        compareServer->m_rwLock.wrlock();
+        compareServer->loadDBData(str_config);
+        compareServer->m_dbReady = true;
+        compareServer->m_rwLock.unlock();
+        INFO("m_dbReady is true");
+    }
+
+    virtual void loadDBData(std::string tableName) = 0;
+
+    bool m_dbSet;
+    bool m_dbReady;
+
+    bool dataAddBufferUpdated;
+    bool dataRemoveBufferUpdated;
+    bool dateResetUpdated;
+
+    RWLock m_rwLock;
+
+    void updateDataRemove() {
+        if (dataRemoveBufferUpdated) {
+            std::lock_guard<std::mutex> dataRemoveGuard(dataRemoveBufferMtx);
+            std::lock_guard<std::mutex> dataGuard(dataMtx);
+            if (!dataRemoveBufferUpdated)return;
+            for (auto key: dataRemoveBuffer) {
+                this->dataMap.erase(key);
+            }
+            dataRemoveBuffer.clear();
+            dataRemoveBufferUpdated = false;
+        }
+    }
+
+    void updateDataAdd() {
+        if (dataAddBufferUpdated) {
+            std::lock_guard<std::mutex> dataRemoveGuard(dataAddBufferMtx);
+            std::lock_guard<std::mutex> dataGuard(dataMtx);
+            if (!dataAddBufferUpdated)return;
+            for (auto addData: dataAddBuffer) {
+                this->dataMap.insert(addData);
+            }
+            dataAddBuffer.clear();
+            dataAddBufferUpdated = false;
+        }
+    }
+
+protected:
+    Base64 base64;
+    //#todo value is vector not is struct
+    std::map<std::string, FeatureData> dataMap;
+    std::map<std::string, FeatureData> dataAddBuffer;
+    std::set<std::string> dataRemoveBuffer;
+    std::mutex dataMtx;
+    std::mutex dataAddBufferMtx;
+    std::mutex dataRemoveBufferMtx;
+    std::mutex dataRestMtx;
+
+    void parallelFor(int threads, ParalleFunc func) {
+        updateDataRemove();
+        updateDataAdd();
+//        std::lock_guard<std::mutex> dataGuard(dataMtx);
+        m_rwLock.rdlock();
+        MultiThread mthd(threads, [&func, this](int idx, int num) {
+            int size = dataMap.size();
+            int step = size / num;
+            if (step < 1) {
+                step = 1;
+                if (idx >= size)return;
+            }
+            auto iter = dataMap.begin();
+            for (int i = idx * step; i > 0; i--) {
+                iter++;
+            }
+            for (int i = 0; i < step && iter != dataMap.end(); iter++, i++) {
+                auto &data = iter->second;
+                std::string key = iter->first;
+                func(key, data);
+            }
+        });
+        mthd.join();
+        m_rwLock.unlock();
+    }
+};
+
+
+#endif //COMPARETEST_COMPARESERVER_H
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..e1e7212
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,142 @@
+cmake_minimum_required(VERSION 3.5)
+project(FaceSearchServer)
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../build)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_BUILD_TYPE debug)
+add_definitions(-DDEBUG_ERR -DDEBUG_INFO -DDEBUG_INFO)
+add_definitions(-DGLOG)
+add_compile_options(-fPIC)
+
+SET(LIBS
+    glog
+    Ice
+    opencv_world
+    Qt5Core
+    Qt5Sql
+    THFaceImage
+    THFeature
+    THFaceProperty
+    ei
+    erl_interface_st
+    ei_st
+    erl_interface
+    curl
+    jsoncpp
+    uuid
+    sqlite3
+    rt
+    pthread
+    )
+include_directories(
+    ./rpc
+    ./CasiaFaceWrapper
+
+    #glog
+    ../../../BasicPlatForm/libs/glog/include
+    ../LocalDBTool
+    ../../../BasicPlatForm
+    ../../../BasicPlatForm/libs/crul/include
+    ../../../BasicPlatForm/libs/opencv/include
+    ../../../BasicPlatForm/libs/Ice-3.7.0/include
+    ../../../BasicPlatForm/libs/ffmpeg/include
+    ../../../BasicPlatForm/libs/Casia_Face/FaceSdk/include
+    #    ../../BasicPlatForm/libs/erlang/erl_interface/include
+
+
+    ../../../BasicPlatForm/libs/jsoncpp/include
+    ../../../BasicPlatForm/libs/crul/include
+    ../../../BasicPlatForm/libs/libuuid/include/
+    ../../../BasicPlatForm/basic/util/curl/
+    ../../../BasicPlatForm/basic/util/ShareMemory/
+    ../../../BasicPlatForm/basic/db/Elasticsearch/
+    ../../../BasicPlatForm/wrapper/casia/include
+    ../../../BasicPlatForm/libs/libboost/include
+
+
+    ../../syncDBTool/
+
+    ../../../BasicPlatForm/basic/db/sqlite/
+    ../../../BasicPlatForm/basic/db/sqlite/sqlite-v-3220000
+
+    /usr/include/x86_64-linux-gnu/qt5
+    /usr/include/x86_64-linux-gnu/qt5/QtCore/
+    /usr/include/x86_64-linux-gnu/qt5/QtSql/
+
+    /usr/include/boost/
+)
+
+link_directories(
+    /usr/local/cuda/lib64
+    #glog
+    ../../../BasicPlatForm/libs/glog/lib
+    ../../../BasicPlatForm/libs/openssl/lib/
+    ../../../BasicPlatForm/libs/Ice-3.7.0/lib64
+    ../../../BasicPlatForm/libs/opencv/lib
+    ../../../BasicPlatForm/libs/ffmpeg/lib
+    ../../../BasicPlatForm/libs/Casia_Face/FaceSdk/lib/cpu
+    ../../../BasicPlatForm/libs/crul/lib
+    ../../../BasicPlatForm/libs/jsoncpp/lib
+    ../../../BasicPlatForm/libs/libuuid/lib
+    #    ../../BasicPlatForm/libs/erlang/erl_interface/libs
+
+    ../../../BasicPlatForm/basic/db/sqlite/sqlite-v-3220000
+    ../../../BasicPlatForm/libs/libuuid/lib
+
+    /usr/lib/erlang/lib/erl_interface-3.8.2/lib/
+)
+
+
+add_executable(${PROJECT_NAME}
+    main.cpp
+    rpc/FaceSearchServer.cpp
+    FaceFeatureSearchServerI.cpp
+    FaceFeatureSearchServerI.h
+    CasiaFaceWrapper/CasiaFaceWrapperN.cpp
+    CasiaFaceWrapper/CasiaFaceWrapperN.h
+    CasiaFaceWrapper/FaceData.hpp
+    AlarmServer.hpp
+    FaceDBCompareServer.cpp
+    FaceDBCompareServer.h
+    ../../../BasicPlatForm/basic/util/thread/MultiThread.cpp
+    ../../../BasicPlatForm/basic/util/thread/MultiThread.h
+    ../../../BasicPlatForm/basic/util/BASE64/Base64.cpp
+    ../../../BasicPlatForm/basic/util/curl/HttpRequestWithCrul.hpp
+    ../../../BasicPlatForm/basic/db/Elasticsearch/EsDBTool.cpp
+    ../../../BasicPlatForm/basic/db/Elasticsearch/EsDBTool.h
+
+    ../../../BasicPlatForm/basic/timer_counter/Clocktimer.cpp
+
+    #todo file path error
+    ../LocalDBTool/SqliteFaceEncap.cpp
+    ../../../BasicPlatForm/basic/db/sqlite/sqliteEncapsulation.cpp
+    ../../../BasicPlatForm/basic/db/sqlite/sqliteEncapsulation.h
+
+
+    ../../syncDBTool/ErlangDbTool.cpp
+    )
+
+target_link_libraries(${PROJECT_NAME}
+    ${LIBS}
+    )
+
+#add_executable(SearchFaceTest
+#    Cleint.cpp
+#    ./rpc/FaceSearchServer.cpp
+#    ./CasiaFaceWrapper/CasiaFaceWrapperN.cpp
+#    )
+#target_link_libraries(SearchFaceTest
+#    opencv_world
+#    glog
+#    curl
+#    IceStorm
+#    Ice
+#    jsoncpp
+#    uuid
+#    THFaceImage
+#    THFacialPos
+#    THFaceProperty
+#    THFeature
+#    pthread
+#    )
+
+add_subdirectory(LoadFeaTool)
diff --git a/CasiaFaceWrapper/CasiaFaceWrapperN.cpp b/CasiaFaceWrapper/CasiaFaceWrapperN.cpp
new file mode 100644
index 0000000..9b9fe3a
--- /dev/null
+++ b/CasiaFaceWrapper/CasiaFaceWrapperN.cpp
@@ -0,0 +1,145 @@
+//
+// Created by pans on 4/27/18.
+//
+#include <iostream>
+#include <string>
+#include <basic/util/app/AppPreference.hpp>
+#include <atomic>
+
+#include "CasiaFaceWrapperN.h"
+
+using namespace std;
+
+std::atomic_int CasiaFaceWrapperN::instanceCount(0);
+
+CasiaFaceWrapperN::CasiaFaceWrapperN() {
+    threadMax = appPref.getLongData("thread.max");
+//    long gpuIndex = appPref.getLongData("gpu.index");
+//    for(int i = 0;i<threadMax;i++){
+//        resourcesManager.pushResource(i);
+//    }
+//    if(gpuIndex < 0){
+//        THFI_Param* param = new THFI_Param[threadMax];
+////        THFI_Create(threadMax, param);
+//        CHKERR(THFI_Create(threadMax, param), threadMax, "THFI_Create return");//old version ,default GPU device ID is 0
+//        CHKERR(EF_Init(threadMax), threadMax, "EF_Create return");//old version ,default GPU device ID is 0
+//        delete[] param;
+//    }else{
+//        THFI_Param_Ex* param = new THFI_Param_Ex[threadMax];
+//        THFI_Param detParam;
+//        EF_Param pParam[threadMax];
+//        detParam.nMinFaceSize = 20;
+//        detParam.nRollAngle = 60;
+//        for(int i = 0;i<threadMax;i++){
+//            param[i].tp = detParam;
+//            param[i].nDeviceID = gpuIndex;
+//            pParam[i].nDeviceID = gpuIndex;//GPU device ID,eg:0,1,2....
+//        }
+//        THFI_Create_Ex(threadMax, param);
+//        CHKERR(EF_Init_Ex(threadMax,pParam), threadMax, "EF_Create return");//old version ,default GPU device ID is 0
+////        EF_Init_Ex(gpuIndexs.size(),pParam);
+//        delete[] param;
+//    }
+//    THFP_Create(threadMax);
+
+    channel = instanceCount;
+    THFI_Param detParam;
+    detParam.nMinFaceSize = 50;
+    detParam.nRollAngle = 60;
+    if(instanceCount++ == 0){
+//        if(gpuIndexs.empty()){
+            CHKERR(THFI_Create(threadMax, &detParam), threadMax, "THFI_Create return");//old version ,default GPU device ID is 0
+            CHKERR(EF_Init(threadMax), threadMax, "EF_Create return");//old version ,default GPU device ID is 0
+//        }
+//        else{
+//            THFI_Param_Ex pParamx[gpuIndexs.size()];
+//            EF_Param pParam[gpuIndexs.size()];
+//            for(int i = 0; i<gpuIndexs.size(); i++){
+//                pParamx[i].tp=detParam;
+//                pParamx[i].nDeviceID=gpuIndexs[i];//GPU device ID,eg:0,1,2....
+//                pParam[i].nDeviceID=gpuIndexs[i];//GPU device ID,eg:0,1,2....
+//            }
+//            int ret=THFI_Create_Ex(gpuIndexs.size(), pParamx);
+//            if(ret !=gpuIndexs.size()){
+//                printf("THFI_Create failed!(ret=%d)\n",ret);
+//            }
+//            ret=EF_Init_Ex(gpuIndexs.size(),pParam);
+//            if(ret !=gpuIndexs.size()){
+//                printf("EF_Init_Ex failed!(ret=%d)\n",ret);
+//            }
+//        }
+    }else if(instanceCount> threadMax){
+        channel = -1;
+        ERR("too many channels instanced, channel "<<channel<<" instance faild.");
+    }
+
+}
+
+CasiaFaceWrapperN::~CasiaFaceWrapperN() {
+    //#todo
+    THFI_Release();
+    THFP_Release();
+}
+
+float CasiaFaceWrapperN::compareFeature(std::vector<unsigned char> &feature1, std::vector<unsigned char> &feature2) {
+    if(feature1.size()!= EF_Size()){
+        ERR("feature1 size is not incorrect");
+        return 0;
+    }else if(feature2.size()!= EF_Size()){
+        ERR("feature2 size is not incorrect");
+        return 0;
+    }
+    return EF_Compare(feature1.data(), feature2.data());
+}
+#define COPY(NAME) memcpy(&face.NAME, &pos.NAME, sizeof (pos.NAME));s
+Features CasiaFaceWrapperN::extractFace(FaceImageN img) {
+    Features results;
+    if(channel ==-1){
+        ERR("invalid face channel, face detect faild");
+        return results;
+    }
+    vector<unsigned char> feature;
+    THFI_FacePos facesPos[30];
+//    int channel;
+//    for(int loop = 0;loop < threadMax;loop++){
+//        channel = resourcesManager.getAvilableChannel(to_string(loop));
+//        if(channel > 0){
+//            cout << channel << endl;
+//            break;
+//        }
+//    }
+    int faceNum = THFI_DetectFace(channel, img.data,24, img.width, img.height, facesPos ,30);
+    if(faceNum>0){
+        if(feature.size()!= EF_Size()*faceNum){
+            feature.resize(EF_Size()*faceNum);
+        }
+        CHKERR(EF_Extract_M(channel, img.data, img.width, img.height, 3, facesPos, feature.data(), faceNum), 1, " return");
+        for(int i = 0; i< faceNum; i++){
+            FaceFeaWithScore result;
+            THFI_FacePos& face = facesPos[i];
+            result.left = face.rcFace.left;
+            result.top = face.rcFace.top;
+            result.width = face.rcFace.right - face.rcFace.left;
+            result.height = face.rcFace.bottom - face.rcFace.top;
+            result.score = face.fAngle.confidence;
+//            if(face.fAngle.confidence >= 0.6){
+                if((face.fAngle.pitch >-30 || face.fAngle.pitch <30 ) &&
+                   (face.fAngle.roll >-30 || face.fAngle.roll <30 ) &&
+                   (face.fAngle.yaw >-30 || face.fAngle.yaw <30 )){
+                    result.feature.resize(EF_Size());
+                    memcpy(result.feature.data(),feature.data()+i*EF_Size(),EF_Size());
+                    results.push_back(result);
+                }
+//            }
+        }
+    } else{
+        DBG("faceNum is < 0");
+    }
+    return results;
+}
+
+
+//#todo
+//Features CasiaFaceWrapperN::extractFace(FaceImageN &img, THFI_FacePos& facePos,int faceNum) {
+//    return Features();
+//}
diff --git a/CasiaFaceWrapper/CasiaFaceWrapperN.h b/CasiaFaceWrapper/CasiaFaceWrapperN.h
new file mode 100644
index 0000000..87ed35e
--- /dev/null
+++ b/CasiaFaceWrapper/CasiaFaceWrapperN.h
@@ -0,0 +1,48 @@
+//
+// Created by pans on 4/27/18.
+//
+
+#ifndef VIDEOSTRUCTURE_CASIAFACEWRAPPER_H
+#define VIDEOSTRUCTURE_CASIAFACEWRAPPER_H
+
+#include <THFaceImage_i.h>
+#include <THFaceProperty_i.h>
+#include <THFeature_i.h>
+
+#include <basic/util/resource/ResourcesManager.h>
+#include <libs/opencv/include/opencv2/core/mat.hpp>
+#include <atomic>
+
+#include "FaceData.hpp"
+
+class CasiaFaceWrapperN {
+public:
+    CasiaFaceWrapperN();
+
+    virtual ~CasiaFaceWrapperN();
+
+    float compareFeature(Feature &feature1,Feature &feature2);
+
+    //todo extractFace
+    Features extractFace(FaceImageN img);
+//    Features extractFace(FaceImageN &img, THFI_FacePos& facePos,int faceNum);
+
+    //todo detectFace
+
+public:
+
+private:
+
+private:
+    ResourcesManager<int> resourcesManager;
+    long threadMax;
+    int nGPUDeviceID=0;
+    short channel;
+    static std::atomic_int instanceCount;
+//    static std::vector<int> gpuIndexs;
+//    static int channelMax;
+
+};
+
+
+#endif //VIDEOSTRUCTURE_CASIAFACEWRAPPER_H
diff --git a/CasiaFaceWrapper/FaceData.hpp b/CasiaFaceWrapper/FaceData.hpp
new file mode 100644
index 0000000..8124abd
--- /dev/null
+++ b/CasiaFaceWrapper/FaceData.hpp
@@ -0,0 +1,136 @@
+//
+// Created by pans on 5/2/18.
+//
+
+#ifndef VIDEOSTRUCTURE_FACEDATA_HPP
+#define VIDEOSTRUCTURE_FACEDATA_HPP
+
+#include <vector>
+
+struct FaceImageN {
+    int width;
+    int height;
+    int stride;
+    unsigned char *data;
+};
+struct FaceFeaWithScore {
+    int left;
+    int top;
+    int width;
+    int height;
+    std::vector<unsigned char> feature;
+    float score;
+};
+
+typedef std::vector<FaceFeaWithScore> Features;
+
+struct FaceResult {
+    long id;
+    std::string uuid;
+    std::string tableName;
+    float confidence;
+    std::string face_img_url;
+    std::string idCard;
+    std::string alarmRet;
+    std::string enabled;
+};
+
+struct DbAction {
+    long id;
+    std::string tableName;
+    std::string face_img_url;   //#todo 浠ュ浘鎼滃浘澶氬簳搴撴暟鎹悓姝�
+    long actionNo; // 1 add; 2, remove
+};
+
+//        sequence<DbAction> DbActions;
+
+typedef std::vector<FaceResult> FaceResults;
+typedef std::map<float, FaceResult, std::greater<float>> mapFaceResults;
+
+
+namespace {
+
+
+    typedef std::vector<unsigned char> Feature;
+    typedef std::vector<unsigned char> Data;
+
+    struct POINT {
+        int x;
+        int y;
+    };
+
+    struct RECT {
+        int left;
+        int top;
+        int right;
+        int bottom;
+    };
+
+    struct FaceAngle {
+        int yaw;
+        int pitch;
+        int roll;
+        float confidence;
+    };
+
+    struct ThftResult {
+        int gender;//1-male,0-female
+        int age;//range[0-100]
+        int race; //[1-white,2-yellow,3-black]
+        int beauty_level;//range[0-100]
+        int smile_level;//range[0-100]
+    };
+
+    struct FacePos {
+        RECT rcFace;
+        POINT ptLeftEye;
+        POINT ptRightEye;
+        POINT ptMouth;
+        POINT ptNose;
+        FaceAngle fAngle;
+        int nQuality;
+        ThftResult property;
+        Data pFacialData;
+    };
+
+    typedef std::vector<FacePos> Faces;
+
+    long getTimeLong() {
+        time_t tt;
+        time(&tt);
+        tt = tt + 8 * 3600;  // transform the time zone
+        return tt;
+    }
+}
+
+namespace FaceToolData {
+    enum RectSize {
+        horizontal = 10,
+        vertical = 10
+    };
+
+    class CompareData {
+    public:
+        virtual ~CompareData() {}
+    };
+
+
+    class FeatureData : public CompareData {
+    public:
+        FeatureData(int size) : feature(size) {}
+
+        Feature feature;
+        int num;
+        float threshold;
+        std::string tableNameList;
+    };
+
+    struct CompareResult {
+        std::string id;
+        std::string face_img_url;
+        std::string table_Name;
+        float score;
+    };
+}
+
+#endif //VIDEOSTRUCTURE_FACEDATA_HPP
diff --git a/Cleint.cpp b/Cleint.cpp
new file mode 100644
index 0000000..7c6a16e
--- /dev/null
+++ b/Cleint.cpp
@@ -0,0 +1,438 @@
+//
+// Created by pans on 5/4/18.
+//
+
+//
+// Created by ps on 3/1/18.
+//
+
+
+#include <thread>
+#include "opencv2/opencv.hpp"
+#include "basic/util/BASE64/Base64.h"
+#include <basic/util/opencv/CvUtil.h>
+#include <dirent.h>
+#include <THFeature_i.h>
+#include <zconf.h>
+#include <Ice/Ice.h>
+#include <basic/util/app/AppUtil.h>
+#include <FaceData.hpp>
+#include <FaceSearchServer.h>
+#include <CasiaFaceWrapperN.h>
+#include <basic/util/app/AppPreference.hpp>
+#include <basic/rpc/IceRpc.hpp>
+#include <CurlDownloadImg.hpp>
+#include <uuid/uuid.h>
+#include <jsoncpp/json/json.h>
+
+using namespace cv;
+using namespace std;
+
+Base64 base64;
+//void* test(void* arg){
+//#ifdef TestCode
+//    IceRpcClient<AlarmServerInterface::AlarmCompareServerPrx> client("FaceDBCompare", "", 10028, "tcp");
+//    auto server = client.getServer();
+//#else
+//#endif
+//
+//    std::map<int,std::vector<unsigned char>> db_handle;
+//    {
+//        LoginDB g_dbLogin;
+//        g_dbLogin.ip = "192.168.1.81";
+//        g_dbLogin.port = 8066;
+//        g_dbLogin.dbName = "VIDEO_STRUCTURE";
+//        g_dbLogin.userName = "root";
+//        g_dbLogin.pwd = "root";
+//        MYSQL conn;
+//        mysql_init(&conn);
+//        bool connectStatus = mysql_real_connect(&conn,g_dbLogin.ip.c_str(),g_dbLogin.userName.c_str()
+//                ,g_dbLogin.pwd.c_str(),g_dbLogin.dbName.c_str(),g_dbLogin.port,NULL,CLIENT_FOUND_ROWS);
+//        if(connectStatus)
+//        {
+//            //#todo modify sql
+//            string sql = "select drug_id,feature FROM o_t_p_drug_feature where 1=1 and feature is not NULL limit 500";
+//            {
+//                ClockTimer ct2("mysql_query");
+//                int ret=mysql_query(&conn,sql.data());
+//                if(ret == 0){
+//                    printf("OK\n");
+//                }else{
+//                    printf("error::%s\n",mysql_error(&conn));
+//                }
+//            }
+//
+//            //灏嗘煡璇㈠埌鐨勭粨鏋滈泦瀛樻斁鍦ㄤ复鏃跺彉閲忎腑
+//            MYSQL_RES *result = NULL;
+//            result = mysql_store_result( &conn );
+//
+//            //寰楀埌鏌ヨ鍑烘潵鎵�鏈夋暟鎹殑鏉℃暟
+//            int row_count = mysql_num_rows(result);
+//            if (row_count <= 0) {
+//                INFO("not found data!!!")
+//                return NULL;
+//            }
+//            //鏄剧ず琛ㄤ腑鐨勬墍鏈夋暟鎹�
+//            {
+//                ClockTimer ct2("mysql_fetch_row");
+//                int loop = 0;
+//
+//                MYSQL_ROW row = NULL;
+//                row = mysql_fetch_row( result );
+//                while ( NULL != row )
+//                {
+//                    string ft = row[1];
+//                    string str2;
+//                    int a = ft.length();
+//                    str2 = base64.Decode(ft.data(),ft.length());
+//
+//                    FaceFeature tmp;
+//                    tmp.resize(str2.length());
+//                    memset(tmp.data(), 0,str2.length());
+//                    memcpy(tmp.data(),str2.data(),str2.length());
+//                    int b = tmp.size();
+//                    db_handle[atoi(row[0])] = tmp;
+//                    tmp.clear();
+//                    row = mysql_fetch_row( result );
+//                }
+//
+//                mysql_free_result(result);
+//            }
+//
+//        }else{
+//            printf("connectStatus error\n");
+//        }
+//
+//        {
+//            ClockTimer ct3("close");
+//            mysql_close(&conn);
+//        }
+//    }
+//
+//    ::AlarmServerInterface::AlarmInformation t_alarmData;
+//
+//    t_alarmData.carmera_id = "1";
+//    t_alarmData.create_time = "2018-03-25 18:07:53";
+//    t_alarmData.alarm_url = "vvvvvadsfasd";
+//    t_alarmData.resoure_id = "vvvvvadsfasd";
+//    t_alarmData.flag_eq_pf = "aaa";
+//    int loop = 0;
+//    while(true){
+//        for(auto item : db_handle){
+//            if(loop++ > 20 ){
+//                break;
+//            }
+//            t_alarmData.faceFeature = item.second;
+//            int c = t_alarmData.faceFeature.size();
+//            INFO("sumbitData"<<item.first);
+//            server->sumbitData(t_alarmData);
+//            sleep(1);
+//        }
+////        while(loop <= 20)
+////        {
+////            ::AlarmServerInterface::AlarmRule iceP_alarmRule;
+////            ::AlarmServerInterface::PersonAlarmRule m;
+////            iceP_alarmRule.fllow_id = to_string(loop++);
+////            iceP_alarmRule.tableName = "o_t_p_fllow22";
+////            iceP_alarmRule.rule_Type = "0";
+////            server->addRules(iceP_alarmRule);
+////        }
+//        loop=0;
+//    }
+//}
+//
+
+CvUtil cvutil;
+
+int main(int argc, char *argv[]) {
+    SAVE_APP_ARGS
+
+    ENABLEGLOG("./log/");
+    Ice::CommunicatorHolder ich(argc, argv);
+
+//    Ice::ObjectPrx base = ich->stringToProxy("FaceSearchServer");
+    IceRpcClient<FaceSearch::FaceFeatureSearchServerPrx> client("faceCmServer", "", 10004, "tcp");
+    auto server = client.getServer();
+//    auto server = FaceSearch::FaceFeatureSearchServerPrx::checkedCast(base);
+
+
+    string str_uuid;
+    uuid_t t_uuid;
+    char str[36];
+    uuid_generate(t_uuid);
+    uuid_unparse(t_uuid, str);
+    str_uuid = str;
+
+    Json::Value t_json;
+    t_json["Id"] = str_uuid; //涓婚敭
+//#todo
+    t_json["FaceFeature"] = "base64";//纭瀵逛笉瀵� 浜鸿劯鐗瑰緛杞垚瀛楃涓诧紒锛侊紒//鏍煎紡杞寲
+
+    t_json["picName"] = "wait todo";
+
+    t_json["personId"] = "wait todo";//鍏宠仈搴曞簱浜哄憳id,浜鸿劯id
+    t_json["BaseName"] = "wait todo";//鍏宠仈搴曞簱琛ㄥ悕
+
+    t_json["personPicUrl"] = "wait todo";//浜哄憳鍥剧墖 store
+    t_json["likePer"] = "";//浜哄憳鐩镐技搴� Score
+    t_json["likeDate"] = "2018-01-01 01:01:01";//姣旇緝鏃堕棿
+    t_json["picAddress"] = "wait todo";//鎶撴媿鍦板潃
+    t_json["picMaxUrl"] = "wait todo";//澶у浘璺緞
+    t_json["picLocalUrl"] = "wait todo";//鏈湴璺緞
+    t_json["picSmUrl"] = "wait todo";//浜哄憳鎶撳皬鍥�
+    t_json["picDate"] = "2018-01-01 01:01:01";
+    t_json["content"] = "wait todo";
+    t_json["viType"] = "1";//鍙湁4绉嶇被鍨� 1:personface 2:personbody 3:car 4:bicycle 5:none 鏈煡绫诲瀷
+    t_json["personIsHub"] = "1";//1: 鎶ヨ  2: 鍙枒  3: 瀹夊叏  4: 鏈煡
+
+
+    //faceExtractElement.setProperty("dev_id", str_device_id);
+    //faceExtractElement.setProperty("cg_id", str_ch_id);
+    t_json["videoNum"] = "";//Vide缂栧彿 澶栭敭
+    t_json["videoReqNum"] = "123456";//Video璁惧缂栧彿
+    t_json["ChannlId"] = "33";//閫氶亾id
+    t_json["isDelete"] = "1";//榛樿1 ,0鏃犳晥 1鏈夋晥
+
+    //浜鸿劯灞炴��
+    t_json["Age"] = "18";//妫�娴嬬殑骞撮緞  搴旇涓虹┖ 鏃犳娴嬬粨鏋�
+    t_json["Gender"] = "1";//妫�娴嬬殑鎬у埆 涓虹┖ 鏃犳娴嬬粨鏋�
+    t_json["BeautyLevel"] = "5";//妫�娴嬬殑缇庡寲姘村钩 涓虹┖ 鏃犳娴嬬粨鏋�
+    t_json["SimleLevel"] = "25";//妫�娴嬬殑寰瑧姘村钩 涓虹┖ 鏃犳娴嬬粨鏋�
+    t_json["Race"] = "1";//妫�娴嬬殑绉嶆棌  搴旇涓虹┖ 鏃犳娴嬬粨鏋�
+
+
+    DBG(t_json.toStyledString());
+
+
+//    return 0;
+    appPref.setLongData("thread.max", 1);
+    CasiaFaceWrapperN t_CasiaFaceWapper;
+//    string test1 = "http://192.168.1.65:8888/group1/M00/04/52/wKgBQVr5J-WAJ4lQAAAObkm3j38169.jpg";
+//    string test2 = "http://192.168.1.65:8888/group1/M00/04/52/wKgBQVr5JGOAXmx9AAAK0Xp3QhA271.jpg";
+//    CurlDownloadImg curlDownloadImg;
+    {
+//        auto curlImg = curlDownloadImg.download_jpeg(const_cast<char *>(test2.c_str()));
+//        cout << " image is " << test1 << endl;
+        long t_id = 0;
+//        if (curlImg.all > 0) {
+        if (true) {
+            Mat image = imread("/home/bsk/work/development/c++/Qt-test/testFastDfs/build/fastdfs/18.jpg");
+//            cvutil.buffer2CvMat(curlImg.buffer, image);
+
+            FaceImageN faceImage2{image.cols, image.rows, image.step, image.data};
+//            auto res = t_CasiaFaceWapper.extractFace(faceImage2);
+            auto faceResults = t_CasiaFaceWapper.extractFace(faceImage2);
+
+            DBG("faceResults" << faceResults.size());
+            for (auto item : faceResults) {
+                ::FaceSearch::Data t_fea;
+                t_fea.resize(item.feature.size());
+                memcpy(t_fea.data(), item.feature.data(), item.feature.size());
+                try {
+                    std::vector<::std::string> tables{"aaa1", "TestFace2", "TestFace3", "TestFace4"};
+                    auto re = server->faceSearchTopN(t_fea, t_json.toStyledString(), 1, 0.8);
+                    INFO("faceSearchMax  " << re.size());
+                    for (auto item : re) {
+                        INFO("faceSearchMax id " << (item.uuid));
+                        INFO("faceSearchMax confidence " << (item.confidence));
+                        INFO("faceSearchMax tableName " << (item.tableName));
+                    }
+                    //                                sleep(3);
+//                    ::std::vector<::std::string> tables2{"aaa1", "TestFace2", "TestFace3", "TestFace4"};
+//                    auto re2 = server->faceSearchTopN(t_fea, 5, tables2);
+//                    INFO("faceSearchTopN  " << re2.size());
+//                    for (auto item : re2) {
+//                        INFO("faceSearchTopN id " << (item.uuid));
+//                        INFO("faceSearchTopN confidence " << (item.confidence));
+//                        INFO("faceSearchTopN tableName " << (item.tableName));
+//                    }
+                } catch (std::exception ex) {
+                    ERR(ex.what());
+                }
+                t_fea.clear();
+            }
+        }
+    }
+    return 0;
+}
+
+//void test22333() {
+//
+//    int loop = 0;
+////#todo
+//    while (1) {
+//        string t_path = "./img/";
+//        DIR *dp = opendir(t_path.c_str());
+//        if (dp != NULL) {
+//            struct dirent *ep;
+//            int loop = 0;
+//            while (
+//                ep = readdir(dp)
+//                ) {
+//                string path(ep->d_name);
+//                if (path.find(".jpg") == std::string::npos) {
+//                    ERR("Couldn't find jpg.");
+//                    continue;
+//                } else {
+//                    printf("jpg url: %s\n", path.
+//
+//                        c_str()
+//
+//                    );
+//                }
+//
+//                string tName(t_path);
+//                tName.
+//                    append(path);
+//                Mat img1 = imread(tName);           // ST_PIX_FMT_BGR888
+//                if (!img1.data) {
+//                    printf("read first image file failed. url: %s\n", tName.
+//
+//                        c_str()
+//
+//                    );
+//                    continue;
+//                } else {
+//                    INFO("read img ok!");
+//                }
+//                FaceImageN faceImage{img1.cols, img1.rows, img1.step, img1.data};
+////    m_casiaFaceWrapper.extractFace(faceImage);
+//                auto faceResults = t_CasiaFaceWapper.extractFace(faceImage);
+//
+//                DBG("faceResults" << faceResults.size());
+//                for (
+//                    auto item
+//                    : faceResults) {
+//                    ::FaceSearch::Data t_fea;
+//                    t_fea.
+//                        resize(item
+//                                   .feature.
+//
+//                        size()
+//
+//                    );
+//                    memcpy(t_fea
+//                               .
+//
+//                                   data(), item
+//
+//                               .feature.
+//
+//                        data(), item
+//
+//                               .feature.
+//
+//                        size()
+//
+//                    );
+//                    try {
+//                        ::std::vector<::std::string> tables{"o_t_p_escape", "TestFace2", "TestFace3", "TestFace4"};
+//                        auto re = server->faceSearchMax(t_fea, tables);
+//                        INFO("faceSearchMax  " << re.size());
+//                        for (
+//                            auto &item
+//                            : re) {
+//                            INFO("faceSearchMax id " << (item.id));
+//                            INFO("faceSearchMax confidence " << (item.confidence));
+//                            INFO("faceSearchMax tableName " << (item.tableName));
+//                        }
+////                                sleep(3);
+//                        ::std::vector<::std::string> tables2{"o_t_p_escape", "TestFace2", "TestFace3", "TestFace4"};
+//                        auto re2 = server->faceSearchTopN(t_fea, 5, tables2);
+//                        INFO("faceSearchTopN  " << re2.size());
+//                        for (
+//                            auto &item
+//                            : re2) {
+//                            INFO("faceSearchTopN id " << (item.id));
+//                            INFO("faceSearchTopN confidence " << (item.confidence));
+//                            INFO("faceSearchTopN tableName " << (item.tableName));
+//                        }
+//                    } catch (
+//                        std::exception ex
+//                    ) {
+//                        ERR(ex.what());
+//                    }
+//                    t_fea.
+//
+//                        clear();
+////#todo if sc add message
+////else nothing
+//                }
+////        extractFace(FaceImage image, vector<unsigned char>& feature, int& faceNum);
+////                        vector<unsigned char> feature;
+////                        vector<unsigned char> feature2;
+////                        cvutil.cvMat2Buffer(img1,feature);
+////                        auto test = feature.size();
+//////                        DBG(test)
+////                        ::FaceSearch::Data t_fea;
+////                        t_fea.resize(feature.size());
+////                        memcpy(t_fea.data(),feature.data(),feature.size());
+////                        try {
+//////                server->addFace(t_fea,"aaa");addFaceWithId
+//////                            server->addFaceWithId(t_fea,(++loop),"aaa");
+//////                            sleep(1);
+//////                            server->addFaceWithId(t_fea,(loop),"bbb");
+////                            ::std::vector< ::std::string> tables{"aaa","bbb"};
+////                            auto re = server->faceSearchMax(t_fea,tables);
+////
+////                            INFO("faceSearchMax  " << re.size() );
+////                            for (auto& item : re) {
+////                                INFO("faceSearchMax id " << ( item.id));
+////                                INFO("faceSearchMax confidence " << ( item.confidence));
+////                                INFO("faceSearchMax tableName " << ( item.tableName));
+////                            }
+////                            sleep(3);
+////                        }catch (std::exception ex){
+////                            ERR(ex.what());
+////                        }
+////                        feature.clear();
+////            break;
+////            int faceNum;
+////            FaceImageN faceImage {img1.cols, img1.rows, img1.step, img1.data};
+////            //#todo pthread
+////            auto res = t_CasiaFaceWapper.extractFace(faceImage);
+////            for (auto item : res) {
+//////                item.feature
+//////addFace(const ::FaceSearch::Data& iceP_jpgData, const ::std::string& iceP_tableName, const ::Ice::Context& context = ::Ice::noExplicitContext)
+////                ::FaceSearch::Data t_fea;
+////                t_fea.resize(item.feature.size());
+////                memcpy(t_fea.data(),item.feature.data(),item.feature.size());
+////
+////                try {
+////                    server->addFace(t_fea,"aaa");
+////                    INFO("add");
+////                }catch (std::exception ex){
+////                    ERR(ex.what());
+////                }
+////            }
+//
+//                printf("\n");
+//                printf("\n");
+//                printf("\n");
+//                printf("\n");
+//            }
+//            closedir(dp);
+//        } else {
+//            ERR("Couldn't open the directory.");
+//        }
+////                break;
+//        sleep(10);
+//    }
+//
+//
+//
+//
+////    try {
+////        long out;
+////        auto temp = server2->getDbActions(000,out);
+////        cout << temp.size() << endl;
+////        cout << out << endl;
+////        INFO("getDbActions");
+////    }catch (std::exception ex){
+////        ERR(ex.what());
+////    }
+////getchar();
+//    return 0;
+//
+//}
+
diff --git a/FaceDBCompareServer.cpp b/FaceDBCompareServer.cpp
new file mode 100644
index 0000000..f592c31
--- /dev/null
+++ b/FaceDBCompareServer.cpp
@@ -0,0 +1,217 @@
+//
+// Created by ps on 2/26/18.
+//
+
+#include <cstring>
+#include <THFeature_i.h>
+#include <basic/util/app/AppPreference.hpp>
+#include <basic/util/ShareMemory/ShareMemoryTool.hpp>
+#include "FaceDBCompareServer.h"
+
+using namespace std;
+
+FaceDBCompareServer::FaceDBCompareServer() : m_erlangDbTool(nullptr), m_sqliteFaceEncap(nullptr) {
+
+}
+
+FaceDBCompareServer::FaceDBCompareServer(ErlangTool::ErlangDbTool *erlangDbTool) : m_erlangDbTool(erlangDbTool),
+                                                                                   m_sqliteFaceEncap(nullptr) {
+
+}
+
+FaceDBCompareServer::FaceDBCompareServer(SqliteFaceEncap *sqliteFaceEncap) : m_erlangDbTool(nullptr),
+                                                                             m_sqliteFaceEncap(sqliteFaceEncap) {
+
+}
+
+//FaceDBCompareServer::FaceDBCompareServer(Ice::CommunicatorHolder& ich) : minThreshold(10)  {
+//#ifdef TestCode
+//
+//#else
+//    try {
+//        base_alarm = ich->stringToProxy("ServerAlarm");
+//    }catch(std::exception ex){
+//        ERR("ServerAlarm connceticon fail" << ex.what());
+//    };
+//#endif
+//}
+
+FaceDBCompareServer::~FaceDBCompareServer() {
+
+}
+
+FaceResults FaceDBCompareServer::getTopResult(std::thread::id key) {
+    if (m_dbRWLocks.find(key) == m_dbRWLocks.end()) {
+        m_dbRWLocks[key] = RWLock();
+    }
+    RWLock &t_rwl = m_dbRWLocks[key];
+//    t_rwl.wrlock();
+    FaceResults t_result = topResult[key];
+    topResult.erase(key);
+    t_rwl.unlock();
+    return t_result;
+}
+
+//#todo map 1->2 modify 2->1
+bool FaceDBCompareServer::compare(thread::id key, AlarmData *alarmData, int topN, float score) {
+    if (m_dbRWLocks.find(key) == m_dbRWLocks.end()) {
+        m_dbRWLocks[key] = RWLock();
+    }
+//    閿佷换鍔$殑瀵规瘮缁撴灉
+    RWLock &t_rwl = m_dbRWLocks[key];
+//    ClockTimer clockTimer("compare ");
+    RWLock t_rwLock;
+
+    m_rwLock.rdlock();
+    mapFaceResults t_compareResults;
+
+    parallelFor(ParallelForThreardSize::CPU_Number, [&](string &key, FeatureData &data) {
+        //#todo
+        double sc = 0;
+        for (auto &t_fea : data.features) {
+            double t_sc = m_casiaFaceWapper.compareFeature(alarmData->feature, t_fea);
+//                鑾峰彇褰撳墠瀵规瘮鐨勬渶楂樺垎锛�
+            sc = t_sc > sc ? t_sc : sc;
+        }
+//            FaceResult tface{data.face_id, data.uuid, alarmData->tableName, sc, false};
+        FaceResult tface{0, data.uuid, alarmData->tableName, sc, data.faceUrl, data.idcard, "", data.enabled};
+        t_rwLock.wrlock();
+//            濡傛灉褰撳墠璁板綍鐨勬墍鏈夌壒寰佺殑鏈�楂樺垎灏忎簬缁撴灉涓殑鏈�浣庡垎鍒欎笉淇濆瓨
+        if (sc < score || sc < t_compareResults.end()->second.confidence) {
+            t_rwLock.unlock();
+            return;
+        }
+        t_compareResults.insert(make_pair(tface.confidence, tface));
+        if (topN != 0 && t_compareResults.size() > topN) {
+            t_compareResults.erase((--t_compareResults.end()), t_compareResults.end());
+        }
+        t_rwLock.unlock();
+    });
+
+    m_rwLock.unlock();
+
+    int maxSearchFaces = alarmData->num;
+
+    t_rwl.wrlock();
+    auto &t_topResult = topResult[key];
+    t_topResult.clear();
+    for (auto &item : t_compareResults) {
+        auto &it = item.second;
+        //#todo
+//        if (it.confidence <= 0.6) {
+//            continue;
+//        }
+        FaceResult t_CR{it.id, it.uuid, it.tableName, it.confidence, it.face_img_url, it.idCard, it.alarmRet,
+                        it.enabled};
+        //cout << __FUNCTION__ << " -> " << __LINE__ << " ->  scroe" << it.confidence << endl;
+        t_topResult.push_back(t_CR);
+    }
+    while (topResult.size() > maxSearchFaces)
+        t_topResult.pop_back();
+//    鑾峰彇缁撴灉鍚庨噴鏀�
+//    t_rwl.unlock();
+    return true;
+}
+
+void FaceDBCompareServer::loadDBData(std::string str_config) {
+    string log = "loadDBData  " + str_config;
+    ClockTimer clk(log);
+
+    Json::Value t_json;
+    Json::FastWriter writer;
+    Json::Reader reader;
+
+    if (reader.parse(str_config, t_json)) {
+
+        m_rwLock.wrlock();
+        if (t_json["\"syncTpye\""].type() == Json::nullValue) {
+//            鍚屾搴�/鐗瑰緛鏄痓ase64
+//            #todo sqlite search data from file
+            auto str_tab = t_json["\"tableName\""].asString();
+            m_tableName = str_tab.substr(1, str_tab.length() - 2);//.append("_fea");
+
+
+
+//            string tet = "./syncDBClient ";
+//            string str_json = writer.write(t_json);
+//            tet.append("\"" + str_json.substr(0, str_json.length() - 1) + "\" ");
+//            INFO(tet);
+//            system(tet.c_str());
+            dataMap.clear();
+            try {
+                // init
+//                BISTL::BiMapFeaData biMapFeaData(m_tableName);
+//                auto mymap = biMapFeaData.getMap();
+
+                auto mymap = m_erlangDbTool->loadFaceFeaData(m_tableName);
+                for (auto &item : mymap) {
+                    auto &it = item.second;
+                    string str2;
+                    str2 = base64.Decode(it.feature.data(), it.feature.size());
+                    std::vector<unsigned char> t_fea;
+                    t_fea.resize(str2.size());
+                    memcpy(t_fea.data(), str2.data(), str2.size());
+                    auto &test = dataMap[it.id];
+                    test.uuid = it.id;
+                    test.features.push_back(t_fea);
+                    test.faceUrl = it.img;
+                    test.idcard = it.idcard;
+                }
+//                //#todo
+//                for (auto it = mymap->begin(); it != mymap->end(); it++) {
+//                    string str_uuid(it->second.m_id.data());
+//                    string ft(it->second.m_feature.data());
+//                    string imgUrl(it->second.m_imgUrl.data());
+//                    string strIdCard(it->second.m_idcard.data());
+//                    string str2;
+//                    str2 = base64.Decode(ft.data(), ft.length());
+//                    std::vector<unsigned char> t_fea;
+//                    t_fea.resize(str2.size());
+//                    memcpy(t_fea.data(), str2.data(), str2.size());
+//                    auto &test = dataMap[str_uuid];
+//                    test.uuid = str_uuid;
+//                    test.features.push_back(t_fea);
+//                    test.faceUrl = imgUrl;
+//                    test.idcard = strIdCard;
+//                }
+            } catch (const std::exception &e) {
+                printf("Exception:%s\n", e.what());
+//                BISTL::shared_memory_object::remove(m_tableName.c_str());
+            }
+//            BISTL::shared_memory_object::remove(m_tableName.c_str());
+        } else {
+//            鏈湴搴�/鐗瑰緛鏄痓lob
+            m_tableName = t_json["tableName"].asCString();
+            auto t_res = m_sqliteFaceEncap->getFacesFromTable(m_tableName);
+            auto t_faceInfoCache = m_sqliteFaceEncap->getFaceInfoFromTable(m_tableName);
+            auto &res = *t_res;
+            //#todo
+            DBG(m_tableName << "clear before size is " << dataMap.size());
+            dataMap.clear();
+            DBG(m_tableName << "clear after size is " << dataMap.size());
+            for (auto &item : res) {
+                auto &t_sen = item.second;
+                std::vector<unsigned char> t_fea;
+                t_fea.resize(t_sen.faceFeature.size());
+                memcpy(t_fea.data(), t_sen.faceFeature.data(), t_sen.faceFeature.size());
+                auto &test = dataMap[t_sen.uuid];
+                test.uuid = t_sen.uuid;
+                test.features.push_back(t_fea);
+                test.faceUrl = t_sen.faceurl;
+                test.idcard = t_faceInfoCache[t_sen.uuid].idCard;
+                test.enabled = t_sen.enable;
+            }
+        }
+//            鍛婅瘔鍒锋柊鍑芥暟锛屽綋鍓嶅簳搴撶殑鏁版嵁鍑嗗瀹屾垚
+        appPref.setIntData(m_tableName, 1);
+        DBG(m_tableName << " size is " << dataMap.size());
+        m_rwLock.unlock();
+    } else {
+        ERR("json format error :: " << str_config);
+        appPref.setIntData(str_config, 1);
+    }
+
+}
+
+
+
diff --git a/FaceDBCompareServer.h b/FaceDBCompareServer.h
new file mode 100644
index 0000000..492fbbf
--- /dev/null
+++ b/FaceDBCompareServer.h
@@ -0,0 +1,63 @@
+//
+// Created by ps on 2/26/18.
+//
+
+#ifndef COMPARETEST_FACEDBCOMPARESERVER_H
+#define COMPARETEST_FACEDBCOMPARESERVER_H
+
+#include <pthread.h>
+
+#include <Ice/Ice.h>
+#include <basic/rpc/IceRpc.hpp>
+#include <FaceSearchServer.h>
+#include "AlarmServer.hpp"
+#include "CasiaFaceWrapper/CasiaFaceWrapperN.h"
+#include <basic/util/thread/RWLock.hpp>
+#include <ErlangDbTool.h>
+#include <SqliteFaceEncap.h>
+
+class FaceDBCompareServer : public AlarmServer {
+
+public:
+    FaceDBCompareServer();
+
+    FaceDBCompareServer(SqliteFaceEncap *);
+
+    FaceDBCompareServer(ErlangTool::ErlangDbTool *);
+
+    ~FaceDBCompareServer();
+
+    virtual bool compare(std::thread::id key, AlarmData *alarmData, int topN, float score = 0.0);
+
+    FaceResults getTopResult(std::thread::id key);
+
+private:
+    virtual void loadDBData(std::string str_config);
+
+protected:
+    CasiaFaceWrapperN m_casiaFaceWapper;
+    std::string m_tableName;
+
+    int fea_size;
+//    閿佹暟鎹埛鏂�
+    RWLock m_rwLock;
+    std::mutex topResultMtx;
+    std::map<std::thread::id, FaceResults> topResult;
+    std::map<std::thread::id, RWLock> m_dbRWLocks;
+
+    ErlangTool::ErlangDbTool *m_erlangDbTool;
+    SqliteFaceEncap *m_sqliteFaceEncap;
+
+};
+
+static bool getRet(std::string startTime, std::string endTime) {
+    auto crrentTime = AppUtil::getTimeSecString();
+
+    if (crrentTime.compare(startTime) > 0 && crrentTime.compare(endTime) < 0) {
+        return true;
+    }
+    return false;
+
+}
+
+#endif //COMPARETEST_FACEDBCOMPARESERVER_H
diff --git a/FaceFeatureSearchServerI.cpp b/FaceFeatureSearchServerI.cpp
new file mode 100644
index 0000000..c8e3613
--- /dev/null
+++ b/FaceFeatureSearchServerI.cpp
@@ -0,0 +1,422 @@
+//
+// Created by pans on 4/27/18.
+//
+
+#include <iostream>
+
+#include "jsoncpp/json/json.h"
+
+#include <basic/debug/Debug.h>
+#include <basic/util/app/AppPreference.hpp>
+#include "FaceFeatureSearchServerI.h"
+
+using namespace std;
+
+static std::string t_cNodeName = "FaceSearch";
+
+void erlangCallBackFunc(std::string) {
+    DBG("erlangCallBackFunc");
+    pthread_cond_signal(&(func_cond));
+    pthread_mutex_unlock(&(func_cond_mutex));
+}
+
+FaceFeatureSearchServerI::FaceFeatureSearchServerI()
+    : m_erlangDbTool(appConfig.getStringProperty("erlPath"), appConfig.getStringProperty("erlNode"),
+                     appConfig.getStringProperty("erlCookie"), t_cNodeName), m_retUpdatePthread(true),
+      pManagerEsDB(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort")), m_sqliteFaceEncap("LocalDataDB") {
+
+    auto erlFatherNode = appConfig.getStringProperty("erlFatherNode");
+    if (m_erlangDbTool.initErlang() == 1) {
+        m_erlangDbTool.startNodeDb(erlFatherNode);
+    }
+
+    m_erlangDbTool.test(&func_cond, &func_cond_mutex);
+
+    loadFeatureData(this);
+}
+
+FaceFeatureSearchServerI::FaceFeatureSearchServerI(Ice::CommunicatorPtr &ich, string nodeName, string cookie)
+    : m_erlangDbTool(nodeName, cookie, t_cNodeName), m_retUpdatePthread(true),
+      pManagerEsDB(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort")),
+      m_sqliteFaceEncap("LocalDataDB") {
+
+//    try {
+//        std::string identity2 = ich->getProperties()->getProperty("user.FaceData");
+//        DBG(identity2);
+//        base_FaceMemoryData = ich->stringToProxy(appPref.getStringData("user.FaceData"));
+//    } catch (std::exception ex) {
+//        ERR("base_FaceMemoryData connceticon fail" << ex.what());
+//    };
+
+    loadFeatureData(this);
+}
+
+FaceFeatureSearchServerI::~FaceFeatureSearchServerI() {
+    t_live_ret = false;
+}
+
+/***
+ * @dep
+ */
+::FaceSearch::FaceResults
+FaceFeatureSearchServerI::faceSearchMax(const ::FaceSearch::Data &feature, const ::std::string &info_json,
+                                        const ::Ice::Current &) {
+    return ::FaceSearch::FaceResults();
+}
+
+//#todo 浼樺寲
+::FaceSearch::FaceResults
+FaceFeatureSearchServerI::faceSearchTopN(const ::FaceSearch::Data &feature, const ::std::string &info_json,
+                                         ::Ice::Int topN, ::Ice::Float score, const ::Ice::Current &) {
+    ClockTimer clockTimer("faceSearchTopN  " + to_string(score) + "  :");
+    INFO("faceSearchTopN start");
+//    #鑾峰彇绾跨▼id鍘绘壘璧勬簮鍙ユ焺
+    thread::id key = std::this_thread::get_id();
+//    杩斿洖缁撴灉
+    ::FaceSearch::FaceResults results;
+//    瀵规瘮缁撴灉鐨勪复鏃剁紦瀛�
+    FaceResults t_TableCompareResult;
+//    闇�瑕佸姣旂殑鏁版嵁
+    AlarmData featureData;
+    featureData.num = topN;
+    featureData.feature.resize(feature.size());
+    memcpy(featureData.feature.data(), feature.data(), feature.size());
+
+    Json::Reader reader;
+    Json::Value value;
+
+    if (reader.parse(info_json, value)) {
+        //#todo
+        m_rwLock.rdlock();
+//        寮�濮嬪姣�
+        DBG("auto &it : m_faceFCMAP start " << m_faceFCMAP.size());
+        //#todo lock
+//        閬嶅巻涓嶅悓鐨勫簳搴撶被#TODO鏄惁瑕佸仛涓�娆″ぇ鑼冨洿瀵规瘮鐒跺悗缁欏嚭缁撴灉鍐嶇瓫閫夛紵
+        for (auto &it : m_faceFCMAP) {
+            auto &t_FaceFC = it.second;
+//            琛ㄧ殑淇℃伅#TODO寰呯Щ鍑哄拰涓氬姟瑙h��
+            auto t_tableInfo = m_tableType[it.first];
+//            鍒ゆ柇琛ㄧ殑鐢熸晥鐘舵�侊紝鍐冲畾鏄惁杩涜瀵规瘮/鏃堕棿鍜屽惎鐢ㄧ姸鎬�
+            bool ret = (t_tableInfo.enabled == "1" && getRet(t_tableInfo.startTime, t_tableInfo.endTime));
+            if (ret) {
+//                闇�瑕佸姣�
+
+//                琛ㄧ殑绫诲瀷/榛戠櫧鍚嶅崟
+                string t_alarmRet = t_tableInfo.bwType;
+//                bool alarmRet = atoi(t_tableInfo.bwType.c_str());
+                //#todo 闈炲悓姝ュ簱鏄惁闇�瑕佹瘮杈冿紵
+
+                DBG("m_faceFCMAP compare start " << it.first);
+//                瀵规瘮鍑芥暟
+                t_FaceFC->compare(key, &featureData, topN);
+                DBG("m_faceFCMAP compare end " << it.first);
+//                鑾峰彇瀵规瘮缁撴灉
+                auto t_results = t_FaceFC->getTopResult(key);
+//                閬嶅巻缁撴灉骞舵坊鍔犺ˉ鍏呭瓧娈�
+                for (auto &t_item : t_results) {
+                    t_item.tableName = it.first;
+                    t_item.alarmRet = t_alarmRet;
+//                    鏀惧叆鏈浠诲姟鐨勫姣旂紦瀛�
+                    t_TableCompareResult.push_back(t_item);
+//                    DBG("t_results item : uuid is " << t_item.uuid << " confidence " << t_item.confidence << it.first);
+                }
+            } else {
+//                涓嶉渶瑕佸姣�
+                INFO("m_faceFCMAP ret is false " << it.first);
+            }
+        }
+        m_rwLock.unlock();
+        DBG("auto &it : m_faceFCMAP end");
+//        鏈浠诲姟鐨勫姣旂粨鏋滄暟閲�
+        DBG("t_TableCompareResult size" << t_TableCompareResult.size());
+        //sort_all_results
+//        鎵�鏈夎〃瀵规瘮缁撴潫鍚庯紝鎺掑簭鍙婄粨鏋滄牸寮忚浆鎹�
+        for (auto itor = t_TableCompareResult.begin(); itor != t_TableCompareResult.end(); ++itor) {
+            float new_confidence = itor->confidence;
+            auto rtTR = results.rbegin();
+            if (!results.empty()) {
+                auto temp = rtTR->confidence;
+                while (new_confidence > temp) {
+                    ++rtTR;
+                    if (rtTR == (results.rend() + 1)) {
+                        rtTR--;
+                        break;
+                    } else {
+                    }
+                    temp = rtTR->confidence;
+                }
+            } else {
+                ERR("topResult is null");
+            }
+            auto itTR(rtTR.base());
+            ::FaceSearch::FaceResult t_faceCR;
+            t_faceCR.id = itor->id;
+            t_faceCR.uuid = itor->uuid;
+            t_faceCR.tableName = itor->tableName;
+            t_faceCR.confidence = itor->confidence;
+            //#todo url idcard
+            t_faceCR.imgUrl = itor->face_img_url;
+            t_faceCR.idcard = itor->idCard;
+            t_faceCR.alarmRet = itor->alarmRet;
+            DBG("compare results tablename is " << t_faceCR.tableName << " id is " << t_faceCR.uuid << " pic n "
+                                                << t_faceCR.idcard << " sc is" << t_faceCR.confidence);
+            results.insert(itTR, t_faceCR);
+        }
+        bool retface = true;
+
+        //#todo send message
+//        鎷兼帴闇�瑕佸彂閫佺殑娑堟伅
+//        鐗瑰緛缂栫爜涓篵ase64鐢ㄤ簬涓婁紶锛�#todo 鎷嗚В鍒板闈㈠幓鍋�
+        std::string feature_base64;
+        feature_base64 = base64.Encode(feature.data(), feature.size());
+        if (results.size() > 0) {
+//            鎵惧埌鐩镐技浜� 鍙兘瀵规瘮鍒嗘暟涓嶆弧瓒虫潯浠�
+//            #TODO澶氭潯瀵规瘮缁撴灉鎷兼帴鎴愪竴涓爣绛�
+            for (auto &item : results) {
+                //#todo 寰楀垎姣旇緝锛屽簲璇ュ湪compare涓繘琛�
+//                灏忎簬鎸囧畾鐨勯槇鍊煎垯璁や负娌℃湁鎵惧埌鏄檶鐢熶汉
+                if (item.confidence < score) {
+                    //#todo test
+                    auto str_uuid = value["Id"].asString();
+                    value["personIsHub"] = "4";
+                    value["likePer"] = 0.0;
+//                    DBG(value.toStyledString());
+                    DBG("value.toStyledString()  " << value.toStyledString());
+                    value["FaceFeature"] = feature_base64;
+
+                    retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", value.toStyledString(),
+                                                      str_uuid);
+                    break;
+                }
+                value["personId"] = item.uuid.size() > 0 ? item.uuid : "";//鍏宠仈搴曞簱浜哄憳id,浜鸿劯id
+
+//                string tmp_tableName = item.tableName;
+//                if (tmp_tableName.find("lt_") == 0) {
+//                    tmp_tableName = tmp_tableName.insert(tmp_tableName.find("lt_") + 3, "::");
+//                    value["BaseName"] = tmp_tableName;//鍏宠仈搴曞簱琛ㄥ悕
+//                } else {
+//                    value["BaseName"] = item.tableName.size() > 0 ? item.tableName : "";//鍏宠仈搴曞簱琛ㄥ悕
+//                }
+
+                value["BaseName"] = item.tableName.size() > 0 ? item.tableName : "";//鍏宠仈搴曞簱琛ㄥ悕
+
+                value["likePer"] = item.confidence > 0 ? item.confidence : 0.0;
+                value["personPicUrl"] = item.imgUrl.size() > 0 ? item.imgUrl : "";//diku tupian
+                value["idcard"] = item.idcard.size() > 0 ? item.idcard : "";//diku tupian
+                //濡傛灉 alarmRet 涓嶄负绌烘妸 浠栫殑鍊� 鏀惧叆 personIsHub,鍚﹀垯涓�4
+//                #TODO 濡傛灉鍚敤鍒欐甯稿垽鏂�,鏈竷鎺у垯璁や负鏄湭鐭ワ紵
+//                if () {
+//
+//                }
+                value["personIsHub"] = item.alarmRet.size() > 0 ? item.alarmRet : "4";
+
+                auto str_uuid = value["Id"].asString();
+                DBG("value.toStyledString()  " << value.toStyledString());
+                value["FaceFeature"] = feature_base64;
+
+                retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", value.toStyledString(),
+                                                  str_uuid);
+                break;
+            }
+        } else {
+            auto str_uuid = value["Id"].asString();
+            value["personIsHub"] = "4";
+            value["likePer"] = 0.0;
+            DBG(value.toStyledString());
+            value["FaceFeature"] = feature_base64;
+//            cout << __FUNCTION__ << " -> " << __LINE__ << " ->  " << "value.toStyledString()  "
+//                 << value.toStyledString() << endl;
+            retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", value.toStyledString(),
+                                              str_uuid);
+        }
+        if (!retface) {
+            ERR("insert error");
+        } else {
+            cout << __FUNCTION__ << " -> " << __LINE__ << " ->  " << "retface  " << retface << endl;
+        };
+    } else {
+        ERR("json is error" << info_json);
+    }
+    return results;
+}
+
+bool FaceFeatureSearchServerI::loadFeatureData(FaceFeatureSearchServerI *faceFea) {
+    ErlangTool::map_TabDataCache dataBaseCache = faceFea->m_erlangDbTool.findAllDatabase();
+    if (dataBaseCache.size() < 0 && faceFea->m_retUpdatePthread) {
+        faceFea->m_retUpdatePthread = false;
+        std::thread thd(dataUpdate, faceFea);
+        thd.detach();
+    }
+    auto typeInfoCache = faceFea->m_erlangDbTool.findAllTypeInfo();
+    faceFea->m_tableType.clear();
+    string str_config = faceFea->m_erlangDbTool.getConfigJsonString();
+
+
+    Json::Value t_json;
+    Json::FastWriter writer;
+    Json::Reader reader;
+
+    faceFea->m_rwLock.wrlock();
+    if (reader.parse(str_config, t_json)) {
+        for (auto &item : dataBaseCache) {
+            TableInfo tabInfo;
+            tabInfo.tableName = item.first;
+            tabInfo.startTime = item.second.startTime;
+            tabInfo.endTime = item.second.endTime;
+//            tabInfo.bwType = item.second.bwType = typeInfoCache.find(item.first)->second.bwType;
+            tabInfo.bwType = item.second.bwType;//= typeInfoCache.find(item.first)->second.bwType;
+            tabInfo.createBy = item.second.create_by;
+
+            if ((tabInfo.tableName.find("lt_") == 0) && (tabInfo.createBy != appConfig.getStringProperty("erlNode"))) {
+                continue;
+            }
+            string &tableName = item.second.tableName;
+            faceFea->m_tableType[tableName] = tabInfo;
+            appPref.setIntData(tableName, 0);
+            if (faceFea->m_faceFCMAP.find(tableName) == faceFea->m_faceFCMAP.end()) {
+                faceFea->m_faceFCMAP[tableName] = new FaceDBCompareServer(&(faceFea->m_erlangDbTool));
+//                usleep(1000);
+            }
+            t_json["\"tableName\""] = "\"" + tableName + "\"";
+            std::string str_json = writer.write(t_json);
+
+            str_json.substr(0, str_json.length() - 1);
+//            sleep(1);
+            usleep(1500 * 1000);
+            faceFea->m_faceFCMAP[tableName]->initDB(str_json);
+            DBG("initDB tableName " << tableName);
+        }
+    } else {
+        ERR("json format error :: " << str_config);
+    }
+
+    //#todo get data from sqlite3
+    {
+        //#鏌ヨ浜鸿劯搴曞簱鍒楄〃
+        auto res = faceFea->m_sqliteFaceEncap.getTableInfos();
+        for (auto &item : res) {
+            if (item.tableType == "person") {
+                std::cout << "tableName is  " << item.tableName << std::endl;
+
+                {
+                    std::string tableName = item.tableName;
+                    faceFea->m_tableType[tableName] = item;
+                    appPref.setIntData(tableName, 0);
+                    if (faceFea->m_faceFCMAP.find(tableName) == faceFea->m_faceFCMAP.end()) {
+                        faceFea->m_faceFCMAP[tableName] = new FaceDBCompareServer(&(faceFea->m_sqliteFaceEncap));
+                    }
+
+                    Json::Value t_json2;
+                    t_json2.clear();
+
+                    t_json2["\"syncTpye\""] = "local";
+                    t_json2["tableName"] = tableName;
+                    std::string str_json = writer.write(t_json2);
+
+                    str_json.substr(0, str_json.length() - 1);
+                    faceFea->m_faceFCMAP[tableName]->initDB(str_json);
+                    DBG("initDB tableName " << tableName);
+                }
+
+            }
+        }
+    }
+    faceFea->m_rwLock.unlock();
+
+    INFO("get time");
+    faceFea->m_inTime = getTimeLong();
+    if (faceFea->m_retUpdatePthread) {
+        faceFea->m_retUpdatePthread = false;
+        std::thread thd(dataUpdate, faceFea);
+
+//        faceFea->m_erlangDbTool.test(faceFea, erlangCallBackFunc);
+        INFO("start thread");
+        thd.detach();
+    } else {
+        ERR("m_retUpdatePthread is false ");
+    }
+
+    return false;
+}
+
+void FaceFeatureSearchServerI::waitTables(FaceFeatureSearchServerI *faceFea, int loop) {
+    DBG("waitTales");
+    while (t_live_ret) {
+        faceFea->m_rwLock.rdlock();
+        if (faceFea->m_faceFCMAP.size() == 0) {
+            ERR("table size is 0");
+            faceFea->m_rwLock.unlock();
+            return;
+        }
+        bool tmp = true;
+        for (auto &t_face : faceFea->m_faceFCMAP) {
+            auto t_ret = appPref.getIntData(t_face.first);
+            tmp = t_ret & tmp;
+        }
+        if (tmp && faceFea->m_faceFCMAP.size() > 0) {
+            INFO("waitTables ok");
+            faceFea->m_rwLock.unlock();
+            return;
+        } else {
+            ERR("tmp is " << tmp << "  faceFea->m_faceFCMAP.size() is " << faceFea->m_faceFCMAP.size());
+            faceFea->m_rwLock.unlock();
+            usleep(1000);
+//            if (loop != -1 && loop-- < 1) {
+//                ERR("return " << loop);
+//                return;
+//            }
+        }
+    }
+    return;
+}
+
+
+//void FaceFeatureSearchServerI::erlangCallBackFunc(std::string) {
+//    DBG("erlangCallBackFunc");
+//    pthread_cond_signal(&(func_cond));
+//    pthread_mutex_unlock(&(func_cond_mutex));
+//}
+
+void FaceFeatureSearchServerI::dataUpdate(FaceFeatureSearchServerI *faceFea) {
+    long inTime = faceFea->m_inTime;
+    // modify all db ready start update, <10s
+    faceFea->waitTables(faceFea, 100);
+    int loop = 0;
+    long outTime;
+    //update
+    while (t_live_ret) {
+        DBG(" wait lock?");
+        pthread_mutex_lock(&(func_cond_mutex));
+        DBG(" get lock?");
+        pthread_cond_wait(&(func_cond), &(func_cond_mutex));
+        try {
+//            faceFea->m_rwLock.rdlock();
+//            if (faceFea->m_faceFCMAP.size() > 0) {
+//                faceFea->m_rwLock.unlock();
+//            } else {
+//                faceFea->m_rwLock.unlock();
+//            }
+            DBG("update data sleep before ");
+            int sleepTime = appConfig.getIntProperty("FaceSeachSleepTime");
+            sleepTime = sleepTime > 30 ? sleepTime : 30;
+            DBG("sleepTime is " << sleepTime);
+            sleep(30);
+            inTime = outTime;
+            outTime = 0;
+            cout << " loop is " << loop++ << endl;
+            faceFea->loadFeatureData(faceFea);
+            faceFea->waitTables(faceFea, 100000);
+            pthread_mutex_unlock(&func_cond_mutex);
+        } catch (std::exception ex) {
+            ERR(ex.what());
+        }
+    }
+}
+
+
+bool FaceFeatureSearchServerI::initErlang(std::string nodeName, std::string cookie) {
+    //#todo
+//    m_erlangDbTool = ErlangTool::ErlangDbTool(nodeName, cookie);
+    return false;
+}
+
diff --git a/FaceFeatureSearchServerI.h b/FaceFeatureSearchServerI.h
new file mode 100644
index 0000000..7a1c16b
--- /dev/null
+++ b/FaceFeatureSearchServerI.h
@@ -0,0 +1,85 @@
+//
+// Created by pans on 4/27/18.
+//
+
+#ifndef FACESEARCHSERVER_FACEFEATURESEARCHSERVERI_H
+#define FACESEARCHSERVER_FACEFEATURESEARCHSERVERI_H
+
+#include <FaceSearchServer.h>
+#include <Ice/Ice.h>
+#include <basic/rpc/IceRpc.hpp>
+#include <basic/db/Elasticsearch/EsDBTool.h>
+#include <basic/util/app/AppConfig.h>
+
+#include <ErlangDbTool.h>
+#include <SqliteFaceEncap.h>
+#include "FaceDBCompareServer.h"
+
+//struct TableInfo {
+//    std::string tab_name;
+//    std::string startTime;
+//    std::string endTime;
+//    std::string bwType;
+//    std::string create_by;
+//};
+
+static bool t_live_ret = true;
+static pthread_cond_t func_cond(PTHREAD_COND_INITIALIZER);
+static pthread_mutex_t func_cond_mutex(PTHREAD_MUTEX_INITIALIZER);
+
+
+void erlangCallBackFunc(std::string);
+
+class FaceFeatureSearchServerI : public FaceSearch::FaceFeatureSearchServer {
+public:
+    FaceFeatureSearchServerI();
+
+    FaceFeatureSearchServerI(Ice::CommunicatorPtr &ich, std::string nodeName, std::string cookie);
+
+    virtual ~FaceFeatureSearchServerI();
+
+public:
+    virtual ::FaceSearch::FaceResults faceSearchMax(const ::FaceSearch::Data &, const ::std::string &,
+                                                    const ::Ice::Current & = ::Ice::emptyCurrent);
+
+    virtual ::FaceSearch::FaceResults
+    faceSearchTopN(const ::FaceSearch::Data &, const ::std::string &, ::Ice::Int, ::Ice::Float,
+                   const ::Ice::Current & = ::Ice::emptyCurrent);
+
+private:
+    bool initErlang(std::string nodeName, std::string cookie);
+
+    //#todo delete cache
+
+    //#todo loadData
+    static bool loadFeatureData(FaceFeatureSearchServerI *faceFea);
+
+    static void dataUpdate(FaceFeatureSearchServerI *faceFea);
+
+    static void waitTables(FaceFeatureSearchServerI *faceFea, int loop = -1);
+
+//    void erlangCallBackFunc(std::string);
+
+private:
+    long m_inTime;
+    std::map<std::string, FaceDBCompareServer *> m_faceFCMAP;
+    std::map<std::string, TableInfo> m_tableType;
+
+    RWLock m_rwLock;
+    ErlangTool::ErlangDbTool m_erlangDbTool;
+    SqliteFaceEncap m_sqliteFaceEncap;
+    std::mutex m_mutex;
+    bool m_retUpdatePthread;
+
+    Base64 base64;
+//    Ice::ObjectPrx base_FaceMemoryData;
+//    IceRpcClient<::FaceSearch::FaceMemoryDataPrx> m_faceMemoryClient;
+//    ::FaceSearch::FaceMemoryDataPrx serverFaceMemoryData;
+
+//    func_cond_mutex(PTHREAD_MUTEX_INITIALIZER), func_cond(PTHREAD_COND_INITIALIZER)
+
+    EsDBTool pManagerEsDB;//(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort"));
+};
+
+
+#endif //FACESEARCHSERVER_FACEFEATURESEARCHSERVERI_H
diff --git a/LoadFeaTool/CMakeLists.txt b/LoadFeaTool/CMakeLists.txt
new file mode 100644
index 0000000..2c8486f
--- /dev/null
+++ b/LoadFeaTool/CMakeLists.txt
@@ -0,0 +1,76 @@
+cmake_minimum_required(VERSION 3.5)
+project(LoadDBClient)
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../build)
+
+add_definitions(-DGLOG)
+set(CMAKE_CXX_STANDARD 11)
+
+include_directories(
+    /home/ps/boost_1_68_0
+    /usr/include/
+    ../../../../BasicPlatForm/libs/glog/include
+    ../../../../BasicPlatForm/libs/jsoncpp/include
+    ../../../../BasicPlatForm/basic/util/ShareMemory/
+    ../../../syncDBTool
+)
+
+link_directories(
+    /usr/lib/erlang/lib/erl_interface-3.8.2/lib/
+    ../../../../BasicPlatForm/libs/glog/lib
+    ../../../../BasicPlatForm/libs/jsoncpp/lib
+)
+
+
+add_executable(syncDBClient
+    main.cpp
+
+    ../../../syncDBTool/ErlangDbTool.cpp
+    #    ../../../BasicPlatForm/basic/util/ShareMemory/SemTool.cpp
+    )
+
+target_link_libraries(
+    syncDBClient
+    glog
+    Qt5Core
+    Qt5Sql
+    ei
+    erl_interface_st
+    ei_st
+    erl_interface
+    rt
+    jsoncpp
+    pthread
+)
+
+add_executable(TestCilent
+    Client.cpp
+    #    ../../../BasicPlatForm/basic/util/ShareMemory/SemTool.cpp
+
+    )
+
+target_link_libraries(TestCilent
+    pthread
+    jsoncpp
+    rt
+    )
+
+
+#include_directories(
+#    /usr/include/x86_64-linux-gnu/qt5
+#    /usr/include/x86_64-linux-gnu/qt5/QtCore/
+#    /usr/include/x86_64-linux-gnu/qt5/QtSql/
+#)
+#add_executable(demoTime
+#    demoTime.cpp
+#    #    ../../../BasicPlatForm/basic/util/ShareMemory/SemTool.cpp
+#    )
+#
+#target_link_libraries(demoTime
+#    pthread
+#    Qt5Core
+#    Qt5Sql
+#    )
+
+
+#./syncDBClient "{"\"cookie\"":"\"12121\"","\"nodeName\"":"\"wp1@192.168.1.103\"","\"path\"":"\"/opt/erlang/wp1\"","\"tableName\"":"\"娴嬭瘯涓枃\""}" > tl1 &  \
+#./syncDBClient "{"\"cookie\"":"\"12121\"","\"nodeName\"":"\"wp1@192.168.1.103\"","\"path\"":"\"/opt/erlang/wp1\"","\"tableName\"":"\"娴嬭瘯涓枃2\""}" > tl2
\ No newline at end of file
diff --git a/LoadFeaTool/Client.cpp b/LoadFeaTool/Client.cpp
new file mode 100644
index 0000000..560e08e
--- /dev/null
+++ b/LoadFeaTool/Client.cpp
@@ -0,0 +1,112 @@
+//
+// Created by ps on 8/9/18.
+//
+
+
+#include "ShareMemoryTool.hpp"
+#include <jsoncpp/json/json.h>
+#include <SemTool.h>
+
+
+using namespace std;
+
+static std::string getTimeSecString() {
+    char buf[128] = {0};
+    time_t t = time(nullptr);
+    timeval time{0};
+    gettimeofday(&time, nullptr);
+    tm *local = localtime(&t); //杞负鏈湴鏃堕棿
+    strftime(buf, 64, "%Y-%m-%d %H:%M:%S", local);
+    return std::string(buf);
+}
+
+int main() {
+
+//    string str_json = "{\"path\":\"/opt/erlang/sub1/\",\"nodeName\":\"sub1@192.168.1.186\",\"cookie\":\"abc\",\"tableName\":\"test\"}";
+
+//    int key = 1234;
+//    SemTool semTool(key);
+//    semTool.set_semvalue();
+
+    auto str = getTimeSecString();
+
+    cout << str.substr(0, 10) << endl;
+
+
+    srand(time(0));
+
+    bool ret = true;
+    if (rand() % 2) {
+        for (int i = 0; i < 10; ++i) {
+            int loop = 3;
+            cout << loop << "   " << loop % 2 << endl;
+            ret &= loop % 2;
+        }
+    } else {
+        ret = false;
+    }
+
+    if (ret) {
+        cout << "true" << endl;
+    } else {
+        cout << "false" << endl;
+    }
+
+    return 0;
+
+    Json::Value t_json;
+    Json::FastWriter writer;
+
+    t_json["\"path\""] = "\"/opt/erlang/sub1/\"";
+    t_json["\"nodeName\""] = "\"sub1@192.168.1.186\"";
+    t_json["\"cookie\""] = "\"abc\"";
+    t_json["\"tableName\""] = "\"test\"";
+//    t_json["\"key\""] = "\""+to_string(key)+"\"";
+    string tet = "./syncDBClient ";
+    string str_json = writer.write(t_json);
+
+    tet.append("\"" + str_json.substr(0, str_json.length() - 1) + "\" ");
+    cout << tet << endl;
+    system(tet.c_str());
+//    return 0;
+//    sleep(2);
+
+//    semTool.semaphore_p();
+
+    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);
+            string a = string(it->second.m_id.data());
+            string b = string(it->second.m_feature.data());
+            std::cout << "id      " << a << std::endl;
+            std::cout << "feature " << b << 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/LoadFeaTool/demoTime.cpp b/LoadFeaTool/demoTime.cpp
new file mode 100644
index 0000000..6efa814
--- /dev/null
+++ b/LoadFeaTool/demoTime.cpp
@@ -0,0 +1,118 @@
+//
+// Created by ps on 18-9-30.
+//
+
+#include<QDateTime>
+#include <iostream>
+
+using namespace std;
+
+typedef struct {
+    int Year;
+    int Month;
+    int Day;
+    int Hour;
+    int Minute;
+    int Second;
+} TimeSt, *pTimeSt;
+
+void DownLoad(QDateTime startTime, QDateTime endTime) {
+    cout << __FUNCTION__ << "  " << startTime.toString("yyyy-MM-dd hh:mm:ss").toStdString() << endl;
+    cout << __FUNCTION__ << "  " << endTime.toString("yyyy-MM-dd hh:mm:ss").toStdString() << endl;
+
+
+    cout << "\n\n\n" << endl;
+}
+
+void testFunc(QDateTime startTime, QDateTime endTime);
+
+void testFunc(QDateTime startTime, QDateTime endTime) {
+
+    int loop = 0;
+
+    QDateTime tmp_EndTime = startTime.addSecs(1 * 60 * 15);
+    if (tmp_EndTime < endTime) {
+        DownLoad(startTime, tmp_EndTime);
+        testFunc(tmp_EndTime, endTime);
+    } else {
+        DownLoad(startTime, endTime);
+        return;
+    }
+
+
+}
+
+
+int main() {
+
+
+    QDateTime startTime = QDateTime::fromString("2018-10-08 13:03:07", "yyyy-MM-dd hh:mm:ss");
+//    QDateTime startTime = QDateTime::currentDateTime();//鍗冲皢涓嬭浇鐨勬枃浠剁殑寮�濮嬫椂闂�
+    QDateTime endTime;//璁板綍鏇存柊鏃堕棿
+
+    int nDuration = 2;
+    endTime = startTime.addSecs(nDuration * 60 * 59);
+
+    cout << __LINE__ << "  " << startTime.toString("yyyy-MM-dd hh:mm:ss").toStdString() << endl;
+    cout << __LINE__ << "  " << endTime.toString("yyyy-MM-dd hh:mm:ss").toStdString() << endl;
+
+
+    //task_time Start
+    TimeSt stTimeSt;
+    stTimeSt.Year = startTime.date().year();
+    stTimeSt.Month = startTime.date().month();
+    stTimeSt.Day = startTime.date().day();
+    stTimeSt.Hour = startTime.time().hour();
+    stTimeSt.Minute = startTime.time().minute();
+    stTimeSt.Second = startTime.time().second();
+
+
+    char ch_StringStartTime[128];
+    sprintf(ch_StringStartTime, "%04d-%02d-%02d %02d:%02d:%02d", stTimeSt.Year, stTimeSt.Month, stTimeSt.Day,
+            stTimeSt.Hour,
+            stTimeSt.Minute, stTimeSt.Second);
+    string str_StringStartTime(ch_StringStartTime);
+//    string str_StringStartTime(
+//        to_string(stTimeSt.Year) + "-" + to_string(stTimeSt.Month) + "-" + to_string(stTimeSt.Day) + " "
+//        + to_string(stTimeSt.Hour) + ":" + to_string(stTimeSt.Minute) + ":" +
+//        to_string(stTimeSt.Second));
+
+    cout << "str_____" << str_StringStartTime << endl;
+    QDateTime
+        taskStartTime = QDateTime::fromString(QString::fromStdString(str_StringStartTime), "yyyy-MM-dd hh:mm:ss");
+    cout << taskStartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString() << endl;
+    //task_time Start -------------------------------------------------
+
+    //task_time end
+    TimeSt endTimeSt;
+    endTimeSt.Year = endTime.date().year();
+    endTimeSt.Month = endTime.date().month();
+    endTimeSt.Day = endTime.date().day();
+    endTimeSt.Hour = endTime.time().hour();
+    endTimeSt.Minute = endTime.time().minute();
+    endTimeSt.Second = endTime.time().second();
+
+    char ch_StringEndTime[128];
+    sprintf(ch_StringEndTime, "%04d-%02d-%02d %02d:%02d:%02d", endTimeSt.Year, endTimeSt.Month, endTimeSt.Day,
+            endTimeSt.Hour, endTimeSt.Minute, endTimeSt.Second);
+    string str_StringEndTime(ch_StringEndTime);
+
+//    string str_StringEndTime(
+//        to_string(endTimeSt.Year) + "-" + to_string(endTimeSt.Month) + "-" + to_string(endTimeSt.Day) + " "
+//        + to_string(endTimeSt.Hour) + ":" + to_string(endTimeSt.Minute) + ":" +
+//        to_string(endTimeSt.Second));
+
+    cout << "str_____" << str_StringEndTime << endl;
+    QDateTime
+        taskEndTime = QDateTime::fromString(QString::fromStdString(str_StringEndTime), "yyyy-MM-dd hh:mm:ss");
+    cout << taskEndTime.toString("yyyy-MM-dd hh:mm:ss").toStdString() << endl;
+    //task_time end -------------------------------------------------
+
+
+    cout << "\n\n\n" << endl;
+
+    testFunc(taskStartTime, taskEndTime);
+
+    return 0;
+
+}
\ No newline at end of file
diff --git a/LoadFeaTool/main.cpp b/LoadFeaTool/main.cpp
new file mode 100644
index 0000000..621a55f
--- /dev/null
+++ b/LoadFeaTool/main.cpp
@@ -0,0 +1,100 @@
+#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 <SemTool.h>
+#include <basic/util/app/AppConfig.h>
+#include <basic/debug/Debug.h>
+
+#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) {
+    std::cout << "Hello, World!" << std::endl;
+    ENABLEGLOG(GET_STR_CONFIG("logPath").c_str());
+
+    if (argc <= 1) {
+        ERR("argc size is err");
+        exit(-1);
+    }
+
+    string str_json(argv[1]);
+//    cout << str_json << endl;
+//    string str_json = "{\"path\":\"/opt/erlang/sub1/\",\"nodeName\":\"sub1@192.168.1.186\",\"cookie\":\"abc\",\"tableName\":\"test\"}";
+
+    Json::Value t_json;
+    Json::Reader reader;
+
+    if (!reader.parse(str_json, t_json)) {
+        ERR("json format error :: " << str_json);
+        return -1;
+    }
+
+    int loop = 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();
+
+//    SemTool semTool(t_json["key"].asInt());
+//
+//    semTool.semaphore_p();
+
+
+    /***
+     * jiazai renlian
+     */
+//    struct timeval t1, t2;
+//    gettimeofday(&t1, NULL);
+
+
+    std::string str_node("testNode");
+    str_node.append(to_string((int) getpid()));
+    ErlangTool::ErlangDbTool erlangDbTool(nodeName, cookie, str_node);
+    while (1) {
+        /***
+     * load fea
+     */
+
+        auto cache = erlangDbTool.loadFaceFeaData(tableName);
+
+//        gettimeofday(&t2, NULL);
+        //閭d箞鍑芥暟f杩愯鎵�鑺辩殑鏃堕棿涓�
+//        auto deltaT = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec;
+//        DBG(" loadData " << deltaT << "us")
+//        DBG(tableName << "size is " << cache.size() << " " << loop);
+        if (cache.size() <= 0 && loop++ <= 10) {
+            usleep(100);
+            continue;
+        }
+        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, item.second.feature, item.second.img, item.second.idcard,
+                                            item.second.create_by, item.second.create_time, item.second.update_time);
+            }
+            auto mymap = biMapFeaData.getMap();
+//        for (auto it = mymap->begin(); it != mymap->end(); it++) {
+//            std::cout << "feature " << it->second.m_feature << std::endl;
+//        }
+            DBG("load ok " << tableName << "mymap size is " << mymap->size());
+        }
+        catch (const std::exception &e) {
+            printf("Exception:%s\n", e.what());
+            BISTL::shared_memory_object::remove(tableName.c_str());
+        }
+        break;
+    }
+
+    return 0;
+}
diff --git a/README.md b/README.md
index f9aaf6f..42f5cf7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1 @@
 ## FaceCompareMoudle
-
-浜鸿劯瀵规瘮妯″潡
-
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..90f7577
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,37 @@
+//
+// Created by pans on 4/27/18.
+//
+#include <iostream>
+#include <Ice/Ice.h>
+#include <thread>
+
+#include <basic/rpc/IceRpc.hpp>
+#include <basic/util/app/AppPreference.hpp>
+#include "FaceFeatureSearchServerI.h"
+#include <basic/util/app/AppConfig.h>
+#include <basic/debug/Debug.h>
+
+using namespace std;
+
+int main(int argc, char **argv) {
+
+    SAVE_APP_ARGS;
+    ENABLEGLOG(GET_STR_CONFIG("logPath").c_str());
+    auto ich = Ice::initialize(argc, argv);
+
+    DBG("\n\n\nstart\n\n");
+
+    appPref.setLongData("thread.max", 32);
+    //#todo
+
+//    appPref.setStringData("ipAdd", "192.168.1.185");
+//    appPref.setIntData("ipPort", 9200);
+    appPref.setStringData("ipAdd", appConfig.getStringProperty("ES_IP"));
+    appPref.setIntData("ipPort", appConfig.getIntProperty("ES_PORT"));
+
+    IceRpcServer<FaceFeatureSearchServerI> server("faceCmServer", 10004, "tcp");
+    server.setMessageSizeMax(1024 * 1024 * 50);
+    server.setPoolInitSize(10);
+    server.setPoolMaxSize(32);
+    server.runWaitShutDown();
+}
\ No newline at end of file
diff --git a/rpc/FaceSearchServer.cpp b/rpc/FaceSearchServer.cpp
new file mode 100644
index 0000000..19fec76
--- /dev/null
+++ b/rpc/FaceSearchServer.cpp
@@ -0,0 +1,515 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+//
+// Ice version 3.7.0
+//
+// <auto-generated>
+//
+// Generated from file `FaceSearchServer.ice'
+//
+// Warning: do not edit this file.
+//
+// </auto-generated>
+//
+
+#include <FaceSearchServer.h>
+#include <IceUtil/PushDisableWarnings.h>
+#include <Ice/LocalException.h>
+#include <Ice/ValueFactory.h>
+#include <Ice/OutgoingAsync.h>
+#include <Ice/InputStream.h>
+#include <Ice/OutputStream.h>
+#include <IceUtil/PopDisableWarnings.h>
+
+#if defined(_MSC_VER)
+#   pragma warning(disable:4458) // declaration of ... hides class member
+#elif defined(__clang__)
+#   pragma clang diagnostic ignored "-Wshadow"
+#elif defined(__GNUC__)
+#   pragma GCC diagnostic ignored "-Wshadow"
+#endif
+
+#ifndef ICE_IGNORE_VERSION
+#   if ICE_INT_VERSION / 100 != 307
+#       error Ice version mismatch!
+#   endif
+#   if ICE_INT_VERSION % 100 > 50
+#       error Beta header file detected
+#   endif
+#   if ICE_INT_VERSION % 100 < 0
+#       error Ice patch level mismatch!
+#   endif
+#endif
+
+#ifdef ICE_CPP11_MAPPING // C++11 mapping
+
+namespace
+{
+
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_ids[2] =
+{
+    "::FaceSearch::FaceFeatureSearchServer",
+    "::Ice::Object"
+};
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_ops[] =
+{
+    "faceSearchMax",
+    "faceSearchTopN",
+    "ice_id",
+    "ice_ids",
+    "ice_isA",
+    "ice_ping"
+};
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name = "faceSearchMax";
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name = "faceSearchTopN";
+
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::ice_isA(::std::string s, const ::Ice::Current&) const
+{
+    return ::std::binary_search(iceC_FaceSearch_FaceFeatureSearchServer_ids, iceC_FaceSearch_FaceFeatureSearchServer_ids + 2, s);
+}
+
+::std::vector<::std::string>
+FaceSearch::FaceFeatureSearchServer::ice_ids(const ::Ice::Current&) const
+{
+    return ::std::vector<::std::string>(&iceC_FaceSearch_FaceFeatureSearchServer_ids[0], &iceC_FaceSearch_FaceFeatureSearchServer_ids[2]);
+}
+
+::std::string
+FaceSearch::FaceFeatureSearchServer::ice_id(const ::Ice::Current&) const
+{
+    return ice_staticId();
+}
+
+const ::std::string&
+FaceSearch::FaceFeatureSearchServer::ice_staticId()
+{
+    static const ::std::string typeId = "::FaceSearch::FaceFeatureSearchServer";
+    return typeId;
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::_iceD_faceSearchMax(::IceInternal::Incoming& inS, const ::Ice::Current& current)
+{
+    _iceCheckMode(::Ice::OperationMode::Normal, current.mode);
+    auto istr = inS.startReadParams();
+    ::FaceSearch::Data iceP_feature;
+    ::std::string iceP_info;
+    istr->readAll(iceP_feature, iceP_info);
+    inS.endReadParams();
+    ::FaceSearch::FaceResults ret = this->faceSearchMax(::std::move(iceP_feature), ::std::move(iceP_info), current);
+    auto ostr = inS.startWriteParams();
+    ostr->writeAll(ret);
+    inS.endWriteParams();
+    return true;
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::_iceD_faceSearchTopN(::IceInternal::Incoming& inS, const ::Ice::Current& current)
+{
+    _iceCheckMode(::Ice::OperationMode::Normal, current.mode);
+    auto istr = inS.startReadParams();
+    ::FaceSearch::Data iceP_feature;
+    ::std::string iceP_info;
+    int iceP_topN;
+    float iceP_score;
+    istr->readAll(iceP_feature, iceP_info, iceP_topN, iceP_score);
+    inS.endReadParams();
+    ::FaceSearch::FaceResults ret = this->faceSearchTopN(::std::move(iceP_feature), ::std::move(iceP_info), iceP_topN, iceP_score, current);
+    auto ostr = inS.startWriteParams();
+    ostr->writeAll(ret);
+    inS.endWriteParams();
+    return true;
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)
+{
+    ::std::pair<const ::std::string*, const ::std::string*> r = ::std::equal_range(iceC_FaceSearch_FaceFeatureSearchServer_ops, iceC_FaceSearch_FaceFeatureSearchServer_ops + 6, current.operation);
+    if(r.first == r.second)
+    {
+        throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
+    }
+
+    switch(r.first - iceC_FaceSearch_FaceFeatureSearchServer_ops)
+    {
+        case 0:
+        {
+            return _iceD_faceSearchMax(in, current);
+        }
+        case 1:
+        {
+            return _iceD_faceSearchTopN(in, current);
+        }
+        case 2:
+        {
+            return _iceD_ice_id(in, current);
+        }
+        case 3:
+        {
+            return _iceD_ice_ids(in, current);
+        }
+        case 4:
+        {
+            return _iceD_ice_isA(in, current);
+        }
+        case 5:
+        {
+            return _iceD_ice_ping(in, current);
+        }
+        default:
+        {
+            assert(false);
+            throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
+        }
+    }
+}
+
+void
+FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchMax(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::FaceSearch::FaceResults>>& outAsync, const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context)
+{
+    _checkTwowayOnly(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name);
+    outAsync->invoke(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context,
+        [&](::Ice::OutputStream* ostr)
+        {
+            ostr->writeAll(iceP_feature, iceP_info);
+        },
+        nullptr);
+}
+
+void
+FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchTopN(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::FaceSearch::FaceResults>>& outAsync, const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, int iceP_topN, float iceP_score, const ::Ice::Context& context)
+{
+    _checkTwowayOnly(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name);
+    outAsync->invoke(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context,
+        [&](::Ice::OutputStream* ostr)
+        {
+            ostr->writeAll(iceP_feature, iceP_info, iceP_topN, iceP_score);
+        },
+        nullptr);
+}
+
+::std::shared_ptr<::Ice::ObjectPrx>
+FaceSearch::FaceFeatureSearchServerPrx::_newInstance() const
+{
+    return ::IceInternal::createProxy<FaceFeatureSearchServerPrx>();
+}
+
+const ::std::string&
+FaceSearch::FaceFeatureSearchServerPrx::ice_staticId()
+{
+    return FaceSearch::FaceFeatureSearchServer::ice_staticId();
+}
+
+namespace Ice
+{
+}
+
+#else // C++98 mapping
+
+namespace
+{
+
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name = "faceSearchMax";
+
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name = "faceSearchTopN";
+
+}
+::IceProxy::Ice::Object* ::IceProxy::FaceSearch::upCast(::IceProxy::FaceSearch::FaceFeatureSearchServer* p) { return p; }
+
+void
+::IceProxy::FaceSearch::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< ::IceProxy::FaceSearch::FaceFeatureSearchServer>& v)
+{
+    ::Ice::ObjectPrx proxy;
+    istr->read(proxy);
+    if(!proxy)
+    {
+        v = 0;
+    }
+    else
+    {
+        v = new ::IceProxy::FaceSearch::FaceFeatureSearchServer;
+        v->_copyFrom(proxy);
+    }
+}
+
+::Ice::AsyncResultPtr
+IceProxy::FaceSearch::FaceFeatureSearchServer::_iceI_begin_faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync)
+{
+    _checkTwowayOnly(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name, sync);
+    ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name, del, cookie, sync);
+    try
+    {
+        result->prepare(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name, ::Ice::Normal, context);
+        ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat);
+        ostr->write(iceP_feature);
+        ostr->write(iceP_info);
+        result->endWriteParams();
+        result->invoke(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name);
+    }
+    catch(const ::Ice::Exception& ex)
+    {
+        result->abort(ex);
+    }
+    return result;
+}
+
+::FaceSearch::FaceResults
+IceProxy::FaceSearch::FaceFeatureSearchServer::end_faceSearchMax(const ::Ice::AsyncResultPtr& result)
+{
+    ::Ice::AsyncResult::_check(result, this, iceC_FaceSearch_FaceFeatureSearchServer_faceSearchMax_name);
+    ::FaceSearch::FaceResults ret;
+    if(!result->_waitForResponse())
+    {
+        try
+        {
+            result->_throwUserException();
+        }
+        catch(const ::Ice::UserException& ex)
+        {
+            throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id());
+        }
+    }
+    ::Ice::InputStream* istr = result->_startReadParams();
+    istr->read(ret);
+    result->_endReadParams();
+    return ret;
+}
+
+::Ice::AsyncResultPtr
+IceProxy::FaceSearch::FaceFeatureSearchServer::_iceI_begin_faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync)
+{
+    _checkTwowayOnly(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name, sync);
+    ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name, del, cookie, sync);
+    try
+    {
+        result->prepare(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name, ::Ice::Normal, context);
+        ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat);
+        ostr->write(iceP_feature);
+        ostr->write(iceP_info);
+        ostr->write(iceP_topN);
+        ostr->write(iceP_score);
+        result->endWriteParams();
+        result->invoke(iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name);
+    }
+    catch(const ::Ice::Exception& ex)
+    {
+        result->abort(ex);
+    }
+    return result;
+}
+
+::FaceSearch::FaceResults
+IceProxy::FaceSearch::FaceFeatureSearchServer::end_faceSearchTopN(const ::Ice::AsyncResultPtr& result)
+{
+    ::Ice::AsyncResult::_check(result, this, iceC_FaceSearch_FaceFeatureSearchServer_faceSearchTopN_name);
+    ::FaceSearch::FaceResults ret;
+    if(!result->_waitForResponse())
+    {
+        try
+        {
+            result->_throwUserException();
+        }
+        catch(const ::Ice::UserException& ex)
+        {
+            throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id());
+        }
+    }
+    ::Ice::InputStream* istr = result->_startReadParams();
+    istr->read(ret);
+    result->_endReadParams();
+    return ret;
+}
+
+::IceProxy::Ice::Object*
+IceProxy::FaceSearch::FaceFeatureSearchServer::_newInstance() const
+{
+    return new FaceFeatureSearchServer;
+}
+
+const ::std::string&
+IceProxy::FaceSearch::FaceFeatureSearchServer::ice_staticId()
+{
+    return ::FaceSearch::FaceFeatureSearchServer::ice_staticId();
+}
+
+FaceSearch::FaceFeatureSearchServer::~FaceFeatureSearchServer()
+{
+}
+
+::Ice::Object* FaceSearch::upCast(::FaceSearch::FaceFeatureSearchServer* p) { return p; }
+
+
+namespace
+{
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_ids[2] =
+{
+    "::FaceSearch::FaceFeatureSearchServer",
+    "::Ice::Object"
+};
+
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::ice_isA(const ::std::string& s, const ::Ice::Current&) const
+{
+    return ::std::binary_search(iceC_FaceSearch_FaceFeatureSearchServer_ids, iceC_FaceSearch_FaceFeatureSearchServer_ids + 2, s);
+}
+
+::std::vector< ::std::string>
+FaceSearch::FaceFeatureSearchServer::ice_ids(const ::Ice::Current&) const
+{
+    return ::std::vector< ::std::string>(&iceC_FaceSearch_FaceFeatureSearchServer_ids[0], &iceC_FaceSearch_FaceFeatureSearchServer_ids[2]);
+}
+
+const ::std::string&
+FaceSearch::FaceFeatureSearchServer::ice_id(const ::Ice::Current&) const
+{
+    return ice_staticId();
+}
+
+const ::std::string&
+FaceSearch::FaceFeatureSearchServer::ice_staticId()
+{
+#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC
+    static const ::std::string typeId = "::FaceSearch::FaceFeatureSearchServer";
+    return typeId;
+#else
+    return iceC_FaceSearch_FaceFeatureSearchServer_ids[0];
+#endif
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::_iceD_faceSearchMax(::IceInternal::Incoming& inS, const ::Ice::Current& current)
+{
+    _iceCheckMode(::Ice::Normal, current.mode);
+    ::Ice::InputStream* istr = inS.startReadParams();
+    ::FaceSearch::Data iceP_feature;
+    ::std::string iceP_info;
+    istr->read(iceP_feature);
+    istr->read(iceP_info);
+    inS.endReadParams();
+    ::FaceSearch::FaceResults ret = this->faceSearchMax(iceP_feature, iceP_info, current);
+    ::Ice::OutputStream* ostr = inS.startWriteParams();
+    ostr->write(ret);
+    inS.endWriteParams();
+    return true;
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::_iceD_faceSearchTopN(::IceInternal::Incoming& inS, const ::Ice::Current& current)
+{
+    _iceCheckMode(::Ice::Normal, current.mode);
+    ::Ice::InputStream* istr = inS.startReadParams();
+    ::FaceSearch::Data iceP_feature;
+    ::std::string iceP_info;
+    ::Ice::Int iceP_topN;
+    ::Ice::Float iceP_score;
+    istr->read(iceP_feature);
+    istr->read(iceP_info);
+    istr->read(iceP_topN);
+    istr->read(iceP_score);
+    inS.endReadParams();
+    ::FaceSearch::FaceResults ret = this->faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, current);
+    ::Ice::OutputStream* ostr = inS.startWriteParams();
+    ostr->write(ret);
+    inS.endWriteParams();
+    return true;
+}
+
+namespace
+{
+const ::std::string iceC_FaceSearch_FaceFeatureSearchServer_all[] =
+{
+    "faceSearchMax",
+    "faceSearchTopN",
+    "ice_id",
+    "ice_ids",
+    "ice_isA",
+    "ice_ping"
+};
+
+}
+
+bool
+FaceSearch::FaceFeatureSearchServer::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)
+{
+    ::std::pair<const ::std::string*, const ::std::string*> r = ::std::equal_range(iceC_FaceSearch_FaceFeatureSearchServer_all, iceC_FaceSearch_FaceFeatureSearchServer_all + 6, current.operation);
+    if(r.first == r.second)
+    {
+        throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
+    }
+
+    switch(r.first - iceC_FaceSearch_FaceFeatureSearchServer_all)
+    {
+        case 0:
+        {
+            return _iceD_faceSearchMax(in, current);
+        }
+        case 1:
+        {
+            return _iceD_faceSearchTopN(in, current);
+        }
+        case 2:
+        {
+            return _iceD_ice_id(in, current);
+        }
+        case 3:
+        {
+            return _iceD_ice_ids(in, current);
+        }
+        case 4:
+        {
+            return _iceD_ice_isA(in, current);
+        }
+        case 5:
+        {
+            return _iceD_ice_ping(in, current);
+        }
+        default:
+        {
+            assert(false);
+            throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
+        }
+    }
+}
+
+void
+FaceSearch::FaceFeatureSearchServer::_iceWriteImpl(::Ice::OutputStream* ostr) const
+{
+    ostr->startSlice(ice_staticId(), -1, true);
+    Ice::StreamWriter< ::FaceSearch::FaceFeatureSearchServer, ::Ice::OutputStream>::write(ostr, *this);
+    ostr->endSlice();
+}
+
+void
+FaceSearch::FaceFeatureSearchServer::_iceReadImpl(::Ice::InputStream* istr)
+{
+    istr->startSlice();
+    Ice::StreamReader< ::FaceSearch::FaceFeatureSearchServer, ::Ice::InputStream>::read(istr, *this);
+    istr->endSlice();
+}
+
+void
+FaceSearch::_icePatchObjectPtr(FaceFeatureSearchServerPtr& handle, const ::Ice::ObjectPtr& v)
+{
+    handle = ::FaceSearch::FaceFeatureSearchServerPtr::dynamicCast(v);
+    if(v && !handle)
+    {
+        IceInternal::Ex::throwUOE(::FaceSearch::FaceFeatureSearchServer::ice_staticId(), v);
+    }
+}
+
+namespace Ice
+{
+}
+
+#endif
diff --git a/rpc/FaceSearchServer.h b/rpc/FaceSearchServer.h
new file mode 100644
index 0000000..8233434
--- /dev/null
+++ b/rpc/FaceSearchServer.h
@@ -0,0 +1,678 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+//
+// Ice version 3.7.0
+//
+// <auto-generated>
+//
+// Generated from file `FaceSearchServer.ice'
+//
+// Warning: do not edit this file.
+//
+// </auto-generated>
+//
+
+#ifndef __FaceSearchServer_h__
+#define __FaceSearchServer_h__
+
+#include <IceUtil/PushDisableWarnings.h>
+#include <Ice/ProxyF.h>
+#include <Ice/ObjectF.h>
+#include <Ice/ValueF.h>
+#include <Ice/Exception.h>
+#include <Ice/LocalObject.h>
+#include <Ice/StreamHelpers.h>
+#include <Ice/Comparable.h>
+#include <Ice/Proxy.h>
+#include <Ice/Object.h>
+#include <Ice/GCObject.h>
+#include <Ice/Value.h>
+#include <Ice/Incoming.h>
+#include <Ice/FactoryTableInit.h>
+#include <IceUtil/ScopedArray.h>
+#include <Ice/Optional.h>
+#include <IceUtil/UndefSysMacros.h>
+
+#ifndef ICE_IGNORE_VERSION
+#   if ICE_INT_VERSION / 100 != 307
+#       error Ice version mismatch!
+#   endif
+#   if ICE_INT_VERSION % 100 > 50
+#       error Beta header file detected
+#   endif
+#   if ICE_INT_VERSION % 100 < 0
+#       error Ice patch level mismatch!
+#   endif
+#endif
+
+#ifdef ICE_CPP11_MAPPING // C++11 mapping
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServer;
+class FaceFeatureSearchServerPrx;
+
+}
+
+namespace FaceSearch
+{
+
+using Data = ::std::vector<::Ice::Byte>;
+
+struct FaceResult
+{
+    long long int id;
+    ::std::string uuid;
+    ::std::string tableName;
+    float confidence;
+    ::std::string imgUrl;
+    ::std::string idcard;
+    ::std::string alarmRet;
+
+    std::tuple<const long long int&, const ::std::string&, const ::std::string&, const float&, const ::std::string&, const ::std::string&, const ::std::string&> ice_tuple() const
+    {
+        return std::tie(id, uuid, tableName, confidence, imgUrl, idcard, alarmRet);
+    }
+};
+
+using FaceResults = ::std::vector<::FaceSearch::FaceResult>;
+
+using Ice::operator<;
+using Ice::operator<=;
+using Ice::operator>;
+using Ice::operator>=;
+using Ice::operator==;
+using Ice::operator!=;
+
+}
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServer : public virtual ::Ice::Object
+{
+public:
+
+    using ProxyType = FaceFeatureSearchServerPrx;
+
+    virtual bool ice_isA(::std::string, const ::Ice::Current&) const override;
+    virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current&) const override;
+    virtual ::std::string ice_id(const ::Ice::Current&) const override;
+
+    static const ::std::string& ice_staticId();
+
+    virtual ::FaceSearch::FaceResults faceSearchMax(::FaceSearch::Data, ::std::string, const ::Ice::Current&) = 0;
+    bool _iceD_faceSearchMax(::IceInternal::Incoming&, const ::Ice::Current&);
+
+    virtual ::FaceSearch::FaceResults faceSearchTopN(::FaceSearch::Data, ::std::string, int, float, const ::Ice::Current&) = 0;
+    bool _iceD_faceSearchTopN(::IceInternal::Incoming&, const ::Ice::Current&);
+
+    virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override;
+};
+
+}
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServerPrx : public virtual ::Ice::Proxy<FaceFeatureSearchServerPrx, ::Ice::ObjectPrx>
+{
+public:
+
+    ::FaceSearch::FaceResults faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context = Ice::noExplicitContext)
+    {
+        return _makePromiseOutgoing<::FaceSearch::FaceResults>(true, this, &FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchMax, iceP_feature, iceP_info, context).get();
+    }
+
+    template<template<typename> class P = ::std::promise>
+    auto faceSearchMaxAsync(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context = Ice::noExplicitContext)
+        -> decltype(::std::declval<P<::FaceSearch::FaceResults>>().get_future())
+    {
+        return _makePromiseOutgoing<::FaceSearch::FaceResults, P>(false, this, &FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchMax, iceP_feature, iceP_info, context);
+    }
+
+    ::std::function<void()>
+    faceSearchMaxAsync(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info,
+                       ::std::function<void(::FaceSearch::FaceResults)> response,
+                       ::std::function<void(::std::exception_ptr)> ex = nullptr,
+                       ::std::function<void(bool)> sent = nullptr,
+                       const ::Ice::Context& context = Ice::noExplicitContext)
+    {
+        return _makeLamdaOutgoing<::FaceSearch::FaceResults>(response, ex, sent, this, &FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchMax, iceP_feature, iceP_info, context);
+    }
+
+    void _iceI_faceSearchMax(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::FaceSearch::FaceResults>>&, const ::FaceSearch::Data&, const ::std::string&, const ::Ice::Context&);
+
+    ::FaceSearch::FaceResults faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, int iceP_topN, float iceP_score, const ::Ice::Context& context = Ice::noExplicitContext)
+    {
+        return _makePromiseOutgoing<::FaceSearch::FaceResults>(true, this, &FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchTopN, iceP_feature, iceP_info, iceP_topN, iceP_score, context).get();
+    }
+
+    template<template<typename> class P = ::std::promise>
+    auto faceSearchTopNAsync(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, int iceP_topN, float iceP_score, const ::Ice::Context& context = Ice::noExplicitContext)
+        -> decltype(::std::declval<P<::FaceSearch::FaceResults>>().get_future())
+    {
+        return _makePromiseOutgoing<::FaceSearch::FaceResults, P>(false, this, &FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchTopN, iceP_feature, iceP_info, iceP_topN, iceP_score, context);
+    }
+
+    ::std::function<void()>
+    faceSearchTopNAsync(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, int iceP_topN, float iceP_score,
+                        ::std::function<void(::FaceSearch::FaceResults)> response,
+                        ::std::function<void(::std::exception_ptr)> ex = nullptr,
+                        ::std::function<void(bool)> sent = nullptr,
+                        const ::Ice::Context& context = Ice::noExplicitContext)
+    {
+        return _makeLamdaOutgoing<::FaceSearch::FaceResults>(response, ex, sent, this, &FaceSearch::FaceFeatureSearchServerPrx::_iceI_faceSearchTopN, iceP_feature, iceP_info, iceP_topN, iceP_score, context);
+    }
+
+    void _iceI_faceSearchTopN(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::FaceSearch::FaceResults>>&, const ::FaceSearch::Data&, const ::std::string&, int, float, const ::Ice::Context&);
+
+    static const ::std::string& ice_staticId();
+
+protected:
+
+    FaceFeatureSearchServerPrx() = default;
+    friend ::std::shared_ptr<FaceFeatureSearchServerPrx> IceInternal::createProxy<FaceFeatureSearchServerPrx>();
+
+    virtual ::std::shared_ptr<::Ice::ObjectPrx> _newInstance() const override;
+};
+
+}
+
+namespace Ice
+{
+
+template<>
+struct StreamableTraits<::FaceSearch::FaceResult>
+{
+    static const StreamHelperCategory helper = StreamHelperCategoryStruct;
+    static const int minWireSize = 17;
+    static const bool fixedLength = false;
+};
+
+template<typename S>
+struct StreamReader<::FaceSearch::FaceResult, S>
+{
+    static void read(S* istr, ::FaceSearch::FaceResult& v)
+    {
+        istr->readAll(v.id, v.uuid, v.tableName, v.confidence, v.imgUrl, v.idcard, v.alarmRet);
+    }
+};
+
+}
+
+namespace FaceSearch
+{
+
+using FaceFeatureSearchServerPtr = ::std::shared_ptr<FaceFeatureSearchServer>;
+using FaceFeatureSearchServerPrxPtr = ::std::shared_ptr<FaceFeatureSearchServerPrx>;
+
+}
+
+#else // C++98 mapping
+
+namespace IceProxy
+{
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServer;
+void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< ::IceProxy::FaceSearch::FaceFeatureSearchServer>&);
+::IceProxy::Ice::Object* upCast(::IceProxy::FaceSearch::FaceFeatureSearchServer*);
+
+}
+
+}
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServer;
+::Ice::Object* upCast(::FaceSearch::FaceFeatureSearchServer*);
+typedef ::IceInternal::Handle< ::FaceSearch::FaceFeatureSearchServer> FaceFeatureSearchServerPtr;
+typedef ::IceInternal::ProxyHandle< ::IceProxy::FaceSearch::FaceFeatureSearchServer> FaceFeatureSearchServerPrx;
+typedef FaceFeatureSearchServerPrx FaceFeatureSearchServerPrxPtr;
+void _icePatchObjectPtr(FaceFeatureSearchServerPtr&, const ::Ice::ObjectPtr&);
+
+}
+
+namespace FaceSearch
+{
+
+typedef ::std::vector< ::Ice::Byte> Data;
+
+struct FaceResult
+{
+    ::Ice::Long id;
+    ::std::string uuid;
+    ::std::string tableName;
+    ::Ice::Float confidence;
+    ::std::string imgUrl;
+    ::std::string idcard;
+    ::std::string alarmRet;
+};
+
+typedef ::std::vector< ::FaceSearch::FaceResult> FaceResults;
+
+}
+
+namespace FaceSearch
+{
+
+class Callback_FaceFeatureSearchServer_faceSearchMax_Base : public virtual ::IceInternal::CallbackBase { };
+typedef ::IceUtil::Handle< Callback_FaceFeatureSearchServer_faceSearchMax_Base> Callback_FaceFeatureSearchServer_faceSearchMaxPtr;
+
+class Callback_FaceFeatureSearchServer_faceSearchTopN_Base : public virtual ::IceInternal::CallbackBase { };
+typedef ::IceUtil::Handle< Callback_FaceFeatureSearchServer_faceSearchTopN_Base> Callback_FaceFeatureSearchServer_faceSearchTopNPtr;
+
+}
+
+namespace IceProxy
+{
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServer : public virtual ::Ice::Proxy<FaceFeatureSearchServer, ::IceProxy::Ice::Object>
+{
+public:
+
+    ::FaceSearch::FaceResults faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context = ::Ice::noExplicitContext)
+    {
+        return end_faceSearchMax(_iceI_begin_faceSearchMax(iceP_feature, iceP_info, context, ::IceInternal::dummyCallback, 0, true));
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context = ::Ice::noExplicitContext)
+    {
+        return _iceI_begin_faceSearchMax(iceP_feature, iceP_info, context, ::IceInternal::dummyCallback, 0);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::CallbackPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchMax(iceP_feature, iceP_info, ::Ice::noExplicitContext, del, cookie);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context, const ::Ice::CallbackPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchMax(iceP_feature, iceP_info, context, del, cookie);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::FaceSearch::Callback_FaceFeatureSearchServer_faceSearchMaxPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchMax(iceP_feature, iceP_info, ::Ice::noExplicitContext, del, cookie);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchMax(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, const ::Ice::Context& context, const ::FaceSearch::Callback_FaceFeatureSearchServer_faceSearchMaxPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchMax(iceP_feature, iceP_info, context, del, cookie);
+    }
+
+    ::FaceSearch::FaceResults end_faceSearchMax(const ::Ice::AsyncResultPtr&);
+
+private:
+
+    ::Ice::AsyncResultPtr _iceI_begin_faceSearchMax(const ::FaceSearch::Data&, const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false);
+
+public:
+
+    ::FaceSearch::FaceResults faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::Ice::Context& context = ::Ice::noExplicitContext)
+    {
+        return end_faceSearchTopN(_iceI_begin_faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, context, ::IceInternal::dummyCallback, 0, true));
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::Ice::Context& context = ::Ice::noExplicitContext)
+    {
+        return _iceI_begin_faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, context, ::IceInternal::dummyCallback, 0);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::Ice::CallbackPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, ::Ice::noExplicitContext, del, cookie);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::Ice::Context& context, const ::Ice::CallbackPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, context, del, cookie);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::FaceSearch::Callback_FaceFeatureSearchServer_faceSearchTopNPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, ::Ice::noExplicitContext, del, cookie);
+    }
+
+    ::Ice::AsyncResultPtr begin_faceSearchTopN(const ::FaceSearch::Data& iceP_feature, const ::std::string& iceP_info, ::Ice::Int iceP_topN, ::Ice::Float iceP_score, const ::Ice::Context& context, const ::FaceSearch::Callback_FaceFeatureSearchServer_faceSearchTopNPtr& del, const ::Ice::LocalObjectPtr& cookie = 0)
+    {
+        return _iceI_begin_faceSearchTopN(iceP_feature, iceP_info, iceP_topN, iceP_score, context, del, cookie);
+    }
+
+    ::FaceSearch::FaceResults end_faceSearchTopN(const ::Ice::AsyncResultPtr&);
+
+private:
+
+    ::Ice::AsyncResultPtr _iceI_begin_faceSearchTopN(const ::FaceSearch::Data&, const ::std::string&, ::Ice::Int, ::Ice::Float, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false);
+
+public:
+
+    static const ::std::string& ice_staticId();
+
+protected:
+
+    virtual ::IceProxy::Ice::Object* _newInstance() const;
+};
+
+}
+
+}
+
+namespace FaceSearch
+{
+
+class FaceFeatureSearchServer : public virtual ::Ice::Object
+{
+public:
+
+    typedef FaceFeatureSearchServerPrx ProxyType;
+    typedef FaceFeatureSearchServerPtr PointerType;
+
+    virtual ~FaceFeatureSearchServer();
+
+    virtual bool ice_isA(const ::std::string&, const ::Ice::Current& = ::Ice::emptyCurrent) const;
+    virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& = ::Ice::emptyCurrent) const;
+    virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::emptyCurrent) const;
+
+    static const ::std::string& ice_staticId();
+
+    virtual ::FaceSearch::FaceResults faceSearchMax(const ::FaceSearch::Data&, const ::std::string&, const ::Ice::Current& = ::Ice::emptyCurrent) = 0;
+    bool _iceD_faceSearchMax(::IceInternal::Incoming&, const ::Ice::Current&);
+
+    virtual ::FaceSearch::FaceResults faceSearchTopN(const ::FaceSearch::Data&, const ::std::string&, ::Ice::Int, ::Ice::Float, const ::Ice::Current& = ::Ice::emptyCurrent) = 0;
+    bool _iceD_faceSearchTopN(::IceInternal::Incoming&, const ::Ice::Current&);
+
+    virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&);
+
+protected:
+
+    virtual void _iceWriteImpl(::Ice::OutputStream*) const;
+    virtual void _iceReadImpl(::Ice::InputStream*);
+};
+
+inline bool operator==(const FaceFeatureSearchServer& lhs, const FaceFeatureSearchServer& rhs)
+{
+    return static_cast<const ::Ice::Object&>(lhs) == static_cast<const ::Ice::Object&>(rhs);
+}
+
+inline bool operator<(const FaceFeatureSearchServer& lhs, const FaceFeatureSearchServer& rhs)
+{
+    return static_cast<const ::Ice::Object&>(lhs) < static_cast<const ::Ice::Object&>(rhs);
+}
+
+}
+
+namespace Ice
+{
+
+template<>
+struct StreamableTraits< ::FaceSearch::FaceResult>
+{
+    static const StreamHelperCategory helper = StreamHelperCategoryStruct;
+    static const int minWireSize = 17;
+    static const bool fixedLength = false;
+};
+
+template<typename S>
+struct StreamWriter< ::FaceSearch::FaceResult, S>
+{
+    static void write(S* ostr, const ::FaceSearch::FaceResult& v)
+    {
+        ostr->write(v.id);
+        ostr->write(v.uuid);
+        ostr->write(v.tableName);
+        ostr->write(v.confidence);
+        ostr->write(v.imgUrl);
+        ostr->write(v.idcard);
+        ostr->write(v.alarmRet);
+    }
+};
+
+template<typename S>
+struct StreamReader< ::FaceSearch::FaceResult, S>
+{
+    static void read(S* istr, ::FaceSearch::FaceResult& v)
+    {
+        istr->read(v.id);
+        istr->read(v.uuid);
+        istr->read(v.tableName);
+        istr->read(v.confidence);
+        istr->read(v.imgUrl);
+        istr->read(v.idcard);
+        istr->read(v.alarmRet);
+    }
+};
+
+}
+
+namespace FaceSearch
+{
+
+template<class T>
+class CallbackNC_FaceFeatureSearchServer_faceSearchMax : public Callback_FaceFeatureSearchServer_faceSearchMax_Base, public ::IceInternal::TwowayCallbackNC<T>
+{
+public:
+
+    typedef IceUtil::Handle<T> TPtr;
+
+    typedef void (T::*Exception)(const ::Ice::Exception&);
+    typedef void (T::*Sent)(bool);
+    typedef void (T::*Response)(const ::FaceSearch::FaceResults&);
+
+    CallbackNC_FaceFeatureSearchServer_faceSearchMax(const TPtr& obj, Response cb, Exception excb, Sent sentcb)
+        : ::IceInternal::TwowayCallbackNC<T>(obj, cb != 0, excb, sentcb), _response(cb)
+    {
+    }
+
+    virtual void completed(const ::Ice::AsyncResultPtr& result) const
+    {
+        ::FaceSearch::FaceFeatureSearchServerPrx proxy = ::FaceSearch::FaceFeatureSearchServerPrx::uncheckedCast(result->getProxy());
+        ::FaceSearch::FaceResults ret;
+        try
+        {
+            ret = proxy->end_faceSearchMax(result);
+        }
+        catch(const ::Ice::Exception& ex)
+        {
+            ::IceInternal::CallbackNC<T>::exception(result, ex);
+            return;
+        }
+        if(_response)
+        {
+            (::IceInternal::CallbackNC<T>::_callback.get()->*_response)(ret);
+        }
+    }
+
+private:
+
+    Response _response;
+};
+
+template<class T> Callback_FaceFeatureSearchServer_faceSearchMaxPtr
+newCallback_FaceFeatureSearchServer_faceSearchMax(const IceUtil::Handle<T>& instance, void (T::*cb)(const ::FaceSearch::FaceResults&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0)
+{
+    return new CallbackNC_FaceFeatureSearchServer_faceSearchMax<T>(instance, cb, excb, sentcb);
+}
+
+template<class T> Callback_FaceFeatureSearchServer_faceSearchMaxPtr
+newCallback_FaceFeatureSearchServer_faceSearchMax(T* instance, void (T::*cb)(const ::FaceSearch::FaceResults&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0)
+{
+    return new CallbackNC_FaceFeatureSearchServer_faceSearchMax<T>(instance, cb, excb, sentcb);
+}
+
+template<class T, typename CT>
+class Callback_FaceFeatureSearchServer_faceSearchMax : public Callback_FaceFeatureSearchServer_faceSearchMax_Base, public ::IceInternal::TwowayCallback<T, CT>
+{
+public:
+
+    typedef IceUtil::Handle<T> TPtr;
+
+    typedef void (T::*Exception)(const ::Ice::Exception& , const CT&);
+    typedef void (T::*Sent)(bool , const CT&);
+    typedef void (T::*Response)(const ::FaceSearch::FaceResults&, const CT&);
+
+    Callback_FaceFeatureSearchServer_faceSearchMax(const TPtr& obj, Response cb, Exception excb, Sent sentcb)
+        : ::IceInternal::TwowayCallback<T, CT>(obj, cb != 0, excb, sentcb), _response(cb)
+    {
+    }
+
+    virtual void completed(const ::Ice::AsyncResultPtr& result) const
+    {
+        ::FaceSearch::FaceFeatureSearchServerPrx proxy = ::FaceSearch::FaceFeatureSearchServerPrx::uncheckedCast(result->getProxy());
+        ::FaceSearch::FaceResults ret;
+        try
+        {
+            ret = proxy->end_faceSearchMax(result);
+        }
+        catch(const ::Ice::Exception& ex)
+        {
+            ::IceInternal::Callback<T, CT>::exception(result, ex);
+            return;
+        }
+        if(_response)
+        {
+            (::IceInternal::Callback<T, CT>::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie()));
+        }
+    }
+
+private:
+
+    Response _response;
+};
+
+template<class T, typename CT> Callback_FaceFeatureSearchServer_faceSearchMaxPtr
+newCallback_FaceFeatureSearchServer_faceSearchMax(const IceUtil::Handle<T>& instance, void (T::*cb)(const ::FaceSearch::FaceResults&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0)
+{
+    return new Callback_FaceFeatureSearchServer_faceSearchMax<T, CT>(instance, cb, excb, sentcb);
+}
+
+template<class T, typename CT> Callback_FaceFeatureSearchServer_faceSearchMaxPtr
+newCallback_FaceFeatureSearchServer_faceSearchMax(T* instance, void (T::*cb)(const ::FaceSearch::FaceResults&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0)
+{
+    return new Callback_FaceFeatureSearchServer_faceSearchMax<T, CT>(instance, cb, excb, sentcb);
+}
+
+template<class T>
+class CallbackNC_FaceFeatureSearchServer_faceSearchTopN : public Callback_FaceFeatureSearchServer_faceSearchTopN_Base, public ::IceInternal::TwowayCallbackNC<T>
+{
+public:
+
+    typedef IceUtil::Handle<T> TPtr;
+
+    typedef void (T::*Exception)(const ::Ice::Exception&);
+    typedef void (T::*Sent)(bool);
+    typedef void (T::*Response)(const ::FaceSearch::FaceResults&);
+
+    CallbackNC_FaceFeatureSearchServer_faceSearchTopN(const TPtr& obj, Response cb, Exception excb, Sent sentcb)
+        : ::IceInternal::TwowayCallbackNC<T>(obj, cb != 0, excb, sentcb), _response(cb)
+    {
+    }
+
+    virtual void completed(const ::Ice::AsyncResultPtr& result) const
+    {
+        ::FaceSearch::FaceFeatureSearchServerPrx proxy = ::FaceSearch::FaceFeatureSearchServerPrx::uncheckedCast(result->getProxy());
+        ::FaceSearch::FaceResults ret;
+        try
+        {
+            ret = proxy->end_faceSearchTopN(result);
+        }
+        catch(const ::Ice::Exception& ex)
+        {
+            ::IceInternal::CallbackNC<T>::exception(result, ex);
+            return;
+        }
+        if(_response)
+        {
+            (::IceInternal::CallbackNC<T>::_callback.get()->*_response)(ret);
+        }
+    }
+
+private:
+
+    Response _response;
+};
+
+template<class T> Callback_FaceFeatureSearchServer_faceSearchTopNPtr
+newCallback_FaceFeatureSearchServer_faceSearchTopN(const IceUtil::Handle<T>& instance, void (T::*cb)(const ::FaceSearch::FaceResults&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0)
+{
+    return new CallbackNC_FaceFeatureSearchServer_faceSearchTopN<T>(instance, cb, excb, sentcb);
+}
+
+template<class T> Callback_FaceFeatureSearchServer_faceSearchTopNPtr
+newCallback_FaceFeatureSearchServer_faceSearchTopN(T* instance, void (T::*cb)(const ::FaceSearch::FaceResults&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0)
+{
+    return new CallbackNC_FaceFeatureSearchServer_faceSearchTopN<T>(instance, cb, excb, sentcb);
+}
+
+template<class T, typename CT>
+class Callback_FaceFeatureSearchServer_faceSearchTopN : public Callback_FaceFeatureSearchServer_faceSearchTopN_Base, public ::IceInternal::TwowayCallback<T, CT>
+{
+public:
+
+    typedef IceUtil::Handle<T> TPtr;
+
+    typedef void (T::*Exception)(const ::Ice::Exception& , const CT&);
+    typedef void (T::*Sent)(bool , const CT&);
+    typedef void (T::*Response)(const ::FaceSearch::FaceResults&, const CT&);
+
+    Callback_FaceFeatureSearchServer_faceSearchTopN(const TPtr& obj, Response cb, Exception excb, Sent sentcb)
+        : ::IceInternal::TwowayCallback<T, CT>(obj, cb != 0, excb, sentcb), _response(cb)
+    {
+    }
+
+    virtual void completed(const ::Ice::AsyncResultPtr& result) const
+    {
+        ::FaceSearch::FaceFeatureSearchServerPrx proxy = ::FaceSearch::FaceFeatureSearchServerPrx::uncheckedCast(result->getProxy());
+        ::FaceSearch::FaceResults ret;
+        try
+        {
+            ret = proxy->end_faceSearchTopN(result);
+        }
+        catch(const ::Ice::Exception& ex)
+        {
+            ::IceInternal::Callback<T, CT>::exception(result, ex);
+            return;
+        }
+        if(_response)
+        {
+            (::IceInternal::Callback<T, CT>::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie()));
+        }
+    }
+
+private:
+
+    Response _response;
+};
+
+template<class T, typename CT> Callback_FaceFeatureSearchServer_faceSearchTopNPtr
+newCallback_FaceFeatureSearchServer_faceSearchTopN(const IceUtil::Handle<T>& instance, void (T::*cb)(const ::FaceSearch::FaceResults&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0)
+{
+    return new Callback_FaceFeatureSearchServer_faceSearchTopN<T, CT>(instance, cb, excb, sentcb);
+}
+
+template<class T, typename CT> Callback_FaceFeatureSearchServer_faceSearchTopNPtr
+newCallback_FaceFeatureSearchServer_faceSearchTopN(T* instance, void (T::*cb)(const ::FaceSearch::FaceResults&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0)
+{
+    return new Callback_FaceFeatureSearchServer_faceSearchTopN<T, CT>(instance, cb, excb, sentcb);
+}
+
+}
+
+#endif
+
+#include <IceUtil/PopDisableWarnings.h>
+#endif
diff --git a/rpc/FaceSearchServer.ice b/rpc/FaceSearchServer.ice
new file mode 100644
index 0000000..13cc9c3
--- /dev/null
+++ b/rpc/FaceSearchServer.ice
@@ -0,0 +1,24 @@
+module FaceSearch
+{
+	sequence<byte> Data;
+	
+	struct FaceResult
+	{
+		long id;
+		string uuid;
+		string tableName;
+		float confidence;
+		string imgUrl;
+		string idcard;
+		string alarmRet;
+	}
+
+	sequence<FaceResult> FaceResults;
+
+	interface FaceFeatureSearchServer
+	{
+		FaceResults faceSearchMax(Data feature,string info);
+		FaceResults faceSearchTopN(Data feature,string info, int topN,float score);
+	}
+
+}
diff --git a/rpc/gen.sh b/rpc/gen.sh
new file mode 100644
index 0000000..5e04a07
--- /dev/null
+++ b/rpc/gen.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/bsk/development/c++/Qt/BasicPlatForm/libs/Ice-3.7.0/lib64/
+./../../../BasicPlatForm/libs/Ice-3.7.0/bin/slice2cpp FaceSearchServer.ice

--
Gitblit v1.8.0