diff --git a/src/filter_plugin/tail.rs b/src/filter_plugin/tail.rs index 3663a9f..fadec4b 100644 --- a/src/filter_plugin/tail.rs +++ b/src/filter_plugin/tail.rs @@ -25,6 +25,7 @@ impl FilterPlugin for TailBytesFilter { } fn finish(&mut self) -> Result> { + // Collect all bytes from the ring buffer let mut result = Vec::with_capacity(self.ring_buffer.len()); for byte in self.ring_buffer.iter() { result.push(*byte); @@ -61,35 +62,34 @@ impl FilterPlugin for TailLinesFilter { } fn finish(&mut self) -> Result> { - // Count lines in the buffer to find where to start - let mut lines_to_keep = std::cmp::min(self.count, self.lines_found); - let mut bytes_to_keep = 0; - let mut lines_seen = 0; + // For ring buffer, we can use the iter() method to get all elements + // Since it's a circular buffer, we need to handle the wrap-around + let mut result = Vec::with_capacity(self.ring_buffer.len()); - // Iterate backwards to find the starting point - for i in (0..self.ring_buffer.len()).rev() { - let index = (self.ring_buffer.write_pos() as isize - 1 - i as isize) - .rem_euclid(self.ring_buffer.capacity() as isize) as usize; - let byte = self.ring_buffer[index]; - - if byte == b'\n' { - lines_seen += 1; - if lines_seen > lines_to_keep { - break; - } - } - bytes_to_keep += 1; + // The ring buffer maintains elements in insertion order + for byte in self.ring_buffer.iter() { + result.push(*byte); } - // Extract the relevant bytes - let start_index = self.ring_buffer.len() - bytes_to_keep; - let mut result = Vec::with_capacity(bytes_to_keep); - for i in start_index..self.ring_buffer.len() { - let index = (self.ring_buffer.write_pos() as isize - (self.ring_buffer.len() - i) as isize) - .rem_euclid(self.ring_buffer.capacity() as isize) as usize; - result.push(self.ring_buffer[index]); + // Now, we need to find the last 'count' lines + if self.count == 0 { + return Ok(Vec::new()); } - Ok(result) + // Split into lines and take the last 'count' lines + let text = String::from_utf8_lossy(&result); + let lines: Vec<&str> = text.split('\n').collect(); + + // Take the last 'count' lines + let start_index = if lines.len() > self.count { + lines.len() - self.count + } else { + 0 + }; + + let selected_lines = &lines[start_index..]; + let result_text = selected_lines.join("\n"); + + Ok(result_text.into_bytes()) } } diff --git a/src/services/item_service.rs b/src/services/item_service.rs index aa2bd39..4e834ce 100644 --- a/src/services/item_service.rs +++ b/src/services/item_service.rs @@ -147,13 +147,13 @@ impl ItemService { conn: &Connection, id: i64, head_bytes: Option, - _head_words: Option, + head_words: Option, head_lines: Option, tail_bytes: Option, - _tail_words: Option, + tail_words: Option, tail_lines: Option, - _line_start: Option, - _line_end: Option, + line_start: Option, + line_end: Option, grep: Option, ) -> Result<(Vec, String, bool), CoreError> { // Use streaming approach to handle all filtering options consistently