目录
	  我的Spellcorrect开发文档
	  相关配置文件及准备工作:
	  演示效果(中文):
	  演示效果(英语):
	  代码部分:
	  相关配置文件及准备工作:
	  演示效果(中文):
	  演示效果(英语):
	  代码部分:
	  ---恢复内容开始---
	  我的Spellcorrect开发文档
	  相关配置文件及准备工作:
	  我的主要文件夹分为三个:分别为客户端,cppjieba分词库,离线部分及服务器部分
	  1560856582308
	  客户端部分:内部为客户端源码及运行程序
	  1560856552431
	  cppjieba分词库部分,就不赘述,请自行安装
	  离线部分:内部有中英文件夹放置索引及词典文件,还有配置文件及分词库,其余为代码
	  1560857073864
	  服务器部分:最为重要的配置文件及数据部分,头文件在include,实现文件在src里面
	  1560857034230
	  演示效果(中文):
	  ==启动时服务器:==
	  1560857677039
	  ==客户端连入时时服务器:==
	  1560857739202
	  ==输入“赵”==
	  1560858117388
	  ==输入“周杰伦”==
	  1560858201376
	  ==输入清华大学==
	  1560858560147
	  演示效果(英语):
	  ==启动时服务器:==
	  1560857677039
	  ==客户端连入时时服务器:==
	  1560857739202
	  ==输入student:==
	  1560858008297
	  ==输入spell:==
	  1560858872540
	  ==输入computer:==
	  1560859162357
	  代码部分:
	  离线部分:
	  img
	  ==Makefile:==
	  SRCS:=$(wildcard*.cc)
	  OBJS:=$(patsubst%.cc,%.o,$(SRCS))
	  CXX:=g++
	  CXXFLAGS:=-w-g-std=c++11$(addprefix-I,$(INC_DIR))$(LIBS)-Wno-deprecated-I../cppjieba/include/-I../cppjieba/deps
	  EXE:=./main
	  $(EXE):$(OBJS)
	  $(CXX)-o$(EXE)$(OBJS)$(CXXFLAGS)
	  clean:
	  rm-rf$(EXE)
	  rm-rf$(OBJS)
	  ==Configuration:==
	  ///=======================================
	  ///File:Configuration.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1200:30:39
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__CONFIGURATION_H__
	  #define__CONFIGURATION_H__
	  #include"Nocopyable.h"
	  #include<string>
	  #include<map>
	  usingnamespacestd;
	  classConfiguration
	  :publicNoncopyable
	  {
	  public:
	  Configuration(conststring&filePath);
	  stringgetEnglishDir()const{return_englishDir;}
	  stringgetChineseDir()const{return_chineseDir;}
	  private:
	  string_filePath;
	  string_englishDir;
	  string_chineseDir;
	  };
	  template<typenameT>
	  classSingleton
	  {
	  public:
	  template<typename...Args>
	  staticT*getInstance(Args...args)
	  {
	  if(!_pInstance)
	  _pInstance=newT(args...);
	  return_pInstance;
	  }
	  staticvoiddestroy()
	  {
	  if(_pInstance)
	  delete_pInstance;
	  }
	  private:
	  Singleton();
	  ~Singleton();
	  staticT*_pInstance;
	  };
	  template<typenameT>
	  T*Singleton<T>::_pInstance=NULL;
	  #endif
	  1///=======================================
	  2///File:Configuration.cc
	  3///Author:wtptorres(1584292712@qq.com)
	  4///Date:2019-06-1200:30:04
	  5///Dream:Don'tforgetyourdreams!
	  6///======================================
	  7
	  8
	  9#include"Configuration.h"
	  10#include<utility>
	  11#include<fstream>
	  12#include<iostream>
	  13usingnamespacestd;
	  14
	  15Configuration::Configuration(conststring&filePath)
	  16:_filePath(std::move(filePath))
	  17{
	  18ifstreamifs(_filePath);
	  19if(!ifs)
	  20cout<<"fileopenerror!"<<endl;
	  21ifs>>_englishDir;
	  22ifs>>_chineseDir;
	  23ifs.close();
	  24}
	  ///=======================================
	  ///File:Nocopyable.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1200:24:36
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__NOCOPYABLE_H__
	  #define__NOCOPYABLE_H__
	  classNoncopyable
	  {
	  public:
	  Noncopyable()=default;
	  ~Noncopyable()=default;
	  private:
	  Noncopyable(constNoncopyable&rhs);
	  Noncopyable&operator=(constNoncopyable&rhs);
	  };
	  #endif
	  ==DictProducer:==
	  ///=======================================
	  ///File:DictProducer.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1216:40:25
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__DICTPRODUCER_H__
	  #define__DICTPRODUCER_H__
	  #include"SplitTool.h"
	  usingnamespacestd;
	  #include"Nocopyable.h"
	  #include<memory>
	  #include<string>
	  #include<vector>
	  #include<map>
	  #include<utility>
	  classDictProducer
	  :publicNoncopyable
	  {
	  public:
	  DictProducer(conststring,conststring,conststring&,SplitToolJieba*);
	  ~DictProducer(){}
	  voidbuild_dict();
	  voidbuild_cn_dict();
	  voidstore_dict();
	  vector<pair<string,int>>&getIndict(){return_indict;}
	  private:
	  voidprocessEnglishWord(string&word);
	  voidprocessChineseWord(string&word);//除去中文的数字
	  voidconstruct_indict();
	  string_englishDir;
	  string_chineseDir;
	  string_goleFilePath;
	  vector<string>_englishFiles;
	  vector<string>_chineseFiles;
	  map<string,int>_dict;
	  vector<pair<string,int>>_indict;
	  shared_ptr<SplitToolJieba>_splitTool;
	  };
	  #endif
	  ///=======================================
	  ///File:DictProducer.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1216:50:46
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"DictProducer.h"
	  #include<cctype>
	  #include<utility>
	  #include<fstream>
	  #include<iostream>
	  #defineFIRSTSIZE10000
	  usingnamespacestd;
	  DictProducer::DictProducer(conststringenglishDir,conststringchineseDir,conststring&goleFilePath,SplitToolJieba*splitToolPtr)
	  :_englishDir(englishDir)
	  ,_chineseDir(chineseDir)
	  ,_goleFilePath(goleFilePath)
	  {
	  _splitTool.reset(splitToolPtr);
	  std::ifstreamifsEnglish(_englishDir);
	  std::ifstreamifsChinese(_chineseDir);
	  stringfilePath;
	  if(!ifsEnglish||!ifsChinese){
	  cout<<"Dictfileopenerror!"<<endl;
	  }
	  while(ifsEnglish>>filePath)
	  {
	  _englishFiles.push_back(filePath);
	  }
	  while(ifsChinese>>filePath)
	  {
	  _chineseFiles.push_back(filePath);
	  }
	  _indict.reserve(FIRSTSIZE);
	  }
	  voidDictProducer::processEnglishWord(string&word)
	  {
	  autocit=word.begin();
	  for(;cit!=word.end();++cit)
	  {//去除标点符号或数字
	  if(!isalpha(*cit)){
	  word.erase(cit);
	  --cit;//迭代器位置发生改变
	  }elseif(isupper(*cit)){//将大写字母改为小写
	  *cit=tolower(*cit);
	  }
	  }
	  }
	  voidDictProducer::processChineseWord(string&word)
	  {
	  autocit=word.begin();
	  for(;cit!=word.end();++cit)
	  {//去除数字
	  if(!isalnum(*cit)){
	  word.erase(cit);
	  --cit;
	  }
	  }
	  }
	  voidDictProducer::build_dict()//建立英文词典
	  {
	  for(auto&filePath:_englishFiles)
	  {
	  ifstreamifs(filePath);
	  if(!ifs){
	  cout<<"EnglishFileopenerror!"<<endl;
	  }
	  stringword;
	  while(ifs>>word)
	  {
	  processEnglishWord(word);
	  autocit=_dict.find(word);
	  if(word.size()>0&&cit==_dict.end()){
	  _dict.insert(std::make_pair(word,1));
	  }elseif(cit!=_dict.end()){
	  ++cit->second;
	  }
	  }
	  }
	  }
	  voidDictProducer::build_cn_dict()
	  {
	  vector<string>words;
	  for(autofilePath:_chineseFiles)
	  {
	  ifstreamifs(filePath);
	  if(!ifs){
	  cout<<"Chinesefileopenerror!"<<endl;
	  }
	  stringsentence;
	  while(std::getline(ifs,sentence))
	  {
	  _splitTool->Cut(sentence);
	  }
	  }
	  vector<string>&results=_splitTool->getResult();
	  for(auto&res:results)
	  {
	  processChineseWord(res);
	  autocit=_dict.find(res);
	  if(cit==_dict.end()){
	  _dict.insert(std::make_pair(res,1));
	  }else{
	  ++cit->second;
	  }
	  }
	  }
	  voidDictProducer::store_dict()
	  {
	  construct_indict();
	  ofstreamofs(_goleFilePath);
	  if(!ofs)
	  cout<<"Store_dictopenfileerror!"<<endl;
	  for(auto&mypair:_indict)
	  {
	  ofs<<mypair.first<<""<<mypair.second<<endl;
	  }
	  ofs.close();
	  }
	  voidDictProducer::construct_indict()
	  {
	  for(autodictpair:_dict){
	  _indict.push_back(dictpair);
	  }
	  }
	  ==GetIndex:==
	  ///=======================================
	  ///File:GetIndex.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1208:52:04
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__GETINDEX_H__
	  #define__GETINDEX_H__
	  #include<string>
	  #include<unordered_map>
	  #include<set>
	  #include<vector>
	  #include<utility>
	  #include<unordered_set>
	  usingnamespacestd;
	  classGetIndex
	  {
	  public:
	  GetIndex(conststring&,conststring&,conststring&);
	  ~GetIndex(){}
	  voidconstruct_index();
	  voidstore_index();
	  private:
	  boolisEnglish(conststring&rhs)const;
	  vector<string>getOneCharacter(conststring&word);
	  string_sourceFilePath;
	  string_goleFilePath;
	  string_stopWordsFilePath;
	  vector<pair<string,int>>_dict;
	  unordered_set<string>_stopWords;
	  unordered_map<string,set<int>>_index;
	  };
	  #endif
	  ///=======================================
	  ///File:GetIndex.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1209:00:11
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"GetIndex.h"
	  #include<fstream>
	  #include<sstream>
	  #include<iostream>
	  usingnamespacestd;
	  GetIndex::GetIndex(conststring&sourceFilePath,conststring&goleFilePath,conststring&stopWordsFilePath)
	  :_sourceFilePath(std::move(sourceFilePath))
	  ,_goleFilePath(std::move(goleFilePath))
	  ,_stopWordsFilePath(std::move(stopWordsFilePath))
	  {
	  ifstreamifs(_sourceFilePath);
	  if(!ifs){
	  cout<<"GetIndexfileopenerror!"<<endl;
	  }
	  stringline;
	  while(getline(ifs,line))
	  {
	  istringstreamiss(line);
	  stringkey;
	  intvalue;
	  iss>>key>>value;
	  _dict.push_back(std::make_pair(key,value));
	  }
	  ifstreamifs1(_stopWordsFilePath);
	  if(!ifs1){
	  cout<<"fileopenerror!"<<endl;
	  }
	  stringstopWord;
	  while(ifs1>>stopWord,!ifs1.eof())
	  {
	  _stopWords.insert(stopWord);
	  }
	  }
	  vector<string>GetIndex::getOneCharacter(conststring&word)
	  {
	  vector<string>tmp;
	  autocit=word.begin();
	  while(cit<word.end())
	  {
	  if(224==(*cit&224))
	  {
	  stringoneCharacter;
	  oneCharacter.append(cit,cit+3);
	  tmp.push_back(oneCharacter);
	  cit+=3;
	  }elseif(240==(*cit&240)){
	  stringoneCharacter;
	  oneCharacter.append(cit,cit+4);
	  tmp.push_back(oneCharacter);
	  cit+=4;
	  }else
	  break;
	  }
	  returntmp;
	  }
	  boolGetIndex::isEnglish(conststring&rhs)const
	  {
	  charch=*(rhs.begin());
	  if(ch<0)
	  returnfalse;
	  returntrue;
	  }
	  #if0
	  boolGetIndex::isEnglish(conststring&rhs)const
	  {
	  charch=*(rhs.begin());
	  if(ch<0){
	  returnfalse;
	  }
	  returntrue;
	  }
	  #endif
	  voidGetIndex::construct_index()
	  {
	  for(size_ti=0;i!=_dict.size();++i)
	  {
	  stringtmp=_dict[i].first;
	  if(isEnglish(tmp))
	  {
	  for(autoch:tmp)
	  {
	  stringcharactor(1,ch);
	  if(isalpha(ch))
	  {
	  autocit=_index.find(charactor);
	  if(cit==_index.end())
	  {
	  set<int>smp;
	  smp.insert(i);
	  _index.insert(std::make_pair(charactor,smp));
	  }else{//已经存在了该字母的索引
	  cit->second.insert(i);
	  }
	  }
	  }
	  }else{//中文处理部分
	  vector<string>oneCharacterRally=getOneCharacter(tmp);
	  for(autooneCharacter:oneCharacterRally)
	  {//stop_words中不存在该单词,则加入索引中
	  if(_stopWords.find(oneCharacter)==_stopWords.end()){
	  autoit=_index.find(oneCharacter);
	  if(it==_index.end()){
	  set<int>tmp;
	  tmp.insert(i);
	  _index.insert(std::make_pair(oneCharacter,tmp));
	  }else{
	  it->second.insert(i);
	  }
	  }
	  }
	  }
	  }
	  }
	  voidGetIndex::store_index()
	  {
	  //ofs存储索引的内容
	  std::ofstreamofs(_goleFilePath);
	  if(!ofs){
	  cout<<"fileopenerror!"<<endl;
	  return;
	  }
	  for(autodata:_index)
	  {
	  ofs<<data.first<<"";
	  for(autolinenum:data.second)
	  {
	  ofs<<linenum<<"";
	  }
	  ofs<<endl;
	  }
	  ofs.close();
	  }
	  ==SplitTool:==
	  ///=======================================
	  ///File:SplitTool.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1217:12:01
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__SPLITTOOL_H__
	  #define__SPLITTOOL_H__
	  #include"../cppjieba/include/cppjieba/Jieba.hpp"//需要自己将cppjieba安装在项目目录下
	  #include"Configuration.h"
	  #include<string>
	  #include<vector>
	  usingnamespacestd;
	  usingnamespacecppjieba;
	  classSplitToolJieba
	  {
	  public:
	  SplitToolJieba(conststring&dict_path,conststring&model_path,conststring&user_dict_path,conststring&idfPath,conststring&stopWordPath)
	  :_jieba(dict_path,model_path,user_dict_path,idfPath,stopWordPath)
	  {}
	  ~SplitToolJieba(){}
	  voidCut(conststring&sentence)
	  {
	  vector<string>tmp;
	  _jieba.Cut(sentence,tmp);
	  _result.insert(_result.end(),tmp.begin(),tmp.end());
	  }
	  vector<string>&getResult(){return_result;}
	  private:
	  vector<string>_result;
	  cppjieba::Jieba_jieba;
	  };
	  #endif
	  ==main:==
	  ///=======================================
	  ///File:main.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1220:38:50
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"Configuration.h"
	  #include"SplitTool.h"
	  usingnamespacestd;
	  #include"DictProducer.h"
	  #include"GetIndex.h"
	  #include<iostream>
	  #include<memory>
	  constchar*constDICT_PATH="../cppjieba/dict/jieba.dict.utf8";
	  constchar*constHMM_PATH="../cppjieba/dict/hmm_model.utf8";
	  constchar*constUSER_DICT_PATH="../cppjieba/dict/user.dict.utf8";
	  constchar*constIDF_PATH="../cppjieba/dict/idf.utf8";
	  constchar*constSTOP_WORD_PATH="../cppjieba/dict/stop_words.utf8";
	  conststringGOLE_DICT_PATH="../server/data/dict.txt";
	  conststringGOLE_INDEX_PATH="../server/data/index.txt";
	  classSplitTool;
	  intmain(void)
	  {
	  Configuration*pconfig=Singleton<Configuration>::getInstance("configure.txt");
	  SplitToolJieba*ptool=newSplitToolJieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH);
	  DictProducermydictProducer(pconfig->getEnglishDir(),pconfig->getChineseDir(),GOLE_DICT_PATH,ptool);
	  mydictProducer.build_dict();//建立英语词典
	  mydictProducer.build_cn_dict();//建立中文词典
	  mydictProducer.store_dict();//储存词典
	  GetIndexmyindex(GOLE_DICT_PATH,GOLE_INDEX_PATH,"stop_words_zh.txt");
	  myindex.construct_index();//建立索引
	  myindex.store_index();//存储索引
	  Singleton<Configuration>::destroy();
	  return0;
	  }
	  在线部分:
	  img
	  ==ConFiguration:==
	  ///=======================================
	  ///File:ConFiguration.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0610:32:43
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__CONFIGURATION_H__
	  #define__CONFIGURATION_H__
	  #include"Noncopyable.h"
	  #include<string>
	  #include<map>
	  #defineCONFPATH"/home/wtp/spell/server/conf/configure.txt"
	  usingnamespacestd;
	  namespacewd
	  {
	  classConfiguration
	  :publicNoncopyable
	  {
	  public:
	  Configuration(conststring&filePath);
	  ~Configuration()=default;
	  stringgetDictDir()const;
	  stringgetIndexDir()const;
	  stringgetIp()const;
	  stringgetCache()const;
	  unsignedshortgetPort()const;
	  private:
	  string_filePath;
	  map<string,string>_conf;
	  };
	  };
	  template<typenameT>
	  classSingleton
	  {
	  public:
	  template<typename...Args>
	  staticT*getInstance(Args...args)
	  {
	  if(!_pInstance)
	  _pInstance=newT(args...);
	  return_pInstance;
	  }
	  staticvoiddestroy()
	  {
	  if(_pInstance)
	  delete_pInstance;
	  }
	  private:
	  Singleton();
	  ~Singleton();
	  staticT*_pInstance;
	  };
	  template<typenameT>
	  T*Singleton<T>::_pInstance=NULL;
	  #endif
	  ///=======================================
	  ///File:ConFiguration.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0715:24:14
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"ConFiguration.h"
	  #include<stdlib.h>
	  #include<utility>
	  #include<fstream>
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  wd::Configuration::Configuration(conststring&filePath)
	  :_filePath(std::move(filePath))
	  {
	  ifstreamifs(_filePath);
	  if(!ifs){
	  cout<<"fileopenerror!"<<endl;
	  }
	  stringkey,value;
	  while(ifs>>key)
	  {
	  ifs>>value;
	  _conf.insert(std::make_pair(key,value));
	  }
	  ifs.close();
	  }
	  stringwd::Configuration::getDictDir()const
	  {
	  autocit=_conf.find("mydict");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  stringwd::Configuration::getIndexDir()const
	  {
	  autocit=_conf.find("myindex");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  stringwd::Configuration::getIp()const
	  {
	  autocit=_conf.find("myip");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  unsignedshortwd::Configuration::getPort()const
	  {
	  autocit=_conf.find("myport");
	  if(cit==_conf.end())
	  return0;
	  else
	  returnatoi(cit->second.c_str());
	  }
	  stringwd::Configuration::getCache()const
	  {
	  autocit=_conf.find("mycache");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  ==Acceptor:==
	  ///=======================================
	  ///File:Acceptor.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0523:47:05
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_ACCEPTOR_H__
	  #define__WD_ACCEPTOR_H__
	  #include"Socket.h"
	  #include"InetAddress.h"
	  namespacewd
	  {
	  classAcceptor
	  {
	  public:
	  Acceptor(intlistenfd,constInetAddress&addr);
	  voidready();//服务器监听准备
	  intaccept();//服务器接收新连接
	  intfd()const{return_listenSock.fd();}
	  private:
	  voidsetReuseAddr(boolon);//设置地址重用
	  voidsetReusePort(boolon);//设置端口重用
	  voidbind();//绑定
	  voidlisten();//监听
	  Socket_listenSock;
	  InetAddress_addr;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:Acceptor.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0523:52:12
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include<iostream>
	  #include"Acceptor.h"
	  #include"SocketUtil.h"
	  namespacewd
	  {
	  Acceptor::Acceptor(intlistenfd,constInetAddress&addr)
	  :_listenSock(listenfd)
	  ,_addr(addr)
	  {}
	  voidAcceptor::ready()
	  {
	  setReuseAddr(true);
	  setReusePort(true);
	  bind();
	  listen();
	  }
	  intAcceptor::accept()
	  {
	  intpeerfd=::accept(_listenSock.fd(),NULL,NULL);
	  if(-1==peerfd)
	  {
	  perror("accepterror!");
	  }
	  returnpeerfd;
	  }
	  voidAcceptor::setReuseAddr(boolflag)
	  {
	  inton=(flag?1:0);
	  if(::setsockopt(_listenSock.fd()
	  ,SOL_SOCKET
	  ,SO_REUSEADDR
	  ,&on
	  ,static_cast<socklen_t>(size_t(on)))==-1)
	  {
	  perror("setsockoptreuseaddrerror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  }
	  voidAcceptor::setReusePort(boolflag)
	  {
	  #ifndefSO_REUSEPORT
	  inton=(flag?1:0);
	  if(::setsockopt(_listenSock.fd()
	  ,SOL_SOCKET
	  ,SO_REUSEADDR
	  ,&on
	  ,static_cast<socklen_t>(size_t(on)))==-1)
	  {
	  perror("setsockoptreuseporterror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  #else
	  if(flag)
	  {
	  fprintf(stderr,"SO_REUSEPORTisnotsupported!\n");
	  }
	  #endif
	  }
	  voidAcceptor::bind()
	  {
	  if(-1==::bind(_listenSock.fd()
	  ,(conststructsockaddr*)_addr.getSockAddrPtr()
	  ,sizeof(InetAddress)))
	  {
	  perror("binderror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  }
	  voidAcceptor::listen()
	  {
	  if(-1==::listen(_listenSock.fd(),10))
	  {
	  perror("listenerror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  }
	  }
	  #if0
	  intmain()
	  {
	  std::cout<<"Acceptoriscorrect!"<<std::endl;
	  }
	  #endif
	  ==Condition.h:==
	  #ifndef__WD_CONDITION_H__
	  #define__WD_CONDITION_H__
	  #include"Noncopyable.h"
	  #include"MutexLock.h"
	  #include<pthread.h>
	  namespacewd
	  {
	  classCondition
	  :Noncopyable
	  {
	  public:
	  Condition(MutexLock&mutex)
	  :_mutex(mutex)
	  {pthread_cond_init(&_cond,NULL);}
	  ~Condition()
	  {pthread_cond_destroy(&_cond);}
	  voidwait()
	  {pthread_cond_wait(&_cond,_mutex.getMutexLockPtr());}
	  voidnotify()
	  {pthread_cond_signal(&_cond);}
	  voidnotifyAll()
	  {pthread_cond_broadcast(&_cond);}
	  private:
	  pthread_cond_t_cond;
	  MutexLock&_mutex;
	  };
	  }
	  #endif
	  ==Cache:==
	  ///=======================================
	  ///File:Cache.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0519:52:40
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__CACHE_H__
	  #define__CACHE_H__
	  #include<unordered_map>
	  #include<string>
	  usingnamespacestd;
	  namespacewd
	  {
	  classCache
	  {
	  public:
	  voidaddElement(string,string);//增加缓存信息
	  voidreadFromFile(string);//从文件中读取信息
	  voidwriteToFile(string);//将信息写入文件中
	  voidupdate(constCache&);//更新缓存消息
	  boolfind(stringquerry);//从数据库中找寻信息
	  string&operator[](stringkey);
	  private:
	  unordered_map<string,string>_hashTable;//采用hashTable进行缓存
	  };
	  };
	  #endif
	  ///=======================================
	  ///File:Cache.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0520:01:25
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"Cache.h"
	  #include<fstream>
	  #include<utility>
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  voidCache::addElement(stringquerry,stringresult)
	  {
	  _hashTable[querry]=result;
	  }
	  voidCache::readFromFile(stringfilePath)
	  {
	  ifstreamifs(filePath);
	  if(!ifs){
	  cout<<"Cache::readreadFromFilefileopenerror!"<<endl;
	  return;
	  }
	  stringquerry,result;
	  while(ifs>>querry,!ifs.eof())
	  {
	  ifs>>result;
	  _hashTable[querry]=result;
	  }
	  }
	  #if0
	  voidCache::writeToFile(stringfilePath)
	  {
	  ofstreamofs(filePath);
	  if(!ofs){
	  cout<<""<<endl;
	  return;
	  }
	  for(auto&mypair:_hashTable)
	  {
	  ofs<<mypair.first<<"";
	  ofs<<mypair.second<<endl;
	  }
	  }
	  voidCache::update(constCache&cache)
	  {
	  for(auto&mypair:cache._hashTable)
	  {
	  autocit=_hashTable.find(mypair.first);
	  if(cit==_hashTable.end())
	  {
	  _hashTable.insert(std::move(mypair));
	  }
	  }
	  }
	  #endif
	  voidCache::writeToFile(stringfilePath)
	  {
	  ofstreamofs(filePath);
	  if(!ofs){
	  cout<<"filewriteerror!"<<endl;
	  return;
	  }
	  for(auto&mypair:_hashTable)
	  {
	  ofs<<mypair.first<<"";
	  ofs<<mypair.second<<endl;
	  }
	  }
	  voidCache::update(constCache&cache)
	  {
	  for(auto&mypair:cache._hashTable)
	  {
	  autocit=_hashTable.find(mypair.first);
	  if(cit==_hashTable.end())
	  {
	  _hashTable.insert(std::move(mypair));
	  }
	  }
	  }
	  boolCache::find(stringquerry)
	  {
	  autocit=_hashTable.find(querry);
	  if(cit==_hashTable.end())
	  returnfalse;
	  returntrue;
	  }
	  string&Cache::operator[](stringkey)
	  {
	  return_hashTable[key];
	  }
	  #if0
	  intmain()
	  {
	  cout<<"cacheiscorrect!"<<endl;
	  }
	  #endif
	  ==CacheManger:==
	  ///=======================================
	  ///File:CacheManger.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0520:51:09
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__CACHEMANGER_H__
	  #define__CACHEMANGER_H__
	  #include"Cache.h"
	  #include<vector>
	  #defineTHREADNUM4//线程数目设置为4个,可自定义
	  usingstd::vector;
	  namespacewd
	  {
	  classCacheManger
	  {
	  public:
	  CacheManger(stringfilePath);
	  voidinit(string);//创建缓存
	  Cache&getCache(size_t);//获取某个缓存
	  voidperiodicUpdate();//定时更新所有缓存
	  private:
	  string_cacheFilePath;
	  vector<Cache>_cacheList;
	  };
	  };
	  #endif
	  ///=======================================
	  ///File:CacheManger.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0520:56:50
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"CacheManger.h"
	  #include<iostream>
	  #include<fstream>
	  #include<utility>
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  CacheManger::CacheManger(stringcacheFilePath)
	  {
	  init(cacheFilePath);
	  }
	  voidCacheManger::init(stringcacheFilePath)
	  {
	  _cacheFilePath=cacheFilePath;
	  _cacheList.reserve(THREADNUM);
	  Cachetmp;
	  tmp.readFromFile(_cacheFilePath);
	  for(size_ti=0;i!=THREADNUM;++i)
	  {
	  _cacheList.push_back(std::move(tmp));
	  }
	  }
	  Cache&CacheManger::getCache(size_tnumber)
	  {
	  return_cacheList[number];
	  }
	  voidCacheManger::periodicUpdate()
	  {
	  autocit=_cacheList.begin();
	  CachelastWrite=*(cit++);
	  for(;cit<_cacheList.end();++cit)
	  {
	  lastWrite.update(*cit);
	  }
	  for(cit=_cacheList.begin()+1;cit!=_cacheList.end();++cit)
	  {
	  (*cit).update(lastWrite);
	  }
	  lastWrite.writeToFile(_cacheFilePath);
	  }
	  ==EpollPoller:==
	  ///=======================================
	  ///File:EpollPoller.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0611:03:36
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_EPOLLPOLLER_H__
	  #define__WD_EPOLLPOLLER_H__
	  #include"TcpConnection.h"
	  #include"Noncopyable.h"
	  #include"MutexLock.h"
	  #include<sys/epoll.h>
	  #include<vector>
	  #include<map>
	  #include<functional>
	  namespacewd
	  {
	  classAcceptor;
	  classEpollPoller
	  :Noncopyable
	  {
	  public:
	  typedefTcpConnection::TcpConnectionCallbackEpollCallback;
	  typedefstd::function<void()>Functor;
	  EpollPoller(Acceptor&acceptor);
	  ~EpollPoller();
	  voidloop();
	  voidunloop();
	  voidrunInLoop(constFunctor&&cb);
	  voiddoPendingFunctors();
	  voidwakeup();
	  voidsetConnectionCallback(EpollCallbackcb);
	  voidsetMessageCallback(EpollCallbackcb);
	  voidsetCloseCallback(EpollCallbackcb);
	  private:
	  voidwaitEpollfd();
	  voidhandleConnection();
	  voidhandleMessage(intpeerfd);
	  voidhandleRead();
	  Acceptor&_acceptor;
	  int_epollfd;
	  int_eventfd;
	  int_listenfd;
	  bool_isLooping;
	  MutexLock_mutex;
	  std::vector<Functor>_pendingFunctors;
	  typedefstd::vector<structepoll_event>Eventlist;
	  Eventlist_eventList;
	  typedefstd::map<int,TcpConnectionPtr>ConnectionMap;
	  ConnectionMap_connMap;
	  EpollCallback_onConnectionCb;
	  EpollCallback_onMessageCb;
	  EpollCallback_onCloseCb;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:EpollPoller.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0715:42:54
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"EpollPoller.h"
	  #include"SocketUtil.h"
	  #include"Acceptor.h"
	  #include<assert.h>
	  #include<iostream>
	  usingnamespacestd;
	  namespacewd
	  {
	  EpollPoller::EpollPoller(Acceptor&acceptor)
	  :_acceptor(acceptor)
	  ,_epollfd(createEpollFd())
	  ,_eventfd(createEventFd())
	  ,_listenfd(_acceptor.fd())
	  ,_isLooping(false)
	  ,_eventList(1024)
	  {
	  addEpollFdRead(_epollfd,_listenfd);
	  addEpollFdRead(_epollfd,_eventfd);
	  }
	  EpollPoller::~EpollPoller()
	  {
	  ::close(_epollfd);
	  }
	  voidEpollPoller::loop()
	  {
	  _isLooping=true;
	  while(_isLooping)
	  {
	  waitEpollfd();
	  }
	  }
	  voidEpollPoller::unloop()
	  {
	  if(_isLooping)
	  _isLooping=false;
	  }
	  voidEpollPoller::setConnectionCallback(EpollCallbackcb)
	  {
	  _onConnectionCb=cb;
	  }
	  voidEpollPoller::setMessageCallback(EpollCallbackcb)
	  {
	  _onMessageCb=cb;
	  }
	  voidEpollPoller::setCloseCallback(EpollCallbackcb)
	  {
	  _onCloseCb=cb;
	  }
	  voidEpollPoller::waitEpollfd()
	  {
	  intnready;
	  do
	  {
	  nready=::epoll_wait(_epollfd,&(*_eventList.begin()),_eventList.size(),10000);
	  }while(-1==nready&&errno==EINTR);
	  if(-1==nready){
	  perror("epollwaiterror!");
	  exit(EXIT_FAILURE);
	  }elseif(0==nready){
	  cout<<"epoll_waittimeout!"<<endl;
	  }else{//扩容
	  if(nready==static_cast<int>(_eventList.size())){
	  _eventList.resize(_eventList.size()*2);
	  }
	  for(intidx=0;idx!=nready;++idx)//正宗罗老师循环体(TwT)
	  {
	  if(_eventList[idx].data.fd==_listenfd)
	  {
	  if(_eventList[idx].events&EPOLLIN)
	  {
	  handleConnection();
	  }
	  }elseif(_eventList[idx].data.fd==_eventfd){
	  handleRead();
	  cout<<">>doPendingFunctors()"<<endl;
	  doPendingFunctors();
	  }else{
	  if(_eventList[idx].events&EPOLLIN){
	  handleMessage(_eventList[idx].data.fd);
	  }
	  }
	  }
	  }
	  }
	  voidEpollPoller::handleConnection()
	  {
	  intpeerfd=_acceptor.accept();
	  addEpollFdRead(_epollfd,peerfd);
	  TcpConnectionPtrconn(newTcpConnection(peerfd,this));
	  conn->setConnectionCallback(_onConnectionCb);
	  conn->setMessageCallback(_onMessageCb);
	  conn->setCloseCallback(_onCloseCb);
	  std::pair<ConnectionMap::iterator,bool>ret;
	  ret=_connMap.insert(std::make_pair(peerfd,conn));
	  assert(ret.second==true);
	  (void)ret;
	  conn->handleConnectionCallback();
	  }
	  voidEpollPoller::handleMessage(intpeerfd)
	  {
	  boolisClosed=isConnectionClosed(peerfd);
	  ConnectionMap::iteratorit=_connMap.find(peerfd);
	  assert(it!=_connMap.end());
	  if(isClosed)
	  {
	  it->second->handleCloseCallback();
	  delEpollReadFd(_epollfd,peerfd);
	  _connMap.erase(it);
	  }else{
	  it->second->handleMessageCallback();
	  }
	  }
	  voidEpollPoller::runInLoop(constFunctor&&cb)//在计算线程中执行
	  {
	  MutexLockGuardmlg(_mutex);
	  _pendingFunctors.push_back(std::move(cb));
	  wakeup();
	  }
	  voidEpollPoller::doPendingFunctors()
	  {
	  std::vector<Functor>tmp;
	  {
	  MutexLockGuardmlg(_mutex);
	  tmp.swap(_pendingFunctors);
	  }
	  for(auto&functor:tmp)
	  {
	  functor();
	  }
	  }
	  voidEpollPoller::handleRead()
	  {
	  uint64_thowmany;
	  intret=::read(_eventfd,&howmany,sizeof(howmany));
	  if(ret!=sizeof(howmany))
	  {
	  perror("readerror!");
	  }
	  }
	  voidEpollPoller::wakeup()
	  {
	  uint64_tone=1;
	  intret=::write(_eventfd,&one,sizeof(one));
	  if(ret!=sizeof(one))
	  {
	  perror("writeerror!");
	  }
	  }
	  }
	  ==InetAddress:==
	  ///=======================================
	  ///File:InetAddress.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0521:55:19
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_INETADDRESS_H__
	  #define__WD_INETADDRESS_H__
	  #include<netinet/in.h>
	  #include<string>
	  namespacewd
	  {
	  classInetAddress
	  {
	  public:
	  InetAddress(shortport);
	  InetAddress(constchar*pIp,shortport);
	  InetAddress(conststructsockaddr_in&addr);
	  std::stringip()const;
	  unsignedshortport()const;
	  conststructsockaddr_in*getSockAddrPtr()const;
	  private:
	  structsockaddr_in_addr;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:InetAddress.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0720:55:18
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"InetAddress.h"
	  #include<stdio.h>
	  #include<stdlib.h>
	  #include<sys/socket.h>
	  #include<arpa/inet.h>
	  #include<string.h>
	  namespacewd
	  {
	  InetAddress::InetAddress(shortport)
	  {
	  ::memset(&_addr,0,sizeof(_addr));
	  _addr.sin_family=AF_INET;
	  _addr.sin_port=htons(port);
	  _addr.sin_addr.s_addr=INADDR_ANY;
	  }
	  InetAddress::InetAddress(constchar*pIp,shortport)
	  {
	  ::memset(&_addr,0,sizeof(_addr));
	  _addr.sin_family=AF_INET;
	  _addr.sin_port=htons(port);
	  _addr.sin_addr.s_addr=inet_addr(pIp);
	  }
	  InetAddress::InetAddress(conststructsockaddr_in&addr)
	  :_addr(addr)
	  {}
	  conststructsockaddr_in*InetAddress::getSockAddrPtr()const
	  {
	  return&_addr;
	  }
	  std::stringInetAddress::ip()const
	  {
	  returnstd::string(inet_ntoa(_addr.sin_addr));
	  }
	  unsignedshortInetAddress::port()const
	  {
	  returnntohs(_addr.sin_port);
	  }
	  }
	  ==MutexLock:==
	  #ifndef__WD_MUTEXLOCK_H__
	  #define__WD_MUTEXLOCK_H__
	  #include"Noncopyable.h"
	  #include<pthread.h>
	  namespacewd
	  {
	  classMutexLock
	  :Noncopyable
	  {
	  public:
	  MutexLock()
	  {pthread_mutex_init(&_mutex,NULL);}
	  ~MutexLock()
	  {pthread_mutex_destroy(&_mutex);}
	  voidlock()
	  {pthread_mutex_lock(&_mutex);}
	  voidunlock()
	  {pthread_mutex_unlock(&_mutex);}
	  pthread_mutex_t*getMutexLockPtr()
	  {return&_mutex;}
	  private:
	  pthread_mutex_t_mutex;
	  };
	  classMutexLockGuard//C++之父BS提出的RAII
	  {
	  public:
	  MutexLockGuard(MutexLock&mutex)
	  :_mutex(mutex)
	  {
	  _mutex.lock();
	  }
	  ~MutexLockGuard()
	  {
	  _mutex.unlock();
	  }
	  private:
	  MutexLock&_mutex;
	  };
	  }
	  #endif
	  ==Mydict:==
	  ///=======================================
	  ///File:Mydict.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0611:12:19
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__MYDICT_H__
	  #define__MYDICT_H__
	  #include<string>
	  #include<vector>
	  #include<map>
	  #include<utility>
	  #include<set>
	  #include<fstream>
	  #include<iostream>
	  #include<sstream>
	  usingnamespacestd;
	  namespacewd
	  {
	  structMyResult
	  {
	  string_word;
	  int_iFreq;//词频
	  int_iDist;//最小编辑距离
	  };
	  classMydict
	  {
	  public:
	  Mydict(conststringdictDir,conststringindexDir)
	  {
	  ifstreamifs1(dictDir),ifs2(indexDir);
	  if(!ifs1||!ifs2)
	  cout<<"Mydictopenfileerror!"<<endl;
	  stringkey;
	  intvalue;
	  ifs1>>value;
	  _dict.push_back(std::make_pair(string(""),value));
	  ifs1>>value;
	  _dict.push_back(std::make_pair(string(""),value));
	  while(ifs1>>key)
	  {
	  ifs1>>value;
	  _dict.push_back(std::make_pair(key,value));
	  }
	  stringline;
	  while(std::getline(ifs2,line))
	  {
	  istringstreamiss(line);
	  stringikey;
	  intivalue;
	  iss>>ikey;
	  set<int>tmp;
	  while(iss>>ivalue)
	  {
	  tmp.insert(ivalue);
	  }
	  _index.insert(std::make_pair(ikey,tmp));
	  }
	  }
	  vector<pair<string,int>>&getDict(){return_dict;}
	  map<string,set<int>>&getIndexTable(){return_index;}
	  private:
	  vector<pair<string,int>>_dict;
	  map<string,set<int>>_index;
	  };
	  }
	  #endif
	  ==MyTask:==
	  ///=======================================
	  ///File:MyTask.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0621:04:54
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__MYTASK_H__
	  #define__MYTASK_H__
	  #include"TcpConnection.h"
	  #include"ConFiguration.h"
	  #include"Mydict.h"
	  #include"Cache.h"
	  #include<string>
	  #include<queue>
	  usingnamespacestd;
	  classMyCompare
	  {
	  public:
	  booloperator()(constwd::MyResult&lhs,constwd::MyResult&rhs)
	  {
	  if(lhs._iDist!=rhs._iDist)
	  returnlhs._iDist<rhs._iDist;
	  else
	  returnlhs._iFreq>rhs._iFreq;
	  }
	  private:
	  };
	  usingCharacter=string;
	  classMyTask
	  {
	  public:
	  MyTask(conststring&querry,constwd::TcpConnectionPtrconn)
	  :_querry(std::move(querry))
	  ,_conn(conn)
	  {}
	  voidexecute();
	  private:
	  voidqueryIndexTable();//查询索引(四个索引)
	  voidstatistic(set<int>&iset);//计算
	  intdistance(conststring&rhs);//计算最小编辑距离
	  boolresponse(wd::Cache&cache);//响应客户端的请求
	  vector<Character>getOneCharacter(conststring&word);//获取字符数组
	  string_querry;
	  wd::TcpConnectionPtr_conn;
	  priority_queue<wd::MyResult,vector<wd::MyResult>,MyCompare>_resultQue;
	  };
	  #endif
	  ///=======================================
	  ///File:MyTask.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0722:47:19
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"MyTask.h"
	  #include"ConFiguration.h"
	  #include"Mydict.h"
	  #include"CacheManger.h"
	  #include"json/json.h"
	  #include<string.h>
	  #include<algorithm>
	  extern__threadintt_number;
	  boolMyTask::response(wd::Cache&cache)
	  {
	  if(cache.find(_querry))
	  {
	  _conn->sendInLoop(cache[_querry]);
	  returntrue;
	  }
	  returnfalse;
	  }
	  intMyTask::distance(conststring&rhs)
	  {
	  vector<Character>querryCharacter=getOneCharacter(_querry);
	  vector<Character>indexCharacter=getOneCharacter(rhs);
	  intlen1,len2;
	  len1=querryCharacter.size();
	  len2=indexCharacter.size();
	  intedit[len1+1][len2+1];
	  inti,j;
	  for(i=0;i<=len1;++i){
	  for(j=0;j<=len2;++j){
	  edit[i][j]=0;
	  }
	  }
	  for(i=0;i<len1;++i){
	  edit[i][0]=i;
	  }
	  for(j=0;j<=len2;++j){
	  edit[0][j]=j;
	  }
	  for(i=1;i<len1;++i){
	  for(j=1;j<=len2;++j){
	  intcost=((querryCharacter[i-1]==indexCharacter[j-1])?0:1);
	  intdeletion=edit[i-1][j]+1;
	  intinsertion=edit[i][j-1]+1;
	  intsubstitution=edit[i-1][j-1]+cost;
	  edit[i][j]=std::min(deletion,std::min(insertion,substitution));
	  }
	  }
	  returnedit[len1][len2];
	  }
	  voidMyTask::statistic(set<int>&iset)
	  {
	  vector<pair<string,int>>dict=(Singleton<wd::Mydict>::getInstance(Singleton<wd::Configuration>::getInstance(CONFPATH)->getDictDir(),
	  Singleton<wd::Configuration>::getInstance(CONFPATH)->getIndexDir()))->getDict();
	  for(auto&idx:iset)
	  {
	  stringkey=dict[idx].first;
	  intiDist=distance(key);
	  if(iDist<=3)
	  {
	  wd::MyResultres;
	  res._word=key;
	  res._iDist=iDist;
	  res._iFreq=dict[idx].second;
	  _resultQue.push(res);
	  }
	  }
	  }
	  vector<Character>MyTask::getOneCharacter(conststring&word)
	  {
	  autocit=word.begin();
	  vector<Character>ret;
	  while(cit<word.end())
	  {
	  if(224==(*cit&224)){
	  CharacteroneCharacter;
	  oneCharacter.append(cit,cit+3);
	  ret.push_back(oneCharacter);
	  cit=cit+3;
	  }elseif(240==(*cit&240)){
	  CharacteroneCharacter;
	  oneCharacter.append(cit,cit+4);
	  ret.push_back(oneCharacter);
	  cit=cit+4;
	  }else{
	  CharacteroneCharacter(1,*cit);
	  ret.push_back(oneCharacter);
	  cit++;
	  }
	  }
	  returnret;
	  }
	  voidMyTask::queryIndexTable()
	  {
	  map<string,set<int>>index=(Singleton<wd::Mydict>::getInstance(Singleton<wd::Configuration>::getInstance(CONFPATH)->getDictDir(),
	  Singleton<wd::Configuration>::getInstance(CONFPATH)->getIndexDir()))->getIndexTable();
	  vector<Character>oneCharacter=getOneCharacter(_querry);
	  set<int>allRally;
	  for(automyCharacter:oneCharacter)
	  {
	  autocit=index.find(myCharacter);
	  if(cit!=index.end())
	  {
	  for(auto&idx:cit->second)
	  allRally.insert(idx);
	  }
	  }
	  statistic(allRally);
	  }
	  voidMyTask::execute()
	  {
	  wd::Cache&mycache=(Singleton<wd::CacheManger>::getInstance(Singleton<wd::Configuration>::getInstance(CONFPATH)->getCache()))->getCache(t_number);
	  if(response(mycache))
	  return;
	  else{
	  queryIndexTable();
	  Json::FastWriterwriterinfo;
	  Json::ValuearrayObj;
	  while(!_resultQue.empty())
	  {
	  Json::Valuenew_item;
	  new_item[""]=_resultQue.top()._word;
	  _resultQue.pop();
	  arrayObj.append(new_item);
	  }
	  stringstrEmail=writerinfo.write(arrayObj);
	  mycache.addElement(_querry,strEmail);
	  _conn->sendInLoop(strEmail);
	  }
	  }
	  ==Noncopyable:==
	  #ifndef__WD_NONCOPYABLE_H__
	  #define__WD_NONCOPYABLE_H__
	  namespacewd
	  {
	  classNoncopyable
	  {
	  protected:
	  Noncopyable(){}
	  ~Noncopyable(){}
	  private:
	  Noncopyable(constNoncopyable&);
	  Noncopyable&operator=(constNoncopyable&);
	  };
	  }
	  #endif
	  ==Socket:==
	  ///=======================================
	  ///File:Socket.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0521:46:26
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_SOCKET_H__
	  #define__WD_SOCKET_H__
	  #include"Noncopyable.h"
	  namespacewd
	  {
	  classInetAddress;
	  classSocket
	  :Noncopyable
	  {
	  public:
	  Socket(intsocket);
	  Socket();
	  ~Socket();
	  voidshutdownWrite();
	  intfd()const{return_sockfd;}
	  voidnonblock();
	  staticInetAddressgetLocalAddr(intsocketfd);
	  staticInetAddressgetPeerAddr(intsockfd);
	  private:
	  int_sockfd;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:Socket.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0720:38:20
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"Socket.h"
	  #include"SocketUtil.h"
	  #include"InetAddress.h"
	  namespacewd
	  {
	  Socket::Socket(intsockfd)
	  :_sockfd(sockfd)
	  {}
	  Socket::Socket()
	  :_sockfd(createSocketFd())
	  {}
	  Socket::~Socket()
	  {
	  ::close(_sockfd);
	  }
	  voidSocket::nonblock()
	  {
	  setNonblock(_sockfd);
	  }
	  voidSocket::shutdownWrite()
	  {
	  if(-1==::shutdown(_sockfd,SHUT_WR)){
	  perror("shutdownwriteerror!");
	  }
	  }
	  InetAddressSocket::getLocalAddr(intsockfd)
	  {
	  structsockaddr_inaddr;
	  socklen_tlen=sizeof(sockaddr_in);
	  if(-1==::getsockname(sockfd,(structsockaddr*)&addr,&len)){
	  perror("getsocknameerror!");
	  }
	  returnInetAddress(addr);
	  }
	  InetAddressSocket::getPeerAddr(intsockfd)
	  {
	  structsockaddr_inaddr;
	  socklen_tlen=sizeof(sockaddr_in);
	  if(-1==::getpeername(sockfd,(structsockaddr*)&addr,&len)){
	  perror("getpeernameerror!");
	  }
	  returnInetAddress(addr);
	  }
	  }
	  ==SocketIO:==
	  ///=======================================
	  ///File:SocketIO.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0617:10:23
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__SOCKETIO_H__
	  #define__SOCKETIO_H__
	  #include<stdio.h>
	  namespacewd
	  {
	  classSocketIO
	  {
	  public:
	  SocketIO(intsockfd);
	  size_treadn(char*buf,size_tcount);
	  size_twriten(constchar*buf,size_tcount);
	  size_treadline(char*buf,size_tmax_len);
	  private:
	  size_trecv_peek(char*buf,size_tcount);
	  int_sockfd;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:SocketIO.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0721:56:34
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"SocketIO.h"
	  #include"SocketUtil.h"
	  namespacewd
	  {
	  SocketIO::SocketIO(intsockfd)
	  :_sockfd(sockfd)
	  {}
	  size_tSocketIO::readn(char*buf,size_tcount)
	  {
	  size_tnleft=count;
	  char*pbuf=buf;
	  while(nleft>0)
	  {
	  intnread=::read(_sockfd,pbuf,nleft);
	  if(-1==nread)
	  {
	  if(errno==EINTR)
	  continue;
	  returnEXIT_FAILURE;
	  }elseif(0==nread){
	  break;
	  }
	  pbuf=pbuf+nread;
	  nleft=nleft-nread;
	  }
	  return(count-nleft);
	  }
	  size_tSocketIO::writen(constchar*buf,size_tcount)
	  {
	  size_tnleft=count;
	  constchar*pbuf=buf;
	  while(nleft>0)
	  {
	  intnwrite=::write(_sockfd,pbuf,nleft);
	  if(-1==nwrite)
	  {
	  if(errno==EINTR)
	  continue;
	  returnEXIT_FAILURE;
	  }
	  nleft=nleft-nwrite;
	  pbuf=pbuf+nwrite;
	  }
	  return(count-nleft);
	  }
	  size_tSocketIO::recv_peek(char*buf,size_tcount)
	  {
	  intnread;
	  do{
	  nread=::recv(_sockfd,buf,count,MSG_PEEK);
	  }while(-1==nread&&errno==EINTR);
	  returnnread;
	  }
	  size_tSocketIO::readline(char*buf,size_tmaxlen)
	  {
	  size_tnleft=maxlen-1;
	  char*pbuf=buf;
	  size_ttotal=0;
	  while(nleft>0)
	  {
	  size_tnread=recv_peek(pbuf,nleft);
	  if(nread<=0)
	  returnnread;
	  for(size_tidx=0;idx!=nread;++idx){//检查换行符/n
	  if(pbuf[idx]=='\n'){
	  size_tnsize=idx+1;
	  if(readn(pbuf,nsize)!=nsize)
	  returnEXIT_FAILURE;
	  pbuf+=nsize;
	  total+=nsize;
	  *pbuf=0;
	  returntotal;
	  }
	  }
	  if(readn(pbuf,nread)!=nread)
	  returnEXIT_FAILURE;
	  pbuf+=nread;
	  nleft-=nread;
	  total+=nread;
	  }
	  *pbuf=0;
	  returnmaxlen-1;
	  }
	  }
	  ==SockUtil(根据陈硕编写的LINUX书上分开头文件)==
	  ///=======================================
	  ///File:SocktUtil.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0522:01:30
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_SOCKERUTIL_H__
	  #define__WD_SOCKERUTIL_H__
	  #include<stdio.h>
	  #include<stdlib.h>
	  #include<errno.h>
	  #include<string.h>
	  #include<unistd.h>
	  #include<fcntl.h>
	  #include<sys/types.h>
	  #include<sys/socket.h>
	  #include<netinet/in.h>
	  #include<arpa/inet.h>
	  #include<sys/eventfd.h>
	  #include<sys/epoll.h>
	  namespacewd
	  {
	  inlineintcreateSocketFd()
	  {
	  intfd=::socket(AF_INET,SOCK_STREAM,0);
	  if(-1==fd)
	  {
	  perror("socketcreateerror!");
	  }
	  returnfd;
	  }
	  inlinevoidsetNonblock(intfd)
	  {
	  intflags=::fcntl(fd,F_GETFL,0);
	  flags|=O_NONBLOCK;
	  ::fcntl(fd,F_SETFL,flags);
	  }
	  inlineintcreateEpollFd()
	  {
	  intefd=::epoll_create1(0);
	  if(-1==efd)
	  {
	  perror("epollcreate1error!");
	  exit(EXIT_FAILURE);
	  }
	  returnefd;
	  }
	  inlineintcreateEventFd()
	  {
	  intevtfd=::eventfd(0,EFD_NONBLOCK|EFD_CLOEXEC);
	  if(-1==evtfd)
	  {
	  perror("eventfdcreateerror!");
	  }
	  returnevtfd;
	  }
	  inlinevoidaddEpollFdRead(intefd,intfd)
	  {
	  structepoll_eventev;
	  ev.data.fd=fd;
	  ev.events=EPOLLIN;
	  intret=epoll_ctl(efd,EPOLL_CTL_ADD,fd,&ev);
	  if(-1==ret)
	  {
	  perror("epollctladderror!");
	  exit(EXIT_FAILURE);
	  }
	  }
	  inlinevoiddelEpollReadFd(intefd,intfd)
	  {
	  structepoll_eventev;
	  ev.data.fd=fd;
	  intret=epoll_ctl(efd,EPOLL_CTL_DEL,fd,&ev);
	  if(-1==ret)
	  {
	  perror("epollctldeleteerror!");
	  exit(EXIT_FAILURE);
	  }
	  }
	  inlinesize_trecvPeek(intsockfd,void*buf,size_tlen)
	  {
	  intnread;
	  do{
	  nread=::recv(sockfd,buf,len,MSG_PEEK);
	  }while(nread==-1&&errno==EINTR);
	  returnnread;
	  }
	  inlineboolisConnectionClosed(intsockfd)
	  {
	  charbuf[1024];
	  intnread=recvPeek(sockfd,buf,sizeof(buf));
	  if(-1==nread)
	  {
	  perror("recvPeekerror!");
	  returntrue;
	  }
	  return(0==nread);
	  }
	  }
	  #endif
	  ==SpellCorrrectSever:==
	  ///=======================================
	  ///File:SpellCorrectServer.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0620:41:13
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__SPELLCORRECTSERVER_H__
	  #define__SPELLCORRECTSERVER_H__
	  #include"TcpServer.h"
	  #include"Threadpool.h"
	  usingnamespacewd;
	  namespacewd
	  {
	  classSpellCorrectServer
	  {
	  public:
	  SpellCorrectServer(conststring&ip
	  ,unsignedshortport
	  ,size_tthreadNUM
	  ,size_tqueSize);
	  voidstart();
	  private:
	  voidonConnection(constTcpConnectionPtr&);
	  voidonMessage(constTcpConnectionPtr&);
	  voidonClose(constTcpConnectionPtr&);
	  TcpServer_tcpserver;
	  Threadpool_threadpoll;
	  };
	  };
	  #endif
	  ///=======================================
	  ///File:SpellCorrectServer.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0721:20:41
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"SpellCorrectServer.h"
	  #include"MyTask.h"
	  #include<stdio.h>
	  #include<iostream>
	  #include<string>
	  #include<utility>
	  #include<functional>
	  usingnamespacestd;
	  voidSpellCorrectServer::onConnection(constwd::TcpConnectionPtr&conn)
	  {
	  cout<<conn->toString()<<endl;
	  conn->send("hello,welcometoWTPChatServer.\r\n");
	  }
	  voidSpellCorrectServer::onMessage(constwd::TcpConnectionPtr&conn)
	  {
	  strings(conn->receive());
	  MyTasktask(s,conn);
	  _threadpoll.addTask(std::bind(&MyTask::execute,&task));
	  cout<<">addtasktothreadpool"<<endl;
	  }
	  voidSpellCorrectServer::onClose(constwd::TcpConnectionPtr&conn)
	  {
	  ::printf("%sclose\n",conn->toString().c_str());
	  }
	  SpellCorrectServer::SpellCorrectServer(conststring&ip
	  ,unsignedshortport
	  ,size_tthreadNUM
	  ,size_tqueSize)
	  :_tcpserver(ip,port)
	  ,_threadpoll(threadNUM,queSize)
	  {}
	  voidSpellCorrectServer::start()
	  {
	  _threadpoll.start();
	  _tcpserver.setConnectionCallback(std::bind(&SpellCorrectServer::onConnection,this,std::placeholders::_1));
	  _tcpserver.setMessageCallback(std::bind(&SpellCorrectServer::onMessage,this,std::placeholders::_1));
	  _tcpserver.setCloseCallback(std::bind(&SpellCorrectServer::onClose,this,std::placeholders::_1));
	  _tcpserver.start();
	  }
	  ==TaskQue:==
	  #ifndef__WD_TASKQUEUE_H__
	  #define__WD_TASKQUEUE_H__
	  #include"MutexLock.h"
	  #include"Condition.h"
	  #include<queue>
	  #include<functional>
	  namespacewd
	  {
	  typedefstd::function<void()>Task;
	  classTaskQueue
	  {
	  public:
	  TaskQueue(size_tqueSize)
	  :_queSize(queSize)
	  ,_mutex()
	  ,_notFull(_mutex)
	  ,_notEmpty(_mutex)
	  ,_flag(true)
	  {}
	  voidpush(Task&&task);
	  Taskpop();
	  boolempty()const
	  {
	  return_que.size()==0;
	  }
	  boolfull()const
	  {return_que.size()==_queSize;}
	  voidwakeup()
	  {
	  if(_flag)
	  _flag=false;
	  _notEmpty.notifyAll();
	  }
	  private:
	  size_t_queSize;
	  std::queue<Task>_que;
	  MutexLock_mutex;
	  Condition_notFull;
	  Condition_notEmpty;
	  bool_flag;
	  };
	  }
	  #endif
	  #include"TaskQueue.h"
	  usingnamespacewd;
	  //生产者所在的线程
	  voidTaskQueue::push(Task&&task)
	  {
	  MutexLockGuardautoLock(_mutex);
	  while(full())
	  {
	  _notFull.wait();
	  }
	  _que.push(std::move(task));
	  _notEmpty.notify();
	  }
	  //消费者所在线程
	  TaskTaskQueue::pop()
	  {
	  MutexLockGuardautoLock(_mutex);
	  while(_flag&&empty())
	  {
	  _notEmpty.wait();
	  }
	  if(_flag){
	  Tasktask=_que.front();
	  _que.pop();
	  _notFull.notify();
	  returntask;
	  }else{
	  returnNULL;
	  }
	  }
	  #if0
	  TaskTaskQueue::pop()
	  {
	  MutexLockGuardautoLock(_mutex);
	  while(_flag&&empty())
	  {
	  _notEmpty.wait();
	  }
	  if(_flag){
	  Tasktask=_que.front();
	  _que.pop();
	  _notFull.notify();
	  returntask;
	  }else{
	  returnNULL;
	  }
	  }
	  #endif
	  ==TcpConnection:==
	  ///=======================================
	  ///File:TcpConnection.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0617:15:33
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_TCPCONNECTION_H__
	  #define__WD_TCPCONNECTION_H__
	  #include"Noncopyable.h"
	  #include"InetAddress.h"
	  #include"Socket.h"
	  #include"SocketIO.h"
	  #include<string>
	  #include<memory>
	  #include<functional>
	  namespacewd
	  {
	  classEpollPoller;
	  classTcpConnection;
	  typedefstd::shared_ptr<TcpConnection>TcpConnectionPtr;
	  classTcpConnection
	  :Noncopyable
	  ,publicstd::enable_shared_from_this<TcpConnection>
	  {
	  public:
	  typedefstd::function<void(constTcpConnectionPtr&)>TcpConnectionCallback;
	  TcpConnection(intsockfd,EpollPoller*loop);
	  ~TcpConnection();
	  std::stringreceive();
	  voidsend(conststd::string&msg);
	  voidsendInLoop(conststd::string&msg);
	  voidshutdown();
	  std::stringtoString();
	  voidsetConnectionCallback(TcpConnectionCallbackcb);
	  voidsetMessageCallback(TcpConnectionCallbackcb);
	  voidsetCloseCallback(TcpConnectionCallbackcb);
	  voidhandleConnectionCallback();
	  voidhandleMessageCallback();
	  voidhandleCloseCallback();
	  private:
	  Socket_sockfd;
	  SocketIO_sockIO;
	  constInetAddress_localAddr;
	  constInetAddress_peerAddr;
	  bool_isShutdownWrite;
	  EpollPoller*_loop;
	  TcpConnectionCallback_onConnectionCb;
	  TcpConnectionCallback_onMessageCb;
	  TcpConnectionCallback_onCloseCb;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:TcpConnection.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0722:22:22
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"TcpConnection.h"
	  #include"EpollPoller.h"
	  #include<string.h>
	  #include<stdio.h>
	  namespacewd
	  {
	  TcpConnection::TcpConnection(intsockfd,EpollPoller*loop)
	  :_sockfd(sockfd)
	  ,_sockIO(sockfd)
	  ,_localAddr(wd::Socket::getLocalAddr(sockfd))
	  ,_peerAddr(wd::Socket::getPeerAddr(sockfd))
	  ,_isShutdownWrite(false)
	  ,_loop(loop)
	  {_sockfd.nonblock();}
	  TcpConnection::~TcpConnection()
	  {
	  if(!_isShutdownWrite)
	  {
	  _isShutdownWrite=true;
	  shutdown();
	  }
	  printf("~TcpConnection()\n");
	  }
	  std::stringTcpConnection::receive()
	  {
	  charbuf[65536];
	  memset(buf,0,sizeof(buf));
	  size_tret=_sockIO.readline(buf,sizeof(buf));
	  if(0==ret){
	  returnstd::string();
	  }else{
	  returnstd::string(buf);
	  }
	  }
	  voidTcpConnection::send(conststd::string&msg)
	  {
	  size_tlen=msg.size();
	  _sockIO.writen((constchar*)&len,sizeof(int));
	  _sockIO.writen(msg.c_str(),len);
	  }
	  voidTcpConnection::shutdown()
	  {
	  if(!_isShutdownWrite)
	  _sockfd.shutdownWrite();
	  _isShutdownWrite=true;
	  }
	  std::stringTcpConnection::toString()
	  {
	  charstr[100];
	  snprintf(str,sizeof(str),"%s:%d->%s:%d"
	  ,_localAddr.ip().c_str()
	  ,_localAddr.port()
	  ,_peerAddr.ip().c_str()
	  ,_peerAddr.port());
	  returnstd::string(str);
	  }
	  voidTcpConnection::setConnectionCallback(TcpConnectionCallbackcb)
	  {
	  _onConnectionCb=cb;
	  }
	  voidTcpConnection::setMessageCallback(TcpConnectionCallbackcb)
	  {
	  _onMessageCb=cb;
	  }
	  voidTcpConnection::setCloseCallback(TcpConnectionCallbackcb)
	  {
	  _onCloseCb=cb;
	  }
	  voidTcpConnection::handleConnectionCallback()
	  {
	  if(_onConnectionCb){
	  _onConnectionCb(shared_from_this());
	  }
	  }
	  voidTcpConnection::handleMessageCallback()
	  {
	  if(_onMessageCb){
	  _onMessageCb(shared_from_this());
	  }
	  }
	  voidTcpConnection::handleCloseCallback()
	  {
	  if(_onCloseCb){
	  _onCloseCb(shared_from_this());
	  }
	  }
	  voidTcpConnection::sendInLoop(conststd::string&msg)
	  {
	  _loop->runInLoop(std::bind(&TcpConnection::send,this,msg));
	  }
	  }
	  ==TcpServer:==
	  ///=======================================
	  ///File:TcpServer.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0620:15:21
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_TCPSERVER_H__
	  #define__WD_TCPSERVER_H__
	  #include"Acceptor.h"
	  #include"EpollPoller.h"
	  #include<string>
	  usingstd::string;
	  namespacewd
	  {
	  classTcpServer
	  {
	  public:
	  typedefEpollPoller::EpollCallbackTcpServerCallback;
	  TcpServer(conststring&ip,unsignedshortport);
	  TcpServer(unsignedshortport);
	  voidstart();
	  voidstop();
	  voidsetConnectionCallback(TcpServerCallbackcb);
	  voidsetMessageCallback(TcpServerCallbackcb);
	  voidsetCloseCallback(TcpServerCallbackcb);
	  private:
	  Acceptor_acceptor;
	  EpollPoller_poller;
	  TcpServerCallback_connectionCallback;
	  TcpServerCallback_messageCallback;
	  TcpServerCallback_closeCallback;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:TcpServer.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0719:59:37
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"TcpServer.h"
	  #include"InetAddress.h"
	  #include"SocketUtil.h"
	  #include<iostream>
	  usingnamespacestd;
	  namespacewd
	  {
	  TcpServer::TcpServer(conststring&ip,unsignedshortport)
	  :_acceptor(createSocketFd(),InetAddress(ip.c_str(),port))
	  ,_poller(_acceptor)
	  {}
	  voidTcpServer::start()
	  {
	  _acceptor.ready();
	  _poller.setConnectionCallback(_connectionCallback);
	  _poller.setMessageCallback(_messageCallback);
	  _poller.setCloseCallback(_closeCallback);
	  _poller.loop();
	  }
	  voidTcpServer::stop()
	  {
	  _poller.unloop();
	  }
	  voidTcpServer::setConnectionCallback(TcpServerCallbackcb)
	  {_connectionCallback=cb;}
	  voidTcpServer::setMessageCallback(TcpServerCallbackcb)
	  {_messageCallback=cb;}
	  voidTcpServer::setCloseCallback(TcpServerCallbackcb)
	  {_closeCallback=cb;}
	  }
	  ==Thread:==
	  #ifndef__WD_THREAD_H__
	  #define__WD_THREAD_H__
	  #include"Noncopyable.h"
	  #include<pthread.h>
	  #include<functional>
	  usingstd::function;
	  namespacewd
	  {
	  classThread;
	  structThreadPtr
	  {
	  int_number;
	  Thread*_pthread;
	  };
	  classThread
	  :Noncopyable
	  {
	  usingThreadCallback=function<void()>;
	  public:
	  Thread(ThreadCallback&&cb);
	  ~Thread();
	  voidstart(intnumber);
	  voidjoin();
	  boolisRunning()const{return_isRunning;}
	  private:
	  staticvoid*threadFunc(void*);
	  pthread_t_pthid;
	  bool_isRunning;
	  ThreadCallback_cb;
	  };
	  }
	  #endif
	  #include"Thread.h"
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  __threadintt_number;//将线程编号作为线程存储的标记
	  Thread::Thread(ThreadCallback&&cb)//这里的右值引用本身取决于是否有名字
	  :_pthid(0)
	  ,_isRunning(false)
	  ,_cb(std::move(cb))
	  {
	  cout<<"Thread(cb)"<<endl;
	  }
	  voidThread::start(intnumber)
	  {
	  ThreadPtr*threadPtr=newThreadPtr();
	  threadPtr->_number=number;
	  threadPtr->_pthread=this;
	  pthread_create(&_pthid,NULL,threadFunc,threadPtr);
	  _isRunning=true;
	  }
	  void*Thread::threadFunc(void*arg)
	  {//应用了线程存储
	  ThreadPtr*threadPtr=static_cast<ThreadPtr*>(arg);
	  Thread*pthread=threadPtr->_pthread;
	  t_number=threadPtr->_number;
	  if(pthread)
	  pthread->_cb();//线程开始工作!
	  deletethreadPtr;
	  //Thread*pthread=threadPtr->_pthread;
	  returnNULL;
	  }
	  #if0
	  void*Thread::threadFunc(void*arg)
	  {
	  ThreadPtr*threadPtr=static_cast<ThreadPtr*>(arg);
	  Thread*pthread=threadPtr->_pthread;
	  t_number=threadPtr->_number;
	  if(pthread)
	  pthread->_cb();
	  deletethreadPtr;
	  returnNULL;
	  }
	  #endif
	  voidThread::join()
	  {
	  pthread_join(_pthid,NULL);
	  _isRunning=false;
	  }
	  Thread::~Thread()
	  {
	  if(_isRunning)
	  {
	  pthread_detach(_pthid);
	  _isRunning=false;
	  }
	  cout<<"~Thread()"<<endl;
	  }
	  ==Threadpool:==
	  #ifndef__WD_THREADPOLL_H__
	  #define__WD_THREADPOLL_H__
	  #include"TaskQueue.h"
	  #include"Thread.h"
	  #include<vector>
	  #include<memory>
	  #include<functional>
	  usingstd::shared_ptr;
	  usingstd::vector;
	  namespacewd
	  {
	  classThreadpool
	  {
	  public:
	  usingTask=std::function<void()>;
	  Threadpool(size_tthreadNum,size_tqueSize)
	  :_threadNum(threadNum)
	  ,_queSize(queSize)
	  ,_taskQue(_queSize)
	  ,_isExit(false)
	  {
	  _threads.reserve(_threadNum);
	  }
	  ~Threadpool();
	  voidstart();
	  voidstop();
	  voidaddTask(Task&&task);
	  private:
	  voidthreadFunc();
	  TaskgetTask();
	  size_t_threadNum;
	  size_t_queSize;
	  vector<shared_ptr<Thread>>_threads;
	  TaskQueue_taskQue;
	  bool_isExit;
	  };
	  }
	  #endif
	  #include"Threadpool.h"
	  #include"Thread.h"
	  #include<unistd.h>
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  voidThreadpool::start()
	  {
	  for(size_tidx=0;idx<_threadNum;++idx)
	  {
	  shared_ptr<Thread>pThread(newThread(std::bind(&Threadpool::threadFunc,this)));
	  _threads.push_back(std::move(pThread));
	  }
	  intnumber=0;
	  for(auto&pThread:_threads)
	  {
	  pThread->start(number);
	  ++number;
	  }
	  }
	  voidThreadpool::stop()//为了线程安全,将stop方法置于主线程中
	  {
	  if(!_isExit)
	  {
	  while(!_taskQue.empty()){
	  ::sleep(1);
	  cout<<"Threadpoolsleep1second!"<<endl;
	  }
	  _isExit=true;
	  cout<<"Threadpool->stop:_isExit="<<_isExit<<endl;
	  _taskQue.wakeup();
	  for(auto&pthread:_threads){
	  pthread->join();
	  }
	  }
	  }
	  Threadpool::~Threadpool()
	  {
	  if(!_isExit){
	  stop();
	  }
	  }
	  voidThreadpool::addTask(Task&&task)
	  {
	  _taskQue.push(std::move(task));
	  }
	  TaskThreadpool::getTask()
	  {
	  return_taskQue.pop();
	  }
	  voidThreadpool::threadFunc()
	  {
	  while(!_isExit)
	  {
	  Tasktask=getTask();
	  if(task){
	  task();
	  }
	  }
	  }
	  ==Timer:==
	  ///=======================================
	  ///File:Timer.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0620:00:45
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_TIMER_H__
	  #define__WD_TIMER_H__
	  #include<functional>
	  namespacewd
	  {
	  classTimer
	  {
	  public:
	  usingTimerCallback=std::function<void()>;
	  Timer(intinitailTime,intintervalTime,TimerCallback&&cb);
	  ~Timer();
	  voidstart();
	  voidstop();
	  private:
	  int_fd;
	  int_initialTime;
	  int_intervalTime;
	  TimerCallback_cb;
	  bool_isStarted;
	  intcreateTimerFd();
	  voidsetTimerfd(intinitialTime,intintervalTime);
	  voidhandleRead();
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:Timer.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0720:09:14
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"Timer.h"
	  #include<unistd.h>
	  #include<errno.h>
	  #include<poll.h>
	  #include<sys/timerfd.h>
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  Timer::Timer(intinitialTime,intintervalTime,TimerCallback&&cb)
	  :_fd(createTimerFd())
	  ,_initialTime(initialTime)
	  ,_intervalTime(intervalTime)
	  ,_cb(std::move(cb))
	  ,_isStarted(false)
	  {}
	  voidTimer::start()
	  {
	  structpollfdpfd;
	  pfd.fd=_fd;
	  pfd.events=POLLIN;
	  setTimerfd(_initialTime,_intervalTime);//开启定时器
	  _isStarted=true;
	  while(_isStarted){
	  intnready=::poll(&pfd,1,5000);
	  if(-1==nready&&errno==EINTR){
	  continue;
	  }elseif(-1==nready){
	  perror(">>>pollerror!");
	  exit(EXIT_FAILURE);
	  }elseif(0==nready){
	  cout<<">>>polltimeout!"<<endl;
	  }else{
	  if(pfd.revents&POLLIN){
	  handleRead();//先对定时器进行处理
	  if(_cb){
	  _cb();//再去执行回调任务
	  }
	  }
	  }
	  }
	  }
	  voidTimer::stop()
	  {
	  setTimerfd(0,0);
	  if(_isStarted){
	  _isStarted=false;
	  }
	  }
	  Timer::~Timer()
	  {
	  if(_isStarted){
	  stop();
	  }
	  }
	  intTimer::createTimerFd()
	  {
	  intfd=::timerfd_create(CLOCK_REALTIME,0);
	  if(-1==fd){
	  perror(">>timerfd_createerror!");
	  }
	  returnfd;
	  }
	  voidTimer::setTimerfd(intinitialTime,intintervalTime)
	  {
	  structitimerspecvalue;
	  value.it_value.tv_sec=initialTime;
	  value.it_value.tv_nsec=0;
	  value.it_interval.tv_sec=intervalTime;
	  value.it_interval.tv_nsec=0;
	  intret=::timerfd_settime(_fd,0,&value,NULL);
	  if(-1==ret){
	  perror(">>>timerfd_settimeerror!");
	  }
	  }
	  #if0
	  voidTimer::handleRead()
	  {
	  uint64_thowmany;
	  intret=::read(_fd,&howmany,sizeof(uint64_t));
	  if(ret!=sizeof(uint64_t)){
	  perror("read!");
	  }
	  }
	  #endif
	  voidTimer::handleRead()
	  {
	  uint64_thowmany;//为一个64位
	  intret=::read(_fd,&howmany,sizeof(uint64_t));
	  if(ret!=sizeof(uint64_t)){
	  perror(">>>readerror!");
	  }
	  }
	  ==TimerThread:==
	  ///=======================================
	  ///File:TimerThread.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0717:12:51
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_TIMERTHREAD_H__
	  #define__WD_TIMERTHREAD_H__
	  #include"Timer.h"
	  #include"Thread.h"
	  #include<functional>
	  namespacewd
	  {
	  classTimerThread
	  {
	  public:
	  usingTimerCallback=std::function<void()>;
	  TimerThread(int,int,TimerCallback&&cb);
	  ~TimerThread();
	  voidstart();
	  voidstop();
	  private:
	  Timer_timer;
	  Thread_subThread;
	  bool_isStarted;
	  };
	  }//endofnamespacewd
	  #endif
	  ///=======================================
	  ///File:TimerThread.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0720:09:14
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"TimerThread.h"
	  usingnamespacewd;
	  TimerThread::TimerThread(intinitialTime,intintervalTime,TimerCallback&&cb)
	  :_timer(initialTime,intervalTime,std::move(cb))
	  ,_subThread(std::bind(&Timer::start,&_timer))
	  ,_isStarted(false)
	  {}
	  voidTimerThread::start()
	  {
	  _subThread.start(0);
	  _isStarted=true;
	  }
	  voidTimerThread::stop()
	  {
	  if(_isStarted){
	  _timer.stop();
	  _subThread.join();
	  _isStarted=false;
	  }
	  }
	  TimerThread::~TimerThread()
	  {
	  if(_isStarted)
	  stop();
	  }
	  ==main:==
	  ///=======================================
	  ///File:main.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0721:09:32
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"SpellCorrectServer.h"
	  #include"ConFiguration.h"
	  #include"CacheManger.h"
	  #include"TimerThread.h"
	  #include<iostream>
	  #include<functional>
	  usingnamespacestd;
	  usingnamespacewd;
	  intmain()
	  {
	  wd::CacheManger*mycacheManger=Singleton<CacheManger>::getInstance(Singleton<Configuration>
	  ::getInstance(CONFPATH)->getCache());
	  TimerThreadtimer(5,600,std::bind(&CacheManger::periodicUpdate,mycacheManger));
	  timer.start();
	  SpellCorrectServermyspell(Singleton<Configuration>::getInstance(CONFPATH)->getIp()
	  ,Singleton<Configuration>::getInstance(CONFPATH)->getPort()
	  ,4
	  ,10);
	  myspell.start();
	  return0;
	  }
	  小结:(1)已经实现项目需求,中文和英文单词都能查询,经过测试,运行稳定,能输出不少候选词
	  ?(2)仍然存在少量bug,例如偶尔会发生段错误
	  ?(3)由于时间问题,json读出的数据key-value的key值没有打印,用户界面还未来得及优化
	  ?(4)陈硕的《linux多线程服务端编程》使用linux接口(timerfd),没用posix接口(eventfd)
	  ---恢复内容结束---
	  #我的Spellcorrect开发文档
	  [TOC]
	  相关配置文件及准备工作:
	  我的主要文件夹分为三个:分别为客户端,cppjieba分词库,离线部分及服务器部分
	  1560856582308
	  客户端部分:内部为客户端源码及运行程序
	  1560856552431
	  cppjieba分词库部分,就不赘述,请自行安装
	  离线部分:内部有中英文件夹放置索引及词典文件,还有配置文件及分词库,其余为代码
	  1560857073864
	  服务器部分:最为重要的配置文件及数据部分,头文件在include,实现文件在src里面
	  1560857034230
	  演示效果(中文):
	  ==启动时服务器:==
	  1560857677039
	  ==客户端连入时时服务器:==
	  1560857739202
	  ==输入“赵”==
	  1560858117388
	  ==输入“周杰伦”==
	  1560858201376
	  ==输入清华大学==
	  1560858560147
	  演示效果(英语):
	  ==启动时服务器:==
	  1560857677039
	  ==客户端连入时时服务器:==
	  1560857739202
	  ==输入student:==
	  1560858008297
	  ==输入spell:==
	  1560858872540
	  ==输入computer:==
	  1560859162357
	  代码部分:
	  离线部分:
	  img
	  ==Makefile:==
	  SRCS:=$(wildcard*.cc)
	  OBJS:=$(patsubst%.cc,%.o,$(SRCS))
	  CXX:=g++
	  CXXFLAGS:=-w-g-std=c++11$(addprefix-I,$(INC_DIR))$(LIBS)-Wno-deprecated-I../cppjieba/include/-I../cppjieba/deps
	  EXE:=./main
	  $(EXE):$(OBJS)
	  $(CXX)-o$(EXE)$(OBJS)$(CXXFLAGS)
	  clean:
	  rm-rf$(EXE)
	  rm-rf$(OBJS)
	  ==Configuration:==
	  ///=======================================
	  ///File:Configuration.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1200:30:39
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__CONFIGURATION_H__
	  #define__CONFIGURATION_H__
	  #include"Nocopyable.h"
	  #include<string>
	  #include<map>
	  usingnamespacestd;
	  classConfiguration
	  :publicNoncopyable
	  {
	  public:
	  Configuration(conststring&filePath);
	  stringgetEnglishDir()const{return_englishDir;}
	  stringgetChineseDir()const{return_chineseDir;}
	  private:
	  string_filePath;
	  string_englishDir;
	  string_chineseDir;
	  };
	  template<typenameT>
	  classSingleton
	  {
	  public:
	  template<typename...Args>
	  staticT*getInstance(Args...args)
	  {
	  if(!_pInstance)
	  _pInstance=newT(args...);
	  return_pInstance;
	  }
	  staticvoiddestroy()
	  {
	  if(_pInstance)
	  delete_pInstance;
	  }
	  private:
	  Singleton();
	  ~Singleton();
	  staticT*_pInstance;
	  };
	  template<typenameT>
	  T*Singleton<T>::_pInstance=NULL;
	  #endif
	  1///=======================================
	  2///File:Configuration.cc
	  3///Author:wtptorres(1584292712@qq.com)
	  4///Date:2019-06-1200:30:04
	  5///Dream:Don'tforgetyourdreams!
	  6///======================================
	  7
	  8
	  9#include"Configuration.h"
	  10#include<utility>
	  11#include<fstream>
	  12#include<iostream>
	  13usingnamespacestd;
	  14
	  15Configuration::Configuration(conststring&filePath)
	  16:_filePath(std::move(filePath))
	  17{
	  18ifstreamifs(_filePath);
	  19if(!ifs)
	  20cout<<"fileopenerror!"<<endl;
	  21ifs>>_englishDir;
	  22ifs>>_chineseDir;
	  23ifs.close();
	  24}
	  ///=======================================
	  ///File:Nocopyable.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1200:24:36
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__NOCOPYABLE_H__
	  #define__NOCOPYABLE_H__
	  classNoncopyable
	  {
	  public:
	  Noncopyable()=default;
	  ~Noncopyable()=default;
	  private:
	  Noncopyable(constNoncopyable&rhs);
	  Noncopyable&operator=(constNoncopyable&rhs);
	  };
	  #endif
	  ==DictProducer:==
	  ///=======================================
	  ///File:DictProducer.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1216:40:25
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__DICTPRODUCER_H__
	  #define__DICTPRODUCER_H__
	  #include"SplitTool.h"
	  usingnamespacestd;
	  #include"Nocopyable.h"
	  #include<memory>
	  #include<string>
	  #include<vector>
	  #include<map>
	  #include<utility>
	  classDictProducer
	  :publicNoncopyable
	  {
	  public:
	  DictProducer(conststring,conststring,conststring&,SplitToolJieba*);
	  ~DictProducer(){}
	  voidbuild_dict();
	  voidbuild_cn_dict();
	  voidstore_dict();
	  vector<pair<string,int>>&getIndict(){return_indict;}
	  private:
	  voidprocessEnglishWord(string&word);
	  voidprocessChineseWord(string&word);//除去中文的数字
	  voidconstruct_indict();
	  string_englishDir;
	  string_chineseDir;
	  string_goleFilePath;
	  vector<string>_englishFiles;
	  vector<string>_chineseFiles;
	  map<string,int>_dict;
	  vector<pair<string,int>>_indict;
	  shared_ptr<SplitToolJieba>_splitTool;
	  };
	  #endif
	  ///=======================================
	  ///File:DictProducer.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1216:50:46
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"DictProducer.h"
	  #include<cctype>
	  #include<utility>
	  #include<fstream>
	  #include<iostream>
	  #defineFIRSTSIZE10000
	  usingnamespacestd;
	  DictProducer::DictProducer(conststringenglishDir,conststringchineseDir,conststring&goleFilePath,SplitToolJieba*splitToolPtr)
	  :_englishDir(englishDir)
	  ,_chineseDir(chineseDir)
	  ,_goleFilePath(goleFilePath)
	  {
	  _splitTool.reset(splitToolPtr);
	  std::ifstreamifsEnglish(_englishDir);
	  std::ifstreamifsChinese(_chineseDir);
	  stringfilePath;
	  if(!ifsEnglish||!ifsChinese){
	  cout<<"Dictfileopenerror!"<<endl;
	  }
	  while(ifsEnglish>>filePath)
	  {
	  _englishFiles.push_back(filePath);
	  }
	  while(ifsChinese>>filePath)
	  {
	  _chineseFiles.push_back(filePath);
	  }
	  _indict.reserve(FIRSTSIZE);
	  }
	  voidDictProducer::processEnglishWord(string&word)
	  {
	  autocit=word.begin();
	  for(;cit!=word.end();++cit)
	  {//去除标点符号或数字
	  if(!isalpha(*cit)){
	  word.erase(cit);
	  --cit;//迭代器位置发生改变
	  }elseif(isupper(*cit)){//将大写字母改为小写
	  *cit=tolower(*cit);
	  }
	  }
	  }
	  voidDictProducer::processChineseWord(string&word)
	  {
	  autocit=word.begin();
	  for(;cit!=word.end();++cit)
	  {//去除数字
	  if(!isalnum(*cit)){
	  word.erase(cit);
	  --cit;
	  }
	  }
	  }
	  voidDictProducer::build_dict()//建立英文词典
	  {
	  for(auto&filePath:_englishFiles)
	  {
	  ifstreamifs(filePath);
	  if(!ifs){
	  cout<<"EnglishFileopenerror!"<<endl;
	  }
	  stringword;
	  while(ifs>>word)
	  {
	  processEnglishWord(word);
	  autocit=_dict.find(word);
	  if(word.size()>0&&cit==_dict.end()){
	  _dict.insert(std::make_pair(word,1));
	  }elseif(cit!=_dict.end()){
	  ++cit->second;
	  }
	  }
	  }
	  }
	  voidDictProducer::build_cn_dict()
	  {
	  vector<string>words;
	  for(autofilePath:_chineseFiles)
	  {
	  ifstreamifs(filePath);
	  if(!ifs){
	  cout<<"Chinesefileopenerror!"<<endl;
	  }
	  stringsentence;
	  while(std::getline(ifs,sentence))
	  {
	  _splitTool->Cut(sentence);
	  }
	  }
	  vector<string>&results=_splitTool->getResult();
	  for(auto&res:results)
	  {
	  processChineseWord(res);
	  autocit=_dict.find(res);
	  if(cit==_dict.end()){
	  _dict.insert(std::make_pair(res,1));
	  }else{
	  ++cit->second;
	  }
	  }
	  }
	  voidDictProducer::store_dict()
	  {
	  construct_indict();
	  ofstreamofs(_goleFilePath);
	  if(!ofs)
	  cout<<"Store_dictopenfileerror!"<<endl;
	  for(auto&mypair:_indict)
	  {
	  ofs<<mypair.first<<""<<mypair.second<<endl;
	  }
	  ofs.close();
	  }
	  voidDictProducer::construct_indict()
	  {
	  for(autodictpair:_dict){
	  _indict.push_back(dictpair);
	  }
	  }
	  ==GetIndex:==
	  ///=======================================
	  ///File:GetIndex.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1208:52:04
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__GETINDEX_H__
	  #define__GETINDEX_H__
	  #include<string>
	  #include<unordered_map>
	  #include<set>
	  #include<vector>
	  #include<utility>
	  #include<unordered_set>
	  usingnamespacestd;
	  classGetIndex
	  {
	  public:
	  GetIndex(conststring&,conststring&,conststring&);
	  ~GetIndex(){}
	  voidconstruct_index();
	  voidstore_index();
	  private:
	  boolisEnglish(conststring&rhs)const;
	  vector<string>getOneCharacter(conststring&word);
	  string_sourceFilePath;
	  string_goleFilePath;
	  string_stopWordsFilePath;
	  vector<pair<string,int>>_dict;
	  unordered_set<string>_stopWords;
	  unordered_map<string,set<int>>_index;
	  };
	  #endif
	  ///=======================================
	  ///File:GetIndex.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1209:00:11
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"GetIndex.h"
	  #include<fstream>
	  #include<sstream>
	  #include<iostream>
	  usingnamespacestd;
	  GetIndex::GetIndex(conststring&sourceFilePath,conststring&goleFilePath,conststring&stopWordsFilePath)
	  :_sourceFilePath(std::move(sourceFilePath))
	  ,_goleFilePath(std::move(goleFilePath))
	  ,_stopWordsFilePath(std::move(stopWordsFilePath))
	  {
	  ifstreamifs(_sourceFilePath);
	  if(!ifs){
	  cout<<"GetIndexfileopenerror!"<<endl;
	  }
	  stringline;
	  while(getline(ifs,line))
	  {
	  istringstreamiss(line);
	  stringkey;
	  intvalue;
	  iss>>key>>value;
	  _dict.push_back(std::make_pair(key,value));
	  }
	  ifstreamifs1(_stopWordsFilePath);
	  if(!ifs1){
	  cout<<"fileopenerror!"<<endl;
	  }
	  stringstopWord;
	  while(ifs1>>stopWord,!ifs1.eof())
	  {
	  _stopWords.insert(stopWord);
	  }
	  }
	  vector<string>GetIndex::getOneCharacter(conststring&word)
	  {
	  vector<string>tmp;
	  autocit=word.begin();
	  while(cit<word.end())
	  {
	  if(224==(*cit&224))
	  {
	  stringoneCharacter;
	  oneCharacter.append(cit,cit+3);
	  tmp.push_back(oneCharacter);
	  cit+=3;
	  }elseif(240==(*cit&240)){
	  stringoneCharacter;
	  oneCharacter.append(cit,cit+4);
	  tmp.push_back(oneCharacter);
	  cit+=4;
	  }else
	  break;
	  }
	  returntmp;
	  }
	  boolGetIndex::isEnglish(conststring&rhs)const
	  {
	  charch=*(rhs.begin());
	  if(ch<0)
	  returnfalse;
	  returntrue;
	  }
	  #if0
	  boolGetIndex::isEnglish(conststring&rhs)const
	  {
	  charch=*(rhs.begin());
	  if(ch<0){
	  returnfalse;
	  }
	  returntrue;
	  }
	  #endif
	  voidGetIndex::construct_index()
	  {
	  for(size_ti=0;i!=_dict.size();++i)
	  {
	  stringtmp=_dict[i].first;
	  if(isEnglish(tmp))
	  {
	  for(autoch:tmp)
	  {
	  stringcharactor(1,ch);
	  if(isalpha(ch))
	  {
	  autocit=_index.find(charactor);
	  if(cit==_index.end())
	  {
	  set<int>smp;
	  smp.insert(i);
	  _index.insert(std::make_pair(charactor,smp));
	  }else{//已经存在了该字母的索引
	  cit->second.insert(i);
	  }
	  }
	  }
	  }else{//中文处理部分
	  vector<string>oneCharacterRally=getOneCharacter(tmp);
	  for(autooneCharacter:oneCharacterRally)
	  {//stop_words中不存在该单词,则加入索引中
	  if(_stopWords.find(oneCharacter)==_stopWords.end()){
	  autoit=_index.find(oneCharacter);
	  if(it==_index.end()){
	  set<int>tmp;
	  tmp.insert(i);
	  _index.insert(std::make_pair(oneCharacter,tmp));
	  }else{
	  it->second.insert(i);
	  }
	  }
	  }
	  }
	  }
	  }
	  voidGetIndex::store_index()
	  {
	  //ofs存储索引的内容
	  std::ofstreamofs(_goleFilePath);
	  if(!ofs){
	  cout<<"fileopenerror!"<<endl;
	  return;
	  }
	  for(autodata:_index)
	  {
	  ofs<<data.first<<"";
	  for(autolinenum:data.second)
	  {
	  ofs<<linenum<<"";
	  }
	  ofs<<endl;
	  }
	  ofs.close();
	  }
	  ==SplitTool:==
	  ///=======================================
	  ///File:SplitTool.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1217:12:01
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__SPLITTOOL_H__
	  #define__SPLITTOOL_H__
	  #include"../cppjieba/include/cppjieba/Jieba.hpp"//需要自己将cppjieba安装在项目目录下
	  #include"Configuration.h"
	  #include<string>
	  #include<vector>
	  usingnamespacestd;
	  usingnamespacecppjieba;
	  classSplitToolJieba
	  {
	  public:
	  SplitToolJieba(conststring&dict_path,conststring&model_path,conststring&user_dict_path,conststring&idfPath,conststring&stopWordPath)
	  :_jieba(dict_path,model_path,user_dict_path,idfPath,stopWordPath)
	  {}
	  ~SplitToolJieba(){}
	  voidCut(conststring&sentence)
	  {
	  vector<string>tmp;
	  _jieba.Cut(sentence,tmp);
	  _result.insert(_result.end(),tmp.begin(),tmp.end());
	  }
	  vector<string>&getResult(){return_result;}
	  private:
	  vector<string>_result;
	  cppjieba::Jieba_jieba;
	  };
	  #endif
	  ==main:==
	  ///=======================================
	  ///File:main.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-1220:38:50
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"Configuration.h"
	  #include"SplitTool.h"
	  usingnamespacestd;
	  #include"DictProducer.h"
	  #include"GetIndex.h"
	  #include<iostream>
	  #include<memory>
	  constchar*constDICT_PATH="../cppjieba/dict/jieba.dict.utf8";
	  constchar*constHMM_PATH="../cppjieba/dict/hmm_model.utf8";
	  constchar*constUSER_DICT_PATH="../cppjieba/dict/user.dict.utf8";
	  constchar*constIDF_PATH="../cppjieba/dict/idf.utf8";
	  constchar*constSTOP_WORD_PATH="../cppjieba/dict/stop_words.utf8";
	  conststringGOLE_DICT_PATH="../server/data/dict.txt";
	  conststringGOLE_INDEX_PATH="../server/data/index.txt";
	  classSplitTool;
	  intmain(void)
	  {
	  Configuration*pconfig=Singleton<Configuration>::getInstance("configure.txt");
	  SplitToolJieba*ptool=newSplitToolJieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH);
	  DictProducermydictProducer(pconfig->getEnglishDir(),pconfig->getChineseDir(),GOLE_DICT_PATH,ptool);
	  mydictProducer.build_dict();//建立英语词典
	  mydictProducer.build_cn_dict();//建立中文词典
	  mydictProducer.store_dict();//储存词典
	  GetIndexmyindex(GOLE_DICT_PATH,GOLE_INDEX_PATH,"stop_words_zh.txt");
	  myindex.construct_index();//建立索引
	  myindex.store_index();//存储索引
	  Singleton<Configuration>::destroy();
	  return0;
	  }
	  在线部分:
	  img
	  ==ConFiguration:==
	  ///=======================================
	  ///File:ConFiguration.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0610:32:43
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__CONFIGURATION_H__
	  #define__CONFIGURATION_H__
	  #include"Noncopyable.h"
	  #include<string>
	  #include<map>
	  #defineCONFPATH"/home/wtp/spell/server/conf/configure.txt"
	  usingnamespacestd;
	  namespacewd
	  {
	  classConfiguration
	  :publicNoncopyable
	  {
	  public:
	  Configuration(conststring&filePath);
	  ~Configuration()=default;
	  stringgetDictDir()const;
	  stringgetIndexDir()const;
	  stringgetIp()const;
	  stringgetCache()const;
	  unsignedshortgetPort()const;
	  private:
	  string_filePath;
	  map<string,string>_conf;
	  };
	  };
	  template<typenameT>
	  classSingleton
	  {
	  public:
	  template<typename...Args>
	  staticT*getInstance(Args...args)
	  {
	  if(!_pInstance)
	  _pInstance=newT(args...);
	  return_pInstance;
	  }
	  staticvoiddestroy()
	  {
	  if(_pInstance)
	  delete_pInstance;
	  }
	  private:
	  Singleton();
	  ~Singleton();
	  staticT*_pInstance;
	  };
	  template<typenameT>
	  T*Singleton<T>::_pInstance=NULL;
	  #endif
	  ///=======================================
	  ///File:ConFiguration.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0715:24:14
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include"ConFiguration.h"
	  #include<stdlib.h>
	  #include<utility>
	  #include<fstream>
	  #include<iostream>
	  usingnamespacestd;
	  usingnamespacewd;
	  wd::Configuration::Configuration(conststring&filePath)
	  :_filePath(std::move(filePath))
	  {
	  ifstreamifs(_filePath);
	  if(!ifs){
	  cout<<"fileopenerror!"<<endl;
	  }
	  stringkey,value;
	  while(ifs>>key)
	  {
	  ifs>>value;
	  _conf.insert(std::make_pair(key,value));
	  }
	  ifs.close();
	  }
	  stringwd::Configuration::getDictDir()const
	  {
	  autocit=_conf.find("mydict");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  stringwd::Configuration::getIndexDir()const
	  {
	  autocit=_conf.find("myindex");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  stringwd::Configuration::getIp()const
	  {
	  autocit=_conf.find("myip");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  unsignedshortwd::Configuration::getPort()const
	  {
	  autocit=_conf.find("myport");
	  if(cit==_conf.end())
	  return0;
	  else
	  returnatoi(cit->second.c_str());
	  }
	  stringwd::Configuration::getCache()const
	  {
	  autocit=_conf.find("mycache");
	  if(cit==_conf.end())
	  return"";
	  else
	  returncit->second;
	  }
	  ==Acceptor:==
	  ///=======================================
	  ///File:Acceptor.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0523:47:05
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #ifndef__WD_ACCEPTOR_H__
	  #define__WD_ACCEPTOR_H__
	  #include"Socket.h"
	  #include"InetAddress.h"
	  namespacewd
	  {
	  classAcceptor
	  {
	  public:
	  Acceptor(intlistenfd,constInetAddress&addr);
	  voidready();//服务器监听准备
	  intaccept();//服务器接收新连接
	  intfd()const{return_listenSock.fd();}
	  private:
	  voidsetReuseAddr(boolon);//设置地址重用
	  voidsetReusePort(boolon);//设置端口重用
	  voidbind();//绑定
	  voidlisten();//监听
	  Socket_listenSock;
	  InetAddress_addr;
	  };
	  }
	  #endif
	  ///=======================================
	  ///File:Acceptor.cc
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0523:52:12
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
	  #include<iostream>
	  #include"Acceptor.h"
	  #include"SocketUtil.h"
	  namespacewd
	  {
	  Acceptor::Acceptor(intlistenfd,constInetAddress&addr)
	  :_listenSock(listenfd)
	  ,_addr(addr)
	  {}
	  voidAcceptor::ready()
	  {
	  setReuseAddr(true);
	  setReusePort(true);
	  bind();
	  listen();
	  }
	  intAcceptor::accept()
	  {
	  intpeerfd=::accept(_listenSock.fd(),NULL,NULL);
	  if(-1==peerfd)
	  {
	  perror("accepterror!");
	  }
	  returnpeerfd;
	  }
	  voidAcceptor::setReuseAddr(boolflag)
	  {
	  inton=(flag?1:0);
	  if(::setsockopt(_listenSock.fd()
	  ,SOL_SOCKET
	  ,SO_REUSEADDR
	  ,&on
	  ,static_cast<socklen_t>(size_t(on)))==-1)
	  {
	  perror("setsockoptreuseaddrerror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  }
	  voidAcceptor::setReusePort(boolflag)
	  {
	  #ifndefSO_REUSEPORT
	  inton=(flag?1:0);
	  if(::setsockopt(_listenSock.fd()
	  ,SOL_SOCKET
	  ,SO_REUSEADDR
	  ,&on
	  ,static_cast<socklen_t>(size_t(on)))==-1)
	  {
	  perror("setsockoptreuseporterror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  #else
	  if(flag)
	  {
	  fprintf(stderr,"SO_REUSEPORTisnotsupported!\n");
	  }
	  #endif
	  }
	  voidAcceptor::bind()
	  {
	  if(-1==::bind(_listenSock.fd()
	  ,(conststructsockaddr*)_addr.getSockAddrPtr()
	  ,sizeof(InetAddress)))
	  {
	  perror("binderror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  }
	  voidAcceptor::listen()
	  {
	  if(-1==::listen(_listenSock.fd(),10))
	  {
	  perror("listenerror!");
	  ::close(_listenSock.fd());
	  exit(EXIT_FAILURE);
	  }
	  }
	  }
	  #if0
	  intmain()
	  {
	  std::cout<<"Acceptoriscorrect!"<<std::endl;
	  }
	  #endif
	  ==Condition.h:==
	  #ifndef__WD_CONDITION_H__
	  #define__WD_CONDITION_H__
	  #include"Noncopyable.h"
	  #include"MutexLock.h"
	  #include<pthread.h>
	  namespacewd
	  {
	  classCondition
	  :Noncopyable
	  {
	  public:
	  Condition(MutexLock&mutex)
	  :_mutex(mutex)
	  {pthread_cond_init(&_cond,NULL);}
	  ~Condition()
	  {pthread_cond_destroy(&_cond);}
	  voidwait()
	  {pthread_cond_wait(&_cond,_mutex.getMutexLockPtr());}
	  voidnotify()
	  {pthread_cond_signal(&_cond);}
	  voidnotifyAll()
	  {pthread_cond_broadcast(&_cond);}
	  private:
	  pthread_cond_t_cond;
	  MutexLock&_mutex;
	  };
	  }
	  #endif
	  ==Cache:==
	  ///=======================================
	  ///File:Cache.h
	  ///Author:wtptorres(1584292712@qq.com)
	  ///Date:2019-06-0519:52:40
	  ///Dream:Don'tforgetyourdreams!
	  ///======================================
     如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h56751.shtml








