sph04匹配对应的类为RankerState_ProximityBM25Exact_fn
dasf
// sph04, proximity + exact boost
struct RankerState_ProximityBM25Exact_fn
{
BYTE m_uLCS[SPH_MAX_FIELDS];
BYTE m_uCurLCS;
int m_iExpDelta;
DWORD m_uMinExpPos;
int m_iFields;
const int * m_pWeights;
DWORD m_uHeadHit;
DWORD m_uExactHit;
int m_iMaxQuerypos;
bool Init ( int iFields, const int * pWeights, ExtRanker_c * pRanker, CSphString & )
{
memset ( m_uLCS, 0, sizeof(m_uLCS) );
m_uCurLCS = 0;
m_iExpDelta = -INT_MAX;
m_uMinExpPos = 0;
m_iFields = iFields;
m_pWeights = pWeights;
m_uHeadHit = 0;
m_uExactHit = 0;
m_iMaxQuerypos = pRanker->m_iMaxQuerypos;
return true;
}
void Update ( const ExtHit_t * pHlist )
{
// upd LCS
DWORD uField = HITMAN::GetField ( pHlist->m_uHitpos );
int iDelta = HITMAN::GetLCS ( pHlist->m_uHitpos ) - pHlist->m_uQuerypos;
if ( iDelta==m_iExpDelta && HITMAN::GetLCS ( pHlist->m_uHitpos )>=m_uMinExpPos )
{
m_uCurLCS = m_uCurLCS + BYTE(pHlist->m_uWeight);
if ( HITMAN::IsEnd ( pHlist->m_uHitpos ) && (int)pHlist->m_uQuerypos==m_iMaxQuerypos && HITMAN::GetPos ( pHlist->m_uHitpos )==m_iMaxQuerypos )
//将m_uHitpos 右移24位
m_uExactHit |= ( 1UL << HITMAN::GetField ( pHlist->m_uHitpos ) );
} else
{
m_uCurLCS = BYTE(pHlist->m_uWeight);
if ( HITMAN::GetPos ( pHlist->m_uHitpos )==1 )
{
m_uHeadHit |= ( 1UL << HITMAN::GetField ( pHlist->m_uHitpos ) );
if ( HITMAN::IsEnd ( pHlist->m_uHitpos ) && m_iMaxQuerypos==1 )
m_uExactHit |= ( 1UL << HITMAN::GetField ( pHlist->m_uHitpos ) );
}
}
if ( m_uCurLCS>m_uLCS[uField] )
m_uLCS[uField] = m_uCurLCS;
m_iExpDelta = iDelta + pHlist->m_uSpanlen - 1;
m_uMinExpPos = HITMAN::GetLCS ( pHlist->m_uHitpos ) + 1;
}
DWORD Finalize ( const CSphMatch & tMatch )
{
m_uCurLCS = 0;
m_iExpDelta = -1;
DWORD uRank = 0;
for ( int i=0; i<m_iFields; i++ )
{
uRank += ( 4*m_uLCS[i] + 2*((m_uHeadHit>>i)&1) + ((m_uExactHit>>i)&1) )*m_pWeights[i];
m_uLCS[i] = 0;
}
m_uHeadHit = 0;
m_uExactHit = 0;
return tMatch.m_iWeight + uRank*SPH_BM25_SCALE;
}
};
其中update函数用于计算,Finalize函数用于计算uRank排名
update函数中的HITMAN
typedef Hitman_c<8> HITMAN;
/// hit processing tools
/// (because we now allow multiple actual formats within a single storage type!)
template < int FIELD_BITS >
class Hitman_c
{
protected:
enum
{
POS_BITS = 31 - FIELD_BITS,
FIELD_OFF = 32 - FIELD_BITS,
FIELDEND_OFF = 31 - FIELD_BITS,
FIELDEND_MASK = (1UL << POS_BITS),
POS_MASK = (1UL << POS_BITS) - 1,
};
public:
static Hitpos_t Create ( int iField, int iPos )
{
//如果FIED_BITS为8
//取iField的后8位乘以2的24次方+iPos从左边数第9到16位
return ( iField << FIELD_OFF ) + ( iPos & POS_MASK );
}
static Hitpos_t Create ( int iField, int iPos, bool bEnd )
{
//如果FIED_BITS为8
//取iField的后8位乘以2的24次方+(true位2的23次方,false为0)+iPos的从左边数第10到16位
return ( iField << FIELD_OFF ) + ( ((int)bEnd) << FIELDEND_OFF ) + ( iPos & POS_MASK );
}
static inline int GetField ( Hitpos_t uHitpos )
{
//取uHitpos的前8位
return uHitpos >> FIELD_OFF;
}
static inline int GetPos ( Hitpos_t uHitpos )
{
//uHitpos的从左边数第10到16位
return uHitpos & POS_MASK;
}
static inline bool IsEnd ( Hitpos_t uHitpos )
{
//uHitpos的从右边数第24位为1,则未结束
return ( uHitpos & FIELDEND_MASK )!=0;
}
static inline DWORD GetLCS ( Hitpos_t uHitpos )
{
//1左移23位取反与uHitpos进行与操作
return uHitpos & ~FIELDEND_MASK;
}
static void AddPos ( Hitpos_t * pHitpos, int iAdd )
{
// FIXME! add range checks (eg. so that 0:0-1 does not overflow)
*pHitpos += iAdd;
}
static Hitpos_t CreateSum ( Hitpos_t uHitpos, int iAdd )
{
// FIXME! add range checks (eg. so that 0:0-1 does not overflow)
return ( uHitpos+iAdd ) & ~FIELDEND_MASK;
}
static void SetEndMarker ( Hitpos_t * pHitpos )
{
*pHitpos |= FIELDEND_MASK;
}
};
接下来看update函数到底做了什么