注册一个插件
#define NS_SCORER_PLUGIN_REGISTER(name, cls) CTOOL_PLUGIN_REGISTER(ns::SearchScorerPluginMgr, name, cls)
search scorer插件
class SearchScorerPlugin : public Plugin {
public:
// 信息初始化
bool Init() { return true;}
virtual bool Init(RankParam *rank_param, pugi::xml_node &instance_node) {
const char *instance_name = instance_node.attribute("name").value();
name_ = string(instance_name);
const char *output_key = instance_node.attribute("output_key").value();
output_key_ = string(output_key);
return LoadConfig(rank_param, instance_node);
}
// 加载配置文件
virtual bool LoadConfig(RankParam *rank_param, pugi::xml_node &instance_node) = 0;
// 获取ScorerParam
virtual ScorerParam *GetScorerParam(SearchSession *session) {
ScorerParam *param = new ScorerParam(session);
return param;
}
// query预处理
virtual bool ProcessQuery(SearchSession *session, ScorerParam *param) {
return true;
}
// 打分+输出
virtual double ProcessDoc(s::DocValue *doc, ScorerParam *param, int index) {
double score = CalScore(doc, param, index);
if (output_key_.length() > 0) {
doc->SetParam(output_key_, score);
}
return score;
}
// 打分
virtual double CalScore(s::DocValue *doc, ScorerParam *param, int index) = 0;
protected:
string name_;
string output_key_;
};
typedef PluginMgr<SearchScorerPlugin> SearchScorerPluginMgr;
注册插件宏定义
#define CTOOL_PLUGIN_REGISTER(mgr_name, name, cls) \
class RegisterPlugin##name##cls { \
public: \
RegisterPlugin##name##cls () { \
mgr_name::GetInstance()->Register(#name, new cls); \
} \
}; \
RegisterPlugin##name##cls ___g_cRegisterPlugin##name##cls; \
插件基础类
class Plugin {
public:
virtual bool GlobalInit() {return true;} // 全局初始化,进程级,在注册插件时调用
virtual bool Init() {return true;} // 插件初始化接口
virtual void Reset() { } // 重置本插件中间结果
virtual Plugin *NewInstance() = 0; // 创建一个新的插件
};
插件管理器
template<class _Tp>
class PluginMgr {
// 获取新实例
_Tp *NewInstance(string name) {
string temp_name = strings::ToLowerCase(name);
typename map<string, _Tp *>::iterator itr = class_map_.find(temp_name);
if (itr != class_map_.end()) {
_Tp *tp = (_Tp *) itr->second->NewInstance();
if (tp->Init()) {
// 这里要实始化
return tp;
}
delete tp;
}
return NULL;
}
// 获取所有注册名
CStringList GetAllName() {
CStringList name_list;
typename map<string, _Tp *>::iterator itr = class_map_.begin();
for (; itr != class_map_.end(); itr++) {
name_list.push_back(itr->first);
}
return name_list;
}
// 注册插件
void Register(string name, _Tp *cls) {
string temp_name = strings::ToLowerCase(name);
ScopeLock scope_lock(lock_);
class_map_[temp_name] = cls;
}
// 全局初始化
bool GlobalInit() {
ScopeLock scope_lock(lock_);
typename map<string, _Tp *>::iterator itr = class_map_.begin();
for (; itr != class_map_.end(); itr++) {
if (!itr->second->GlobalInit()) { return false; }
}
return true;
}
// 获取单例
static PluginMgr<_Tp> *GetInstance() {
static SingletonHolder<PluginMgr<_Tp> > inst;
return inst.Get();
}
protected:
SpinLock lock_; // 锁
map<string, _Tp *> class_map_; // 类型和实例指针map
};