Skip to content

Commit

Permalink
Eliminate sorter memleak
Browse files Browse the repository at this point in the history
index fd
{
   type              = rt
   rt_field          = txt
   rt_attr_uint      = foo
   rt_attr_uint      = bar
}

insert into fd (id,foo,bar,txt) values (1,22,33,'bla');
select foo from fd facet bar as foo;

Executing last 'select' returns error; at the same time created sorter leaks.

That fixes #1425
  • Loading branch information
klirichek committed Jun 8, 2020
1 parent ce2d97c commit 26e094a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 47 deletions.
9 changes: 3 additions & 6 deletions src/gtests/gtests_rtstuff.cpp
Expand Up @@ -305,8 +305,7 @@ TEST_P ( RTN, WeightBoundary )
tQuery.m_sQuery = "@title cat";
tQuery.m_pQueryParser = sphCreatePlainQueryParser();

SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema (), nullptr );
tQueueSettings.m_iMaxMatches = DEFAULT_MAX_MATCHES;
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema () );
SphQueueRes_t tRes;
ISphMatchSorter * pSorter = sphCreateQueue ( tQueueSettings, tQuery, tResult.m_sError, tRes, nullptr );
ASSERT_TRUE ( pSorter );
Expand Down Expand Up @@ -410,9 +409,8 @@ TEST_F ( RT, RankerFactors )
CSphMultiQueryArgs tArgs ( 1 );
tArgs.m_uPackedFactorFlags = SPH_FACTOR_ENABLE | SPH_FACTOR_CALC_ATC;

SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema (), nullptr );
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema () );
tQueueSettings.m_bComputeItems = true;
tQueueSettings.m_iMaxMatches = DEFAULT_MAX_MATCHES;
SphQueueRes_t tRes;

for ( auto szQuery : dQueries )
Expand Down Expand Up @@ -566,8 +564,7 @@ TEST_F ( RT, SendVsMerge )
tQuery.m_sQuery = "@title cat";
tQuery.m_pQueryParser = sphCreatePlainQueryParser();

SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema (), nullptr );
tQueueSettings.m_iMaxMatches = DEFAULT_MAX_MATCHES;
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema () );
SphQueueRes_t tRes;
auto pSorter = sphCreateQueue ( tQueueSettings, tQuery, tResult.m_sError, tRes, nullptr );
ASSERT_TRUE ( pSorter );
Expand Down
94 changes: 57 additions & 37 deletions src/searchd.cpp
Expand Up @@ -4932,6 +4932,10 @@ class SearchHandler_c final : public ISphSearchHandler
void CalcPerIndexStats ( int iStart, int iEnd, const CSphVector<DistrServedByAgent_t> & dDistrServedByAgent ) const;
void CalcGlobalStats ( int64_t tmCpu, int64_t tmSubset, int64_t tmLocal, int iStart, int iEnd, const CSphIOStats & tIO, const VecRefPtrsAgentConn_t & dRemotes ) const;
int CreateSorters ( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter*> & dSorters, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const;
int CreateSingleSorters( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter*> & dSorters, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const;
int CreateMultiQueryOrFacetSorters ( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter*> & dSorters, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const;

SphQueueSettings_t MakeQueueSettings ( const CSphIndex * pIndex, int iMaxMatches ) const;
};


Expand Down Expand Up @@ -5553,56 +5557,72 @@ static int GetMaxMatches ( int iQueryMaxMatches, const CSphIndex * pIndex )
}
}

int SearchHandler_c::CreateSorters ( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter*> & dSorters, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const
SphQueueSettings_t SearchHandler_c::MakeQueueSettings ( const CSphIndex * pIndex, int iMaxMatches ) const
{
int iValidSorters = 0;
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema (), m_pProfile );
tQueueSettings.m_bComputeItems = true;
tQueueSettings.m_pUpdate = m_pUpdates;
tQueueSettings.m_pCollection = m_pDelDocs;
tQueueSettings.m_pHook = &m_tHook;
tQueueSettings.m_iMaxMatches = GetMaxMatches ( iMaxMatches, pIndex );
return tQueueSettings;
}

if ( !m_bMultiQueue && !m_bFacetQueue )
{
tQueueRes.m_bAlowMulti = false;
for ( int iQuery=m_iStart; iQuery<=m_iEnd; ++iQuery )
{
CSphQuery & tQuery = m_dQueries[iQuery];

// create queue
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema(), m_pProfile );
tQueueSettings.m_bComputeItems = true;
tQueueSettings.m_pUpdate = m_pUpdates;
tQueueSettings.m_pCollection = m_pDelDocs;
tQueueSettings.m_pHook = &m_tHook;
StrVec_t * pExtra = ( dExtraSchemas.IsEmpty() ? nullptr : dExtraSchemas.begin() + iQuery - m_iStart );
tQueueSettings.m_iMaxMatches = GetMaxMatches ( tQuery.m_iMaxMatches, pIndex );
int SearchHandler_c::CreateMultiQueryOrFacetSorters ( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter *> & dSorters
, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const
{
int iValidSorters = 0;

ISphMatchSorter * pSorter = sphCreateQueue ( tQueueSettings, tQuery, dErrors[iQuery - m_iStart], tQueueRes, pExtra );
if ( !pSorter )
continue;
auto tQueueSettings = MakeQueueSettings ( pIndex, m_dQueries[m_iStart].m_iMaxMatches );
const VecTraits_T<CSphQuery> & dQueries = m_dQueries.Slice ( m_iStart );
sphCreateMultiQueue ( tQueueSettings, dQueries, dSorters, dErrors, tQueueRes, dExtraSchemas );

tQuery.m_bZSlist = tQueueRes.m_bZonespanlist;
dSorters[iQuery-m_iStart] = pSorter;
m_dQueries[m_iStart].m_bZSlist = tQueueRes.m_bZonespanlist;
dSorters.Apply ( [&iValidSorters] ( const ISphMatchSorter * pSorter ) {
if ( pSorter )
++iValidSorters;
}
} else
} );
if ( m_bFacetQueue && iValidSorters<dSorters.GetLength () )
{
CSphString sError;
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema(), m_pProfile );
tQueueSettings.m_bComputeItems = true;
tQueueSettings.m_pUpdate = m_pUpdates;
tQueueSettings.m_pCollection = m_pDelDocs;
tQueueSettings.m_pHook = &m_tHook;
tQueueSettings.m_iMaxMatches = GetMaxMatches ( m_dQueries[m_iStart].m_iMaxMatches, pIndex );
dSorters.Apply ( [] ( ISphMatchSorter *& pSorter ) { SafeDelete (pSorter); } );
return 0;
}
return iValidSorters;
}

int SearchHandler_c::CreateSingleSorters ( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter *> & dSorters
, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const
{
int iValidSorters = 0;
tQueueRes.m_bAlowMulti = false;
for ( int iQuery = m_iStart; iQuery<=m_iEnd; ++iQuery )
{
CSphQuery & tQuery = m_dQueries[iQuery];

const VecTraits_T<CSphQuery> & dQueries = m_dQueries.Slice ( m_iStart );
sphCreateMultiQueue ( tQueueSettings, dQueries, dSorters, dErrors, tQueueRes, dExtraSchemas );
// create queue
auto tQueueSettings = MakeQueueSettings ( pIndex, tQuery.m_iMaxMatches );
StrVec_t * pExtra = ( dExtraSchemas.IsEmpty () ? nullptr : &dExtraSchemas[iQuery-m_iStart] );

m_dQueries[m_iStart].m_bZSlist = tQueueRes.m_bZonespanlist;
dSorters.Apply ( [&iValidSorters] ( const ISphMatchSorter * pSorter ) { if ( pSorter ) iValidSorters++; } );
if ( m_bFacetQueue && iValidSorters<dSorters.GetLength() )
iValidSorters = 0;
}
ISphMatchSorter * pSorter = sphCreateQueue ( tQueueSettings, tQuery, dErrors[iQuery-m_iStart], tQueueRes, pExtra );
if ( !pSorter )
continue;

tQuery.m_bZSlist = tQueueRes.m_bZonespanlist;
dSorters[iQuery-m_iStart] = pSorter;
++iValidSorters;
}
return iValidSorters;
}

int SearchHandler_c::CreateSorters ( const CSphIndex * pIndex, VecTraits_T<ISphMatchSorter *> & dSorters
, VecTraits_T<CSphString> & dErrors, VecTraits_T<StrVec_t> & dExtraSchemas, SphQueueRes_t & tQueueRes ) const
{
if ( m_bMultiQueue || m_bFacetQueue )
return CreateMultiQueryOrFacetSorters ( pIndex, dSorters, dErrors, dExtraSchemas, tQueueRes );
return CreateSingleSorters ( pIndex, dSorters, dErrors, dExtraSchemas, tQueueRes );
}

void SearchHandler_c::RunLocalSearches()
{
m_dQueryIndexStats.Resize ( m_dLocal.GetLength () );
Expand Down
4 changes: 2 additions & 2 deletions src/sphinx.h
Expand Up @@ -3466,7 +3466,7 @@ struct CSphAttrUpdateEx
int m_iAffected = 0; ///< num of updated rows.
};

struct SphQueueSettings_t : public ISphNoncopyable
struct SphQueueSettings_t
{
const ISphSchema & m_tSchema;
CSphQueryProfile * m_pProfiler;
Expand All @@ -3477,7 +3477,7 @@ struct SphQueueSettings_t : public ISphNoncopyable
const CSphFilterSettings * m_pAggrFilter = nullptr;
int m_iMaxMatches = DEFAULT_MAX_MATCHES;

SphQueueSettings_t ( const ISphSchema & tSchema, CSphQueryProfile * pProfiler = nullptr )
explicit SphQueueSettings_t ( const ISphSchema & tSchema, CSphQueryProfile * pProfiler = nullptr )
: m_tSchema ( tSchema )
, m_pProfiler ( pProfiler )
{}
Expand Down
3 changes: 1 addition & 2 deletions src/testrt.cpp
Expand Up @@ -55,8 +55,7 @@ void DoSearch ( CSphIndex * pIndex )
tQuery.m_sQuery = "@title cat";
tQuery.m_pQueryParser = sphCreatePlainQueryParser ();

SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema(), nullptr );
tQueueSettings.m_iMaxMatches = DEFAULT_MAX_MATCHES;
SphQueueSettings_t tQueueSettings ( pIndex->GetMatchSchema() );
CSphString sError;
SphQueueRes_t tRes;
ISphMatchSorter * pSorter = sphCreateQueue ( tQueueSettings, tQuery, sError, tRes, nullptr );
Expand Down

0 comments on commit 26e094a

Please sign in to comment.