bool AsyncThriftForwarder::reloadConfig()
{
	TDEBUG("Load configuration...");

	if (!config_dir.exists(LOG4CXX_CONFIG_FILE)) {
		TWARN("Cannot find '%s'", LOG4CXX_CONFIG_FILE);
		return false;
	}

	if (!config_dir.exists(ASYNCTHRIFT_CONFIG_FILE)) {
		TWARN("Cannot find '%s'", ASYNCTHRIFT_CONFIG_FILE);
		return false;
	}

	TLogger::configure(qPrintable(config_dir.absoluteFilePath(LOG4CXX_CONFIG_FILE)));

	QSettings settings(config_dir.absoluteFilePath(ASYNCTHRIFT_CONFIG_FILE), QSettings::IniFormat);

	QString socket(settings.value("ForwarderSocket", QString(PKGSTATEDIR "/logger")).toString());

	// TODO: Check reconfiguration. We could reconfigure delay and flush_interval
	settings.beginGroup("LogForwarder");
	int nentries = settings.beginReadArray("Forwarders");
	for (int i = 0; i < nentries; i++) {
		settings.setArrayIndex(i);
		forwarders.append(new ForwarderManager(settings.value("Name").toString(), settings.value("ZQuorum").toString(), settings.value("Delay").toUInt(), settings.value("FlushInterval").toUInt(), socket));
	}
	settings.endArray();

	return true;
}
Ejemplo n.º 2
0
void
mtd_thread_t::did_reply ()
{
  time_t tm = sfs_get_timenow() - start;
  if (tm > LONG_REPLY_TIME) {
    if (cell->sbp) {
      TWARN ("long service time (" << tm << " secs) for PROC=" 
	     << cell->sbp->proc ());
    } else {
      TWARN ("long service time (" << tm  << " secs); no procno given");
    }
  }
}
Ejemplo n.º 3
0
sth_t
amysql_thread_t::prepare (const str &q, u_int o)
{
  if (readied) {
    TWARN ("security precaution: cannot prepare queries "
	   "after servicing requests\n");
    return NULL;
  }
	   
  sth_t r = mysql.prepare (q, o);
  if (!r) 
    TWARN (mysql.error ());
  return r;
}
Ejemplo n.º 4
0
void ConnectionManager::connectionReadyRead()
{
	struct msghdr msg;
	struct iovec iov;
	TTRACE("ConnectionManager::connectionReadyRead");

	/* Response data */
	iov.iov_base = buffer.data();
	iov.iov_len = buffer.length();

	/* compose the message */
	memset(&msg, 0, sizeof(msg));
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;

	while(connectionFd >= 0) {
		int nread = recvmsg(connectionFd, &msg, MSG_DONTWAIT);
		if (nread == 0) {
			connectionClose();
			return;
		} else if (nread < 0) {
			if (errno != EAGAIN) {
				TWARN("recvmsg error %s", strerror(errno));
				//close(connFd);
				connectionClose();
			}
			return;
		}

		receiveDatagram(buffer.data(), nread);
	}

}
Ejemplo n.º 5
0
void
mtd_thread_t::run ()
{ 
  mtd_status_t rc;

  GIANT_LOCK();
  bool ok = init_phase0() && init();
  GIANT_UNLOCK();

  if (!ok) {
    TWARN ("thread could not initialize");
    msg_send (MTD_SHUTDOWN);
    delete this;
    return;
  }

  become_ready ();
  do {
    GIANT_LOCK();
    take_svccb ();
    GIANT_UNLOCK();
    rc = msg_recv ();
  } while (rc == MTD_CONTINUE);
  
  cell->status = MTD_SHUTDOWN;
  msg_send (MTD_SHUTDOWN);
  return;
}
Ejemplo n.º 6
0
void ConnectionManager::sendDatagram(const char* buf, size_t len, int controlFd)
{
	char control[sizeof(struct cmsghdr)+10];
	struct msghdr msg;
	struct cmsghdr *cmsg;
	struct iovec iov;

	/* Response data */
	iov.iov_base = const_cast<char*>(buf);
	iov.iov_len = len;

	/* compose the message */
	memset(&msg, 0, sizeof(msg));
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;

	/* send controlFd */
	if (controlFd > 0) {
		msg.msg_control = control;
		msg.msg_controllen = sizeof(control);
		cmsg = CMSG_FIRSTHDR(&msg);
		cmsg->cmsg_level = SOL_SOCKET;
		cmsg->cmsg_type = SCM_RIGHTS;
		cmsg->cmsg_len = CMSG_LEN(sizeof(controlFd));
		memcpy(reinterpret_cast<void *>(CMSG_DATA(cmsg)), &controlFd, sizeof(controlFd));
		msg.msg_controllen = cmsg->cmsg_len;
	}

	if (sendmsg(connectionFd, &msg, MSG_DONTWAIT) < 0) {
		TWARN("sendmsg error %s", strerror(errno));
		connectionClose();
		//close(connFd);
		return;
	}
}
Ejemplo n.º 7
0
void
tst2_srv_t::get (ptr<amt::req_t> b)
{
  rpc::tst2_prog_1::tst2_get_srv_t<amt::req_t> srv (b);
  const tst2_get_arg_t *arg  = srv.getarg ();
  adb_status_t rc;

  ptr<tst2_get_res_t> res = srv.alloc_res (ADB_OK);
  
  if (!_q_get->execute (*arg)) {
    rc = ADB_EXECUTE_ERROR;
  } else {
    rc = _q_get->fetch (&res->dat->pk, &res->dat->d, &res->dat->i,
			&res->dat->d2);
  }

  if (rc != ADB_OK) {
    res->set_status (rc);
    str es;
    if ((es = _q_get->error ())) 
      TWARN(es);
  }

  srv.reply (res);
}
Ejemplo n.º 8
0
void
mtd_thread_t::become_ready ()
{
  readied = true;
  TWARN ("called become_ready ()"); // debug
  cell->status = MTD_READY;
  msg_send (MTD_READY);
}
Ejemplo n.º 9
0
void ConnectionManager::receiveDatagram(const char* buf, size_t len)
{
	if (memcmp(buf, "watch ", 6) == 0) {
		receiveWatch(buf, len);
	} else if (memcmp(buf, "CAPABILITIES ", 6) == 0) {
		receiveHandshake(buf, len);
	} else {
		TWARN("Unknown command %.*s", (int)len, buf);
	}
}
Ejemplo n.º 10
0
mtd_status_t 
mtd_thread_t::msg_recv ()
{
  mtd_msg_t msg;
  int rc = ::msg_recv (fdin, &msg);
  if (rc < 0) {
    TWARN ("mtd_thread_t::msg_recv: bad read; (errno=%d" << errno << ")");
    return MTD_ERROR;
  }
  return msg.status;
}
Ejemplo n.º 11
0
void showSortResult(sort_framework::SortResult *pSortResult)
{
    if (pSortResult == NULL)
        return ;
    FILE *pOutput = NULL;
    int32_t num = 0;
    int32_t DocsReturn = 0;
    int64_t *pNID = NULL;
    int64_t *szFirstRanks = NULL;
    int64_t *szSecondRanks = NULL;
    pOutput = fopen(OUTPUTFILE, "a+");
    if (pOutput == NULL) {
        fprintf(stderr, "open file %s error\n", OUTPUTFILE);
        return ;
    }
    //Get Nid List
    DocsReturn =
        pSortResult->getNidList(pNID);
    //Get FirstRank List
    num = pSortResult->getFirstRankList(szFirstRanks);
    if (num < 0) {
        TWARN("Get FirstRank List error.");
        return ;
    }
    //Get SecondRank List
    num = pSortResult->getSecondRankList(szSecondRanks);
    if (num < 0) {
        TWARN("Get SecondRank List error.");
        return ;
    }
    fprintf(pOutput, "\nSort Result Begin:\nDocsFound = %d\n", pSortResult->getDocsFound());
    for (uint32_t i=0; i<DocsReturn; i++)
    {
        fprintf(pOutput, "%d\tnid=%lu\tfirst=%lld\tsecond=%lld\n", 
                i, pNID[i], szFirstRanks[i], szSecondRanks[i]);
    }
    fprintf(pOutput, "Sort Result End");
    fflush(pOutput);
    fclose(pOutput);
    return ;
}
Ejemplo n.º 12
0
void
tst2_srv_t::mget (ptr<amt::req_t> b)
{
  rpc::tst2_prog_1::tst2_mget_srv_t<amt::req_t> srv (b);
  const tst2_mget_arg_t *arg = srv.getarg ();
  ptr<tst2_mget_res_t> res = srv.alloc_res (ADB_OK);

  if (!_q_mget->execute (arg->sleep_msec, arg->lim)) {
    res->set_status (ADB_EXECUTE_ERROR);
    TWARN("mget error: " << _q_mget->error ());
  } else {
    adb_status_t s;
    tst2_data_t dat;
    while ((s = _q_mget->fetch (&dat.d, &dat.i, &dat.pk, &dat.d2)) == ADB_OK) {
      res->rows->push_back (dat);
    }
    if (s != ADB_NOT_FOUND) {
      TWARN("mget error: " << _q_mget->error ());
      res->set_status (s);
    }
  }
  srv.reply (res);
}
Ejemplo n.º 13
0
void
mtd_thread_t::reply (ptr<void> d)
{
  if (ok_kthread_safe) {
    TWARN ("XX WARNING!! Do not call mth_thread_t::reply "
	   "in thread-safe mode!\n");
  }
  did_reply ();
  cell->rsp_u.p = d;
  d = NULL;
  cell->status = MTD_REPLY;
  cell->rstat = MTD_RPC_DATA;
  msg_send (MTD_REPLY);
}
Ejemplo n.º 14
0
void
tst2_srv_t::put (ptr<amt::req_t> b)
{
  rpc::tst2_prog_1::tst2_put_srv_t<amt::req_t> srv (b);
  const tst2_put_arg_t *arg = srv.getarg ();
  ptr<adb_status_t> res = srv.alloc_res (ADB_OK);

  if (!_q_put->execute (arg->key, arg->data.d, arg->data.i, arg->data.d2)) {
    *res = ADB_EXECUTE_ERROR;
    str es;
    if ((es = _q_put->error ())) 
      TWARN("put error: " << es);
  }

  b->reply (res);
}
Ejemplo n.º 15
0
int32_t SearcherWorker::getDetailInfo(const char *q_reslut, uint32_t q_size, const char *pureString, char** res, int* res_size)
{
    //for detail
    char** args = NULL;
    int fieldCount = 0;
    char* pLightKey = 0;
    char* pDL = 0;
    if(!q_reslut || 0 == q_size){
        return KS_EFAILED;
    }

    pLightKey = FRAMEWORK::Query::getParam(pureString, q_size, LIGHTKEY);
    if(pLightKey && pLightKey[0]!=0){
        int len = strlen(pLightKey);
        int ret = decode_url(pLightKey, len, pLightKey, len+1);
        if(ret<0){
            TWARN("decode_url pLightKey error, return!");
            _session.setStatus(FRAMEWORK::ss_error);
            _session.response();
            return KS_EFAILED;
        }
        pLightKey[ret] = 0;
    }
    pDL = FRAMEWORK::Query::getParam(pureString, q_size, DL);

    fieldCount = get_di_field_count();
    if(di_detail_arg_alloc(&args)<(fieldCount+1)){
        TERR("di_detail_arg_alloc error, return!");
        _session.setStatus(FRAMEWORK::ss_error);
        _session.response();
        return KS_EFAILED;
    }
    di_detail_arg_set(args, fieldCount+1, "title", 5, pLightKey, pDL);
    //Deal with detail
    if(di_detail_get_v3(q_reslut, pDL, args, fieldCount, res, res_size)){
        *res = (char*)malloc(2);
        (*res)[0] = '0';
        (*res)[1] = 0;
        *res_size = 1;
    }

    if(pLightKey)std::free(pLightKey);
    if(pDL)std::free(pDL);
    if(args)di_detail_arg_free(args);

    return KS_SUCCESS;
}
Ejemplo n.º 16
0
bool
tst2_srv_t::init ()
{
  bool rc = true;
  if (!mysql.connect ("okws_db_tst2", "okws", "localhost", "abc123")) {
    TWARN (mysql.error ());
    rc = false;
  } else if (!(_q_get = PREP("SELECT id,d,i,d2 FROM tst2 WHERE s = ?")) ||
	     !(_q_put = PREP("INSERT INTO tst2(s,d,i,d2) VALUES(?,?,?,?)")) ||
	     !(_q_mget = PREP("SELECT SLEEP(?/1000),id,d,i,d2 "
			      "FROM tst2 ORDER BY RAND() "
			      "LIMIT ?"))) {
    rc = false;
  }
  return rc;

}
Ejemplo n.º 17
0
int32_t SearcherWorker::run() {
    const char *pureString = NULL;
    uint32_t pureSize = 0;
    char *resData = NULL;
    uint32_t resSize = 0;
    char *resDetailData = NULL;
    int32_t resDetailSize = 0;
    int32_t ret = 0;
    MemPool *memPool = NULL;
    int64_t *pNid = NULL;
    commdef::ClusterResult *pClusterResult = NULL;
    queryparser::QueryRewriterResult *pQRWResult = NULL;
    queryparser::QPResult *pQueryResult = NULL;
    SearchResult *pSearchResult = NULL;
    statistic::StatisticResult *pStatisticResult = NULL;
    sort_framework::SortResult *pSortResult = NULL;
    ResultSerializer resultSerial;
    FRAMEWORK::Context context;
    FILE *pOutput = NULL;
    //check session status
    FRAMEWORK::session_status_t status = _session.getStatus();
    if (status == FRAMEWORK::ss_timeout) {
        handleTimeout();
        return KS_SUCCESS;
    }
    //get query infomation
    FRAMEWORK::Query &query = _session.getQuery();
    pureSize = query.getPureQuerySize();
    pureString = query.getPureQueryData();
    if (!pureString || pureSize == 0) {
        _session.setStatus(FRAMEWORK::ss_error);
        _session.response();
        return KS_EFAILED;
    }
    //set LogInfo level
    _session._logInfo._eRole = FRAMEWORK::sr_simple;
    //get MemPool from factory
    memPool = _memFactory.make((uint64_t)(getOwner()));
    if (memPool == NULL) {
        TWARN("Make mem pool failed!");
        return KS_EFAILED;
    }
    //create memory pool monitor
    MemMonitor memMonitor(memPool, _memLimit);
    memPool->setMonitor(&memMonitor);
    memMonitor.enableException();
    //initialize context class
    context.setMemPool(memPool);
	//initialize format processor
    _formatProcessor.init(memPool);
    //Deal with search proccess
    do{  
        if(_session.isHttp()){
            pQRWResult = NEW(memPool, queryparser::QueryRewriterResult)();
            if (pQRWResult == NULL) {
                TWARN("SEARCHER: new Result no mem");
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
        }
        pQueryResult = NEW(memPool, queryparser::QPResult)(memPool);
        pSearchResult = NEW(memPool, SearchResult);
        pStatisticResult = NEW(memPool, statistic::StatisticResult); 
        pSortResult = NEW(memPool, sort_framework::SortResult)(memPool);
        if(unlikely(!pQueryResult || !pSearchResult || !pStatisticResult
                    || !pSortResult)) {
            TWARN("SEARCHER: new Result no mem");
            _session.setStatus(FRAMEWORK::ss_error);
            break;
        }
        //add queryrewrite process
        if(_session.isHttp()){     
            ret = _qrewriter.doRewrite(&context, pureString, pureSize, pQRWResult);
            if (timeoutCheck && (_timeout > 0) && (_session.getLatencyTime() > _timeout)) {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: qrewriter.doRewrite function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret != KS_SUCCESS)) {
                _session.setStatus(FRAMEWORK::ss_error);
                TWARN("qrewriter.doRewrite function error. query is %s", pureString);                
                break;
            }
            pureString = pQRWResult->getRewriteQuery();
        }
        //end add
        ret = _qp.doParse(&context, pQueryResult, pureString);
        if (timeoutCheck && (_timeout > 0) && 
                (_session.getLatencyTime() > _timeout)) 
        {
            _session.setStatus(FRAMEWORK::ss_timeout);
            TWARN("SEARCHER: qp.doParse function over time. query is %s", pureString);
            break;
        }
        if (unlikely(ret != KS_SUCCESS)){
            TWARN("SEARCHER: queryparser doParse function error. query is %s", pureString);
            _session.setStatus(FRAMEWORK::ss_error);
            break;
        }

        // cache命中情况下, mempool reset时调用CacheResult析构函数,释放命中的节点,
        // 否则sortResult对节点内存的引用失效,变为野指针(bug#118631)
        {
            ret = _is.doQuery(&context, pQueryResult, &_sort, pSearchResult);
            if (timeoutCheck && (_timeout > 0) &&
                    (_session.getLatencyTime() > _timeout)) 
            {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: is.doQuery function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret != KS_SUCCESS)){
                TWARN("SEARCHER: search doQuery function error. query is %s", pureString);
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
            ret = _stat.doStatisticOnSearcher(&context, 
                    *(pQueryResult->getParam()),
                    pSearchResult, pStatisticResult);
            if (timeoutCheck && (_timeout > 0) &&
                    (_session.getLatencyTime() > _timeout)) 
            {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: doStatisticOnSearcher function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret != KS_SUCCESS)){
                TWARN("SEARCHER: statistic doStatisticOnSearcher function error. query is %s", pureString);
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
            ret = _sort.doProcess(context, *(pQueryResult->getParam()), 
                    *pSearchResult, *pSortResult);
            if (timeoutCheck && (_timeout > 0) &&
                    (_session.getLatencyTime() > _timeout))
            {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: sort.doProcess function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret)) {
                TWARN("SEARCHER: sort doProcess function error. query is %s", pureString);
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
        }


        pNid = NULL;
        //get docs return number
        int32_t num = pSortResult->getNidList(pNid);
        pClusterResult = NEW(memPool, commdef::ClusterResult)();

        if ( NULL == pClusterResult ){
            TWARN("SEARCHER: malloc from memPool failed ");
            _session.setStatus(FRAMEWORK::ss_error);
            break;            
        }

        memset(pClusterResult, 0x0, sizeof(commdef::ClusterResult));
        pClusterResult->_nDocsFound = pSortResult->getDocsFound();//pSearchResult->nDocFound;
        pClusterResult->_nEstimateDocsFound = pSortResult->getEstimateDocsFound();//pSearchResult->nEstimateDocFound;
        pClusterResult->_nDocsSearch = pSearchResult->nDocSearch;
        pClusterResult->_nDocsReturn = num;
        pClusterResult->_nDocsRestrict = pSearchResult->nEstimateDocFound;//pSearchResult->nDocFound;
        pClusterResult->_pStatisticResult = pStatisticResult;
        pClusterResult->_pSortResult = pSortResult;
        pClusterResult->_pQPResult = pQueryResult;
        pClusterResult->_ppDocuments = NULL;

        if(_session.isHttp() && _detail){

            if(!pClusterResult->_nDocsReturn){
                break;
            }  
            char* pid = NULL;
            uint32_t pid_size = 0;
            ret = get_nid_str(pNid, num, memPool, &pid, &pid_size);
            if(KS_SUCCESS != ret){
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }            
            ret = getDetailInfo(pid, pid_size, pureString, &resDetailData, &resDetailSize);
            if(KS_SUCCESS != ret){
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
            if(timeoutCheck && _timeout>0 && _session.getLatencyTime()>_timeout){
        		_session.setStatus(FRAMEWORK::ss_timeout); 
                break;
        	} 

            if (!translateV3(resDetailData, pClusterResult->_ppDocuments, (uint32_t &)pClusterResult->_nDocsReturn, memPool)) {
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
        }
    } while (0);

    if(resDetailData)std::free(resDetailData);

    if(_session.isHttp() && _detail){
        //fromat result
        get_outfmt_type(pureString, pureSize);
        result_container_t container;
        container.pClusterResult = pClusterResult;
        container.cost = _session.getLatencyTime();
        if(_formatProcessor.frmt(_ofmt_type, container, &resData , &resSize) < 0){
            TERR("FORMATRESULT: format_processor process error!"); 
            _session.setStatus(FRAMEWORK::ss_error);
        }
    }
    else{     
        //serialize search result
        ret = resultSerial.serialClusterResult(pClusterResult,
                resData, resSize, "Z");
        if (ret != KS_SUCCESS) {
            _session.setStatus(FRAMEWORK::ss_error);
        }
    }
    //recycle mem pool
    context.getMemPool()->reset();
    _session.setResponseData(resData, resSize);
    _session.response();
    return KS_SUCCESS;
}
Ejemplo n.º 18
0
int32_t SearcherWorkerFactory::initilize(const char *path) 
{
    ini_context_t cfg;
    const ini_section_t *grp = NULL;
    const char *val = NULL;
    const char *seconf = NULL;
    uint32_t nval = 0;
    int32_t ret = 0;
    if (_ready) {
        return KS_SUCCESS;
    }
    if (!_server)
    {
        TERR("initialize _server error.");
        return KS_EFAILED;
    }
    _server->_type = FRAMEWORK::srv_type_searcher;
    ret = ini_load_from_file(path, &cfg);
    if (unlikely(ret != 0)) {
        TERR("initialize SearcherWorkerFactory by `%s' error.", 
                SAFE_STRING(path));
        return KS_EFAILED;
    }
    grp = &cfg.global;
    if (unlikely(!grp)) {
        TERR("invalid config file `%s' for SearcherWorkerFactory.",
                SAFE_STRING(path));
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    //获得搜索xml文件句柄
    val = ini_get_str_value1(grp, "module_config_path");
    if (val && (val[0] != '\0')) {
        FILE *fp = NULL;
        if ((fp = fopen(val, "r")) == NULL) {
            TERR("模块配置文件 %s 打开出错, 文件可能不存在.\n", val);
            ini_destroy(&cfg);
            return KS_EFAILED;
        }
        _pXMLTree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
        if (_pXMLTree == NULL) {
            TERR("模块配置文件 %s 格式有错, 请修正您的配置文件.\n", val);
            fclose(fp);
            ini_destroy(&cfg);
            return KS_EFAILED;
        }
        fclose(fp);
    }
    else {
        TERR("search module config path is null");
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    //各个处理模块的初始化工作
    if (index_lib::init(_pXMLTree) != KS_SUCCESS) {
        TERR("init index lib failed!");
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    if (_qrewiter.init(_pXMLTree) != KS_SUCCESS){
        TERR("init query rewriter failed!");
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    if (_qp.init(_pXMLTree) != KS_SUCCESS){
        TERR("init query parser failed!");
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    if (_is.init(_pXMLTree) != KS_SUCCESS){
        TERR("init index searcher failed!");
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    if (_stat.init(_pXMLTree) != KS_SUCCESS){
        TWARN("init statistic failed!");
    }
    //get default value of format type
    _ofmt_type = get_outfmt_type(_pXMLTree);
    //get sort config
    val = ini_get_str_value1(grp, "sort_config_path");
    if (val && (val[0] != '\0')) {
        if (_sort.init(val) != KS_SUCCESS) {
            TERR("init sort failed! path = %s\n", val);
            ini_destroy(&cfg);
            return KS_EFAILED;
        }
    }
    else {
        TERR("sort config file is error!");
        ini_destroy(&cfg);
        return KS_EFAILED;
    }
    val = ini_get_str_value1(grp, "update_config_path");
    if (val && (val[0] != '\0')) {
        _pIndexUpdater = new UPDATE::IndexUpdater;
        int32_t nRes = -1;
        if ((nRes = _pIndexUpdater->init(val)) != 0) {
            TERR("init IndexUpdater failed! errno=%d", nRes);
        }
        else if (pthread_create(&_updateTid, NULL, UPDATE::Updater::start, _pIndexUpdater) != 0) {
            TERR("start updater thread failed!");
            ini_destroy(&cfg);
            return KS_EFAILED;
        }
    }
    else {
        TERR("update config path is null");
    }

    //获得detail_module.xml文件句柄
    val = ini_get_str_value1(grp, "detail_module_config_path");
    if (val && (val[0] != '\0')) {
        FILE *fp = NULL;
        if ((fp = fopen(val, "r")) == NULL) {
            TERR("模块配置文件 %s 打开出错, 文件可能不存在.\n", val);
            ini_destroy(&cfg);
            return KS_EFAILED;
        }
        _pXMLTreeDetail= mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
        if (_pXMLTreeDetail == NULL) {
            TERR("模块配置文件 %s 格式有错, 请修正您的配置文件.\n", val);
            fclose(fp);
            ini_destroy(&cfg);
            return KS_EFAILED;
        }
        fclose(fp);
        _detail = true;
    }
    else {
        _detail = false;
    }

    if(_detail)
    {
		//初始化detail各模块
    	if(di_detail_init(_pXMLTreeDetail)!=KS_SUCCESS){
    		TERR("di_detail_init failed!");
    		ini_destroy(&cfg);
    		return KS_EFAILED;
    	}
    }

    ini_destroy(&cfg);

    _ready = true;
    return KS_SUCCESS;
}
Ejemplo n.º 19
0
int IndexFieldInc::addTerm(uint64_t termSign, uint32_t docId, uint8_t firstOcc)
{
    // 检查并删除idx_dict中超时的buffer空间
    idx_dict_free_oldblock(_bitmapDict);
    idx_dict_free_oldblock(_invertedDict);

    if(unlikely((_fullDocNum + 8*_maxIncBitmapSize) <= docId))
    {
        TWARN("inc reach max doc count limit!");
        return KS_SUCCESS;
    }
    if(_bitmapDict)
    {
        idict_node_t* pNodeBitmap = idx_dict_find(_bitmapDict, termSign);
        if(pNodeBitmap)
        {
            bitmap_idx1_unit_t* pIncBitmap = (bitmap_idx1_unit_t*)pNodeBitmap;
            uint64_t * pBitmap =  (uint64_t*)(_pIncMemManager->offset2Addr(pIncBitmap->pos));
            pBitmap -= _fullDocNum / 64;
            pBitmap[docId / 64] |= bit_mask_tab[docId % 64];
            pIncBitmap->doc_count++;
            pIncBitmap->max_docId = docId;
            if (_bitmapDict->syncMgr) {
                IndexFieldSyncManager * pSyncMgr = (IndexFieldSyncManager *) _bitmapDict->syncMgr;
                pSyncMgr->putIdxDictNode(pNodeBitmap);
                pSyncMgr->syncToDisk();
            }
        }
    }
    inc_idx2_header_t* head = NULL;

    // 确定新的2级索引单元的写入位置
    idict_node_t* pNode = idx_dict_find(_invertedDict, termSign);

    if(pNode == NULL) { // 没有这个token, 申请一个新的block
        int32_t pageSize = getPageSize(0, 0);
        uint32_t off  = 0;
        if(_pIncMemManager->makeNewPage(pageSize, off) < 0) {
            return KS_ENOMEM;
        }
        char* buf = _pIncMemManager->offset2Addr(off);
        head = (inc_idx2_header_t*)buf;
        head->pageSize = _pIncMemManager->size(off);
        head->endOff = sizeof(inc_idx2_header_t);
        head->zipFlag = 0;

        idict_node_t node = {0L, 0, 0, 0, 0};
        node.sign = termSign;
        ((inc_idx1_unit_t*)&node)->pos = off;
        if (0 != idx_dict_add(_invertedDict, &node)) {
            TWARN("add token %lu to idx1 dict failed", node.sign);
            return KS_EFAILED;
        }
        pNode = idx_dict_find(_invertedDict, termSign);
    }

    if(NULL == pNode) {
        TWARN("add token %lu to idx1 dict failed", termSign);
        return KS_EFAILED;
    }

    // 获取头信息,定位到空白内存处
    inc_idx1_unit_t* pind1 = (inc_idx1_unit_t*)pNode;
    char* begin = _pIncMemManager->offset2Addr(pind1->pos);
    head = (inc_idx2_header_t*)begin;
    char* end = begin + head->pageSize;
//    begin = _pIncMemManager->offset2Addr(head->endOff);
    begin += head->endOff;

    uint32_t docCount = getDocNumByEndOff(head->endOff, head->zipFlag);
    if (unlikely(docCount != pind1->doc_count)) {
        TWARN("doc_count[%u] in idx1 mismatch idx2_header[%u]!", pind1->doc_count, docCount);
        pind1->doc_count = docCount;
    }

    /*
    if (head->zipFlag == 1) {
        idx2_zip_header_t *zipHeader = (idx2_zip_header_t*)(head + 1);
        idx2_zip_skip_unit_t *skip = (idx2_zip_skip_unit_t*)(zipHeader + 1);

        if (skip[zipHeader->block_num - 1].off > (docCount - 1)) {
            TWARN("reduce block_num!");
            zipHeader->block_num--;
            skip[zipHeader->block_num].off         = docCount;
            skip[zipHeader->block_num].doc_id_base = IDX_GET_BASE(INVALID_DOCID);
        }
    }
    */

    // 扩容
    uint32_t len = 0;
    if(head->zipFlag == 1)
    {
        len = (_maxOccNum > 0) ? sizeof(idx2_zip_list_unit_t) : sizeof(uint16_t);
        if(begin + (len<<1) > end)
        {
            int32_t ret = expend(head, pind1, begin, end);
            if(ret != KS_SUCCESS)
                return ret;
        }
    }
    else
    {
        len = (_maxOccNum > 0) ? sizeof(idx2_nzip_unit_t) : sizeof(uint32_t);
        if(begin + (len<<1) > end)
        {
            int32_t ret = expend(head, pind1, begin, end);
            if(ret != KS_SUCCESS)
                return ret;
        }
    }
    // 增加一篇文档
    if(head->zipFlag == 1)
    {
        uint16_t base = IDX_GET_BASE(docId);
        uint16_t diff = IDX_GET_DIFF(docId);
        idx2_zip_header_t *zipHeader = (idx2_zip_header_t*)(head + 1);
        idx2_zip_skip_unit_t *skip = (idx2_zip_skip_unit_t*)(zipHeader + 1);

        if(_maxOccNum == 0)
        {
            *(uint16_t*)(begin+sizeof(uint16_t)) = IDX_GET_DIFF(INVALID_DOCID);;
            *(uint16_t*)begin = diff;
            begin += sizeof(uint16_t);
            zipHeader->doc_list_len += sizeof(uint16_t);
        }
        else
        {
            ((idx2_zip_list_unit_t*)(begin+sizeof(idx2_zip_list_unit_t)))->doc_id_diff = IDX_GET_DIFF(INVALID_DOCID);
            ((idx2_zip_list_unit_t*)begin)->doc_id_diff = diff;
            ((idx2_zip_list_unit_t*)begin)->occ = firstOcc;
            begin += sizeof(idx2_zip_list_unit_t);
            zipHeader->doc_list_len += sizeof(idx2_zip_list_unit_t);
        }

        if(zipHeader->block_num == 0 || base > skip[zipHeader->block_num-1].doc_id_base)
        {
            if(unlikely(zipHeader->block_num == _maxIncSkipCnt))
            {
                TWARN("inc reach max doc count limit!");
                return KS_SUCCESS;
            }
            skip[zipHeader->block_num+1].doc_id_base = IDX_GET_BASE(INVALID_DOCID);
            skip[zipHeader->block_num+1].off = pind1->doc_count + 1;
            skip[zipHeader->block_num].doc_id_base = base;
            skip[zipHeader->block_num].off = pind1->doc_count;
            zipHeader->block_num++;
        }
        else
        {
            skip[zipHeader->block_num].off = pind1->doc_count + 1;
        }

        pind1->doc_count++;
    }
    else
    {
        if(_maxOccNum == 0)
        {
            *(uint32_t*)(begin+sizeof(uint32_t)) = INVALID_DOCID;
            *(uint32_t*)begin = docId;
            pind1->doc_count++;
            begin += sizeof(uint32_t);
        }
        else
        {
            ((idx2_nzip_unit_t*)(begin+sizeof(idx2_nzip_unit_t)))->doc_id = INVALID_DOCID;
            ((idx2_nzip_unit_t*)begin)->doc_id = docId;
            ((idx2_nzip_unit_t*)begin)->occ    = firstOcc;
            pind1->doc_count++;
            begin += sizeof(idx2_nzip_unit_t);
        }
    }

    char* p1 = _pIncMemManager->offset2Addr(pind1->pos);
    head->endOff = begin - p1;

    if (_invertedDict->syncMgr)
    {
        IndexFieldSyncManager * pSyncMgr = (IndexFieldSyncManager *) _invertedDict->syncMgr;
        pSyncMgr->putIdxDictNode(pNode);
        pSyncMgr->syncToDisk();
    }

    return 1;
}
Ejemplo n.º 20
0
int32_t IndexFieldInc::nzip2zip(inc_idx2_header_t *&head, inc_idx1_unit_t *&pind, char *&begin, char *&end, uint32_t baseNum, uint32_t validCount)
{
    int32_t pageSize = getPageSize(validCount, 1);
    uint32_t off = 0;
    if(_pIncMemManager->makeNewPage(pageSize, off) < 0)
    {
        TWARN("inc makeNewPage error");
        return KS_ENOMEM;
    }
    char* p1 = _pIncMemManager->offset2Addr(off);
    inc_idx2_header_t* tHead = (inc_idx2_header_t*)p1;
    char* p2 = _pIncMemManager->offset2Addr(pind->pos);
    memcpy(p1, p2, sizeof(inc_idx2_header_t));

    char *zip = p1+sizeof(inc_idx2_header_t);
    char *nzip = p2+sizeof(inc_idx2_header_t);
    idx2_zip_header_t *pheader = (idx2_zip_header_t*)zip;
    idx2_zip_skip_unit_t *pskip = (idx2_zip_skip_unit_t*)(pheader + 1);
    pheader->skip_list_len = (_maxIncSkipCnt + 1) * sizeof(idx2_zip_skip_unit_t);
    pheader->block_num = baseNum;

    uint16_t pre_base = IDX_GET_BASE(INVALID_DOCID);
    uint16_t cur_base = 0;
    uint32_t doc_count = pind->doc_count;
    uint32_t doc_pos  = 0;

    if(_maxOccNum > 0)
    {   // has occ info
        idx2_nzip_unit_t     * notzip  = (idx2_nzip_unit_t*)nzip;
        pheader->doc_list_len  = (validCount +1) * sizeof(idx2_zip_list_unit_t);
        idx2_zip_list_unit_t * plist   = (idx2_zip_list_unit_t*)(pskip + _maxIncSkipCnt + 1);

        for (unsigned int i=0, j=0; i<doc_count; i++)
        {
            // build doc_list unit
            if ( _docIdMgr->isDocIdDelUseLess( notzip[i].doc_id ))  continue;

            plist[doc_pos].doc_id_diff = IDX_GET_DIFF(notzip[i].doc_id);
            plist[doc_pos].occ         = notzip[i].occ;

            // build skip_list unit
            cur_base = IDX_GET_BASE(notzip[i].doc_id);
            if (cur_base != pre_base)
            {
                pskip[j].doc_id_base = cur_base;
                pskip[j].off         = doc_pos;
                pre_base             = cur_base;
                j++;
            }
            ++doc_pos;
        }

        if (unlikely(doc_pos != validCount)) {
            TERR("inc expand error, count miss[%u:%u]", validCount, doc_pos);
            return KS_EINVAL;
        }

        // build end doc list
        plist[validCount].doc_id_diff = IDX_GET_DIFF(INVALID_DOCID);
        plist[validCount].occ = 0;
        begin = (char*)(plist + validCount);
    }
    else
    {   // null occ info
        uint32_t * notzip  = (uint32_t*)nzip;
        pheader->doc_list_len  = (validCount + 1) * sizeof(uint16_t);
        uint16_t* plist   = (uint16_t*)(pskip + _maxIncSkipCnt + 1);

        for (unsigned int i=0, j=0; i<doc_count; i++)
        {
            if ( _docIdMgr->isDocIdDelUseLess( notzip[i] ))  continue;

            // build doc_list unit
            plist[doc_pos] = IDX_GET_DIFF((notzip[i]));

            // build skip_list unit
            cur_base = IDX_GET_BASE(notzip[i]);
            if (cur_base != pre_base)
            {
                pskip[j].doc_id_base = cur_base;
                pskip[j].off         = doc_pos;
                pre_base             = cur_base;
                j++;
            }
            ++doc_pos;
        }

        if (unlikely(doc_pos != validCount)) {
            TERR("inc expand error, count miss[%u:%u]", validCount, doc_pos);
            return KS_EINVAL;
        }
        // build end doc list
        plist[validCount] = IDX_GET_DIFF(INVALID_DOCID);
        begin = (char*)(plist + validCount);
    }

    // build auxillary block at the end of skiplist
    pskip[baseNum].doc_id_base = IDX_GET_BASE(INVALID_DOCID);
    pskip[baseNum].off         = validCount;

    tHead->pageSize = _pIncMemManager->size(off);
    tHead->endOff = begin - p1;
    tHead->zipFlag = 1;
    end = p1 + tHead->pageSize;
    _pIncMemManager->freeOldPage(head->pageSize, pind->pos);
    head = tHead;
    pind->pos = off;
    pind->doc_count = validCount;

    return KS_SUCCESS;
}
Ejemplo n.º 21
0
int32_t IndexFieldInc::nzip2nzip(inc_idx2_header_t *&head, inc_idx1_unit_t *&pind, char *&begin, char *&end, uint32_t validCount)
{
    int32_t pageSize = getPageSize(validCount, 0);
    uint32_t off = 0;
    if(_pIncMemManager->makeNewPage(pageSize, off) < 0) {
        TWARN("inc makeNewPage error");
        return KS_ENOMEM;
    }

    char* p1 = _pIncMemManager->offset2Addr(off);
    inc_idx2_header_t* tHead = (inc_idx2_header_t*)p1;
    char* p2 = _pIncMemManager->offset2Addr(pind->pos);
    memcpy(p1, p2, sizeof(inc_idx2_header_t));

    char *newNzip = p1 + sizeof(inc_idx2_header_t);
    char *oldNzip = p2 + sizeof(inc_idx2_header_t);

    uint32_t doc_count = pind->doc_count;
    uint32_t doc_pos  = 0;

    if (_maxOccNum > 0) {
        idx2_nzip_unit_t * newNotzip = (idx2_nzip_unit_t*)newNzip;
        idx2_nzip_unit_t * oldNotzip = (idx2_nzip_unit_t*)oldNzip;

        for (unsigned int i=0; i<doc_count; i++)
        {
            // build doc_list unit
            if ( _docIdMgr->isDocIdDelUseLess( oldNotzip[i].doc_id ))  continue;

            newNotzip[doc_pos++] = oldNotzip[i];
        }

        if (unlikely(doc_pos != validCount)) {
            TERR("inc expand error, count miss[%u:%u]", validCount, doc_pos);
            return KS_EINVAL;
        }

        // build end doc list
        newNotzip[validCount].doc_id = INVALID_DOCID;
        newNotzip[validCount].occ    = 0;
        begin = (char*)(newNotzip + validCount);
    }
    else {
        uint32_t * newNotzip = (uint32_t *)newNzip;
        uint32_t * oldNotzip = (uint32_t *)oldNzip;

        for (unsigned int i=0; i<doc_count; i++)
        {
            // build doc_list unit
            if ( _docIdMgr->isDocIdDelUseLess( oldNotzip[i] ))  continue;

            newNotzip[doc_pos++] = oldNotzip[i];
        }

        if (unlikely(doc_pos != validCount)) {
            TERR("inc expand error, count miss[%u:%u]", validCount, doc_pos);
            return KS_EINVAL;
        }

        // build end doc list
        newNotzip[validCount] = INVALID_DOCID;
        begin = (char*)(newNotzip + validCount);
    }

    // build auxillary block at the end of skiplist
    tHead->pageSize = _pIncMemManager->size(off);
    tHead->endOff   = begin - p1;
    tHead->zipFlag  = 0;
    end = p1 + tHead->pageSize;

    _pIncMemManager->freeOldPage(head->pageSize, pind->pos);
    head = tHead;
    pind->pos = off;
    pind->doc_count = validCount;
    return KS_SUCCESS;
}
Ejemplo n.º 22
0
int32_t IndexFieldInc::zip2zip(inc_idx2_header_t *&head, inc_idx1_unit_t *&pind, char *&begin, char *&end, uint32_t validCount)
{
    int32_t pageSize = getPageSize(validCount, 1);
    uint32_t off = 0;
    if(_pIncMemManager->makeNewPage(pageSize, off) < 0) {
        TWARN("inc makeNewPage error");
        return KS_ENOMEM;
    }

    char* p1 = _pIncMemManager->offset2Addr(off);
    char* p2 = _pIncMemManager->offset2Addr(pind->pos);
    memcpy(p1, p2, sizeof(inc_idx2_header_t));

    char *newZip = p1 + sizeof(inc_idx2_header_t);
    char *oldZip = p2 + sizeof(inc_idx2_header_t);

    inc_idx2_header_t * tHead = (inc_idx2_header_t *)p1;

    idx2_zip_header_t    *pNewHeader = (idx2_zip_header_t*)newZip;
    pNewHeader->skip_list_len = (_maxIncSkipCnt + 1) * sizeof(idx2_zip_skip_unit_t);

    idx2_zip_header_t    *pOldHeader = (idx2_zip_header_t*)oldZip;
    idx2_zip_skip_unit_t *pOldSkip   = (idx2_zip_skip_unit_t*)(pOldHeader + 1);
    idx2_zip_skip_unit_t *pNewSkip   = (idx2_zip_skip_unit_t*)(pNewHeader + 1);

    uint32_t baseNum    = pOldHeader->block_num;

    uint32_t baseId     = 0;
    uint32_t docId      = 0;
    uint32_t baseDocCnt = 0;

    uint32_t listPos    = 0;    // 扩展后的doclist个数
    uint32_t basePos    = 0;    // 扩展后的base block个数
    uint32_t beginPos   = INVALID_DOCID;

    if (_maxOccNum > 0) {
        idx2_zip_list_unit_t * pOldList = (idx2_zip_list_unit_t*)(pOldSkip + _maxIncSkipCnt + 1);
        idx2_zip_list_unit_t * pNewList = (idx2_zip_list_unit_t*)(pNewSkip + _maxIncSkipCnt + 1);

        for(unsigned int i = 0; i < baseNum; i++)
        {
            baseDocCnt = 0;
            beginPos   = INVALID_DOCID;
            baseId     = (pOldSkip[i].doc_id_base << 16);
            for(unsigned int j = pOldSkip[i].off; j < pOldSkip[i+1].off; j++) {
                docId = baseId + pOldList[j].doc_id_diff;

                if ( _docIdMgr->isDocIdDelUseLess( docId ))  continue;

                if (beginPos == INVALID_DOCID) {
                    beginPos = listPos;
                }
                pNewList[listPos++] = pOldList[j];
                baseDocCnt++;
            }

            if (baseDocCnt == 0) {
                continue;
            }
            pNewSkip[basePos].doc_id_base = pOldSkip[i].doc_id_base;
            pNewSkip[basePos].off         = beginPos;
            basePos++;
        }
        pNewList[listPos].doc_id_diff = IDX_GET_DIFF(INVALID_DOCID);
        pNewList[listPos].occ         = 0;
        begin = (char *)(pNewList + listPos);
        pNewHeader->doc_list_len = (listPos + 1) * sizeof(idx2_zip_list_unit_t);
    }
    else {
        uint16_t * pOldList = (uint16_t *)(pOldSkip + _maxIncSkipCnt + 1);
        uint16_t * pNewList = (uint16_t *)(pNewSkip + _maxIncSkipCnt + 1);
        for(unsigned int i = 0; i < baseNum; i++)
        {
            baseDocCnt = 0;
            beginPos   = INVALID_DOCID;
            baseId = (pOldSkip[i].doc_id_base << 16);
            for(unsigned int j = pOldSkip[i].off; j < pOldSkip[i+1].off; j++) {
                docId = baseId + pOldList[j];

                if ( _docIdMgr->isDocIdDelUseLess( docId ))  continue;

                if (beginPos == INVALID_DOCID) {
                    beginPos = listPos;
                }
                pNewList[listPos++] = pOldList[j];
                baseDocCnt++;
            }

            if (baseDocCnt == 0) {
                continue;
            }
            pNewSkip[basePos].doc_id_base = pOldSkip[i].doc_id_base;
            pNewSkip[basePos].off         = beginPos;
            basePos++;
        }
        pNewList[listPos] = IDX_GET_DIFF(INVALID_DOCID);
        begin = (char *)(pNewList + listPos);
        pNewHeader->doc_list_len = (listPos + 1) * sizeof(uint16_t);
    }

    pNewSkip[basePos].doc_id_base = IDX_GET_BASE(INVALID_DOCID);
    pNewSkip[basePos].off         = listPos;
    pNewHeader->block_num = basePos;

    tHead->pageSize = _pIncMemManager->size(off);
    tHead->endOff   = begin - p1;
    tHead->zipFlag  = 1;
    end = p1 + tHead->pageSize;

    _pIncMemManager->freeOldPage(head->pageSize, pind->pos);
    head = tHead;
    pind->pos = off;
    pind->doc_count = listPos;

    return KS_SUCCESS;
}
Ejemplo n.º 23
0
/**
 * 将IncManger中的,的字段处理策略初始化
 *
 * @param  node  在配置文件中的 xml 节点 update_add2Modify
 *
 * @return  0: success ;   -1: 程序处理失败
 */
int initIncManager( mxml_node_t * node )
{
    if ( NULL == node )  return 0;

    mxml_node_t        * field  = NULL;
    IndexReader        * reader = IndexReader::getInstance();
    IncManager         * incMgr = IncManager::getInstance();
    ProfileDocAccessor * pflAcr = ProfileManager::getDocAccessor();

    field  = mxmlFindElement( node, node, "index_field", NULL, NULL, MXML_DESCEND_FIRST );

    while ( field != NULL )
    {
        const char * name = mxmlElementGetAttr( field, "name" );
        const char * proc = mxmlElementGetAttr( field, "proc" );


        if ( ( NULL == name ) || (0 == strlen(name)) )
        {
            TERR("update_add2Modify: must have field name");
            return -1;
        }

        if ( ( NULL == proc ) || (0 == strlen(proc)) )
        {
            TERR("update_add2Modify: must have proc: depend or ignore");
            return -1;
        }

        if ( false == reader->hasField( name ) )
        {
            TWARN("update_add2Modify: can't find field in index:%s, are you sure", name);
        }

        if ( 0 == strcmp( proc , "ignore" ) )
        {
            if ( false == incMgr->addIgnIdxField( name ) )
            {
                TERR("update_add2Modify: add ignore field to incManager failed:%s", name);
                return -1;
            }
        }
        else if ( 0 == strcmp( proc , "depend" ) )
        {
            const char * pflFieldName = mxmlElementGetAttr( field, "profile_field" );

            if ( ( NULL == pflFieldName ) || (0 == strlen(pflFieldName)) )
            {
                TERR("update_add2Modify: field:%s must have profile_field", name);
                return -1;
            }

            if ( NULL == pflAcr->getProfileField( pflFieldName ) )
            {
                TERR("update_add2Modify: can't find field in profile:%s", pflFieldName);
                return -1;
            }

            if ( false == incMgr->addIgnIdxField( name ) )
            {
                TERR("update_add2Modify: add ignore field to incManager failed:%s", name);
                return -1;
            }

            if ( false == incMgr->addDepPflField( pflFieldName ) )
            {
                TERR("update_add2Modify: add depend pfl field to incManager failed:%s", pflFieldName);
                return -1;
            }
        }
        else
        {
            TERR("update_add2Modify: field:%s proc must be depend or ignore", name);
            return -1;
        }

        field = mxmlFindElement( field, node, "index_field", NULL, NULL, MXML_NO_DESCEND );
    }

    return 0;
}
Ejemplo n.º 24
0
/**
 * 解析配置文件, 初始化 index_lib内部的各个模块
 *
 * @param  config  xml的配置节点。  内部的子节点包括了 索引的各个配置项
 *         样例:
 *         <indexLib>
 *            <profile  path="/dir" />
 *            <index    path="/dir" />
 *            <idDict   path="/dir" />
 *            <provcity path="/dir" />
 *         </indexLib>
 *
 * @return  0: success ;   -1: 程序处理失败
 */
int init( mxml_node_t * config )
{
    mxml_node_t  * modulesNode  = NULL;
    mxml_node_t  * indexLibNode = NULL;               // index_lib的根节点
    mxml_node_t  * profileNode  = NULL;               // profile配置节点
    mxml_node_t  * indexNode    = NULL;               // index配置节点
    mxml_node_t  * idDictNode   = NULL;               // nid->docId 字典及deletemap节点
    mxml_node_t  * provcityNode = NULL;               // 行政区划表配置节点
    mxml_node_t  * add2modNode  = NULL;               // add转modify配置节点
    bool           syncFlag     = true;
    bool           exportFlag   = false;

    modulesNode  = mxmlFindElement(config, config, "modules", NULL, NULL, MXML_DESCEND);
    if ( modulesNode == NULL || modulesNode->parent != config )
    {
        TERR("can't find modules's node");
        return -1;
    }

    indexLibNode = mxmlFindElement(modulesNode, modulesNode, "indexLib", NULL, NULL, MXML_DESCEND);
    // 检查节点有效性
    if ( indexLibNode == NULL || indexLibNode->parent != modulesNode )
    {
        TERR("can't find indexLib's node");
        return -1;
    }

    // 检查增量持久化配置
    const char * syncStr = mxmlElementGetAttr(indexLibNode, "sync" );
    if (syncStr && strcasecmp(syncStr, "true") == 0) {
        syncFlag = true;
    }
    else {
        syncFlag = false;
    }

    // 检查mmap_lock配置
    const char * mLockStr = mxmlElementGetAttr(indexLibNode, "mmap_lock" );
    if (mLockStr && strcasecmp(mLockStr, "true") == 0) {
        struct rlimit sysLimit;
        if (getrlimit(RLIMIT_MEMLOCK, &sysLimit) == 0) {
            if ((sysLimit.rlim_cur==RLIM_INFINITY) &&
                    (sysLimit.rlim_max==RLIM_INFINITY))
            {
                IndexConfigParams::getInstance()->setMemLock();
            }
            else {
                TWARN("please unlimited max locked memory to enable mmap_lock");
            }
        }
        else {
            TWARN("get RLIMIT_MEMLOCK size failed, disable mmap_lock");
        }
    }

    // 关闭时是否导出倒排索引
    const char * et = mxmlElementGetAttr(indexLibNode, "export" );
    if (et && strcasecmp(et, "true") == 0) {
        exportFlag = true;
    }

    // 获取配置节点
    profileNode  = mxmlFindElement(indexLibNode, indexLibNode, "profile",  NULL, NULL, MXML_DESCEND);
    indexNode    = mxmlFindElement(indexLibNode, indexLibNode, "index",    NULL, NULL, MXML_DESCEND);
    idDictNode   = mxmlFindElement(indexLibNode, indexLibNode, "idDict",   NULL, NULL, MXML_DESCEND);
    provcityNode = mxmlFindElement(indexLibNode, indexLibNode, "provcity", NULL, NULL, MXML_DESCEND);
    add2modNode  = mxmlFindElement(indexLibNode, indexLibNode, "update_add2Modify", NULL, NULL, MXML_DESCEND);

    // 检查节点有效性
    if ( profileNode == NULL || profileNode->parent != indexLibNode )
    {
        TERR("can't find indexLib's child node profile");
        return -1;
    }

    if ( indexNode == NULL || indexNode->parent != indexLibNode )
    {
        TERR("can't find indexLib's child node index");
        return -1;
    }

    if ( idDictNode == NULL || idDictNode->parent != indexLibNode )
    {
        TERR("can't find indexLib's child node idDict");
        return -1;
    }

    if ( provcityNode == NULL || provcityNode->parent != indexLibNode )
    {
        TERR("can't find indexLib's child node provcity");
        return -1;
    }

    int32_t inc_max_num = 0;
    const char * inc_max_num_str = mxmlElementGetAttr(indexNode, "inc_max_num" );
    if ( inc_max_num_str ) {
        inc_max_num = atol(inc_max_num_str);
    }

    // 开始 初始化 各个模块
    if ( initProfile(   mxmlElementGetAttr(profileNode,  "path" ), syncFlag, false ) )  return -1;
    if ( initIdDict (   mxmlElementGetAttr(idDictNode,   "path" ), syncFlag ) )  return -1;
    if ( initFullIndex( mxmlElementGetAttr(indexNode,    "path" ) ) )  return -1;
    if ( initIncIndex ( mxmlElementGetAttr(indexNode,    "path" ), syncFlag, exportFlag, inc_max_num) )  return -1;
    if ( initProvCity ( mxmlElementGetAttr(provcityNode, "path" ) ) )  return -1;
    if ( initIncManager( add2modNode ) )                               return -1;

    return 0;
}