Skip to content

Commit 42d1067

Browse files
committed
Reduce by one the pointer hop to node instead of graph
1 parent 9891284 commit 42d1067

2 files changed

Lines changed: 31 additions & 27 deletions

File tree

cpp/include/hgraph/types/node.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ namespace hgraph {
221221

222222
void set_error_output(time_series_output_ptr value);
223223

224+
// Performance optimization: provide access to cached evaluation time pointer
225+
[[nodiscard]] const engine_time_t* cached_evaluation_time_ptr() const { return _cached_evaluation_time_ptr; }
226+
224227
friend struct Graph;
225228
friend struct NodeScheduler;
226229

cpp/src/cpp/types/base_time_series.cpp

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ namespace hgraph {
123123
}
124124

125125
bool BaseTimeSeriesOutput::modified() const {
126-
auto g = owning_graph();
127-
if (g.get() == nullptr) { return false; }
128-
// Use cached evaluation time pointer from graph for performance
129-
return *g->cached_evaluation_time_ptr() == _last_modified_time;
126+
auto n = owning_node();
127+
if (n.get() == nullptr) { return false; }
128+
// Use cached evaluation time pointer from node for performance
129+
return *n->cached_evaluation_time_ptr() == _last_modified_time;
130130
}
131131

132132
bool BaseTimeSeriesOutput::valid() const { return _last_modified_time > MIN_DT; }
@@ -140,26 +140,26 @@ namespace hgraph {
140140
void BaseTimeSeriesOutput::mark_invalid() {
141141
if (_last_modified_time > MIN_DT) {
142142
_last_modified_time = MIN_DT;
143-
auto g = owning_graph();
144-
if (g.get() != nullptr) {
145-
// Use cached evaluation time pointer from graph for performance
146-
_notify(*g->cached_evaluation_time_ptr());
143+
auto n = owning_node();
144+
if (n.get() != nullptr) {
145+
// Use cached evaluation time pointer from node for performance
146+
_notify(*n->cached_evaluation_time_ptr());
147147
} else {
148-
// Owning graph not yet attached; skip notify to avoid dereferencing null during start/recover
148+
// Owning node not yet attached; skip notify to avoid dereferencing null during start/recover
149149
}
150150
}
151151
}
152152

153153
void BaseTimeSeriesOutput::mark_modified() {
154154
if (has_parent_or_node()) {
155-
auto g = owning_graph();
156-
if (g.get() != nullptr) {
157-
// Use cached evaluation time pointer from graph for performance
158-
mark_modified(*g->cached_evaluation_time_ptr());
155+
auto n = owning_node();
156+
if (n.get() != nullptr) {
157+
// Use cached evaluation time pointer from node for performance
158+
mark_modified(*n->cached_evaluation_time_ptr());
159159
} else {
160-
// Graph not yet attached; mark with a maximal time to preserve monotonicity without dereferencing
160+
// Owning node not yet attached; mark with a maximal time to preserve monotonicity without dereferencing
161161
// This is a bad situation, I would probably prefer to find out why,
162-
// TODO: find the root cause of why this could be called without a bound graph.
162+
// TODO: find the root cause of why this could be called without a bound node.
163163
}
164164
} else {
165165
mark_modified(MAX_ET);
@@ -312,10 +312,10 @@ namespace hgraph {
312312
// - The input was previously bound (rebinding case), OR
313313
// - The new output is valid
314314
// This matches the Python implementation: (was_bound or self._output.valid)
315-
if ((owning_node()->is_started() || owning_node()->is_starting()) && _output.get() && (was_bound || _output->
316-
valid())) {
317-
// Use cached evaluation time pointer from graph for performance
318-
_sample_time = *owning_graph()->cached_evaluation_time_ptr();
315+
auto n = owning_node();
316+
if ((n->is_started() || n->is_starting()) && _output.get() && (was_bound || _output->valid())) {
317+
// Use cached evaluation time pointer from node for performance
318+
_sample_time = *n->cached_evaluation_time_ptr();
319319
if (active()) {
320320
notify(_sample_time);
321321
// TODO: This might belong to make_active, or not? There is a race with setting sample_time too.
@@ -337,12 +337,13 @@ namespace hgraph {
337337
if (bound()) {
338338
do_un_bind_output(unbind_refs);
339339

340-
if (owning_node()->is_started() && was_valid) {
341-
// Use cached evaluation time pointer from graph for performance
342-
_sample_time = *owning_graph()->cached_evaluation_time_ptr();
340+
auto n = owning_node();
341+
if (n->is_started() && was_valid) {
342+
// Use cached evaluation time pointer from node for performance
343+
_sample_time = *n->cached_evaluation_time_ptr();
343344
if (active()) {
344345
// Notify as the state of the node has changed from bound to un_bound
345-
owning_node()->notify(_sample_time);
346+
n->notify(_sample_time);
346347
}
347348
}
348349
}
@@ -446,10 +447,10 @@ namespace hgraph {
446447
engine_time_t BaseTimeSeriesInput::sample_time() const { return _sample_time; }
447448

448449
bool BaseTimeSeriesInput::sampled() const {
449-
auto g = owning_graph();
450-
if (g.get() == nullptr) { return false; }
451-
// Use cached evaluation time pointer from graph for performance
452-
return _sample_time != MIN_DT && _sample_time == *g->cached_evaluation_time_ptr();
450+
auto n = owning_node();
451+
if (n.get() == nullptr) { return false; }
452+
// Use cached evaluation time pointer from node for performance
453+
return _sample_time != MIN_DT && _sample_time == *n->cached_evaluation_time_ptr();
453454
}
454455

455456
time_series_reference_output_ptr BaseTimeSeriesInput::reference_output() const { return _reference_output; }

0 commit comments

Comments
 (0)