Browse Source

enrich stack calculation

Extract common path and make it available for generic computations
alexey 2 years ago
parent
commit
bebf42cde2
6 changed files with 50 additions and 20 deletions
  1. 8 2
      src/sphinx.cpp
  2. 16 3
      src/sphinxfilter.cpp
  3. 3 1
      src/sphinxfilter.h
  4. 1 0
      src/sphinxint.h
  5. 1 1
      src/stackmock.cpp
  6. 21 13
      src/stackmock.h

+ 8 - 2
src/sphinx.cpp

@@ -10011,13 +10011,19 @@ Strictly speaking, we need to mock it - create rt, then query - without any disk
  and also on query leaves - reading docs/hits from disk with extra functions for caching, working with fs, profiling, etc. That is oneshot extra budget over calculated expression stuff.
  and also on query leaves - reading docs/hits from disk with extra functions for caching, working with fs, profiling, etc. That is oneshot extra budget over calculated expression stuff.
 */
 */
 
 
-int ConsiderStack ( const struct XQNode_t * pRoot, CSphString & sError )
+
+int ConsiderStackAbsolute ( const struct XQNode_t* pRoot )
 {
 {
 	int iHeight = 0;
 	int iHeight = 0;
 	if ( pRoot )
 	if ( pRoot )
 		iHeight = sphQueryHeightCalc ( pRoot );
 		iHeight = sphQueryHeightCalc ( pRoot );
 
 
-	auto iStackNeed = iHeight * SPH_EXTNODE_STACK_SIZE + SPH_EXTRA_BUDGET;
+	return iHeight * SPH_EXTNODE_STACK_SIZE + SPH_EXTRA_BUDGET;
+}
+
+int ConsiderStack ( const struct XQNode_t * pRoot, CSphString & sError )
+{
+	auto iStackNeed = ConsiderStackAbsolute ( pRoot );
 	int64_t iQueryStack = Threads::GetStackUsed() + iStackNeed;
 	int64_t iQueryStack = Threads::GetStackUsed() + iStackNeed;
 //	sphWarning ( "Stack used %d, need %d (%d * %d + %d), sum %d, have %d", (int)Threads::GetStackUsed(), iStackNeed, iHeight, SPH_EXTNODE_STACK_SIZE, SPH_EXTRA_BUDGET, (int)iQueryStack, Threads::MyStackSize() );
 //	sphWarning ( "Stack used %d, need %d (%d * %d + %d), sum %d, have %d", (int)Threads::GetStackUsed(), iStackNeed, iHeight, SPH_EXTNODE_STACK_SIZE, SPH_EXTRA_BUDGET, (int)iQueryStack, Threads::MyStackSize() );
 	auto iMyStackSize = Threads::MyStackSize ();
 	auto iMyStackSize = Threads::MyStackSize ();

+ 16 - 3
src/sphinxfilter.cpp

@@ -1977,11 +1977,24 @@ static std::unique_ptr<ISphFilter> ReorderAndCombine ( CSphVector<FilterInfo_t>
 }
 }
 
 
 static int g_iFilterStackSize = 200;
 static int g_iFilterStackSize = 200;
+static int g_iStartFilterStackSize = 6*1024;
 
 
-void SetFilterStackItemSize ( int iSize )
+void SetFilterStackItemSize ( std::pair<int,int> tSize )
 {
 {
-	if ( iSize>g_iFilterStackSize )
-		g_iFilterStackSize = iSize;
+	if ( tSize.first>g_iFilterStackSize )
+		g_iFilterStackSize = tSize.first;
+	if ( tSize.second > g_iStartFilterStackSize )
+		g_iStartFilterStackSize = tSize.second;
+}
+
+int GetFilterStackItemSize()
+{
+	return g_iFilterStackSize;
+}
+
+int GetStartFilterStackItemSize()
+{
+	return g_iStartFilterStackSize;
 }
 }
 
 
 bool sphCreateFilters ( CreateFilterContext_t & tCtx, CSphString & sError, CSphString & sWarning )
 bool sphCreateFilters ( CreateFilterContext_t & tCtx, CSphString & sError, CSphString & sWarning )

+ 3 - 1
src/sphinxfilter.h

@@ -101,7 +101,9 @@ void OptimizeFilters ( CSphVector<CSphFilterSettings> & dFilters );
 
 
 CSphString FilterType2Str ( ESphFilter eFilterType );
 CSphString FilterType2Str ( ESphFilter eFilterType );
 
 
-void SetFilterStackItemSize ( int iSize );
+void SetFilterStackItemSize ( std::pair<int,int> );
+int GetFilterStackItemSize();
+int GetStartFilterStackItemSize();
 
 
 // fwd
 // fwd
 
 

+ 1 - 0
src/sphinxint.h

@@ -874,6 +874,7 @@ void			SetExtNodeStackSize ( int iDelta, int iExtra );
 // returns -1: query might be run on current frame
 // returns -1: query might be run on current frame
 // other positive: necessary free size of stack
 // other positive: necessary free size of stack
 int				ConsiderStack ( const struct XQNode_t * pRoot, CSphString & sError );
 int				ConsiderStack ( const struct XQNode_t * pRoot, CSphString & sError );
+int				ConsiderStackAbsolute ( const struct XQNode_t* pRoot );
 void			sphTransformExtendedQuery ( XQNode_t ** ppNode, const CSphIndexSettings & tSettings, bool bHasBooleanOptimization, const ISphKeywordsStat * pKeywords );
 void			sphTransformExtendedQuery ( XQNode_t ** ppNode, const CSphIndexSettings & tSettings, bool bHasBooleanOptimization, const ISphKeywordsStat * pKeywords );
 void			TransformAotFilter ( XQNode_t * pNode, const CSphWordforms * pWordforms, const CSphIndexSettings& tSettings );
 void			TransformAotFilter ( XQNode_t * pNode, const CSphWordforms * pWordforms, const CSphIndexSettings& tSettings );
 bool			sphMerge ( const CSphIndex * pDst, const CSphIndex * pSrc, VecTraits_T<CSphFilterSettings> dFilters, CSphIndexProgress & tProgress, CSphString& sError );
 bool			sphMerge ( const CSphIndex * pDst, const CSphIndex * pSrc, VecTraits_T<CSphFilterSettings> dFilters, CSphIndexProgress & tProgress, CSphString& sError );

+ 1 - 1
src/stackmock.cpp

@@ -427,7 +427,7 @@ void EvalExprStackSize_c::PublishValue ( std::pair<int, int> iStack )
 
 
 void FilterCreationMeasureStack_c::PublishValue ( std::pair<int, int> iStack )
 void FilterCreationMeasureStack_c::PublishValue ( std::pair<int, int> iStack )
 {
 {
-	SetFilterStackItemSize ( iStack.first );
+	SetFilterStackItemSize ( iStack );
 }
 }
 
 
 void FullTextStackSize_c::PublishValue ( std::pair<int, int> iStack )
 void FullTextStackSize_c::PublishValue ( std::pair<int, int> iStack )

+ 21 - 13
src/stackmock.h

@@ -17,6 +17,26 @@
 
 
 using StackSizeTuplet_t = std::pair<int,int>; // create, eval
 using StackSizeTuplet_t = std::pair<int,int>; // create, eval
 
 
+template<typename T>
+int EvalMaxTreeHeight ( const VecTraits_T<T>& dTree, int iStartNode )
+{
+	CSphVector<std::pair<int, int>> dNodes;
+	dNodes.Reserve ( dTree.GetLength() / 2 );
+	int iMaxHeight = 1;
+	dNodes.Add ( { iStartNode, 1 } );
+	while ( dNodes.GetLength() )
+	{
+		auto tParent = dNodes.Pop();
+		const auto& tItem = dTree[tParent.first];
+		iMaxHeight = Max ( iMaxHeight, tParent.second );
+		if ( tItem.m_iLeft >= 0 )
+			dNodes.Add ( { tItem.m_iLeft, tParent.second + 1 } );
+		if ( tItem.m_iRight >= 0 )
+			dNodes.Add ( { tItem.m_iRight, tParent.second + 1 } );
+	}
+	return iMaxHeight;
+}
+
 template <typename T>
 template <typename T>
 bool EvalStackForTree ( const VecTraits_T<T> & dTree, int iStartNode, StackSizeTuplet_t tNodeStackSize, int iTreeSizeThresh, int & iStackNeeded, const char * szName, CSphString & sError )
 bool EvalStackForTree ( const VecTraits_T<T> & dTree, int iStartNode, StackSizeTuplet_t tNodeStackSize, int iTreeSizeThresh, int & iStackNeeded, const char * szName, CSphString & sError )
 {
 {
@@ -27,19 +47,7 @@ bool EvalStackForTree ( const VecTraits_T<T> & dTree, int iStartNode, StackSizeT
 	if ( dTree.GetLength()<=iTreeSizeThresh )
 	if ( dTree.GetLength()<=iTreeSizeThresh )
 		return true;
 		return true;
 
 
-	CSphVector<std::pair<int,int>> dNodes;
-	dNodes.Reserve ( dTree.GetLength()/2 );
-	int iMaxHeight = 1;
-	dNodes.Add ( { iStartNode, 1 } );
-	while ( dNodes.GetLength() )
-	{
-		auto tParent = dNodes.Pop();
-		const auto & tItem = dTree[tParent.first];
-		iMaxHeight = Max ( iMaxHeight, tParent.second );
-		if ( tItem.m_iLeft>=0 )		dNodes.Add ( { tItem.m_iLeft,  tParent.second+1 } );
-		if ( tItem.m_iRight>=0 )	dNodes.Add ( { tItem.m_iRight, tParent.second+1 } );
-	}
-
+	int iMaxHeight = EvalMaxTreeHeight ( dTree, iStartNode );
 	iCalculatedStack = Threads::GetStackUsed() + iMaxHeight* std::get<CREATE> ( tNodeStackSize );
 	iCalculatedStack = Threads::GetStackUsed() + iMaxHeight* std::get<CREATE> ( tNodeStackSize );
 
 
 	if ( iCalculatedStack<=iCurStackSize )
 	if ( iCalculatedStack<=iCurStackSize )