1 //
2 // $Id$
3 //
4 
5 //
6 // Copyright (c) 2001-2016, Andrew Aksyonoff
7 // Copyright (c) 2008-2016, Sphinx Technologies Inc
8 // All rights reserved
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License. You should have
12 // received a copy of the GPL license along with this program; if you
13 // did not, you can find it at http://www.gnu.org/
14 //
15 
16 #ifndef _sphinxplugin_
17 #define _sphinxplugin_
18 
19 #include "sphinxstd.h"
20 extern "C"
21 {
22 #include "sphinxudf.h"
23 }
24 
25 //////////////////////////////////////////////////////////////////////////
26 
27 // call prototypes for all the known external plugin symbol types
28 
29 typedef int				(*PluginVer_fn)		();
30 typedef void			(*PluginReinit_fn)	();
31 
32 typedef int				(*UdfInit_fn)		( SPH_UDF_INIT * init, SPH_UDF_ARGS * args, char * error );
33 typedef void			(*UdfDeinit_fn)		( SPH_UDF_INIT * init );
34 
35 typedef int				(*RankerInit_fn)		( void ** userdata, SPH_RANKER_INIT * ranker, char * error );
36 typedef void			(*RankerUpdate_fn)		( void * userdata, SPH_RANKER_HIT * hit );
37 typedef unsigned int	(*RankerFinalize_fn)	( void * userdata, int match_weight );
38 typedef int				(*RankerDeinit_fn)		( void * userdata );
39 
40 typedef int				(*TokenFilterInit_fn)			( void ** userdata, int num_fields, const char ** field_names, const char * options, char * error_message );
41 typedef int				(*TokenFilterBeginDocument_fn)	( void * userdata, const char * options, char * error_message );
42 typedef void			(*TokenFilterBeginField_fn)		( void * userdata, int field_index );
43 typedef char *			(*TokenFilterPushToken_fn)		( void * userdata, char * token, int * extra, int * delta );
44 typedef char *			(*TokenFilterGetExtraToken_fn)	( void * userdata, int * delta );
45 typedef int				(*TokenFilterEndField_fn)		( void * userdata );
46 typedef void			(*TokenFilterDeinit_fn)			( void * userdata );
47 
48 typedef int				(*QueryTokenFilterInit_fn)		( void ** userdata, int max_len, const char * options, char * error );
49 typedef void			(*QueryTokenFilterPreMorph_fn)	( void * userdata, char * token, int * stopword );
50 typedef int				(*QueryTokenFilterPostMorph_fn)	( void * userdata, char * token, int * stopword );
51 typedef void			(*QueryTokenFilterDeinit_fn)	( void * userdata );
52 
53 //////////////////////////////////////////////////////////////////////////
54 
55 /// forward refs
56 struct PluginLib_t;
57 class CSphWriter;
58 
59 /// plugin types
60 /// MUST be in sync with sphPluginSaveState(), sphPluginGetType()
61 enum PluginType_e
62 {
63 	PLUGIN_FUNCTION = 0,
64 	PLUGIN_RANKER,
65 	PLUGIN_INDEX_TOKEN_FILTER,
66 	PLUGIN_QUERY_TOKEN_FILTER,
67 
68 	PLUGIN_TOTAL
69 };
70 
71 /// common plugin descriptor part
72 class PluginDesc_c
73 {
74 public:
75 	PluginLib_t *		m_pLib;			///< library descriptor (pointer to library hash value)
76 	const CSphString *	m_pLibName;		///< library name (pointer to library hash key; filename only, no path!)
77 	mutable int			m_iUserCount;	///< number of active users currently working this function
78 	bool				m_bToDrop;		///< scheduled for DROP; do not use
79 
PluginDesc_c()80 	PluginDesc_c()
81 		: m_pLib ( NULL )
82 		, m_pLibName ( NULL )
83 		, m_iUserCount ( 0 )
84 		, m_bToDrop ( false )
85 	{}
~PluginDesc_c()86 	virtual				~PluginDesc_c() {}
87 	virtual void		Use() const;
88 	virtual void		Release() const;
89 };
90 
91 /// registered user-defined function descriptor
92 class PluginUDF_c : public PluginDesc_c
93 {
94 public:
95 	ESphAttr			m_eRetType;		///< function type, currently FLOAT or INT
96 	UdfInit_fn			m_fnInit;		///< per-query init function, mandatory
97 	UdfDeinit_fn		m_fnDeinit;		///< per-query deinit function, optional
98 	void *				m_fnFunc;		///< per-row worker function, mandatory
99 
PluginUDF_c(ESphAttr eRetType)100 	PluginUDF_c ( ESphAttr eRetType )
101 		: m_eRetType ( eRetType )
102 	{}
103 };
104 
105 /// registered user-defined ranker descriptor
106 class PluginRanker_c : public PluginDesc_c
107 {
108 public:
109 	RankerInit_fn		m_fnInit;		///< init function (called once when ranker is created), optional
110 	RankerUpdate_fn		m_fnUpdate;		///< per-hit update function, optional
111 	RankerFinalize_fn	m_fnFinalize;	///< per-document finalize function, mandatory
112 	RankerDeinit_fn		m_fnDeinit;		///< deinit function (called once when ranker is destroyed), optional
113 };
114 
115 /// registered user-defined token filter descriptor
116 class PluginTokenFilter_c : public PluginDesc_c
117 {
118 public:
119 	TokenFilterInit_fn			m_fnInit;
120 	TokenFilterBeginDocument_fn	m_fnBeginDocument;
121 	TokenFilterBeginField_fn	m_fnBeginField;
122 	TokenFilterPushToken_fn		m_fnPushToken;
123 	TokenFilterGetExtraToken_fn	m_fnGetExtraToken;
124 	TokenFilterEndField_fn		m_fnEndField;
125 	TokenFilterDeinit_fn		m_fnDeinit;
126 };
127 
128 /// registered user-defined token filter descriptor
129 class PluginQueryTokenFilter_c : public PluginDesc_c
130 {
131 public:
132 	QueryTokenFilterInit_fn			m_fnInit;
133 	QueryTokenFilterPreMorph_fn		m_fnPreMorph;
134 	QueryTokenFilterPostMorph_fn	m_fnPostMorph;
135 	QueryTokenFilterDeinit_fn		m_fnDeinit;
136 };
137 
138 /// human readable plugin description (basically for SHOW PLUGINS)
139 struct PluginInfo_t
140 {
141 	PluginType_e	m_eType;	///< plugin type
142 	CSphString		m_sName;	///< plugin name
143 	CSphString		m_sLib;		///< dynamic library file name
144 	int				m_iUsers;	///< current user threads count (just because we can)
145 	CSphString		m_sExtra;	///< extra plugin info (eg UDF return type)
146 };
147 
148 //////////////////////////////////////////////////////////////////////////
149 
150 /// plugin type to human readable name
151 extern const char * g_dPluginTypes[PLUGIN_TOTAL];
152 
153 //////////////////////////////////////////////////////////////////////////
154 
155 /// initialize plugin manager
156 void sphPluginInit ( const char * sDir );
157 
158 /// enable/disable dynamic CREATE/DROP
159 void sphPluginLock ( bool bLocked );
160 
161 /// save SphinxQL state (ie. all active functions)
162 void sphPluginSaveState ( CSphWriter & tWriter );
163 
164 /// call reinit function in every plugin library
165 void sphPluginReinit();
166 
167 /// convert plugin type string to enum
168 PluginType_e sphPluginGetType ( const CSphString & s );
169 
170 /// splits and checks plugin spec string in "mylib.dll:plugname[:options]" format
171 bool sphPluginParseSpec ( const CSphString & sParams, CSphVector<CSphString> & dParams, CSphString & sError );
172 
173 /// check if plugin exists (but do not acquire an instance)
174 bool sphPluginExists ( PluginType_e eType, const char * sName );
175 
176 /// create plugin
177 /// that is, load the library if not yet loaded, import the symbols, register the plugin internally
178 /// eRetType is only used for UDF type; might wanna change it to (void*) and pass a generic argument instead
179 bool sphPluginCreate ( const char * sLib, PluginType_e eType, const char * sName, ESphAttr eUDFRetType, CSphString & sError );
180 
181 /// get plugin instance descriptor by name
182 /// WARNING, increments users count, so non-NULL pointers you get back need to be Release()d
183 PluginDesc_c * sphPluginGet ( PluginType_e eType, const char * sName );
184 
185 /// acquire plugin instance; get-or-create-and-get essentially
186 /// WARNING, increments users count, so non-NULL pointers you get back need to be Release()d
187 PluginDesc_c * sphPluginAcquire ( const char * sLib, PluginType_e eType, const char * sName, CSphString & sError );
188 
189 /// drop plugin by name
190 bool sphPluginDrop ( PluginType_e eType, const char * sName, CSphString & sError );
191 
192 /// list all plugins (basically for SHOW PLUGINS)
193 void sphPluginList ( CSphVector<PluginInfo_t> & dResult );
194 
195 #endif // _sphinxplugin_
196 
197 //
198 // $Id$
199 //
200