]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/V2Writable.pm
v2writable: avoid "part" in internal subs and fields
[public-inbox.git] / lib / PublicInbox / V2Writable.pm
index 09ed4e7b99ff096d194a9e59ff79a9569b745c0f..a23139058a8b72804aac8317e7ac03ab86fbe40a 100644 (file)
@@ -7,7 +7,7 @@ package PublicInbox::V2Writable;
 use strict;
 use warnings;
 use base qw(PublicInbox::Lock);
-use PublicInbox::SearchIdxPart;
+use PublicInbox::SearchIdxShard;
 use PublicInbox::MIME;
 use PublicInbox::Git;
 use PublicInbox::Import;
@@ -23,8 +23,15 @@ use IO::Handle;
 # an estimate of the post-packed size to the raw uncompressed size
 my $PACKING_FACTOR = 0.4;
 
-# assume 2 cores if GNU nproc(1) is not available
-sub nproc_parts ($) {
+# SATA storage lags behind what CPUs are capable of, so relying on
+# nproc(1) can be misleading and having extra Xapian partions is a
+# waste of FDs and space.  It can also lead to excessive IO latency
+# and slow things down.  Users on NVME or other fast storage can
+# use the NPROC env or switches in our script/public-inbox-* programs
+# to increase Xapian shards
+our $NPROC_MAX_DEFAULT = 4;
+
+sub nproc_shards ($) {
        my ($creat_opt) = @_;
        if (ref($creat_opt) eq 'HASH') {
                if (defined(my $n = $creat_opt->{nproc})) {
@@ -32,20 +39,27 @@ sub nproc_parts ($) {
                }
        }
 
-       my $n = int($ENV{NPROC} || `nproc 2>/dev/null` || 2);
+       my $n = $ENV{NPROC};
+       if (!$n) {
+               chomp($n = `nproc 2>/dev/null`);
+               # assume 2 cores if GNU nproc(1) is not available
+               $n = 2 if !$n;
+               $n = $NPROC_MAX_DEFAULT if $n > $NPROC_MAX_DEFAULT;
+       }
+
        # subtract for the main process and git-fast-import
        $n -= 1;
        $n < 1 ? 1 : $n;
 }
 
-sub count_partitions ($) {
+sub count_shards ($) {
        my ($self) = @_;
        my $nparts = 0;
        my $xpfx = $self->{xpfx};
 
        # always load existing partitions in case core count changes:
-       # Also, partition count may change while -watch is running
-       # due to -compact
+       # Also, shard count may change while -watch is running
+       # due to "xcpdb --reshard"
        if (-d $xpfx) {
                foreach my $part (<$xpfx/*>) {
                        -d $part && $part =~ m!/[0-9]+\z! or next;
@@ -89,7 +103,7 @@ sub new {
                rotate_bytes => int((1024 * 1024 * 1024) / $PACKING_FACTOR),
                last_commit => [], # git repo -> commit
        };
-       $self->{partitions} = count_partitions($self) || nproc_parts($creat);
+       $self->{shards} = count_shards($self) || nproc_shards($creat);
        bless $self, $class;
 }
 
@@ -120,9 +134,9 @@ sub add {
 sub do_idx ($$$$$$$) {
        my ($self, $msgref, $mime, $len, $num, $oid, $mid0) = @_;
        $self->{over}->add_overview($mime, $len, $num, $oid, $mid0);
-       my $npart = $self->{partitions};
+       my $npart = $self->{shards};
        my $part = $num % $npart;
-       my $idx = idx_part($self, $part);
+       my $idx = idx_shard($self, $part);
        $idx->index_raw($len, $msgref, $num, $oid, $mid0, $mime);
        my $n = $self->{transact_bytes} += $len;
        $n >= (PublicInbox::SearchIdx::BATCH_BYTES * $npart);
@@ -238,15 +252,15 @@ sub num_for_harder {
        $num;
 }
 
-sub idx_part {
+sub idx_shard {
        my ($self, $part) = @_;
-       $self->{idx_parts}->[$part];
+       $self->{idx_shards}->[$part];
 }
 
 # idempotent
 sub idx_init {
        my ($self, $opt) = @_;
-       return if $self->{idx_parts};
+       return if $self->{idx_shards};
        my $ibx = $self->{-inbox};
 
        # do not leak read-only FDs to child processes, we only have these
@@ -274,19 +288,19 @@ sub idx_init {
                $self->lock_acquire unless ($opt && $opt->{-skip_lock});
                $over->create;
 
-               # -compact can change partition count while -watch is idle
-               my $nparts = count_partitions($self);
-               if ($nparts && $nparts != $self->{partitions}) {
-                       $self->{partitions} = $nparts;
+               # xcpdb can change shard count while -watch is idle
+               my $nparts = count_shards($self);
+               if ($nparts && $nparts != $self->{shards}) {
+                       $self->{shards} = $nparts;
                }
 
                # need to create all parts before initializing msgmap FD
-               my $max = $self->{partitions} - 1;
+               my $max = $self->{shards} - 1;
 
-               # idx_parts must be visible to all forked processes
-               my $idx = $self->{idx_parts} = [];
+               # idx_shards must be visible to all forked processes
+               my $idx = $self->{idx_shards} = [];
                for my $i (0..$max) {
-                       push @$idx, PublicInbox::SearchIdxPart->new($self, $i);
+                       push @$idx, PublicInbox::SearchIdxShard->new($self, $i);
                }
 
                # Now that all subprocesses are up, we can open the FDs
@@ -356,7 +370,7 @@ sub rewrite_internal ($$;$$$) {
        }
        my $over = $self->{over};
        my $cids = content_ids($old_mime);
-       my $parts = $self->{idx_parts};
+       my $parts = $self->{idx_shards};
        my $removed;
        my $mids = mids($old_mime->header_obj);
 
@@ -591,7 +605,7 @@ sub checkpoint ($;$) {
                        $im->checkpoint;
                }
        }
-       my $parts = $self->{idx_parts};
+       my $parts = $self->{idx_shards};
        if ($parts) {
                my $dbh = $self->{mm}->{dbh};
 
@@ -638,7 +652,7 @@ sub done {
        checkpoint($self);
        my $mm = delete $self->{mm};
        $mm->{dbh}->commit if $mm;
-       my $parts = delete $self->{idx_parts};
+       my $parts = delete $self->{idx_shards};
        if ($parts) {
                $_->remote_close for @$parts;
        }
@@ -813,7 +827,7 @@ sub atfork_child {
        my ($self) = @_;
        my $fh = delete $self->{reindex_pipe};
        close $fh if $fh;
-       if (my $parts = $self->{idx_parts}) {
+       if (my $parts = $self->{idx_shards}) {
                $_->atfork_child foreach @$parts;
        }
        if (my $im = $self->{im}) {
@@ -1037,7 +1051,7 @@ sub sync_prepare ($$$) {
 
 sub unindex_oid_remote ($$$) {
        my ($self, $oid, $mid) = @_;
-       $_->remote_remove($oid, $mid) foreach @{$self->{idx_parts}};
+       $_->remote_remove($oid, $mid) foreach @{$self->{idx_shards}};
        $self->{over}->remove_oid($oid, $mid);
 }