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.

Reply via email to