]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/V2Writable.pm
Msgmap.pm: Track the largest value of num ever assigned
[public-inbox.git] / lib / PublicInbox / V2Writable.pm
index 1316d628491f576c0096b3be215826d94e03aae9..c450980c8f51dbb86357602010fa5b1eab455d27 100644 (file)
@@ -63,6 +63,7 @@ sub new {
        }
 
        $v2ibx = PublicInbox::InboxWritable->new($v2ibx);
+       $v2ibx->umask_prepare;
 
        my $xpfx = "$dir/xap" . PublicInbox::Search::SCHEMA_VERSION;
        my $self = {
@@ -95,6 +96,13 @@ sub init_inbox {
 # mimics Import::add and wraps it for v2
 sub add {
        my ($self, $mime, $check_cb) = @_;
+       $self->{-inbox}->with_umask(sub {
+               _add($self, $mime, $check_cb)
+       });
+}
+
+sub _add {
+       my ($self, $mime, $check_cb) = @_;
 
        # spam check:
        if ($check_cb) {
@@ -348,12 +356,16 @@ sub remove_internal {
 
 sub remove {
        my ($self, $mime, $cmt_msg) = @_;
-       remove_internal($self, $mime, $cmt_msg);
+       $self->{-inbox}->with_umask(sub {
+               remove_internal($self, $mime, $cmt_msg);
+       });
 }
 
 sub purge {
        my ($self, $mime) = @_;
-       my $purges = remove_internal($self, $mime, undef, {});
+       my $purges = $self->{-inbox}->with_umask(sub {
+               remove_internal($self, $mime, undef, {});
+       });
        $self->idx_init if @$purges; # ->done is called on purges
        for my $i (0..$#$purges) {
                defined(my $cmt = $purges->[$i]) or next;
@@ -483,15 +495,21 @@ sub git_init {
        PublicInbox::Import::run_die(\@cmd);
 
        my $alt = "$all/objects/info/alternates";
-       my $new_obj_dir = "../../git/$epoch.git/objects";
        my %alts;
+       my @add;
        if (-e $alt) {
                open(my $fh, '<', $alt) or die "open < $alt: $!\n";
                %alts = map { chomp; $_ => 1 } (<$fh>);
        }
-       return $git_dir if $alts{$new_obj_dir};
+       foreach my $i (0..$epoch) {
+               my $dir = "../../git/$i.git/objects";
+               push @add, $dir if !$alts{$dir} && -d "$pfx/$i.git";
+       }
+       return $git_dir unless @add;
        open my $fh, '>>', $alt or die "open >> $alt: $!\n";
-       print $fh "$new_obj_dir\n" or die "print >> $alt: $!\n";
+       foreach my $dir (@add) {
+               print $fh "$dir\n" or die "print >> $alt: $!\n";
+       }
        close $fh or die "close $alt: $!\n";
        $git_dir
 }
@@ -635,7 +653,7 @@ sub mark_deleted {
        my $mids = mids($mime->header_obj);
        my $cid = content_id($mime);
        foreach my $mid (@$mids) {
-               $D->{"$mid\0$cid"} = 1;
+               $D->{"$mid\0$cid"} = $oid;
        }
 }
 
@@ -653,7 +671,7 @@ sub reindex_oid {
        my $num = -1;
        my $del = 0;
        foreach my $mid (@$mids) {
-               $del += (delete $D->{"$mid\0$cid"} || 0);
+               $del += delete($D->{"$mid\0$cid"}) ? 1 : 0;
                my $n = $mm_tmp->num_for($mid);
                if (defined $n && $n > $num) {
                        $mid0 = $mid;
@@ -861,10 +879,10 @@ sub index_sync {
        my $mm_tmp = $self->{mm}->tmp_clone;
        my $ranges = $opts->{reindex} ? [] : $self->last_commits($epoch_max);
 
-       my ($min, $max) = $mm_tmp->minmax;
+       my $high = $self->{mm}->num_highwater();
        my $regen = $self->index_prepare($opts, $epoch_max, $ranges);
-       $$regen += $max if $max;
-       my $D = {};
+       $$regen += $high if $high;
+       my $D = {}; # "$mid\0$cid" => $oid
        my @cmd = qw(log --raw -r --pretty=tformat:%H
                        --no-notes --no-color --no-abbrev --no-renames);
 
@@ -894,13 +912,13 @@ sub index_sync {
                delete $self->{reindex_pipe};
                $self->update_last_commit($git, $i, $cmt) if defined $cmt;
        }
-       my @d = sort keys %$D;
-       if (@d) {
-               warn "BUG: ", scalar(@d)," unseen deleted messages marked\n";
-               foreach (@d) {
-                       my ($mid, undef) = split(/\0/, $_, 2);
-                       warn "<$mid>\n";
-               }
+
+       # unindex is required for leftovers if "deletes" affect messages
+       # in a previous fetch+index window:
+       if (scalar keys %$D) {
+               my $git = $self->{-inbox}->git;
+               $self->unindex_oid($git, $_) for values %$D;
+               $git->cleanup;
        }
        $self->done;
 }