X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=lib%2FMojoFacets%2FData.pm;h=e69c16e5fbac008e77afa35f88b6fbe7a2a862c5;hb=2c8d9972340cb72f8eb5c0eb1385eb32ae657144;hp=b81816b88a89fac2d0f75416e496d6f72c8c0628;hpb=0bb06bc63b9a08116ecfe68938d19087e796bfec;p=MojoFacets.git diff --git a/lib/MojoFacets/Data.pm b/lib/MojoFacets/Data.pm index b81816b..e69c16e 100644 --- a/lib/MojoFacets/Data.pm +++ b/lib/MojoFacets/Data.pm @@ -47,11 +47,15 @@ sub index { sub _load_path { my ( $self, $path ) = @_; - return if defined $loaded->{$path}->{data}; - my $full_path = $self->app->home->rel_file( 'data/' . $path ); die "$full_path $!" unless -r $full_path; + if ( defined $loaded->{$path}->{data} ) { + my $mtime = (stat($full_path))[9]; + return if $loaded->{$path}->{mtime} == $mtime; + warn "reload $full_path, modified ", time() - $mtime, " seconds ago\n"; + } + # we could use Mojo::JSON here, but it's too slow # $data = from_json read_file $path; my $data = read_file $full_path; @@ -91,7 +95,12 @@ sub _load_path { } } my $item; - $item->{ $header[$_] || "f_$_" } = [ $v[$_] ] foreach ( 0 .. $#v ); + foreach my $i ( 0 .. $#v ) { + my $v = $v[$i]; + # unpack numeric values separated by commas + my $a = $v =~ m/\d+\s*,\s*\d+/ ? [ split(/\,\s*/,$v) ] : [ $v ]; + $item->{ $header[$i] || "f_$i" } = $a; + } push @{ $data->{items} }, $item; } } else { @@ -127,6 +136,16 @@ sub _load_path { if $stats->{$n}->{array} == $stats->{$n}->{count}; } + if ( ! @header ) { + if ( defined $data->{header} ) { + if ( ref $data->{header} eq 'ARRAY' ) { + @header = @{ $data->{header} }; + } else { + warn "header not array ", dump( $data->{header} ); + } + } + } + @header = sort { $stats->{$b}->{count} <=> $stats->{$a}->{count} } grep { defined $stats->{$_}->{count} } keys %$stats @@ -139,6 +158,7 @@ sub _load_path { stats => $stats, full_path => $full_path, size => -s $full_path, + mtime => (stat($full_path))[9], data => $data, }; @@ -370,6 +390,8 @@ sub _data_sorted_by { my $path = $self->session('path'); + warn "_data_sorted_by $order from $path"; + if ( defined $loaded->{$path}->{sorted}->{$order} ) { return $loaded->{$path}->{sorted}->{$order}; } @@ -392,7 +414,8 @@ sub _data_sorted_by { } @{ $data->{items} } ; - warn "sorted $order"; # ,dump( @sorted ); + warn "sorted: $order numeric: $numeric items: ", $#sorted + 1, "\n"; + #warn "# sorted ",dump( @sorted ); $loaded->{$path}->{sorted}->{$order} = [ @sorted ]; } @@ -433,15 +456,15 @@ sub items { } } - my $filtered_names = join(' ',sort @filter_names); + my $all_filters = join(' ',sort @filter_names,'order:',$order); -# warn "# filtered_names $filtered_names ", dump( $loaded->{$path}->{filtered}->{$filtered_names} ); +# warn "# all_filters $all_filters ", dump( $loaded->{$path}->{filtered}->{$all_filters} ); - if ( ! defined $loaded->{$path}->{filtered}->{$filtered_names} ) { + if ( ! defined $loaded->{$path}->{filtered}->{$all_filters} ) { my $path_filters = $loaded->{$path}->{filters}; - warn "create combined filter for $filtered_names\n"; + warn "create combined filter for $all_filters\n"; my @filtered; foreach my $i ( 0 .. $#$sorted ) { @@ -461,13 +484,13 @@ sub items { push @filtered, $pos; } - $loaded->{$path}->{filtered}->{$filtered_names} = [ @filtered ]; + $loaded->{$path}->{filtered}->{$all_filters} = [ @filtered ]; } - my $filtered = $loaded->{$path}->{filtered}->{$filtered_names} - if defined $loaded->{$path}->{filtered}->{$filtered_names}; + my $filtered = $loaded->{$path}->{filtered}->{$all_filters} + if defined $loaded->{$path}->{filtered}->{$all_filters}; - warn "filtered_names $filtered_names",dump( $filtered ) if $filtered; + warn "all_filters $all_filters produced ", $#$filtered + 1, " items\n" if $filtered; my $sorted_items; my $data = $self->_loaded('data'); @@ -550,16 +573,15 @@ sub facet { 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}; + my $all_filters = join(' ',sort keys %$filters,'order:',$self->session('order')); + my $filtered = $loaded->{$path}->{filtered}->{$all_filters} + if defined $loaded->{$path}->{filtered}->{$all_filters}; if ( ! $filtered || $all ) { $filtered = [ 0 .. $#{ $data->{items} } ]; warn "filter all values\n"; } else { - warn "filter using $filtered_names\n"; + warn "filter using $all_filters\n"; } foreach my $i ( @$filtered ) { @@ -583,22 +605,26 @@ sub facet { $checked = $self->_checked( @{ $filters->{$name} } ) if defined $filters->{$name}; - my $sort = $self->param('sort') || 'c'; - - # sort facet numerically if more >50% elements are numeric my $numeric = $self->_is_numeric($name); + my $sort = $self->param('sort'); + # sort numeric facets with more than 5 values ascending + $sort ||= $numeric && $#facet_names > 4 ? 'a' : 'c'; + @facet_names = sort { - if ( $sort =~ m/a/i ) { - $numeric ? $a <=> $b : lc $a cmp lc $b; - } elsif ( $sort =~ m/d/i ) { - $numeric ? $b <=> $a : lc $b cmp lc $a; - } elsif ( $sort =~ m/c/i ) { - ( $facet->{$b} || -1 ) <=> ( $facet->{$a} || -1 ) + my $result; + if ( $sort eq 'a' ) { + $result = $numeric ? $a <=> $b : lc $a cmp lc $b; + } elsif ( $sort eq 'd' ) { + $result = $numeric ? $b <=> $a : lc $b cmp lc $a; + } elsif ( $sort eq 'c' ) { + $result = ( $facet->{$b} || -1 ) <=> ( $facet->{$a} || -1 ) } else { warn "unknown sort: $sort"; - $a cmp $b; + $result = $a cmp $b; } + $result = $a cmp $b unless defined $result; # FIXME cludge for numeric facets with invalid data + $result; } @facet_names; $self->render( name => $name, facet => $facet, checked => $checked,