// // $Id$ // // // Copyright (c) 2001-2015, Andrew Aksyonoff // Copyright (c) 2008-2015, Sphinx Technologies Inc // All rights reserved // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License. You should have // received a copy of the GPL license along with this program; if you // did not, you can find it at http://www.gnu.org/ // #ifndef _sphinxplugin_ #define _sphinxplugin_ #include "sphinxstd.h" extern "C" { #include "sphinxudf.h" } ////////////////////////////////////////////////////////////////////////// // call prototypes for all the known external plugin symbol types typedef int (*PluginVer_fn) (); typedef void (*PluginReinit_fn) (); typedef int (*UdfInit_fn) ( SPH_UDF_INIT * init, SPH_UDF_ARGS * args, char * error ); typedef void (*UdfDeinit_fn) ( SPH_UDF_INIT * init ); typedef int (*RankerInit_fn) ( void ** userdata, SPH_RANKER_INIT * ranker, char * error ); typedef void (*RankerUpdate_fn) ( void * userdata, SPH_RANKER_HIT * hit ); typedef unsigned int (*RankerFinalize_fn) ( void * userdata, int match_weight ); typedef int (*RankerDeinit_fn) ( void * userdata ); typedef int (*TokenFilterInit_fn) ( void ** userdata, int num_fields, const char ** field_names, const char * options, char * error_message ); typedef int (*TokenFilterBeginDocument_fn) ( void * userdata, const char * options, char * error_message ); typedef void (*TokenFilterBeginField_fn) ( void * userdata, int field_index ); typedef char * (*TokenFilterPushToken_fn) ( void * userdata, char * token, int * extra, int * delta ); typedef char * (*TokenFilterGetExtraToken_fn) ( void * userdata, int * delta ); typedef int (*TokenFilterEndField_fn) ( void * userdata ); typedef void (*TokenFilterDeinit_fn) ( void * userdata ); typedef int (*QueryTokenFilterInit_fn) ( void ** userdata, int max_len, const char * options, char * error ); typedef void (*QueryTokenFilterPreMorph_fn) ( void * userdata, char * token, int * stopword ); typedef int (*QueryTokenFilterPostMorph_fn) ( void * userdata, char * token, int * stopword ); typedef void (*QueryTokenFilterDeinit_fn) ( void * userdata ); ////////////////////////////////////////////////////////////////////////// /// forward refs struct PluginLib_t; class CSphWriter; /// plugin types /// MUST be in sync with sphPluginSaveState(), sphPluginGetType() enum PluginType_e { PLUGIN_FUNCTION = 0, PLUGIN_RANKER, PLUGIN_INDEX_TOKEN_FILTER, PLUGIN_QUERY_TOKEN_FILTER, PLUGIN_TOTAL }; /// common plugin descriptor part class PluginDesc_c { public: PluginLib_t * m_pLib; ///< library descriptor (pointer to library hash value) const CSphString * m_pLibName; ///< library name (pointer to library hash key; filename only, no path!) mutable int m_iUserCount; ///< number of active users currently working this function bool m_bToDrop; ///< scheduled for DROP; do not use PluginDesc_c() : m_pLib ( NULL ) , m_pLibName ( NULL ) , m_iUserCount ( 0 ) , m_bToDrop ( false ) {} virtual ~PluginDesc_c() {} virtual void Use() const; virtual void Release() const; }; /// registered user-defined function descriptor class PluginUDF_c : public PluginDesc_c { public: ESphAttr m_eRetType; ///< function type, currently FLOAT or INT UdfInit_fn m_fnInit; ///< per-query init function, mandatory UdfDeinit_fn m_fnDeinit; ///< per-query deinit function, optional void * m_fnFunc; ///< per-row worker function, mandatory PluginUDF_c ( ESphAttr eRetType ) : m_eRetType ( eRetType ) {} }; /// registered user-defined ranker descriptor class PluginRanker_c : public PluginDesc_c { public: RankerInit_fn m_fnInit; ///< init function (called once when ranker is created), optional RankerUpdate_fn m_fnUpdate; ///< per-hit update function, optional RankerFinalize_fn m_fnFinalize; ///< per-document finalize function, mandatory RankerDeinit_fn m_fnDeinit; ///< deinit function (called once when ranker is destroyed), optional }; /// registered user-defined token filter descriptor class PluginTokenFilter_c : public PluginDesc_c { public: TokenFilterInit_fn m_fnInit; TokenFilterBeginDocument_fn m_fnBeginDocument; TokenFilterBeginField_fn m_fnBeginField; TokenFilterPushToken_fn m_fnPushToken; TokenFilterGetExtraToken_fn m_fnGetExtraToken; TokenFilterEndField_fn m_fnEndField; TokenFilterDeinit_fn m_fnDeinit; }; /// registered user-defined token filter descriptor class PluginQueryTokenFilter_c : public PluginDesc_c { public: QueryTokenFilterInit_fn m_fnInit; QueryTokenFilterPreMorph_fn m_fnPreMorph; QueryTokenFilterPostMorph_fn m_fnPostMorph; QueryTokenFilterDeinit_fn m_fnDeinit; }; /// human readable plugin description (basically for SHOW PLUGINS) struct PluginInfo_t { PluginType_e m_eType; ///< plugin type CSphString m_sName; ///< plugin name CSphString m_sLib; ///< dynamic library file name int m_iUsers; ///< current user threads count (just because we can) CSphString m_sExtra; ///< extra plugin info (eg UDF return type) }; ////////////////////////////////////////////////////////////////////////// /// plugin type to human readable name extern const char * g_dPluginTypes[PLUGIN_TOTAL]; ////////////////////////////////////////////////////////////////////////// /// initialize plugin manager void sphPluginInit ( const char * sDir ); /// enable/disable dynamic CREATE/DROP void sphPluginLock ( bool bLocked ); /// save SphinxQL state (ie. all active functions) void sphPluginSaveState ( CSphWriter & tWriter ); /// call reinit function in every plugin library void sphPluginReinit(); /// convert plugin type string to enum PluginType_e sphPluginGetType ( const CSphString & s ); /// splits and checks plugin spec string in "mylib.dll:plugname[:options]" format bool sphPluginParseSpec ( const CSphString & sParams, CSphVector<CSphString> & dParams, CSphString & sError ); /// check if plugin exists (but do not acquire an instance) bool sphPluginExists ( PluginType_e eType, const char * sName ); /// create plugin /// that is, load the library if not yet loaded, import the symbols, register the plugin internally /// eRetType is only used for UDF type; might wanna change it to (void*) and pass a generic argument instead bool sphPluginCreate ( const char * sLib, PluginType_e eType, const char * sName, ESphAttr eUDFRetType, CSphString & sError ); /// get plugin instance descriptor by name /// WARNING, increments users count, so non-NULL pointers you get back need to be Release()d PluginDesc_c * sphPluginGet ( PluginType_e eType, const char * sName ); /// acquire plugin instance; get-or-create-and-get essentially /// WARNING, increments users count, so non-NULL pointers you get back need to be Release()d PluginDesc_c * sphPluginAcquire ( const char * sLib, PluginType_e eType, const char * sName, CSphString & sError ); /// drop plugin by name bool sphPluginDrop ( PluginType_e eType, const char * sName, CSphString & sError ); /// list all plugins (basically for SHOW PLUGINS) void sphPluginList ( CSphVector<PluginInfo_t> & dResult ); #endif // _sphinxplugin_ // // $Id$ //