browser: store only changed values in version support
authorMischa POSLAWSKY <perl@shiar.org>
Mon, 15 Nov 2021 18:15:25 +0000 (19:15 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 6 Dec 2021 11:07:29 +0000 (12:07 +0100)
Full storage does not scale well, taking over 1.2s to load the current 23MB
perl structure (mostly indentation, minified it's 3MB like the original json).
Simple deduplication reduces this to 2.6MB pp (800kB as json) which takes only
0.2s excluding parsing.

browser.plp
tools/mkcaniuse

index 2fe75009ef3cd293b8296ee7e19594b24db41592..b6b501e5be17a44efa70275cd939f8fa9b650e03 100644 (file)
@@ -279,9 +279,12 @@ sub featurescore {
                if ($canihas) {
                        while (my ($browser, $versions) = each %$row) {
                                ref $versions eq 'HASH' or next;
-                               while (my ($version, $status) = each %$versions) {
+                               my $prev;
+                               for my $version (@{ $caniuse->{agents}->{$browser}->{versions} }) {
+                                       my $status = $versions->{$version} // $prev;
                                        $status =~ s/\h\#\d+//g;
                                        $rank += ($canihas->{$browser}->{$version} || .001) * $PSTATS{$status};
+                                       $prev = $status;
                                }
                        }
                        return $rank;
@@ -392,15 +395,15 @@ sub saybrowsercols {
                my $compare = (
                        !defined $ver ? undef :      # last column if nameless
                        ref $data ne 'HASH' ? '' :   # unclassified if no support hash
-                       $data->{ $ver->[-1] } // $prev  # known or inherit from predecessor
-                       // (grep { defined } @{$data}{ map { $_->[0] } @{ $versions{$browser} } })[0]
-                          ~~ 'n' && 'n'             # first known version is unsupported
+                       (first { defined } @{$data}{ reverse @{$ver} })  # last known version
+                       // $prev                     # inherit from predecessor
                        || 'u'                       # unsure
                );
-               unless (!defined $prev or $prev ~~ $compare) {
-                       my @vercover = (map { @{$_} } @span);
+               if (defined $prev and not $prev ~~ $compare) {
+                       # different columns
+                       my @vercover = (map { @{$_} } @span);  # accumulated conforming versions
                        for ($ver ? @{$ver} : ()) {
-                               $data->{$_} eq $data->{$vercover[-1]} or last;
+                               last if defined $data->{$_};  # until different
                                push @vercover, $_;  # matches from next span start
                        }
                        my $usage = sum(@{ $canihas->{$browser} }{@vercover});
@@ -438,7 +441,11 @@ sub saybrowsercols {
                        undef $prev;
                        @span = ();
                }
-               push @span, $ver && [ grep { $data->{ $_ } eq $data->{ $ver->[-1] } } @{$ver} ];
+               if ($ver) {
+                       my $startversion = first { defined $data->{ $ver->[$_] } }
+                               reverse 0 .. $#{$ver};  # compare index
+                       push @span, [ @{$ver}[ $startversion .. $#{$ver} ] ];
+               }
                $prev = $compare;
        }
 }
index f72122b6f309538a494d027a27d1194ac3068d76..b162c2f3f1d521ea8fb536f39b980963e7e56ccb 100755 (executable)
@@ -8,7 +8,7 @@ use File::stat;
 use Time::Piece;
 use List::Util 'uniq';
 
-our $VERSION = '1.03';
+our $VERSION = '1.04';
 
 my %BROWSERJOIN = (
        edge    => 'ie',
@@ -58,6 +58,22 @@ for my $feature (values %{ $data->{data} }) {
 
 while (my ($agent, $row) = each %{ $data->{agents} }) {
        $row->{versions} = [ uniq map { $_->{version} } @{ $row->{version_list} } ];
+
+       # omit identical values from subsequent versions
+       for my $feature (values %{ $data->{data} }) {
+               my $cmp;  # same value to be omitted
+               my $verstats = $feature->{stats}->{$agent};
+               for my $version (@{ $row->{versions} }) {
+                       defined $verstats->{$version}
+                               or warn "missing feature $feature->{title} for $agent $version";
+                       if (defined $cmp and $verstats->{$version} eq $cmp) {
+                               delete $verstats->{$version};
+                       }
+                       else {
+                               $cmp = $verstats->{$version};
+                       }
+               }
+       }
 }
 
 say "# automatically generated by $0";