use v6.d; unit class MaildirIndexer::Store; use MaildirIndexer::LogTimelineSchema; use MaildirIndexer::Index; use MaildirIndexer::Parser; use MaildirIndexer::ScanDir; has Lock $!lock .= new; has MaildirIndexer::Index @.indices is required; has Channel $.file-channel is required; has Int $.workers = Kernel.cpu-cores - 1; method dump(--> Nil) { $!lock.protect: { .dump() for @!indices; } } method start(--> Nil) { for ^$.workers { start react { CATCH { warn .gist }; whenever $.file-channel -> $file { when $file ~~ MaildirIndexer::ScanDir::End { MaildirIndexer::LogTimelineSchema::Scan::End.log(); } when $file ~~ :e & :f { MaildirIndexer::LogTimelineSchema::Store::Add.log: :file($file.path), { self.add-file($file); } } when $file ~~ :!e { MaildirIndexer::LogTimelineSchema::Store::Rm.log: :file($file.path), { self.del-file($file); } } } } } } method add-file(IO:D $file --> Nil) { my Str $mailbox = mailbox-from-path($file.path) or return; my MaildirIndexer::Email $email = parse-email($file,:headers-only) or return; CATCH { warn .gist; return }; $!lock.protect: { .add-mail($email,$mailbox) for @!indices; } return; } method del-file(IO:D $file --> Nil) { my $mailbox = mailbox-from-path($file.path) or return; $!lock.protect: { .del-path($file,$mailbox) for @!indices; } return; } method mailbox-for-email(MaildirIndexer::Email:D $email --> Str) { MaildirIndexer::LogTimelineSchema::Store::Find.log: { $!lock.protect: { for @!indices -> $index { with $index.mailbox-for-email($email) { return $_ }; } } return Nil; } } sub mailbox-from-path(Str() $path --> Str) { $path ~~ m{'/' (<-[/]>+?) '/' [cur|new|tmp] '/'} and return ~$/[0]; return Nil; }