PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
scratch_readback.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace pineforge::detail {
6
7using ScratchHandle = std::uint64_t;
8inline constexpr ScratchHandle scratch_no_handle = 0;
9
10// Borrowed, immutable, potentially larger than a resident page; size() is
11// constant while the source is alive. read copies EXACTLY destination.size
12// bytes at offset, possibly across physical pages. A zero-length read at
13// size() is valid; an offset beyond size() is out of range even for an empty
14// destination. Out-of-range/null nonempty buffers return
15// programming_error. On error the destination may be partially filled.
16// Callers use fixed buffers; no contiguous owning copy is required anywhere.
18public:
19 virtual ~ScratchByteSource() noexcept = default;
20 virtual std::uint64_t size() const noexcept = 0;
21 virtual const ReportScratchIoError* carried_failure() const noexcept { return nullptr; }
22 virtual ScratchStatus read(std::uint64_t offset, ScratchBuffer destination) const noexcept = 0;
23};
24
25// Convenience adapter borrows the span; it never owns or allocates bytes.
27public:
28 explicit ScratchSpanSource(ScratchBytes bytes) noexcept : bytes_(bytes) {}
29 std::uint64_t size() const noexcept override { return bytes_.size; }
30 ScratchStatus read(std::uint64_t offset, ScratchBuffer destination) const noexcept override {
31 if (offset > bytes_.size || destination.size > bytes_.size - offset
32 || (destination.size && (!bytes_.data || !destination.data)))
34 if (destination.size)
35 std::memmove(destination.data, bytes_.data + static_cast<std::size_t>(offset),
36 destination.size);
37 return ScratchStatus::ok;
38 }
39private:
40 const ScratchBytes bytes_;
41};
42
45 std::uint64_t key_bytes = 0;
46 std::uint64_t value_bytes = 0;
47};
48
49enum class ScratchField : std::uint32_t { key, value };
50
51// View and sources live only until this callback returns. Sources resolve
52// logical bytes, not cache pointers, and remain usable across nested reads.
58
62 std::uint64_t offset;
63 ScratchBytes bytes; // aliases the caller's page, only for this callback
64 bool final; // final chunk of this FIELD
65};
66
67using ScratchRecordVisitor = bool (*)(void*, const ScratchRecordView&) noexcept;
68using ScratchChunkVisitor = bool (*)(void*, const ScratchChunkView&) noexcept;
69
70// Synchronous push readback, no materialised snapshot/owning sequence. All
71// methods see the current transaction's successful edits, or committed state
72// when no transaction is active. Calls are serialized. A visitor may issue
73// nested const reads/walks/digests on the same store using DISJOINT fixed
74// buffers; outer views/cursors remain valid. Mutation (including begin,
75// commit, rollback, close) from any read/comparison callback is a programming
76// error. No callback, source, context, buffer or view is retained afterwards.
78public:
79 virtual ~ScratchReadback() noexcept = default;
80 virtual std::size_t page_size() const noexcept = 0;
81 virtual std::uint64_t record_count() const noexcept = 0;
82 // Borrow the backing's original exception before any cleanup/read can
83 // replace it. A readback without an arena backing has no carried failure.
84 virtual const ReportScratchIoError* carried_failure() const noexcept { return nullptr; }
85
86 // Invalid/erased/rolled-back handle => not_found; info is unchanged. read
87 // obeys the ScratchByteSource range rules for offset and destination
88 // (out-of-range or null nonempty buffer => programming_error) and returns
89 // not_found for an absent handle.
90 virtual ScratchStatus point(ScratchHandle, ScratchRecordInfo& info) const noexcept = 0;
91 virtual ScratchStatus read(ScratchHandle, ScratchField, std::uint64_t offset,
92 ScratchBuffer destination) const noexcept = 0;
93
94 // page is caller-owned, nonnull, exactly page_size() bytes (else
95 // programming_error with no callback). Emit all key chunks followed by all
96 // value chunks, each at most page_size() bytes, with contiguous offsets
97 // starting at zero within each field. Chunks of a nonempty field are
98 // nonempty and the chunk that reaches the field's size is the one marked
99 // final. Emit exactly one final empty chunk for an empty field. false =>
100 // cancelled, with no further callback; an absent handle => not_found with
101 // no callback.
103 ScratchChunkVisitor, void* context) const noexcept = 0;
104
105 // Same page rule; one view per live record in ascending caller-key order.
106 // Empty stream => ok with no calls. false => cancelled, including on the
107 // last record. Errors never masquerade as cancellation or empty success.
109 void* context) const noexcept = 0;
110};
111
112// An owning-return compatibility wrapper may exist ONLY as a non-flat test
113// oracle. It must not be used by a production per-run/per-bar path, advertised
114// as O(1), or substituted for point/page/visitor reads by a consumer lane.
115
116} // namespace pineforge::detail
virtual const ReportScratchIoError * carried_failure() const noexcept
virtual ScratchStatus read(std::uint64_t offset, ScratchBuffer destination) const noexcept=0
virtual std::uint64_t size() const noexcept=0
virtual ~ScratchByteSource() noexcept=default
virtual ~ScratchReadback() noexcept=default
virtual ScratchStatus visit(ScratchHandle, ScratchBuffer page, ScratchChunkVisitor, void *context) const noexcept=0
virtual std::size_t page_size() const noexcept=0
virtual ScratchStatus point(ScratchHandle, ScratchRecordInfo &info) const noexcept=0
virtual ScratchStatus read(ScratchHandle, ScratchField, std::uint64_t offset, ScratchBuffer destination) const noexcept=0
virtual const ReportScratchIoError * carried_failure() const noexcept
virtual std::uint64_t record_count() const noexcept=0
virtual ScratchStatus for_each(ScratchBuffer page, ScratchRecordVisitor, void *context) const noexcept=0
ScratchSpanSource(ScratchBytes bytes) noexcept
ScratchStatus read(std::uint64_t offset, ScratchBuffer destination) const noexcept override
std::uint64_t size() const noexcept override
bool(*)(void *, const ScratchChunkView &) noexcept ScratchChunkVisitor
std::uint64_t ScratchHandle
constexpr ScratchHandle scratch_no_handle
bool(*)(void *, const ScratchRecordView &) noexcept ScratchRecordVisitor