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