Skip to content

Instantly share code, notes, and snippets.

@preaction
Last active February 18, 2016 23:14
Show Gist options
  • Save preaction/ccbf8a638031701e87c2 to your computer and use it in GitHub Desktop.
Save preaction/ccbf8a638031701e87c2 to your computer and use it in GitHub Desktop.
use strict;
use warnings;
use feature qw( :5.10 );
use Benchmark qw( cmpthese );
use List::Util qw( reduce );
my @index_tags = qw( -foo +bar -baz );
my @pages = (
{ tags => [qw( foo )] },
{ tags => [qw( bar )] },
{ tags => [qw( baz )] },
{ tags => [qw( bar foo )] },
{ tags => [qw( foo bar )] },
{ tags => [qw( foo baz )] },
{ tags => [qw( baz bar )] },
{ tags => [qw( bar baz )] },
{ tags => [qw( foo bar baz )] },
{ tags => [qw( baz bar foo )] },
{ tags => [qw( bar baz foo )] },
{ tags => [qw( bar foo baz )] },
);
sub pr454 {
# Filter pages according to their index tags
my @index_post_pages;
my @tags;
my %tag_handler;
for my $tag ( @index_tags ) {
if ($tag =~ /([+-])(.+)/) {
push @tags, $2;
$tag_handler{$2} = $1;
}
}
for my $page ( @pages ) {
# Each tag on this page gets '+', '-', or undef according to site's index_tags
my %page_tag_handler = map { ($_, $tag_handler{$_}) } @{$page->{tags}};
# Each document's tags must be considered in the order decreed by the site's index_tags array
my $add = ( List::Util::reduce { ($page_tag_handler{$b}) // $a } ('+', @tags) ) ne '-';
push @index_post_pages, $page if $add;
}
die unless scalar @index_post_pages == 3;
}
sub doug_reduce {
my @tags;
my %flag;
for my $tag ( @index_tags ) {
if ($tag =~ /([+-])(.+)/) {
push @tags, $2;
$flag{$2} = $1;
}
}
my @index_post_pages;
PAGE: for my $page ( @pages ) {
my %page_flag;
@page_flag{ @{ $page->{tags} } } = @flag{ @{ $page->{tags} } };
my $page_flag = reduce { $page_flag{ $b } || $a } '+', @tags;
push @index_post_pages, $page if $page_flag eq '+';
}
die unless scalar @index_post_pages == 3;
}
sub doug_grep {
my @tags;
my %flag;
for my $tag ( @index_tags ) {
if ($tag =~ /([+-])(.+)/) {
push @tags, $2;
$flag{$2} = $1;
}
}
my @index_post_pages;
PAGE: for my $page ( @pages ) {
my $page_flag = '+';
my %page_tags;
@page_tags{ @{ $page->{tags} } } = 1; # we use exists(), so value doesn't matter
for my $tag ( grep { exists $page_tags{ $_ } } @tags ) {
$page_flag = $flag{ $tag };
}
push @index_post_pages, $page if $page_flag eq '+';
}
die unless scalar @index_post_pages == 3;
}
sub doug_regex {
my @tags;
my %flag;
for my $tag_spec ( @index_tags ) {
$tag_spec =~ /([+-])(.+)/;
push @tags, $2;
$flag{$2} = $1;
}
my @index_post_pages;
PAGE: for my $page ( @pages ) {
my $page_flag = '+';
my %page_tags;
@page_tags{ @{ $page->{tags} } } = 1; # we use exists(), so value doesn't matter
for my $tag ( @tags ) {
if ( exists $page_tags{ $tag } ) {
$page_flag = $flag{ $tag };
}
}
push @index_post_pages, $page if $page_flag eq '+';
}
die unless scalar @index_post_pages == 3;
}
sub doug_plain {
my @tags;
my %flag;
for my $tag_spec ( @index_tags ) {
my $tag = substr $tag_spec, 1;
push @tags, $tag;
$flag{$tag} = substr $tag_spec, 0, 1;
}
my @index_post_pages;
PAGE: for my $page ( @pages ) {
my $page_flag = '+';
my %page_tags;
@page_tags{ @{ $page->{tags} } } = 1; # we use exists(), so value doesn't matter
for my $tag ( @tags ) {
if ( exists $page_tags{ $tag } ) {
$page_flag = $flag{ $tag };
}
}
push @index_post_pages, $page if $page_flag eq '+';
}
die unless scalar @index_post_pages == 3;
}
sub master {
my @index_post_pages;
PAGE: for my $page ( @pages ) {
my $add = 1;
for my $tag_spec ( @index_tags ) {
my $flag = substr $tag_spec, 0, 1;
my $tag = substr $tag_spec, 1;
if ( grep { $_ eq $tag } @{ $page->{tags} } ) {
$add = $flag eq '-' ? 0 : 1;
}
}
push @index_post_pages, $page if $add;
}
die unless scalar @index_post_pages == 3;
}
cmpthese( -2, {
pr454 => \&pr454,
master => \&master,
doug_reduce => \&doug_reduce,
doug_grep => \&doug_grep,
doug_regex => \&doug_regex,
doug_plain => \&doug_plain,
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment