11#pragma once
22
3+ #include < launchdarkly/data/evaluation_reason.hpp>
4+ #include < launchdarkly/server_side/integrations/big_segments/big_segment_store_types.hpp>
5+
36#include < optional>
47#include < string>
8+ #include < unordered_map>
59#include < unordered_set>
610
11+ namespace launchdarkly ::server_side::data_components {
12+ class BigSegmentStoreWrapper ;
13+ } // namespace launchdarkly::server_side::data_components
14+
715namespace launchdarkly ::server_side::evaluation {
816
917/* *
@@ -26,12 +34,22 @@ struct Guard {
2634};
2735
2836/* *
29- * EvaluationStack is used to track which segments and flags have been noticed
30- * during evaluation in order to detect circular references.
37+ * EvaluationStack holds the per-evaluation state for a single top-level flag
38+ * evaluation: the prerequisite/segment chains used for circular-reference
39+ * detection, plus the Big Segments status and membership cache that a Big
40+ * Segment lookup populates.
41+ *
42+ * Not thread-safe: a fresh instance is created per top-level evaluation and is
43+ * never shared across threads.
3144 */
3245class EvaluationStack {
3346 public:
34- EvaluationStack () = default ;
47+ /* *
48+ * @param big_segment_store Non-owning pointer to the Big Segment store
49+ * wrapper, or nullptr if no store is configured. Must outlive the stack.
50+ */
51+ explicit EvaluationStack (
52+ data_components::BigSegmentStoreWrapper* big_segment_store = nullptr );
3553
3654 /* *
3755 * If the given prerequisite key has not been seen, marks it as seen
@@ -52,9 +70,61 @@ class EvaluationStack {
5270 */
5371 [[nodiscard]] std::optional<Guard> NoticeSegment (std::string segment_key);
5472
73+ /* *
74+ * @return The Big Segment store wrapper, or nullptr if none is configured.
75+ */
76+ [[nodiscard]] data_components::BigSegmentStoreWrapper* BigSegmentStore ()
77+ const ;
78+
79+ /* *
80+ * Records the status of a Big Segment lookup. If multiple lookups occur in
81+ * one evaluation, the least-trustworthy status wins (NOT_CONFIGURED >
82+ * STORE_ERROR > STALE > HEALTHY).
83+ */
84+ void RecordBigSegmentsStatus (enum EvaluationReason::BigSegmentsStatus status);
85+
86+ /* *
87+ * @return The aggregated Big Segments status, or std::nullopt if no Big
88+ * Segment was queried during this evaluation.
89+ */
90+ [[nodiscard]] std::optional<enum EvaluationReason::BigSegmentsStatus> BigSegmentsStatus () const ;
91+
92+ /* *
93+ * Returns the cached membership for a context key looked up earlier in this
94+ * evaluation, or nullptr if that key has not been queried yet.
95+ */
96+ [[nodiscard]] integrations::Membership const * FindMembership (
97+ std::string const & context_key) const ;
98+
99+ /* *
100+ * Caches a context key's membership so later Big Segment lookups for the
101+ * same key in this evaluation reuse it instead of re-querying the store.
102+ */
103+ void StoreMembership (std::string context_key,
104+ integrations::Membership membership);
105+
106+ /* *
107+ * Records that the Big Segment store returned an error for the given
108+ * context key during this evaluation. Subsequent Big Segment lookups for
109+ * the same key must be treated as non-matches without re-querying.
110+ */
111+ void RecordStoreError (std::string context_key);
112+
113+ /* *
114+ * @return True if a Big Segment store lookup for the given context key has
115+ * already errored during this evaluation.
116+ */
117+ [[nodiscard]] bool DidStoreError (std::string const & context_key) const ;
118+
55119 private:
56120 std::unordered_set<std::string> prerequisites_seen_;
57121 std::unordered_set<std::string> segments_seen_;
122+
123+ data_components::BigSegmentStoreWrapper* big_segment_store_;
124+ std::optional<enum EvaluationReason::BigSegmentsStatus> big_segments_status_;
125+ // Keyed by unhashed context key. Empty until the first Big Segment lookup.
126+ std::unordered_map<std::string, integrations::Membership> memberships_;
127+ std::unordered_set<std::string> store_error_keys_;
58128};
59129
60130} // namespace launchdarkly::server_side::evaluation
0 commit comments