diff options
author | Eric Wong <e@80x24.org> | 2023-08-24 01:22:33 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-08-24 07:47:51 +0000 |
commit | b18ecb7707e83cb8cb38c3736aecd984999ca0a7 (patch) | |
tree | 0f159212810c98aa07d26b6f7f28f4b8dbc9b302 /lib/PublicInbox/XapClient.pm | |
parent | cf96412eb8f193ebd334fae340b2d91b6b7f2afe (diff) | |
download | public-inbox-b18ecb7707e83cb8cb38c3736aecd984999ca0a7.tar.gz |
This allows us to perform the expensive "dump_ibx" operations in native C++ code using the Xapian C++ library. This provides the majority of the speedup with the -cindex --associate switch. Eventually this may be expanded to cover all uses of Xapian within the project to ensure we have access to Xapian APIs which aren't available in XS|SWIG bindings; and also for ease-of-installation on systems which don't provide pre-packaged Perl Xapian bindings (e.g. OpenBSD 7.3) but do provide Xapian development libraries. Most of the C++ code is still C, as I'm not remotely familiar with C++ compared to C. I suspect many users and potential hackers being from git, Linux kernel, and glibc world are in the same boat.
Diffstat (limited to 'lib/PublicInbox/XapClient.pm')
-rw-r--r-- | lib/PublicInbox/XapClient.pm | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/PublicInbox/XapClient.pm b/lib/PublicInbox/XapClient.pm new file mode 100644 index 00000000..56e3c3b4 --- /dev/null +++ b/lib/PublicInbox/XapClient.pm @@ -0,0 +1,50 @@ +#!perl -w +# Copyright (C) all contributors <meta@public-inbox.org> +# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> + +# This talks to (XapHelperCxx.pm + xap_helper.h) or XapHelper.pm +# and will eventually allow users with neither XS nor SWIG Perl +# bindings to use Xapian as long as they have Xapian development +# headers/libs and a C++ compiler +package PublicInbox::XapClient; +use v5.12; +use PublicInbox::Spawn qw(spawn); +use Socket qw(AF_UNIX SOCK_SEQPACKET MSG_EOR); +use PublicInbox::IPC; + +sub mkreq { + my ($self, $ios, @arg) = @_; + my ($r, $w, $n); + if (!defined($ios->[0])) { + pipe($r, $w) or die "pipe: $!"; + $ios->[0] = $w; + } + my @fds = map fileno($_), @$ios; + my $buf = join("\0", @arg, ''); + $n = PublicInbox::IPC::send_cmd($self->{io}, \@fds, $buf, MSG_EOR) // + die "send_cmd: $!"; + $n == length($buf) or die "send_cmd: $n != ".length($buf); + $r; +} + +sub start_helper { + my @argv = @_; + socketpair(my $sock, my $in, AF_UNIX, SOCK_SEQPACKET, 0) or + die "socketpair: $!"; + my $cls = ($ENV{PI_NO_CXX} ? undef : eval { + require PublicInbox::XapHelperCxx; + PublicInbox::XapHelperCxx::check_build(); + 'PublicInbox::XapHelperCxx'; + }) // do { + require PublicInbox::XapHelper; + 'PublicInbox::XapHelper'; + }; + # ensure the child process has the same @INC we do: + my $env = { PERL5LIB => join(':', @INC) }; + my $pid = spawn([$^X, ($^W ? ('-w') : ()), "-M$cls", '-e', + $cls.'::start(@ARGV)', '--', @argv], + $env, { 0 => $in }); + ((bless { io => $sock, impl => $cls }, __PACKAGE__), $pid); +} + +1; |