Dave Rolsky schreef: > On Fri, 6 Jun 2003, Eugene van der Pijll wrote: > > > The generated TimeZone modules are a bit larger than they could be. With > > the attached patch, their total size is reduced by almost 50%. > > Can you resend this as a unified diff (-u)? I can't read the other kind > very easily so I can't actually figure out what this is doing.
OK. The changes are: - I moved the _generate_spans_until_match() method (that is included in perhaps half of all DT::TZ's, and is a largish piece of code) to TimeZone. This saves about 100kB. - I changed the format of the dst changes, from { 'short_name' => 'LMT', 'utc_end' => '57875470828', 'utc_start' => DateTime::TimeZone::NEG_INFINITY, 'local_end' => '57875472000', 'is_dst' => 0, 'offset' => 1172, 'local_start' => DateTime::TimeZone::NEG_INFINITY }, to ['LMT','57875470828',DateTime::TimeZone::NEG_INFINITY,'57875472000',0,1172,DateTime::TimeZone::NEG_INFINITY] This may make the generated file more obfuscated, but it does make a difference of 2Mb. (And I find the new format clearer in a way: it is easier to get an overview of all the changes.) - $last_observance contains a start date, which contained a language object. This object was included in the generated file, which means that half of the DT::TZ's included this code: 'language' => bless( { 'month_numbers' => {}, 'am_pm' => [ 'AM', 'PM' ], 'ordinal_suffixes' => [], 'month_abbreviations' => [ 'Jan', 'Feb', # etcetera Eugene diff -u -r DateTime-TimeZone/lib/DateTime/TimeZone.pm DateTime-TimeZone-2/lib/DateTime/TimeZone.pm --- DateTime-TimeZone/lib/DateTime/TimeZone.pm 2003-05-26 06:23:28.000000000 +0200 +++ DateTime-TimeZone-2/lib/DateTime/TimeZone.pm 2003-06-06 03:29:25.000000000 +0200 @@ -270,6 +270,59 @@ ); } +sub _generate_spans_until_match +{ + my $self = shift; + my $generate_until_year = shift; + my $seconds = shift; + my $type = shift; + + my @changes; + foreach my $rule (@{$self->_rules}) + { + foreach my $year ( $self->_max_year .. $generate_until_year ) + { + my $next = $rule->date_for_year( $year, $self->_last_offset ); + + # don't bother with changes we've seen already + next if $next->{utc}->utc_rd_as_seconds < $self->max_span->{utc_end}; + + push @changes, + DateTime::TimeZone::OlsonDB::Change->new + ( start_date => $next->{local}, + short_name => + sprintf( $self->_last_observance->format, $rule->letter ), + observance => $self->_last_observance, + rule => $rule, + ); + } + } + + $self->_max_year($generate_until_year); + my @sorted = sort { $a->start_date <=> $b->start_date } @changes; + + my $start_key = $type . '_start'; + my $end_key = $type . '_end'; + + my $match; + for ( my $x = 1; $x < @sorted; $x++ ) + { + my $last_offset = + $x == 1 ? $self->max_span->{offset} : $sorted[ $x - 2 ]->offset; + + my $span = + DateTime::TimeZone::OlsonDB::Change::two_changes_as_span + ( @sorted[ $x - 1, $x ], $last_offset ); + + push @{ $self->{spans} }, $span; + + $match = $span + if $seconds >= $span->{$start_key} && $seconds < $span->{$end_key}; + } + + return $match; +} + 1; diff -u -r DateTime-TimeZone/tools/parse_olson DateTime-TimeZone-2/tools/parse_olson --- DateTime-TimeZone/tools/parse_olson 2003-05-07 19:16:58.000000000 +0200 +++ DateTime-TimeZone-2/tools/parse_olson 2003-06-06 03:33:14.000000000 +0200 @@ -126,7 +126,7 @@ expand_to_year => $max_year, ); - my $spans = Dumper zone_as_data($zone); + my $spans = stringify_zones(zone_as_data($zone)); $spans =~ s/'inf'/DateTime::TimeZone::INFINITY/g; $spans =~ s/'-inf'/DateTime::TimeZone::NEG_INFINITY/g; @@ -325,6 +325,25 @@ return [EMAIL PROTECTED]; } +sub stringify_zones +{ + my $data = shift; + my @keys = keys %{$data->[0]}; + + return <<EOF +[ + map { my \%hash; [EMAIL PROTECTED]/@keys/} = [EMAIL PROTECTED]; \\\%hash } +EOF + . join("\n", map {stringify_zone($_, [EMAIL PROTECTED])} @$data) . "\n]"; +} + +sub stringify_zone +{ + my ($zone, $keys) = @_; + + return "\t[" . join(',', map "'$_'", @[EMAIL PROTECTED]) . '],'; +} + sub zone_generator { my $zone = shift; @@ -335,62 +354,20 @@ my $rules = !RULES; my $last_observance = !LAST_OBSERVANCE; -sub _generate_spans_until_match -{ - my $self = shift; - my $generate_until_year = shift; - my $seconds = shift; - my $type = shift; - - my @changes; - foreach my $rule (@$rules) - { - foreach my $year ( $max_year .. $generate_until_year ) - { - my $next = $rule->date_for_year( $year, !OFFSET ); - - # don't bother with changes we've seen already - next if $next->{utc}->utc_rd_as_seconds < $self->max_span->{utc_end}; - - push @changes, - DateTime::TimeZone::OlsonDB::Change->new - ( start_date => $next->{local}, - short_name => - sprintf( $last_observance->format, $rule->letter ), - observance => $last_observance, - rule => $rule, - ); - } - } - - $max_year = $generate_until_year; - my @sorted = sort { $a->start_date <=> $b->start_date } @changes; - - my $start_key = $type . '_start'; - my $end_key = $type . '_end'; - - my $match; - for ( my $x = 1; $x < @sorted; $x++ ) - { - my $last_offset = - $x == 1 ? $self->max_span->{offset} : $sorted[ $x - 2 ]->offset; - - my $span = - DateTime::TimeZone::OlsonDB::Change::two_changes_as_span - ( @sorted[ $x - 1, $x ], $last_offset ); - - push @{ $self->{spans} }, $span; - - $match = $span - if $seconds >= $span->{$start_key} && $seconds < $span->{$end_key}; - } - - return $match; +sub _last_offset { !OFFSET } +sub _last_observance { $last_observance } +sub _rules { $rules } +sub _max_year { + my ($self, $m) = @_; + $max_year = $m if defined $m; + return $max_year; } EOF my $last_observance = ($zone->sorted_changes)[-1]->observance; + delete $last_observance->{start}{language}; + # This assumes that there is only one observance from end of # changes til end of time, which should be guaranteed by code in # OlsonDB module.