X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=lib%2FMojoFacets%2FData.pm;h=2a35b2db8e37baccd6c3631f7494a6e4e99985ad;hb=d7310b3c552ac0c37c2d85d9c64a46276ade6fff;hp=c75fde5f2785f19618e45f15668ee499e3be88fc;hpb=d9f2a3c7d340f35f244d53d62ed2b4561a8b3174;p=MojoFacets.git diff --git a/lib/MojoFacets/Data.pm b/lib/MojoFacets/Data.pm index c75fde5..2a35b2d 100644 --- a/lib/MojoFacets/Data.pm +++ b/lib/MojoFacets/Data.pm @@ -260,17 +260,8 @@ sub filter { my $name = $self->param('filter_name') || die "name?"; my @vals = $self->param('filter_vals'); - my $path = $self->session('path'); - - if ( @vals ) { - $self->_filter_on_data( $name, @vals ); - } else { - warn "# filter - $name\n"; - delete $filters->{$name}; - delete $loaded->{$path}->{filters}->{$name}; - } - - #warn "# filters ",dump($filters); + $self->_remove_filter( $name ); + $self->_filter_on_data( $name, @vals ) if @vals; $self->session( 'offset' => 0 ); @@ -442,35 +433,52 @@ sub items { } } - my $path_filters = $loaded->{$path}->{filters}; + my $filtered_names = join(' ',sort @filter_names); + +# warn "# filtered_names $filtered_names ", dump( $loaded->{$path}->{filtered}->{$filtered_names} ); + + if ( ! defined $loaded->{$path}->{filtered}->{$filtered_names} ) { - my $sort_descending = $sort eq 'd'; + my $path_filters = $loaded->{$path}->{filters}; - my @filtered; - foreach my $i ( 0 .. $#$sorted ) { - my $pos = $sort_descending ? $sorted->[$i] : $sorted->[ $#$sorted - $i ]; + warn "create combined filter for $filtered_names\n"; - push @filtered, $pos; - next if $#filter_names == -1; + my @filtered; + foreach my $i ( 0 .. $#$sorted ) { + my $pos = $sorted->[$i]; - my $skip = 0; - foreach ( @filter_names ) { - $skip ||= 1 if ! defined $path_filters->{$_}->{$pos}; + if ( $#filter_names == -1 ) { + push @filtered, $pos; + next; + } + + my $skip = 0; + foreach ( @filter_names ) { + $skip ||= 1 if ! defined $path_filters->{$_}->{$pos}; + } + next if $skip; + + push @filtered, $pos; } - next if $skip; - push @filtered, $pos; + $loaded->{$path}->{filtered}->{$filtered_names} = [ @filtered ]; } + my $filtered = $loaded->{$path}->{filtered}->{$filtered_names} + if defined $loaded->{$path}->{filtered}->{$filtered_names}; + + warn "filters $filtered_names" if $filtered; + my $sorted_items; my $data = $self->_loaded('data'); - foreach ( $offset .. $offset + $limit ) { - last unless defined $filtered[$_]; - push @$sorted_items, $data->{items}->[ $filtered[$_] ]; + my $sort_start = $sort eq 'd' ? $#$filtered : 0; + foreach ( 0 .. $limit ) { + my $i = $sort_start - ( $_ + $offset ); + last unless defined $filtered->[$i]; + push @$sorted_items, $data->{items}->[ $filtered->[$i] ]; } - - warn "# sorted_items ", $#$sorted_items + 1; + warn "# sorted_items ", $#$sorted_items + 1, " offset $offset limit $limit"; $self->render( order => $order, @@ -478,7 +486,7 @@ sub items { limit => $limit, sorted => $sorted_items, columns => [ @columns ], - rows => $#filtered + 1, + rows => $#$filtered + 1, numeric => { map { $_, $self->_is_numeric($_) } @columns }, filters => $self->_current_filters, ); @@ -505,14 +513,32 @@ sub _is_numeric { $stats->{$name}->{numeric} > $count / 2; } +sub _remove_filter { + my ($self,$name) = @_; + warn "_remove_filter $name\n"; + + my $path = $self->session('path'); + + delete $filters->{$name}; + delete $loaded->{$path}->{filters}->{$name}; + warn "filters left: ", keys %{ $loaded->{$path}->{filters} }; + + foreach ( + grep { /\b$name\b/ } + keys %{ $loaded->{$path}->{filtered} } + ) { + delete $loaded->{$path}->{filtered}->{$_}; + warn "remove filtered cache $_"; + } +} + sub facet { my $self = shift; my $path = $self->session('path') || $self->redirect_to( '/data/index' ); - if ( my $remove = $self->param('remove') ) { - delete $filters->{$remove}; - delete $loaded->{$path}->{filters}->{$remove}; + if ( my $name = $self->param('remove') ) { + $self->_remove_filter( $name ); $self->redirect_to( '/data/items' ); } @@ -520,14 +546,29 @@ sub facet { my $name = $self->param('name') || die "no name"; my $all = $self->_perm_scalar('all', 1); + my $data = $self->_loaded('data'); + + my $filters = $self->_current_filters; + my $filtered_names = join(' ',sort keys %$filters); +# warn "# filtered_names $filtered_names ", dump( $loaded->{$path}->{filtered}->{$filtered_names} ); + my $filtered = $loaded->{$path}->{filtered}->{$filtered_names} + if defined $loaded->{$path}->{filtered}->{$filtered_names}; + + if ( ! $filtered || $all ) { + $filtered = [ 0 .. $#{ $data->{items} } ]; + warn "filter all values\n"; + } else { + warn "filter using $filtered_names\n"; + } - foreach my $i ( $self->_data_items($all) ) { - if ( ! exists $i->{$name} ) { + foreach my $i ( @$filtered ) { + my $item = $data->{items}->[$i]; + if ( ! exists $item->{$name} ) { $facet->{ _missing }++; - } elsif ( ref $i->{$name} eq 'ARRAY' ) { - $facet->{$_}++ foreach @{ $i->{$name} }; + } elsif ( ref $item->{$name} eq 'ARRAY' ) { + $facet->{$_}++ foreach @{ $item->{$name} }; } else { - $facet->{ $i->{$name} }++; + $facet->{ $item->{$name} }++; } }