X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FMsgmap.pm;h=fdc71e46e214db9526406cf6a6cc76a6686667cf;hb=77704e711685d119fde9d1737029e102c76c9a14;hp=c6a73155401b9bb3c1c6fd4c5adedddb79a01bbf;hpb=b8c41362f2a5c8fcc6b1846a79c72bfa77565297;p=public-inbox.git diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm index c6a73155..fdc71e46 100644 --- a/lib/PublicInbox/Msgmap.pm +++ b/lib/PublicInbox/Msgmap.pm @@ -26,6 +26,9 @@ sub new { sub dbh_new { my ($f, $writable) = @_; + if ($writable && !-f $f) { # SQLite defaults mode to 0644, we want 0666 + open my $fh, '+>>', $f or die "failed to open $f: $!"; + } my $dbh = DBI->connect("dbi:SQLite:dbname=$f",'','', { AutoCommit => 1, RaiseError => 1, @@ -33,7 +36,6 @@ sub dbh_new { ReadOnly => !$writable, sqlite_use_immediate_transaction => 1, }); - $dbh->do('PRAGMA case_sensitive_like = ON'); $dbh; } @@ -78,7 +80,7 @@ sub meta_accessor { $prev = $dbh->selectrow_array($sql, undef, $key); if (defined $prev) { - $sql = 'UPDATE meta SET val = ? WHERE key = ? LIMIT 1'; + $sql = 'UPDATE meta SET val = ? WHERE key = ?'; $dbh->do($sql, undef, $value, $key); } else { $sql = 'INSERT INTO meta (key,val) VALUES (?,?)'; @@ -92,6 +94,14 @@ sub last_commit { $self->meta_accessor('last_commit', $commit); } +# v2 uses this to keep track of how up-to-date Xapian is +# old versions may be automatically GC'ed away in the future, +# but it's a trivial amount of storage. +sub last_commit_xap { + my ($self, $version, $i, $commit) = @_; + $self->meta_accessor("last_xap$version-$i", $commit); +} + sub created_at { my ($self, $second) = @_; $self->meta_accessor('created_at', $second); @@ -100,10 +110,10 @@ sub created_at { sub mid_insert { my ($self, $mid) = @_; my $dbh = $self->{dbh}; - my $sql = 'INSERT OR IGNORE INTO msgmap (mid) VALUES (?)'; - my $sth = $self->{mid_insert} ||= $dbh->prepare($sql); - $sth->bind_param(1, $mid); - return if $sth->execute == 0; + my $sth = $dbh->prepare_cached(<<''); +INSERT OR IGNORE INTO msgmap (mid) VALUES (?) + + return if $sth->execute($mid) == 0; $dbh->last_insert_id(undef, undef, 'msgmap', 'num'); } @@ -130,27 +140,14 @@ sub num_for { sub minmax { my ($self) = @_; my $dbh = $self->{dbh}; - my $sth = $self->{num_minmax} ||= - $dbh->prepare('SELECT MIN(num),MAX(num) FROM msgmap'); + # breaking MIN and MAX into separate queries speeds up from 250ms + # to around 700us with 2.7million messages. + my $sth = $dbh->prepare_cached('SELECT MIN(num) FROM msgmap', undef, 1); $sth->execute; - $sth->fetchrow_array; -} - -sub mid_prefixes { - my ($self, $pfx, $limit) = @_; - - die "No prefix given" unless (defined $pfx && $pfx ne ''); - $pfx =~ s/([%_])/\\$1/g; - $pfx .= '%'; - - $limit ||= 100; - $limit += 0; # force to integer - $limit ||= 100; - - $self->{dbh}->selectcol_arrayref('SELECT mid FROM msgmap ' . - 'WHERE mid LIKE ? ESCAPE ? ' . - "ORDER BY num DESC LIMIT $limit", - undef, $pfx, '\\'); + my $min = $sth->fetchrow_array; + $sth = $dbh->prepare_cached('SELECT MAX(num) FROM msgmap', undef, 1); + $sth->execute; + ($min, $sth->fetchrow_array); } sub mid_delete { @@ -202,7 +199,7 @@ sub msg_range { my $attr = { Columns => [] }; my $mids = $dbh->selectall_arrayref(<<'', $attr, $$beg, $end); SELECT num,mid FROM msgmap WHERE num >= ? AND num <= ? -ORDER BY num ASC +ORDER BY num ASC LIMIT 1000 $$beg = $mids->[-1]->[0] + 1 if @$mids; $mids