pub struct MessageBuffers { /* private fields */ }Expand description
Reusable storage for crate::MessageParser::parse_with.
A parsed message keeps its parts, headers and values in a handful of
vectors. Parsing many messages one after the other (an mbox or Maildir
import, classifier training, a batch of messages from a queue) can reuse
those vectors instead of allocating new ones for every message: pass the
buffers to parse_with, and when done with the message, get them back
with crate::Message::into_buffers. Once the vectors have grown to
fit the messages, parsing allocates nothing.
There is no hidden state: dropping a message instead of calling
into_buffers only means the next parse allocates, and dropping the
buffers frees the memory they hold.
The vectors never shrink on their own: they keep the capacity of the
largest message parsed with them, so one very large message in a batch
holds its memory for the rest of the loop. MessageBuffers::shrink_to
bounds that memory between two parses.
use mail_parser::{MessageBuffers, MessageParser, mailbox::mbox::MessageIterator};
let mbox = b"From a@example.com Sat Jan 3 01:05:34 1996\n\
Subject: first\n\nbody\n\
From b@example.com Sat Jan 3 01:05:35 1996\n\
Subject: second\n\nbody\n";
let parser = MessageParser::new();
let mut buffers = MessageBuffers::new();
let mut subjects = Vec::new();
for entry in MessageIterator::new(&mbox[..]) {
let entry = entry.expect("readable mbox");
if let Some(message) = parser.parse_with(entry.contents(), &mut buffers) {
subjects.push(message.subject().unwrap_or_default().to_string());
buffers = message.into_buffers();
}
}
assert_eq!(subjects, ["first", "second"]);Implementations§
Source§impl MessageBuffers
impl MessageBuffers
Sourcepub fn shrink_to(&mut self, max_bytes: usize)
pub fn shrink_to(&mut self, max_bytes: usize)
Frees the memory held by the buffers when it exceeds max_bytes,
so that they hold at most max_bytes afterwards; the next parse then
allocates again. Call it between two parses, for example after
crate::Message::into_buffers in a batch loop, to keep one large
message from pinning its memory. It costs nothing when the buffers
are within the bound.
use mail_parser::{MessageBuffers, MessageParser};
let parser = MessageParser::new();
let mut buffers = MessageBuffers::new();
for raw in [&b"Subject: small\n\nbody\n"[..], b"Subject: next\n\nbody\n"] {
if let Some(message) = parser.parse_with(raw, &mut buffers) {
assert!(message.subject().is_some());
buffers = message.into_buffers();
buffers.shrink_to(1 << 20);
}
}