stackmock.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. //
  2. // Copyright (c) 2017-2026, Manticore Software LTD (https://manticoresearch.com)
  3. // Copyright (c) 2001-2016, Andrew Aksyonoff
  4. // Copyright (c) 2008-2016, Sphinx Technologies Inc
  5. // All rights reserved
  6. //
  7. // This program is free software; you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License. You should have
  9. // received a copy of the GPL license along with this program; if you
  10. // did not, you can find it at http://www.gnu.org/
  11. //
  12. #pragma once
  13. #include "client_task_info.h"
  14. #include "coroutine.h"
  15. #include "std/sys.h"
  16. struct StackSizeTuplet_t
  17. {
  18. int m_iCreate;
  19. int m_iEval;
  20. StackSizeTuplet_t() = default;
  21. StackSizeTuplet_t (int iCreate, int iEval)
  22. : m_iCreate { iCreate }
  23. , m_iEval { iEval }
  24. {}
  25. };
  26. template<typename T>
  27. int EvalMaxTreeHeight ( const VecTraits_T<T>& dTree, int iStartNode )
  28. {
  29. CSphVector<std::pair<int, int>> dNodes;
  30. dNodes.Reserve ( dTree.GetLength() / 2 );
  31. int iMaxHeight = 1;
  32. dNodes.Add ( { iStartNode, 1 } );
  33. while ( dNodes.GetLength() )
  34. {
  35. auto tParent = dNodes.Pop();
  36. const auto& tItem = dTree[tParent.first];
  37. iMaxHeight = Max ( iMaxHeight, tParent.second );
  38. if ( tItem.m_iLeft >= 0 )
  39. dNodes.Add ( { tItem.m_iLeft, tParent.second + 1 } );
  40. if ( tItem.m_iRight >= 0 )
  41. dNodes.Add ( { tItem.m_iRight, tParent.second + 1 } );
  42. }
  43. return iMaxHeight;
  44. }
  45. struct StackSizeParams_t
  46. {
  47. int iMaxDepth;
  48. StackSizeTuplet_t tNodeStackSize;
  49. const char* szName;
  50. };
  51. inline std::pair<int, CSphString> EvalStackForExpr ( const StackSizeParams_t & tParams ) noexcept
  52. {
  53. const auto iCREATE = tParams.tNodeStackSize.m_iCreate;
  54. const auto iEVAL = tParams.tNodeStackSize.m_iEval;
  55. int64_t iCalculatedStack = iCREATE+(int64_t) tParams.iMaxDepth*iEVAL;
  56. int64_t iCurStackSize = Threads::MyStackSize ();
  57. // sphWarning ( "used %d, height %d, node %d, start %d, calculated %d, current %d", Threads::GetStackUsed (), iMaxHeight, iEVAL, iCREATE, iCalculatedStack, iCurStackSize );
  58. if ( ( Threads::GetStackUsed ()+iCalculatedStack+( iCREATE >> 1 ) )<=iCurStackSize )
  59. return { -1, {} };
  60. auto iStackNeeded = (int) iCalculatedStack+32*1024;
  61. iStackNeeded = sphRoundUp ( iStackNeeded, GetMemPageSize () ); // round up to memory page.
  62. if ( iStackNeeded>session::GetMaxStackSize () )
  63. return { -1, SphSprintf ( "query %s too complex, not enough stack (thread_stack=%dK or higher required)",
  64. tParams.szName, (int) ( ( iStackNeeded+1024-( iStackNeeded%1024 ) )/1024 ) ) };
  65. return { iStackNeeded, {} };
  66. }
  67. void DetermineNodeItemStackSize ( StringBuilder_c& sExport );
  68. void DetermineFilterItemStackSize ( StringBuilder_c& sExport );
  69. void DetermineMatchStackSize ( StringBuilder_c& sExport );