ragc_core/
env_cache.rs

1//! Cached environment variable lookups for debug flags
2//! These are checked once at startup and cached, avoiding ~30% CPU overhead from getenv calls
3
4use std::sync::OnceLock;
5
6// Each flag has a unique static cache and a public accessor function
7
8static DEBUG_LZ_CACHE: OnceLock<bool> = OnceLock::new();
9pub fn debug_lz() -> bool {
10    *DEBUG_LZ_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_LZ").is_ok())
11}
12
13static DEBUG_REF_CACHE: OnceLock<bool> = OnceLock::new();
14pub fn debug_ref() -> bool {
15    *DEBUG_REF_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_REF").is_ok())
16}
17
18static DEBUG_LZ_DECODE_CACHE: OnceLock<bool> = OnceLock::new();
19pub fn debug_lz_decode() -> bool {
20    *DEBUG_LZ_DECODE_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_LZ_DECODE").is_ok())
21}
22
23static DEBUG_LZ_DECODE_FULL_CACHE: OnceLock<bool> = OnceLock::new();
24pub fn debug_lz_decode_full() -> bool {
25    *DEBUG_LZ_DECODE_FULL_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_LZ_DECODE_FULL").is_ok())
26}
27
28static DEBUG_REF_WRITE_CACHE: OnceLock<bool> = OnceLock::new();
29pub fn debug_ref_write() -> bool {
30    *DEBUG_REF_WRITE_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_REF_WRITE").is_ok())
31}
32
33static DEBUG_COMPRESSION_SIZES_CACHE: OnceLock<bool> = OnceLock::new();
34pub fn debug_compression_sizes() -> bool {
35    *DEBUG_COMPRESSION_SIZES_CACHE
36        .get_or_init(|| std::env::var("RAGC_DEBUG_COMPRESSION_SIZES").is_ok())
37}
38
39static DEBUG_IS_DIR_CACHE: OnceLock<bool> = OnceLock::new();
40pub fn debug_is_dir() -> bool {
41    *DEBUG_IS_DIR_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_IS_DIR").is_ok())
42}
43
44static DEBUG_SPLIT_CACHE: OnceLock<bool> = OnceLock::new();
45pub fn debug_split() -> bool {
46    *DEBUG_SPLIT_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_SPLIT").is_ok())
47}
48
49static DEBUG_SPLIT_FIND_CACHE: OnceLock<bool> = OnceLock::new();
50pub fn debug_split_find() -> bool {
51    *DEBUG_SPLIT_FIND_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_SPLIT_FIND").is_ok())
52}
53
54static DEBUG_SPLIT_REF_CACHE: OnceLock<bool> = OnceLock::new();
55pub fn debug_split_ref() -> bool {
56    *DEBUG_SPLIT_REF_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_SPLIT_REF").is_ok())
57}
58
59static DEBUG_SPLIT_MAP_CACHE: OnceLock<bool> = OnceLock::new();
60pub fn debug_split_map() -> bool {
61    *DEBUG_SPLIT_MAP_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_SPLIT_MAP").is_ok())
62}
63
64static DEBUG_TERM_CACHE: OnceLock<bool> = OnceLock::new();
65pub fn debug_term() -> bool {
66    *DEBUG_TERM_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_TERM").is_ok())
67}
68
69static DEBUG_FALLBACK2_CACHE: OnceLock<bool> = OnceLock::new();
70pub fn debug_fallback2() -> bool {
71    *DEBUG_FALLBACK2_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_FALLBACK2").is_ok())
72}
73
74static DEBUG_SEGMENT_COVERAGE_CACHE: OnceLock<bool> = OnceLock::new();
75pub fn debug_segment_coverage() -> bool {
76    *DEBUG_SEGMENT_COVERAGE_CACHE
77        .get_or_init(|| std::env::var("RAGC_DEBUG_SEGMENT_COVERAGE").is_ok())
78}
79
80static DEBUG_ENDPOS_CACHE: OnceLock<bool> = OnceLock::new();
81pub fn debug_endpos() -> bool {
82    *DEBUG_ENDPOS_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_ENDPOS").is_ok())
83}
84
85static DEBUG_OVERLAP_CACHE: OnceLock<bool> = OnceLock::new();
86pub fn debug_overlap() -> bool {
87    *DEBUG_OVERLAP_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_OVERLAP").is_ok())
88}
89
90static TRACE_ALL_SPLITS_CACHE: OnceLock<bool> = OnceLock::new();
91pub fn trace_all_splits() -> bool {
92    *TRACE_ALL_SPLITS_CACHE.get_or_init(|| std::env::var("RAGC_TRACE_ALL_SPLITS").is_ok())
93}
94
95static TRACE_GROUPS_CACHE: OnceLock<bool> = OnceLock::new();
96pub fn trace_groups() -> bool {
97    *TRACE_GROUPS_CACHE.get_or_init(|| std::env::var("RAGC_TRACE_GROUPS").is_ok())
98}
99
100static TRACE_GROUP_CACHE: OnceLock<bool> = OnceLock::new();
101pub fn trace_group() -> bool {
102    *TRACE_GROUP_CACHE.get_or_init(|| std::env::var("RAGC_TRACE_GROUP").is_ok())
103}
104
105static TEST_LZ_ENCODING_CACHE: OnceLock<bool> = OnceLock::new();
106pub fn test_lz_encoding() -> bool {
107    *TEST_LZ_ENCODING_CACHE.get_or_init(|| std::env::var("RAGC_TEST_LZ_ENCODING").is_ok())
108}
109
110static ASSERT_VERBOSE_CACHE: OnceLock<bool> = OnceLock::new();
111pub fn assert_verbose() -> bool {
112    *ASSERT_VERBOSE_CACHE.get_or_init(|| std::env::var("RAGC_ASSERT_VERBOSE").is_ok())
113}
114
115static DEBUG_DECODE_CACHE: OnceLock<bool> = OnceLock::new();
116pub fn debug_decode() -> bool {
117    *DEBUG_DECODE_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_DECODE").is_ok())
118}
119
120static DEBUG_RECONSTRUCT_CACHE: OnceLock<bool> = OnceLock::new();
121pub fn debug_reconstruct() -> bool {
122    *DEBUG_RECONSTRUCT_CACHE.get_or_init(|| std::env::var("RAGC_DEBUG_RECONSTRUCT").is_ok())
123}
124
125// Boolean env vars with specific value checks
126static DEBUG_LZ_ENABLED_CACHE: OnceLock<bool> = OnceLock::new();
127pub fn debug_lz_enabled() -> bool {
128    *DEBUG_LZ_ENABLED_CACHE
129        .get_or_init(|| std::env::var("RAGC_DEBUG_LZ").unwrap_or_default() == "1")
130}
131
132static SPLIT_ALL_CACHE: OnceLock<bool> = OnceLock::new();
133pub fn split_all() -> bool {
134    *SPLIT_ALL_CACHE.get_or_init(|| std::env::var("RAGC_SPLIT_ALL").unwrap_or_default() == "1")
135}
136
137static SPLIT_CREATE_GROUPS_CACHE: OnceLock<bool> = OnceLock::new();
138pub fn split_create_groups() -> bool {
139    *SPLIT_CREATE_GROUPS_CACHE
140        .get_or_init(|| std::env::var("RAGC_SPLIT_CREATE_GROUPS").unwrap_or_default() == "1")
141}
142
143static GROUP_LOG_CACHE: OnceLock<bool> = OnceLock::new();
144pub fn group_log() -> bool {
145    *GROUP_LOG_CACHE.get_or_init(|| std::env::var("RAGC_GROUP_LOG").unwrap_or_default() == "1")
146}
147
148static DEBUG_FALLBACK2_ENABLED_CACHE: OnceLock<bool> = OnceLock::new();
149pub fn debug_fallback2_enabled() -> bool {
150    *DEBUG_FALLBACK2_ENABLED_CACHE
151        .get_or_init(|| std::env::var("RAGC_DEBUG_FALLBACK2").unwrap_or_default() == "1")
152}
153
154// Optional: cache the assert path (less hot but still called)
155static ASSERT_CPP_ARCHIVE_CACHE: OnceLock<Option<String>> = OnceLock::new();
156pub fn assert_cpp_archive() -> Option<&'static str> {
157    ASSERT_CPP_ARCHIVE_CACHE
158        .get_or_init(|| std::env::var("RAGC_ASSERT_CPP_ARCHIVE").ok())
159        .as_deref()
160}
161
162// Disable barrier split feature (for testing C++ AGC parity)
163static DISABLE_BARRIER_SPLIT_CACHE: OnceLock<bool> = OnceLock::new();
164pub fn disable_barrier_split() -> bool {
165    *DISABLE_BARRIER_SPLIT_CACHE.get_or_init(|| std::env::var("RAGC_DISABLE_BARRIER_SPLIT").is_ok())
166}