@@ -49,24 +49,15 @@ using LazyCallback = std::function<sdk::PayloadView()>;
4949
5050struct ObjectEntry {
5151 Timestamp timestamp = 0 ;
52- // Holds either a SharedBuffer (eager owned payload, counted against the
53- // retention budget) or a LazyCallback (lazy resolver). resolveEntry
54- // discriminates via std::get_if; the variant is exhaustive over the two
55- // (and only two) payload kinds.
52+ // Eager owned bytes or a lazy resolver; resolveEntry discriminates via std::get_if.
5653 std::variant<SharedBuffer, LazyCallback> payload;
5754};
5855
5956struct ResolvedObjectEntry {
6057 Timestamp timestamp = 0 ;
61- // PayloadView lets the entry hold an opaque anchor (any shared_ptr<T>) plus
62- // a non-owning Span over the bytes. Consumers read `payload.bytes` for the
63- // data; they retain `payload.anchor` if they need the bytes to outlive the
64- // resolve call. Both `pushOwned` and `pushLazy` paths land here:
65- // - owned: payload.bytes spans the shared_ptr<vector<uint8_t>>; anchor IS that shared_ptr.
66- // - lazy: payload is whatever the closure returns; anchor can be any shared_ptr<T>
67- // (e.g. a C-ABI payload anchor wrapped as shared_ptr<void>).
68- // resolveEntry never casts the anchor to a concrete type; the type erasure
69- // stays opaque all the way to the consumer.
58+ // Non-owning Span over the bytes plus an opaque anchor (any shared_ptr<T>).
59+ // Consumers read `payload.bytes`; retain `payload.anchor` to keep the bytes
60+ // alive past the resolve call. resolveEntry never casts the anchor.
7061 sdk::PayloadView payload;
7162};
7263
@@ -130,11 +121,9 @@ class ObjectStore {
130121
131122 Status pushOwned (ObjectTopicId id, Timestamp timestamp, std::vector<uint8_t > payload);
132123
133- // Fetcher runs on every read. Producers anchor on whatever owns the bytes
134- // (chunk cache, mmap, fresh allocation); the store never copies — it just
135- // retains the anchor through PayloadView. When the producer already holds
136- // the bytes behind a shared_ptr (e.g. a streaming buffer handed off between
137- // stores), the closure captures it and returns a view backed by it.
124+ // Fetcher runs on every read; the store retains the anchor via PayloadView
125+ // and never copies. The closure can return a view over bytes the producer
126+ // already owns (chunk cache, mmap, hand-off between stores).
138127 Status pushLazy (ObjectTopicId id, Timestamp timestamp, LazyCallback fetch);
139128
140129 // --- Read ---
@@ -164,26 +153,17 @@ class ObjectStore {
164153
165154 // --- Cross-store flush ---
166155
167- // Move every entry from this store into `dst`, leaving this store empty
168- // (topic registrations are preserved). Topics are matched by descriptor
169- // (dataset_id + topic_name); both stores must have registered the same
170- // descriptors or the call fails without partial mutation. For each series,
171- // monotonicity is enforced strictly: the earliest timestamp being moved
172- // must be greater than or equal to the destination's current last
173- // timestamp. On any validation failure the call returns an error and
174- // neither store is mutated.
156+ // Move every entry into `dst`, leaving this store empty (registrations kept).
157+ // Topics are matched by descriptor (dataset_id + topic_name); both stores
158+ // must share descriptors. Monotonicity is enforced per series: the earliest
159+ // moved timestamp must be >= the destination's last. Any validation failure
160+ // returns an error and mutates neither store.
175161 //
176- // Zero-copy on the payload bytes. Each ObjectEntry is moved into the
177- // destination's series by value; the std::variant inside holds either a
178- // shared_ptr or a std::function, and moving it is a pointer/buffer move —
179- // bytes captured by the closure or owned by the shared_ptr are never
180- // copied or materialized during the flush. Lazy
181- // entries preserve their semantics in the destination: their closure is
182- // re-invoked only when the destination is read.
183- //
184- // After the move, the destination's retention budget is applied to each
185- // touched series in normal order.
186- Expected<void , std::string> flushTo (ObjectStore& dst);
162+ // Zero-copy: each ObjectEntry is moved by value, so the variant's shared_ptr
163+ // or closure transfers as a pointer move — bytes are never copied. Lazy
164+ // entries keep their semantics; their closure re-runs only on a dst read.
165+ // Afterward, dst's retention budget is applied to each touched series.
166+ Status flushTo (ObjectStore& dst);
187167
188168 // --- Lifecycle ---
189169
0 commit comments