1use crate::error::WalError;
2use crate::storage::iterator::StorageIterator;
3use crate::storage::meta::Meta;
4use crate::wal::{MODE_IDLE, MODE_READ};
5use crate::Wal;
6use std::sync::atomic::Ordering::Relaxed;
7
8pub struct LogEntry {
11 inner: Vec<u8>,
12}
13
14impl LogEntry {
15 pub(crate) fn new(inner: Vec<u8>) -> Self {
16 Self { inner }
17 }
18
19 pub fn data(&self) -> &[u8] {
21 &self.inner
22 }
23
24 pub fn len(&self) -> usize {
26 self.inner.len()
27 }
28
29 pub fn to_struct<T: for<'a> serde::Deserialize<'a>>(&self) -> Result<T, WalError> {
34 bincode::deserialize(&self.inner)
35 .map_err(|e| WalError::DeserializationError(format!("Failed to deserialize: {}", e)))
36 }
37}
38
39pub struct WalIterator {
58 wal: Wal,
59 inner: StorageIterator,
60}
61impl WalIterator {
62 pub(crate) fn new(wal: Wal) -> Result<Self, WalError> {
63 let location = &wal.inner.config.location;
64 let meta = Meta::read_from_file(location)?;
65 let iterator = StorageIterator::new(meta);
66 Ok(Self {
67 wal,
68 inner: iterator,
69 })
70 }
71}
72
73impl Iterator for WalIterator {
74 type Item = LogEntry;
75
76 fn next(&mut self) -> Option<Self::Item> {
77 match self.inner.next() {
78 Some(v) => Some(LogEntry::new(v)),
79 None => {
80 if self
82 .wal
83 .inner
84 .mode
85 .compare_exchange(MODE_READ, MODE_IDLE, Relaxed, Relaxed)
86 .is_err()
87 {
88 panic!("Walcraft error: unable to release read lock on WAL");
89 }
90 None
91 }
92 }
93 }
94}
95
96impl Drop for WalIterator {
97 fn drop(&mut self) {
98 if self.inner.next().is_none() {
99 return;
100 }
101 if self
102 .wal
103 .inner
104 .mode
105 .compare_exchange(MODE_READ, MODE_IDLE, Relaxed, Relaxed)
106 .is_err()
107 {
108 panic!("Walcraft error: unable to release read lock on WAL");
109 }
110 }
111}