Skip to content

Commit 2315b5f

Browse files
authored
feat(log): add first() and last() methods (#402)
### Motivation - Provide convenient accessors for the first and last log entries. ### Solution - Implemented first(&self) -> Option<T> returning self.get(0). - Implemented last(&self) -> Option<T> returning the last entry or None when empty. - Both are inlined and O(1) complexity. ### Details - first/last preserve existing retrieval semantics and types. - last handles empty logs safely by early None. ### Meta updated tests accordingly
1 parent c567ed2 commit 2315b5f

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/log.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,26 @@ impl<T: Storable, INDEX: Memory, DATA: Memory> Log<T, INDEX, DATA> {
180180
log
181181
}
182182

183+
/// Returns the first entry in the log, if any.
184+
///
185+
/// Complexity: O(1)
186+
#[inline]
187+
pub fn first(&self) -> Option<T> {
188+
self.get(0)
189+
}
190+
191+
/// Returns the last entry in the log, if any.
192+
///
193+
/// Complexity: O(1)
194+
#[inline]
195+
pub fn last(&self) -> Option<T> {
196+
let len = self.len();
197+
if len == 0 {
198+
return None;
199+
}
200+
self.get(len - 1)
201+
}
202+
183203
/// Initializes the log based on the contents of the provided memory trait objects.
184204
/// If the memory trait objects already contain a stable log, this function recovers it from the stable
185205
/// memory. Otherwise, this function allocates a new empty log.

src/log/tests.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,25 @@ fn test_iter() {
221221
assert_eq!(log.iter().skip(usize::MAX).count(), 0);
222222
}
223223

224+
#[test]
225+
fn test_first_last() {
226+
let log = Log::<String, _, _>::new(VectorMemory::default(), VectorMemory::default());
227+
assert_eq!(log.first(), None);
228+
assert_eq!(log.last(), None);
229+
230+
log.append(&"apple".to_string()).unwrap();
231+
assert_eq!(log.first(), Some("apple".to_string()));
232+
assert_eq!(log.last(), Some("apple".to_string()));
233+
234+
log.append(&"banana".to_string()).unwrap();
235+
assert_eq!(log.first(), Some("apple".to_string()));
236+
assert_eq!(log.last(), Some("banana".to_string()));
237+
238+
log.append(&"cider".to_string()).unwrap();
239+
assert_eq!(log.first(), Some("apple".to_string()));
240+
assert_eq!(log.last(), Some("cider".to_string()));
241+
}
242+
224243
#[allow(clippy::iter_nth_zero)]
225244
#[test]
226245
fn test_thread_local_iter() {

0 commit comments

Comments
 (0)