PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
pine_position_tail.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <memory>
6#include <string>
7#include <string_view>
8
9namespace pineforge {
10struct CacheCapacity;
11struct Trade;
12namespace detail { struct ReadThroughCacheStats; }
13namespace source::detail {
14
15// DESIGN 3.4: private binary storage, never the text report sink. Records
16// have no padding: entry_id bytes followed by the 30-byte backwards footer.
17// A row holds offsets, not an owning string, so even an id larger than the
18// read window does not allocate another history-sized buffer.
20public:
21 static constexpr std::size_t kWindowBytes = 64 * 1024;
22 static constexpr std::size_t kPageBytes = 4096;
23 static constexpr std::size_t kFooterBytes = 30;
24
25 struct Row {
26 std::int64_t exit_time = 0;
27 double qty = 0.0;
28 std::uint64_t entry_incarnation = 0;
29 bool is_long = false;
30 bool margin_call = false;
31 std::uint64_t entry_id_offset = 0;
32 std::uint32_t entry_id_size = 0;
33 };
34
35 // A second unlinked file in L6b-4's bound scratch directory (DESIGN
36 // 3.8 explicitly permits this). The directory must already be resolved.
37 // Payload bytes, independent of retained rows/id lengths. Complete shared
38 // line metadata is additional; zero/failed optional allocation bypasses.
39 // Pages are at most 4096 bytes; larger allowances keep complete pages.
40 explicit PositionTailSpill(const std::string& scratch_directory,
41 std::size_t cache_bytes = kWindowBytes);
42 // Inclusive shared-line allowance with fixed 4096-byte geometry.
43 PositionTailSpill(const std::string& scratch_directory, CacheCapacity capacity);
47
48 void append(const Trade& trade);
49 void clear();
50 std::uint64_t size_bytes() const noexcept;
51 std::uint64_t row_count() const noexcept;
52 std::size_t cache_capacity_bytes() const noexcept;
53 // Counts actual backing calls, not cache lookups.
54 std::uint64_t backing_read_count() const noexcept;
55 std::uint64_t backing_read_bytes() const noexcept;
56 ::pineforge::detail::ReadThroughCacheStats cache_stats() const noexcept;
57 std::size_t cache_control_bytes() const noexcept;
58
59 // Start cursor at size_bytes(); each successful call moves it to the
60 // preceding record. Separate cursors can repeat/interleave full walks.
61 bool previous(std::uint64_t& cursor, Row& row) const;
62 bool entry_id_equals(const Row& row, std::string_view entry_id) const;
63
64private:
65 struct State;
66 std::unique_ptr<State> state_;
67};
68
69} // namespace source::detail
70} // namespace pineforge
PositionTailSpill & operator=(const PositionTailSpill &)=delete
std::uint64_t backing_read_count() const noexcept
::pineforge::detail::ReadThroughCacheStats cache_stats() const noexcept
PositionTailSpill(const std::string &scratch_directory, std::size_t cache_bytes=kWindowBytes)
bool previous(std::uint64_t &cursor, Row &row) const
std::uint64_t backing_read_bytes() const noexcept
PositionTailSpill(const PositionTailSpill &)=delete
bool entry_id_equals(const Row &row, std::string_view entry_id) const