summaryrefslogtreecommitdiff
path: root/time
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-03-17 21:53:01 +0000
committerJakub Jelinek <jakub@redhat.com>2007-03-17 21:53:01 +0000
commit6ce38a95a4c8318df75cf91fbd90101601b3fa7f (patch)
tree044df11ca5f10f967644dffe5b0f621d6ac36188 /time
parentb428b742cf54d423e5a7a68fcbec9473303eeafa (diff)
Updated to fedora-glibc-20070317T2130cvs/fedora-glibc-2_5_90-19
Diffstat (limited to 'time')
-rw-r--r--time/tst-mktime2.c5
-rw-r--r--time/tzfile.c53
2 files changed, 53 insertions, 5 deletions
diff --git a/time/tst-mktime2.c b/time/tst-mktime2.c
index 6279218cba..0e4fd1e786 100644
--- a/time/tst-mktime2.c
+++ b/time/tst-mktime2.c
@@ -102,7 +102,8 @@ static int
do_test (void)
{
time_t t, delta;
- int i, j;
+ int i;
+ unsigned int j;
setenv ("TZ", "America/Sao_Paulo", 1);
/* This test makes some buggy mktime implementations loop.
@@ -128,7 +129,7 @@ do_test (void)
mktime_test ((time_t) (60 * 60));
mktime_test ((time_t) (60 * 60 * 24));
- for (j = 1; 0 < j; j *= 2)
+ for (j = 1; j <= INT_MAX; j *= 2)
bigtime_test (j);
bigtime_test (j - 1);
}
diff --git a/time/tzfile.c b/time/tzfile.c
index ea2d7cae4c..0d48c8ca0c 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -548,13 +548,60 @@ find_transition (time_t timer)
if (i == num_types)
i = 0;
}
+ else if (timer >= transitions[num_transitions - 1])
+ i = type_idxs[num_transitions - 1];
else
{
/* Find the first transition after TIMER, and
then pick the type of the transition before it. */
- for (i = 1; i < num_transitions; ++i)
- if (timer < transitions[i])
- break;
+ size_t lo = 0;
+ size_t hi = num_transitions - 1;
+ /* Assume that DST is changing twice a year and guess initial
+ search spot from it.
+ Half of a gregorian year has on average 365.2425 * 86400 / 2
+ = 15778476 seconds. */
+ i = (transitions[num_transitions - 1] - timer) / 15778476;
+ if (i < num_transitions)
+ {
+ i = num_transitions - 1 - i;
+ if (timer < transitions[i])
+ {
+ if (i < 10 || timer >= transitions[i - 10])
+ {
+ /* Linear search. */
+ while (timer < transitions[i - 1])
+ --i;
+ goto found;
+ }
+ hi = i - 10;
+ }
+ else
+ {
+ if (i + 10 >= num_transitions || timer < transitions[i + 10])
+ {
+ /* Linear search. */
+ while (timer >= transitions[i])
+ ++i;
+ goto found;
+ }
+ lo = i + 10;
+ }
+ }
+
+ /* Binary search. */
+ /* assert (timer >= transitions[lo] && timer < transitions[hi]); */
+ while (lo + 1 < hi)
+ {
+ i = (lo + hi) / 2;
+ if (timer < transitions[i])
+ hi = i;
+ else
+ lo = i;
+ }
+ i = hi;
+
+ found:
+ /* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
i = type_idxs[i - 1];
}