log/model.rs
1//! Core data types for OpenData Log.
2//!
3//! This module defines the fundamental data structures used throughout the
4//! log API, including records for writing and entries for reading.
5
6use bytes::Bytes;
7
8/// Unique identifier for a segment.
9///
10/// Segment IDs are monotonically increasing integers assigned when segments
11/// are created. Use with [`LogRead::list_keys`](crate::LogRead::list_keys)
12/// to query keys within specific segments.
13pub type SegmentId = u32;
14
15/// Global sequence number for log entries.
16///
17/// Sequence numbers are monotonically increasing integers assigned to each
18/// entry at append time. They provide a total ordering across all keys in
19/// the log.
20pub type Sequence = u64;
21
22/// A segment of the log.
23///
24/// Segments partition the log into coarse-grained chunks based on time or
25/// other policies. Each segment has a unique identifier and tracks the
26/// starting sequence number for entries it contains.
27///
28/// Segments are the natural boundary for attaching metadata such as key
29/// listings. See [`LogRead::list_segments`](crate::LogRead::list_segments)
30/// for querying segments.
31///
32/// # Example
33///
34/// ```ignore
35/// // List all segments
36/// let segments = log.list_segments(..).await?;
37/// for segment in segments {
38/// println!(
39/// "segment {}: start_seq={}, created at {}",
40/// segment.id, segment.start_seq, segment.start_time_ms
41/// );
42/// }
43/// ```
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct Segment {
46 /// Unique segment identifier (monotonically increasing).
47 pub id: SegmentId,
48 /// First sequence number in this segment.
49 pub start_seq: Sequence,
50 /// Wall-clock time when this segment was created (ms since epoch).
51 pub start_time_ms: i64,
52}
53
54/// A record to be appended to the log.
55///
56/// Records are the unit of data written to the log. Each record consists of
57/// a key identifying the log stream and a value containing the payload.
58///
59/// # Key Selection
60///
61/// Keys determine how data is organized in the log. Each unique key represents
62/// an independent log stream with its own sequence of entries. Choose keys based
63/// on your access patterns:
64///
65/// - Use a single key for a simple append-only log
66/// - Use entity IDs as keys for per-entity event streams
67/// - Use composite keys (e.g., `tenant:entity`) for multi-tenant scenarios
68///
69/// # Example
70///
71/// ```
72/// use bytes::Bytes;
73/// use log::Record;
74///
75/// let record = Record {
76/// key: Bytes::from("orders"),
77/// value: Bytes::from(r#"{"id": "123", "amount": 99.99}"#),
78/// };
79/// ```
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct Record {
82 /// The key identifying the log stream.
83 ///
84 /// All records with the same key form a single ordered log. Keys can be
85 /// any byte sequence but are typically human-readable identifiers.
86 pub key: Bytes,
87
88 /// The record payload.
89 ///
90 /// Values can contain any byte sequence. The log does not interpret
91 /// or validate the contents.
92 pub value: Bytes,
93}
94
95/// Result of an append operation.
96///
97/// Contains metadata about the appended records, including the starting
98/// sequence number assigned to the first record in the batch.
99///
100/// # Example
101///
102/// ```ignore
103/// let result = log.append(records).await?;
104/// println!("Appended starting at sequence {}", result.start_sequence);
105/// ```
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct AppendResult {
108 /// Sequence number assigned to the first record in the batch.
109 pub start_sequence: Sequence,
110}
111
112/// An entry read from the log.
113///
114/// Log entries are returned by [`LogIterator`](crate::LogIterator) and contain
115/// the original record data along with metadata assigned at append time.
116///
117/// # Sequence Numbers
118///
119/// Each entry has a globally unique sequence number assigned when it was
120/// appended. Within a single key's log, entries are ordered by sequence
121/// number, but the numbers are not contiguous—other keys' appends are
122/// interleaved in the global sequence.
123///
124/// # Example
125///
126/// ```ignore
127/// let mut iter = log.scan(key, ..);
128/// while let Some(entry) = iter.next().await? {
129/// println!(
130/// "key={:?}, seq={}, value={:?}",
131/// entry.key, entry.sequence, entry.value
132/// );
133/// }
134/// ```
135#[derive(Debug, Clone, PartialEq, Eq)]
136pub struct LogEntry {
137 /// The key of the log stream this entry belongs to.
138 pub key: Bytes,
139
140 /// The sequence number assigned to this entry.
141 ///
142 /// Sequence numbers are monotonically increasing within a key's log
143 /// and globally unique across all keys.
144 pub sequence: Sequence,
145
146 /// The record value.
147 pub value: Bytes,
148}