Skip to content

Commit 781232d

Browse files
committed
Continue to try and improve code prior to implementing nested graph structures.
1 parent cbc5098 commit 781232d

40 files changed

+2175
-399
lines changed

cpp/include/hgraph/types/time_series/time_series_state.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <hgraph/types/value/value_view.h>
99
#include <hgraph/util/tagged_ptr.h>
1010

11+
#include <deque>
1112
#include <memory>
1213
#include <optional>
1314
#include <unordered_map>
@@ -43,10 +44,13 @@ namespace hgraph
4344
struct ViewDispatch;
4445

4546
[[nodiscard]] HGRAPH_EXPORT bool has_local_reference_binding(const TSViewContext &context) noexcept;
47+
[[nodiscard]] HGRAPH_EXPORT bool linked_context_valid(const LinkedTSContext &context) noexcept;
48+
[[nodiscard]] HGRAPH_EXPORT bool linked_context_all_valid(const LinkedTSContext &context) noexcept;
4649
[[nodiscard]] HGRAPH_EXPORT const Value *materialized_target_link_value(const TSViewContext &context) noexcept;
4750
[[nodiscard]] HGRAPH_EXPORT const Value *materialized_reference_value(const TSViewContext &context) noexcept;
4851
[[nodiscard]] HGRAPH_EXPORT bool reference_all_valid(const TSViewContext &context) noexcept;
4952
[[nodiscard]] HGRAPH_EXPORT bool linked_context_equal(const LinkedTSContext &lhs, const LinkedTSContext &rhs) noexcept;
53+
[[nodiscard]] HGRAPH_EXPORT TSViewContext refresh_native_context(const TSViewContext &context) noexcept;
5054
[[nodiscard]] HGRAPH_EXPORT Value snapshot_target_value(const LinkedTSContext &target,
5155
engine_time_t modified_time = MIN_DT);
5256
} // namespace detail
@@ -403,7 +407,10 @@ namespace hgraph
403407
* State carried by a time-series window.
404408
*/
405409
struct HGRAPH_EXPORT TSWState : BaseState
406-
{};
410+
{
411+
engine_time_t first_observed_time{MIN_DT};
412+
bool ready{false};
413+
};
407414

408415
/**
409416
* Storage carried by a target-linked logical time-series position.

cpp/include/hgraph/types/time_series/ts_value.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ struct HGRAPH_EXPORT TSValue {
120120
/**
121121
* Return the window value surface for this time-series.
122122
*/
123-
[[nodiscard]] CyclicBufferView window_value() const;
123+
[[nodiscard]] BufferView window_value() const;
124124

125125
/**
126126
* Return the list delta surface backed by the stored delta-tracking

cpp/include/hgraph/types/time_series/ts_view.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ namespace hgraph
140140
struct TSWindowDispatch : TSDispatch
141141
{
142142
[[nodiscard]] const TSWindowDispatch *as_window() const noexcept override { return this; }
143-
[[nodiscard]] virtual size_t size(const TSViewContext &context) const noexcept = 0;
144-
[[nodiscard]] virtual Range<View> values(const TSViewContext &context) const noexcept = 0;
145-
[[nodiscard]] virtual Range<engine_time_t> value_times(const TSViewContext &context) const noexcept = 0;
143+
[[nodiscard]] virtual size_t size(const TSViewContext &context, engine_time_t evaluation_time) const noexcept = 0;
144+
[[nodiscard]] virtual Range<View> values(const TSViewContext &context, engine_time_t evaluation_time) const noexcept = 0;
145+
[[nodiscard]] virtual Range<engine_time_t> value_times(const TSViewContext &context,
146+
engine_time_t evaluation_time) const noexcept = 0;
146147
};
147148

148149
struct TSInputViewOps
@@ -254,11 +255,15 @@ namespace hgraph
254255
resolved_context.value_dispatch = target_context.value_dispatch;
255256
resolved_context.ts_dispatch = target_context.ts_dispatch;
256257
resolved_context.value_data = target_context.value_data;
258+
resolved_context.owning_output = target.owning_output != nullptr ? target.owning_output : resolved_context.owning_output;
259+
resolved_context.output_view_ops = target.output_view_ops != nullptr ? target.output_view_ops : resolved_context.output_view_ops;
260+
resolved_context.notification_state =
261+
target.notification_state != nullptr ? target.notification_state : resolved_context.notification_state;
257262
};
258263

259264
if (const LinkedTSContext *target = state->linked_target(); target != nullptr) { apply_target(*target); }
260265

261-
return resolved_context;
266+
return detail::refresh_native_context(resolved_context);
262267
}
263268

264269
[[nodiscard]] View value() const noexcept
@@ -1044,15 +1049,15 @@ namespace hgraph
10441049
{
10451050
const auto *dispatch = this->view_ref().context_ref().resolved().ts_dispatch;
10461051
const auto *window_dispatch = dispatch != nullptr ? dispatch->as_window() : nullptr;
1047-
return window_dispatch != nullptr ? window_dispatch->size(this->view_ref().context_ref()) : 0;
1052+
return window_dispatch != nullptr ? window_dispatch->size(this->view_ref().context_ref(), this->view_ref().evaluation_time()) : 0;
10481053
}
10491054

10501055
template <typename TView>
10511056
Range<View> TSWView<TView>::values() const noexcept
10521057
{
10531058
const auto *dispatch = this->view_ref().context_ref().resolved().ts_dispatch;
10541059
const auto *window_dispatch = dispatch != nullptr ? dispatch->as_window() : nullptr;
1055-
return window_dispatch != nullptr ? window_dispatch->values(this->view_ref().context_ref())
1060+
return window_dispatch != nullptr ? window_dispatch->values(this->view_ref().context_ref(), this->view_ref().evaluation_time())
10561061
: Range<View>{nullptr, 0, nullptr, nullptr};
10571062
}
10581063

@@ -1061,7 +1066,7 @@ namespace hgraph
10611066
{
10621067
const auto *dispatch = this->view_ref().context_ref().resolved().ts_dispatch;
10631068
const auto *window_dispatch = dispatch != nullptr ? dispatch->as_window() : nullptr;
1064-
return window_dispatch != nullptr ? window_dispatch->value_times(this->view_ref().context_ref())
1069+
return window_dispatch != nullptr ? window_dispatch->value_times(this->view_ref().context_ref(), this->view_ref().evaluation_time())
10651070
: Range<engine_time_t>{nullptr, 0, nullptr, nullptr};
10661071
}
10671072

cpp/include/hgraph/types/time_series/value/atomic.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ namespace hgraph
8080

8181
template <typename T> struct AtomicDispatch final : ViewDispatch
8282
{
83+
[[nodiscard]] MutationTracking tracking() const noexcept override
84+
{
85+
return MutationTracking::Plain;
86+
}
87+
8388
[[nodiscard]] size_t hash(const void *data) const override
8489
{
8590
return atomic_hash(state(data)->value);
@@ -112,6 +117,11 @@ namespace hgraph
112117
state(dst)->value = state(src)->value;
113118
}
114119

120+
void copy_from(void *dst, const View &src) const override
121+
{
122+
assign(dst, detail::ViewAccess::data(src));
123+
}
124+
115125
void set_from_cpp(void *dst, const void *src, const value::TypeMeta *src_schema) const override
116126
{
117127
if (src_schema != value::scalar_type_meta<T>()) {
@@ -150,6 +160,11 @@ namespace hgraph
150160
*/
151161
template <> struct AtomicDispatch<nb::object> final : ViewDispatch
152162
{
163+
[[nodiscard]] MutationTracking tracking() const noexcept override
164+
{
165+
return MutationTracking::Plain;
166+
}
167+
153168
[[nodiscard]] size_t hash(const void *data) const override
154169
{
155170
const auto &obj = state(data)->value;
@@ -202,6 +217,11 @@ namespace hgraph
202217
state(dst)->value = state(src)->value;
203218
}
204219

220+
void copy_from(void *dst, const View &src) const override
221+
{
222+
assign(dst, detail::ViewAccess::data(src));
223+
}
224+
205225
void set_from_cpp(void *dst, const void *src, const value::TypeMeta *src_schema) const override
206226
{
207227
if (src_schema != value::scalar_type_meta<nb::object>()) {

cpp/include/hgraph/types/time_series/value/value.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,14 @@ namespace hgraph
290290
Storage m_storage;
291291
};
292292

293+
inline Value View::clone(MutationTracking tracking) const
294+
{
295+
return Value{*this, tracking};
296+
}
297+
293298
inline Value View::clone() const
294299
{
295-
return Value{*this};
300+
return clone(MutationTracking::Plain);
296301
}
297302

298303
template <typename T> inline void View::set(T &&value)

cpp/include/hgraph/types/time_series/value/view.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <hgraph/hgraph_base.h>
4+
#include <hgraph/types/time_series/value/tracking.h>
45
#include <hgraph/types/value/type_meta.h>
56

67
#include <compare>
@@ -15,6 +16,12 @@
1516
namespace hgraph
1617
{
1718
struct Value;
19+
struct View;
20+
21+
namespace detail
22+
{
23+
struct ViewAccess;
24+
}
1825

1926
/**
2027
* Lightweight type-erased range over value-layer results.
@@ -239,12 +246,14 @@ namespace hgraph
239246
* preventing accidental polymorphic deletion through a base
240247
* pointer.
241248
*/
249+
[[nodiscard]] virtual MutationTracking tracking() const noexcept = 0;
242250
[[nodiscard]] virtual size_t hash(const void *data) const = 0;
243251
[[nodiscard]] virtual std::string to_string(const void *data) const = 0;
244252
[[nodiscard]] virtual std::partial_ordering compare(const void *lhs, const void *rhs) const = 0;
245253
[[nodiscard]] virtual nb::object to_python(const void *data, const value::TypeMeta *schema) const = 0;
246254
virtual void from_python(void *dst, const nb::object &src, const value::TypeMeta *schema) const = 0;
247255
virtual void assign(void *dst, const void *src) const = 0;
256+
virtual void copy_from(void *dst, const View &src) const = 0;
248257
virtual void set_from_cpp(void *dst, const void *src, const value::TypeMeta *src_schema) const = 0;
249258
virtual void move_from_cpp(void *dst, void *src, const value::TypeMeta *src_schema) const = 0;
250259

@@ -390,20 +399,20 @@ namespace hgraph
390399
* This preserves the represented schema and copies the current payload
391400
* when the view is valid.
392401
*/
402+
[[nodiscard]] Value clone(MutationTracking tracking) const;
393403
[[nodiscard]] Value clone() const;
404+
[[nodiscard]] MutationTracking tracking() const noexcept
405+
{
406+
return context.dispatch != nullptr ? context.dispatch->tracking() : MutationTracking::Plain;
407+
}
394408

395409
/**
396410
* Copy the payload represented by another view into this view.
397411
*
398412
* Both views must be valid and must describe the same schema. This
399413
* copies payload state only; it does not rebind either view.
400414
*/
401-
void copy_from(const View &other) {
402-
if (!has_value() || !other.has_value()) { throw std::runtime_error("View::copy_from requires non-empty views"); }
403-
if (data() == data_of(other)) { return; }
404-
if (schema() != other.schema()) { throw std::invalid_argument("View::copy_from requires matching schemas"); }
405-
dispatch()->assign(data(), data_of(other));
406-
}
415+
void copy_from(const View &other);
407416

408417
template <typename T> [[nodiscard]] T *try_as() noexcept;
409418
template <typename T> [[nodiscard]] const T *try_as() const noexcept;
@@ -447,7 +456,18 @@ namespace hgraph
447456
[[nodiscard]] static void *data_of(const View &view) noexcept { return view.context.data; }
448457

449458
private:
459+
friend struct detail::ViewAccess;
460+
450461
ValueViewContext context;
451462
};
452463

464+
namespace detail
465+
{
466+
struct ViewAccess
467+
{
468+
[[nodiscard]] static const ViewDispatch *dispatch(const View &view) noexcept { return view.context.dispatch; }
469+
[[nodiscard]] static const void *data(const View &view) noexcept { return view.context.data; }
470+
};
471+
} // namespace detail
472+
453473
} // namespace hgraph

cpp/include/hgraph/types/v2/evaluation_engine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ namespace hgraph::v2
455455
EvaluationEngineBuilder &evaluation_mode(EvaluationMode evaluation_mode) noexcept;
456456
EvaluationEngineBuilder &start_time(engine_time_t start_time) noexcept;
457457
EvaluationEngineBuilder &end_time(engine_time_t end_time) noexcept;
458+
EvaluationEngineBuilder &cleanup_on_error(bool cleanup_on_error) noexcept;
458459
EvaluationEngineBuilder &add_life_cycle_observer(EvaluationLifeCycleObserver *observer);
459460

460461
[[nodiscard]] EvaluationEngine build() const;
@@ -464,6 +465,7 @@ namespace hgraph::v2
464465
EvaluationMode m_evaluation_mode{EvaluationMode::SIMULATION};
465466
engine_time_t m_start_time{MIN_DT};
466467
engine_time_t m_end_time{MAX_DT};
468+
bool m_cleanup_on_error{true};
467469
std::vector<EvaluationLifeCycleObserver *> m_life_cycle_observers;
468470
};
469471
} // namespace hgraph::v2

cpp/include/hgraph/types/v2/graph.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace hgraph::v2
5656
[[nodiscard]] const Traits &traits() const;
5757
[[nodiscard]] engine_time_t evaluation_time() const noexcept;
5858
[[nodiscard]] engine_time_t last_evaluation_time() const noexcept;
59+
[[nodiscard]] SenderReceiverState *push_message_receiver() const noexcept;
5960
/** Prefix length of nodes treated as push sources during evaluation. */
6061
[[nodiscard]] int64_t push_source_nodes_end() const noexcept;
6162
[[nodiscard]] engine_time_t scheduled_time(size_t index) const;
@@ -65,6 +66,7 @@ namespace hgraph::v2
6566

6667
void start();
6768
void stop();
69+
void abandon() noexcept;
6870
void evaluate(engine_time_t when);
6971
void schedule_node(int64_t node_index, engine_time_t when, bool force_set = false);
7072

cpp/include/hgraph/types/v2/graph_builder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace hgraph::v2
3939

4040
[[nodiscard]] size_t size() const;
4141
[[nodiscard]] size_t alignment() const;
42+
[[nodiscard]] size_t memory_size() const;
4243
[[nodiscard]] Graph make_graph(GraphEvaluationEngine evaluation_engine) const;
4344

4445
[[nodiscard]] size_t node_builder_count() const noexcept { return m_node_builders.size(); }

cpp/include/hgraph/types/v2/node.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ namespace hgraph::v2
5151

5252
[[nodiscard]] bool (*has_input)(const Node &node) noexcept;
5353
[[nodiscard]] bool (*has_output)(const Node &node) noexcept;
54+
[[nodiscard]] bool (*has_error_output)(const Node &node) noexcept;
55+
[[nodiscard]] bool (*has_recordable_state)(const Node &node) noexcept;
5456
[[nodiscard]] TSInputView (*input_view)(Node &node, engine_time_t evaluation_time);
5557
[[nodiscard]] TSOutputView (*output_view)(Node &node, engine_time_t evaluation_time);
58+
[[nodiscard]] TSOutputView (*error_output_view)(Node &node, engine_time_t evaluation_time);
59+
[[nodiscard]] TSOutputView (*recordable_state_view)(Node &node, engine_time_t evaluation_time);
5660
[[nodiscard]] std::string (*runtime_label)(const Node &node);
5761
};
5862

@@ -82,6 +86,8 @@ namespace hgraph::v2
8286
NodeTypeEnum node_type{NodeTypeEnum::COMPUTE_NODE};
8387
const TSMeta *input_schema{nullptr};
8488
const TSMeta *output_schema{nullptr};
89+
const TSMeta *error_output_schema{nullptr};
90+
const TSMeta *recordable_state_schema{nullptr};
8591

8692
std::span<const size_t> active_inputs{};
8793
std::span<const size_t> valid_inputs{};
@@ -156,8 +162,12 @@ namespace hgraph::v2
156162
[[nodiscard]] bool is_pull_source_node() const noexcept;
157163
[[nodiscard]] const TSMeta *input_schema() const noexcept;
158164
[[nodiscard]] const TSMeta *output_schema() const noexcept;
165+
[[nodiscard]] const TSMeta *error_output_schema() const noexcept;
166+
[[nodiscard]] const TSMeta *recordable_state_schema() const noexcept;
159167
[[nodiscard]] bool has_input() const noexcept;
160168
[[nodiscard]] bool has_output() const noexcept;
169+
[[nodiscard]] bool has_error_output() const noexcept;
170+
[[nodiscard]] bool has_recordable_state() const noexcept;
161171
[[nodiscard]] bool started() const noexcept;
162172
[[nodiscard]] bool uses_scheduler() const noexcept;
163173
[[nodiscard]] bool has_scheduler() const noexcept;
@@ -172,6 +182,8 @@ namespace hgraph::v2
172182
/** View access is delegated to the node family via NodeRuntimeOps. */
173183
[[nodiscard]] TSInputView input_view(engine_time_t evaluation_time = MIN_DT);
174184
[[nodiscard]] TSOutputView output_view(engine_time_t evaluation_time = MIN_DT);
185+
[[nodiscard]] TSOutputView error_output_view(engine_time_t evaluation_time = MIN_DT);
186+
[[nodiscard]] TSOutputView recordable_state_view(engine_time_t evaluation_time = MIN_DT);
175187
[[nodiscard]] const BuiltNodeSpec &spec() const noexcept;
176188

177189
/** Apply top-level valid/all_valid gating before calling eval. */

0 commit comments

Comments
 (0)