forked from manticoresoftware/manticoresearch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
exprtraits.h
236 lines (198 loc) · 7.6 KB
/
exprtraits.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
// Copyright (c) 2017-2023, Manticore Software LTD (https://manticoresearch.com)
// Copyright (c) 2001-2016, Andrew Aksyonoff
// Copyright (c) 2008-2016, 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 _exprtraits_
#define _exprtraits_
#include "sphinxexpr.h"
#include "sphinxfilter.h"
#include "conversion.h"
#include "match.h"
#if _WIN32 && !defined(__clang__)
#ifndef NDEBUG
#define EXPR_CLASS_NAME(name) \
{\
const char * szFuncName = __FUNCTION__; \
const char * szClassNameEnd = strstr ( szFuncName, "::" ); \
assert ( szClassNameEnd ); \
const char * szTemplateNameEnd = strstr ( szFuncName, "<" ); \
if ( szTemplateNameEnd ) szClassNameEnd = szTemplateNameEnd; \
size_t iLen = szClassNameEnd-szFuncName; \
assert ( strlen(name)==iLen && "Wrong expression name specified in ::GetHash" ); \
assert ( !strncmp(name, szFuncName, iLen) && "Wrong expression name specified in ::GetHash" ); \
}\
const char * szClassName = name; \
uint64_t uHash = uPrevHash;
#else
#define EXPR_CLASS_NAME(name) \
const char * szClassName = name; \
uint64_t uHash = uPrevHash;
#endif
#else
#define EXPR_CLASS_NAME(name) \
const char * szClassName = name; \
uint64_t uHash = uPrevHash;
#endif
#define EXPR_CLASS_NAME_NOCHECK(name) \
const char * szClassName = name; \
uint64_t uHash = uPrevHash;
#define CALC_DEP_HASHES() sphCalcExprDepHash ( szClassName, this, tSorterSchema, uHash, bDisable );
#define CALC_DEP_HASHES_EX(hash) sphCalcExprDepHash ( szClassName, this, tSorterSchema, uHash^hash, bDisable );
#define CALC_PARENT_HASH() CalcHash ( szClassName, tSorterSchema, uHash, bDisable );
#define CALC_PARENT_HASH_EX(hash) CalcHash ( szClassName, tSorterSchema, uHash^hash, bDisable );
#define CALC_POD_HASH(value) uHash = sphFNV64 ( &value, sizeof(value), uHash );
#define CALC_POD_HASHES(values) uHash = sphFNV64 ( values.Begin(), values.GetLength()*sizeof(values[0]), uHash );
#define CALC_STR_HASH(str,len) uHash = sphFNV64 ( str.cstr(), len, uHash );
#define CALC_CHILD_HASH(child) if (child) uHash = child->GetHash ( tSorterSchema, uHash, bDisable );
#define CALC_CHILD_HASHES(children) ARRAY_FOREACH ( i, children ) if (children[i]) uHash = children[i]->GetHash ( tSorterSchema, uHash, bDisable );
bool IsNumeric ( ESphAttr eType ); // check whether the type is numeric
ESphAttr GetIntType ( int64_t iValue ); // check for type based on int value
ESphAttr WidestType ( ESphAttr a, ESphAttr b ); // get the widest numeric type of the two
uint64_t sphCalcLocatorHash ( const CSphAttrLocator & tLoc, uint64_t uPrevHash );
uint64_t sphCalcExprDepHash ( const char * szTag, ISphExpr * pExpr, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable );
uint64_t sphCalcExprDepHash ( ISphExpr * pExpr, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable );
int GetConstStrOffset ( int64_t iValue );
int GetConstStrLength ( int64_t iValue );
/// list of constants
class ConstList_c
{
public:
CSphVector<int64_t> m_dInts; ///< dword/int64 storage
CSphVector<float> m_dFloats; ///< float storage
ESphAttr m_eRetType { SPH_ATTR_INTEGER }; ///< SPH_ATTR_INTEGER, SPH_ATTR_BIGINT, SPH_ATTR_STRING, or SPH_ATTR_FLOAT
Str_t m_sExpr; ///< pointer to original whole expr. Not owned.
bool m_bPackedStrings = false; // packed string are offset:len from m_dInts over m_sExpr
void Add ( int64_t iValue );
void Add ( float fValue );
};
/// arg-vs-set function (currently, IN or INTERVAL) evaluator traits
template < typename T >
class Expr_ArgVsSet_T : public ISphExpr
{
public:
explicit Expr_ArgVsSet_T ( ISphExpr * pArg ) : m_pArg ( pArg ) { SafeAddRef ( pArg ); }
float Eval ( const CSphMatch & tMatch ) const override { return (float) IntEval ( tMatch ); }
int64_t Int64Eval ( const CSphMatch & tMatch ) const override { return IntEval ( tMatch ); }
void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override
{
if ( m_pArg )
m_pArg->FixupLocator ( pOldSchema, pNewSchema );
}
void Command ( ESphExprCommand eCmd, void * pArg ) override
{
if ( m_pArg )
m_pArg->Command ( eCmd, pArg );
}
protected:
CSphRefcountedPtr<ISphExpr> m_pArg; /* { nullptr }; */
Expr_ArgVsSet_T ( const Expr_ArgVsSet_T & rhs ) : m_pArg ( SafeClone ( rhs.m_pArg ) ) {}
T ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const;
uint64_t CalcHash ( const char * szTag, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable )
{
EXPR_CLASS_NAME_NOCHECK(szTag);
CALC_CHILD_HASH(m_pArg);
return CALC_DEP_HASHES();
}
};
template<> inline int Expr_ArgVsSet_T<int>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
{
return pArg->IntEval ( tMatch );
}
template<> inline DWORD Expr_ArgVsSet_T<DWORD>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
{
return (DWORD)pArg->IntEval ( tMatch );
}
template<> inline float Expr_ArgVsSet_T<float>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
{
return pArg->Eval ( tMatch );
}
template<> inline int64_t Expr_ArgVsSet_T<int64_t>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
{
return pArg->Int64Eval ( tMatch );
}
/// arg-vs-constant-set
template < typename T >
class Expr_ArgVsConstSet_T : public Expr_ArgVsSet_T<T>
{
public:
/// pre-evaluate and dismiss turn points
Expr_ArgVsConstSet_T ( ISphExpr * pArg, const CSphVector<ISphExpr *> & dArgs, int iSkip )
: Expr_ArgVsSet_T<T> ( pArg )
, m_bFloat ( false )
{
CSphMatch tDummy;
for ( int i=iSkip; i<dArgs.GetLength(); ++i )
m_dValues.Add ( Expr_ArgVsSet_T<T>::ExprEval ( dArgs[i], tDummy ) );
CalcValueHash();
}
/// copy that constlist
Expr_ArgVsConstSet_T ( ISphExpr * pArg, ConstList_c * pConsts, bool bKeepFloat )
: Expr_ArgVsSet_T<T> ( pArg )
, m_bFloat ( false )
{
assert ( pConsts );
if ( pConsts->m_eRetType==SPH_ATTR_FLOAT )
{
m_dValues.Reserve ( pConsts->m_dFloats.GetLength() );
if ( !bKeepFloat )
{
for ( float fV : pConsts->m_dFloats )
m_dValues.Add ( (T)fV );
} else
{
m_bFloat = true;
for ( float fV : pConsts->m_dFloats )
m_dValues.Add ( (T) sphF2DW ( fV ) );
}
} else
{
m_dValues.Reserve ( pConsts->m_dInts.GetLength() );
for ( auto iV : pConsts->m_dInts )
m_dValues.Add ( (T)iV );
}
CalcValueHash();
}
/// copy that uservar
Expr_ArgVsConstSet_T ( ISphExpr * pArg, const UservarIntSet_c & pUservar )
: Expr_ArgVsSet_T<T> ( pArg )
, m_bFloat ( false )
{
assert ( pUservar );
m_dValues.Reserve ( pUservar->GetLength() );
for ( auto iV : *pUservar )
m_dValues.Add ( (T)iV );
CalcValueHash();
}
uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override
{
EXPR_CLASS_NAME("Expr_ArgVsConstSet_T");
return CALC_PARENT_HASH();
}
protected:
CSphVector<T> m_dValues;
uint64_t m_uValueHash=0;
bool m_bFloat = false;
Expr_ArgVsConstSet_T ( const Expr_ArgVsConstSet_T & rhs )
: Expr_ArgVsSet_T<T> ( rhs )
, m_dValues ( rhs.m_dValues )
, m_uValueHash ( rhs.m_uValueHash )
, m_bFloat ( rhs.m_bFloat )
{}
void CalcValueHash()
{
ARRAY_FOREACH ( i, m_dValues )
m_uValueHash = sphFNV64 ( &m_dValues[i], sizeof(m_dValues[i]), i ? m_uValueHash : SPH_FNV64_SEED );
}
uint64_t CalcHash ( const char * szTag, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable )
{
return Expr_ArgVsSet_T<T>::CalcHash ( szTag, tSorterSchema, uPrevHash^m_uValueHash, bDisable );
}
};
#endif // _exprtraits_