X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=lib%2FMojoFacets%2FData.pm;h=7eccd2cd28fa319b82b66fc08c6dd82ace95e2d2;hb=eb91b48c88ce4008232c700a023d9481be5e97d8;hp=5d40d8e279134c8ef3e2bb8c91a677e4707a3f46;hpb=7ed8a4cc53db2b5d5391a46f5a1a5960a5a25613;p=MojoFacets.git diff --git a/lib/MojoFacets/Data.pm b/lib/MojoFacets/Data.pm index 5d40d8e..7eccd2c 100644 --- a/lib/MojoFacets/Data.pm +++ b/lib/MojoFacets/Data.pm @@ -11,6 +11,7 @@ use JSON; use Encode; use locale; use File::Find; +use Storable; our $loaded; our $filters; @@ -44,14 +45,38 @@ sub index { ); } -sub _load_path { +sub _save { my ( $self, $path ) = @_; - return if defined $loaded->{$path}->{data}; + my $name = $path; + my $dir = $self->app->home->rel_dir('data'); + $name =~ s/^$dir//; + $name =~ s/\/+/_/g; + my $dump_path = '/tmp/mojo_facets.' . $name . '.storable'; + + warn "save loaded to $dump_path"; + my $info = $loaded->{$path}; + store $info, $dump_path; + + # sync timestamp + my $mtime = $loaded->{$path}->{mtime}; + utime $mtime, $mtime, $dump_path; + + warn $dump_path, ' ', -s $dump_path, " bytes\n"; +} + +sub _load_path { + my ( $self, $path ) = @_; 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 +116,9 @@ sub _load_path { } } my $item; - $item->{ $header[$_] || "f_$_" } = [ $v[$_] ] foreach ( 0 .. $#v ); + foreach my $i ( 0 .. $#v ) { + $item->{ $header[$i] || "f_$i" } = [ $v[$i] ]; + } push @{ $data->{items} }, $item; } } else { @@ -144,14 +171,18 @@ sub _load_path { warn dump($stats); - $loaded->{ $path } = { + my $info = { header => [ @header ], stats => $stats, full_path => $full_path, size => -s $full_path, + mtime => (stat($full_path))[9], data => $data, }; + $loaded->{ $path } = $info; + $self->_save( $path ); + } @@ -183,8 +214,10 @@ sub load { sub _loaded { my ( $self, $name ) = @_; my $path = $self->session('path'); - die "$path $name doesn't exist in loaded ",dump( $loaded ) - unless defined $loaded->{$path}->{$name}; + if ( ! defined $loaded->{$path}->{$name} ) { + warn "$path $name doesn't exist in loaded ",dump( $loaded ); + $self->redirect_to('/data/index'); + } return $loaded->{$path}->{$name}; } @@ -405,7 +438,7 @@ sub _data_sorted_by { ; warn "sorted: $order numeric: $numeric items: ", $#sorted + 1, "\n"; - warn "# sorted ",dump( @sorted ); + #warn "# sorted ",dump( @sorted ); $loaded->{$path}->{sorted}->{$order} = [ @sorted ]; } @@ -489,7 +522,10 @@ sub items { my $i = $_ + $offset; last unless defined $filtered->[$i]; $i = $from_end - $i if $from_end; - push @$sorted_items, $data->{items}->[ $filtered->[$i] ]; + my $id = $filtered->[$i]; + push @$sorted_items, + my $item = $data->{items}->[ $id ]; + $item->{_row_id} ||= $id; } warn "# sorted_items ", $#$sorted_items + 1, " offset $offset limit $limit order $sort"; @@ -598,19 +634,23 @@ sub facet { my $numeric = $self->_is_numeric($name); my $sort = $self->param('sort'); - $sort ||= $numeric ? 'a' : 'c'; + # 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,