aboutsummaryrefslogtreecommitdiffstats
path: root/log_db/src/forward_log_reader.rs
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2024-11-02 16:58:01 +0200
committerJan Tuomi <jan@jantuomi.fi>2024-11-02 17:39:22 +0200
commit912c32f762ee7585e20fde57c7c5dca1f9b0478d (patch)
treeafad7b189adb3a5189174e1fd9b44823cf63b3fa /log_db/src/forward_log_reader.rs
parent3838cd9ee68ff5433f00a52feed04a9682b79161 (diff)
Refactor in preparation to larger changes
Diffstat (limited to 'log_db/src/forward_log_reader.rs')
-rw-r--r--log_db/src/forward_log_reader.rs124
1 files changed, 0 insertions, 124 deletions
diff --git a/log_db/src/forward_log_reader.rs b/log_db/src/forward_log_reader.rs
deleted file mode 100644
index 03726d0..0000000
--- a/log_db/src/forward_log_reader.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-use super::common::*;
-use std::fs::{self};
-use std::io::{self, BufRead, Read};
-
-pub struct ForwardLogReader<'a> {
- reader: io::BufReader<&'a mut fs::File>,
-}
-
-impl<'a> ForwardLogReader<'a> {
- pub fn new(file: &mut fs::File) -> ForwardLogReader {
- let reader = io::BufReader::new(file);
- ForwardLogReader { reader }
- }
-
- fn read_record(&mut self) -> Result<Option<Record>, io::Error> {
- // The buffer that stores the bytes read from the file.
- let mut read_buf: Vec<u8> = Vec::new();
- // The buffer that stores all the bytes of the record read so far in reverse order.
- let mut result_buf: Vec<u8> = Vec::new();
-
- // Try reading a byte from the file.
- // If we've reached the end of the file, return None.
- let mut peek_buf = vec![0];
- match self.reader.read_exact(&mut peek_buf) {
- Ok(_) => {
- // Go back one byte
- self.reader.seek_relative(-1)?;
- }
- Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof => {
- return Ok(None);
- }
- Err(e) => {
- return Err(e);
- }
- }
-
- loop {
- read_buf.clear();
- self.reader.read_until(ESCAPE_CHARACTER, &mut read_buf)?;
- self.reader.seek_relative(-1)?;
- result_buf.extend(&read_buf[..read_buf.len() - 1]);
-
- // Otherwise, we must have encountered an escape character.
- match self.read_special_sequence()? {
- SpecialSequence::RecordSeparator => {
- // The record is complete, so we can break out of the loop.
- break;
- }
- SpecialSequence::LiteralFieldSeparator => {
- // The field separator is escaped, so we need to add it to the result buffer.
- result_buf.push(FIELD_SEPARATOR);
- }
- SpecialSequence::LiteralEscape => {
- // The escape character is escaped, so we need to add it to the result buffer.
- result_buf.push(ESCAPE_CHARACTER);
- }
- }
- }
-
- let record = Record::deserialize(&result_buf);
- Ok(Some(record))
- }
-
- fn read_special_sequence(&mut self) -> Result<SpecialSequence, io::Error> {
- let mut special_buf: Vec<u8> = vec![0; SEQ_RECORD_SEP.len()];
- self.reader.read_exact(&mut special_buf)?;
-
- match validate_special(&special_buf.as_slice()) {
- Some(special) => Ok(special),
- None => Err(io::Error::new(
- io::ErrorKind::InvalidData,
- "Not a special sequence",
- )),
- }
- }
-}
-
-impl Iterator for ForwardLogReader<'_> {
- type Item = Record;
-
- fn next(&mut self) -> Option<Self::Item> {
- match self.read_record() {
- Ok(Some(record)) => Some(record),
- Ok(None) => None,
- Err(err) => panic!("Error reading record: {:?}", err),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use std::path::Path;
-
- #[test]
- fn test_forward_log_reader_fixture_db1() {
- let db_path = Path::new(TEST_RESOURCES_DIR).join("test_db1");
- let mut file = fs::OpenOptions::new()
- .read(true)
- .open(&db_path)
- .expect("Failed to open file");
- let mut forward_log_reader = ForwardLogReader::new(&mut file);
-
- // There are two records in the log with "schema": Int, Null
-
- let first_record = forward_log_reader
- .next()
- .expect("Failed to read the first record");
- assert!(match first_record.values.as_slice() {
- [RecordValue::Int(0x1D), RecordValue::Null] => true,
- _ => false,
- });
-
- let last_record = forward_log_reader
- .next()
- .expect("Failed to read the last record");
- assert!(match last_record.values.as_slice() {
- [RecordValue::Int(10), RecordValue::Null] => true,
- _ => false,
- });
-
- assert!(forward_log_reader.next().is_none());
- }
-}