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.