Skip to content

Commit

Permalink
Merge pull request #19516 from jakesmith/HPCC-33428-init-regex-cache-…
Browse files Browse the repository at this point in the history
…on-demand

HPCC-33428 Avoid [too] early initialization of regex cache
  • Loading branch information
jakesmith authored Feb 13, 2025
2 parents 9bb72ab + c20ae2f commit 6e9f577
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions rtl/eclrtl/eclregex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,13 @@ class RegexCacheEntry
#define DEFAULT_CACHE_MAX_SIZE 500
static CLRUCache<hash64_t, std::shared_ptr<RegexCacheEntry>> compiledStrRegExprCache(DEFAULT_CACHE_MAX_SIZE);
static CriticalSection compiledStrRegExprLock;
static bool compiledCacheEnabled = true;
enum class CompiledCacheState : int
{
Uninitialized = 0,
Disabled = 1,
Enabled = 2
};
static std::atomic<CompiledCacheState> compiledCacheState = CompiledCacheState::Uninitialized;

/**
* @brief Provide an optional override to the maximum cache size for regex patterns.
Expand All @@ -242,7 +248,7 @@ static bool compiledCacheEnabled = true;
* <Software/Globals> section for an optional "regex" subsection with a "cacheSize" attribute
* By default, the maximum cache size is set to 500 patterns. Override with 0 to disable caching.
*/
static void initMaxCacheSize()
static void initMaxCacheSize() // NB: called when compiledStrRegExprLock held
{
#ifdef _CONTAINERIZED
Owned<IPropertyTree> expert;
Expand Down Expand Up @@ -281,11 +287,26 @@ static void initMaxCacheSize()
}

if (cacheMaxSize > 0)
{
compiledStrRegExprCache.setMaxCacheSize(cacheMaxSize);
compiledCacheState = CompiledCacheState::Enabled;
}
else
compiledCacheEnabled = false;
compiledCacheState = CompiledCacheState::Disabled;
}

inline bool isCacheEnabled()
{
if (likely(CompiledCacheState::Enabled == compiledCacheState)) // common case
return true;
else if (compiledCacheState == CompiledCacheState::Uninitialized)
{
CriticalBlock b(compiledStrRegExprLock);
if (CompiledCacheState::Uninitialized == compiledCacheState) // check again now have crit
initMaxCacheSize();
}
return CompiledCacheState::Enabled == compiledCacheState;
}
//---------------------------------------------------------------------------

class CStrRegExprFindInstance final : implements IStrRegExprFindInstance
Expand Down Expand Up @@ -762,7 +783,7 @@ class CCompiledStrRegExpr final : implements ICompiledStrRegExpr
*/
CCompiledStrRegExpr* fetchOrCreateCompiledStrRegExpr(int _regexLength, const char * _regex, bool _isCaseSensitive)
{
if (compiledCacheEnabled)
if (isCacheEnabled())
{
CCompiledStrRegExpr * compiledObjPtr = nullptr;
uint32_t options = (_isCaseSensitive ? 0 : PCRE2_CASELESS);
Expand Down Expand Up @@ -863,7 +884,7 @@ ECLRTL_API void rtlDestroyStrRegExprFindInstance(IStrRegExprFindInstance * findI
*/
CCompiledStrRegExpr* fetchOrCreateCompiledU8StrRegExpr(int _regexLength, const char * _regex, bool _isCaseSensitive)
{
if (compiledCacheEnabled)
if (isCacheEnabled())
{
CCompiledStrRegExpr * compiledObjPtr = nullptr;
unsigned int regexSize = rtlUtf8Size(_regexLength, _regex);
Expand Down Expand Up @@ -1356,7 +1377,7 @@ class CCompiledUStrRegExpr final : implements ICompiledUStrRegExpr
*/
CCompiledUStrRegExpr* fetchOrCreateCompiledUStrRegExpr(int _regexLength, const UChar * _regex, bool _isCaseSensitive)
{
if (compiledCacheEnabled)
if (isCacheEnabled())
{
CCompiledUStrRegExpr * compiledObjPtr = nullptr;
unsigned int regexSize = _regexLength * sizeof(UChar);
Expand Down Expand Up @@ -1470,7 +1491,6 @@ MODULE_INIT(INIT_PRIORITY_ECLRTL_ECLRTL)
pcre2CompileContext16 = pcre2_compile_context_create_16(pcre2GeneralContext16);
pcre2MatchContext16 = pcre2_match_context_create_16(pcre2GeneralContext16);
#endif // _USE_ICU
initMaxCacheSize();
return true;
}

Expand Down

0 comments on commit 6e9f577

Please sign in to comment.