my ($self, @argv) = @_;
require PublicInbox::LeiXSearch;
require PublicInbox::LeiOverview;
+ require PublicInbox::V2Writable;
PublicInbox::Config->json; # preload before forking
my $opt = $self->{opt};
# prepare any number of LeiXSearch || LeiSearch || Inbox || URL
}
if (@only) {
for my $loc (@only) {
- $lxs->prepare_external($self->ext_canonicalize($loc));
+ my @loc = $self->get_externals($loc) or return;
+ $lxs->prepare_external($_) for @loc;
}
} else {
for my $loc (@{$opt->{include} // []}) {
- $lxs->prepare_external($self->ext_canonicalize($loc));
+ my @loc = $self->get_externals($loc) or return;
+ $lxs->prepare_external($_) for @loc;
}
# --external is enabled by default, but allow --no-external
if ($opt->{external} //= 1) {
- my %x = map {;
- ($self->ext_canonicalize($_), 1)
- } @{$self->{exclude} // []};
+ my %x;
+ for my $loc (@{$opt->{exclude} // []}) {
+ my @l = $self->get_externals($loc, 1) or return;
+ $x{$_} = 1 for @l;
+ }
my $ne = $self->externals_each(\&prep_ext, $lxs, \%x);
$opt->{remote} //= !($lxs->locals - $opt->{'local'});
if ($opt->{'local'}) {
unless ($lxs->locals || $lxs->remotes) {
return $self->fail('no local or remote inboxes to search');
}
- my $xj = $lxs->concurrency($opt);
- my $ovv = PublicInbox::LeiOverview->new($self) or return;
+ my ($xj, $mj) = split(/,/, $opt->{jobs} // '');
+ if (defined($xj) && $xj ne '' && $xj !~ /\A[1-9][0-9]*\z/) {
+ return $self->fail("`$xj' search jobs must be >= 1");
+ }
+ $xj ||= $lxs->concurrency($opt); # allow: "--jobs ,$WRITER_ONLY"
+ my $nproc = $lxs->detect_nproc; # don't memoize, schedtool(1) exists
+ $xj = $nproc if $xj > $nproc;
+ PublicInbox::LeiOverview->new($self) or return;
$self->atfork_prepare_wq($lxs);
$lxs->wq_workers_start('lei_xsearch', $xj, $self->oldset);
delete $lxs->{-ipc_atfork_child_close};
if (my $l2m = $self->{l2m}) {
- my $mj = 4; # TODO: configurable
+ if (defined($mj) && $mj !~ /\A[1-9][0-9]*\z/) {
+ return $self->fail("`$mj' writer jobs must be >= 1");
+ }
+ $mj //= $nproc;
$self->atfork_prepare_wq($l2m);
$l2m->wq_workers_start('lei2mail', $mj, $self->oldset);
delete $l2m->{-ipc_atfork_child_close};
# descending docid order
$mset_opt{relevance} //= -2 if $opt->{thread};
$self->{mset_opt} = \%mset_opt;
- $ovv->ovv_begin($self);
+ $self->{ovv}->ovv_begin($self);
$lxs->do_query($self);
}
+# shell completion helper called by lei__complete
+sub _complete_q {
+ my ($self, @argv) = @_;
+ my $ext = qr/\A(?:-I|(?:--(?:include|exclude|only)))\z/;
+ my @cur;
+ while (@argv) {
+ if ($argv[-1] =~ $ext) {
+ my @c = $self->_complete_forget_external(@cur);
+ # try basename match:
+ if (scalar(@cur) == 1 && index($cur[0], '/') < 0) {
+ my $all = $self->externals_each;
+ my %bn;
+ for my $loc (keys %$all) {
+ my $bn = (split(m!/!, $loc))[-1];
+ ++$bn{$bn};
+ }
+ push @c, grep {
+ $bn{$_} == 1 && /\A\Q$cur[0]/
+ } keys %bn;
+ }
+ return @c if @c;
+ }
+ unshift(@cur, pop @argv);
+ }
+ ();
+}
+
# Stuff we may pass through to curl (as of 7.64.0), see curl manpage for
# details, so most options which make sense for HTTP/HTTPS (including proxy
# support for Tor and other methods of getting past weird networks).