diff options
author | Ori Bernstein <ori@eigenstate.org> | 2017-11-19 19:13:00 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2017-11-20 21:54:54 -0800 |
commit | 2da5de43f610bfd33116a06631a4eaa85deb811d (patch) | |
tree | 1a343c079d5575c8652cb4ded7520fc599614953 /lib/date | |
parent | f637a3c144fe69410d7134cfe57b95258bfabe1f (diff) | |
download | mc-2da5de43f610bfd33116a06631a4eaa85deb811d.tar.gz |
Cache timezone info.
Loading and parsing zoneinfo files every time we print
a date? eugh.
Diffstat (limited to 'lib/date')
-rw-r--r-- | lib/date/zoneinfo+posixy.myr | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/lib/date/zoneinfo+posixy.myr b/lib/date/zoneinfo+posixy.myr index 69b2e85..33edd03 100644 --- a/lib/date/zoneinfo+posixy.myr +++ b/lib/date/zoneinfo+posixy.myr @@ -32,6 +32,11 @@ const zonepath = [ "/etc/zoneinfo" ] +var zonecache : std.htab(byte[:], zifile#)# +const __init__ = { + zonecache = std.mkht() +} + const findtzoff = {tz, tm -> std.option(date.duration) var path var zone @@ -40,26 +45,32 @@ const findtzoff = {tz, tm -> std.option(date.duration) var ds var i - /* load zone */ - if std.sleq(tz, "") || std.sleq(tz, "UTC") - -> `std.Some 0 - elif std.sleq(tz, "local") - path = std.sldup("/etc/localtime") - else - path = "" - for z : zonepath - path = std.pathcat(z, tz) - if sys.stat(path, &sb) == 0 - goto found + match std.htget(zonecache, tz) + | `std.Some z: + zone = z + | `std.None: + /* load zone */ + if std.sleq(tz, "") || std.sleq(tz, "UTC") + -> `std.Some 0 + elif std.sleq(tz, "local") + path = std.sldup("/etc/localtime") + else + path = "" + for z : zonepath + path = std.pathcat(z, tz) + if sys.stat(path, &sb) == 0 + goto found + ;; + std.slfree(path) ;; std.slfree(path) + -> `std.None ;; + :found + zone = load(path) std.slfree(path) - -> `std.None + std.htput(zonecache, std.sldup(tz), zone) ;; -:found - zone = load(path) - std.slfree(path) /* find applicable gmt offset */ cur = (tm / 1_000_000 : int32) @@ -70,28 +81,26 @@ const findtzoff = {tz, tm -> std.option(date.duration) /* nothing */ ;; ds = zone.ttinfo[zone.timetype[i]].gmtoff - free(zone) -> `std.Some ((ds : date.duration) * 1_000_000) } const load = {file var nisgmt, nisstd, nleap, ntime, ntype, nchar - var i, f, p + var i, f, p, data /* check magic */ match std.slurp(file) - | `std.Ok d: p = d - | `std.Err m: - -> std.zalloc() + | `std.Ok d: data = d + | `std.Err m: -> std.zalloc() ;; - if !std.sleq(p[:4], "TZif") + if !std.eq(data[:4], "TZif") std.put("{} is not a zone info file\n", file) -> std.zalloc() ;; /* skip to data */ - p = p[20:] + p = data[20:] (nisgmt, p) = fetchbe32(p) (nisstd, p) = fetchbe32(p) (nleap, p) = fetchbe32(p) @@ -136,6 +145,7 @@ const load = {file for i = 0; i < nisgmt; i++ (f.isgmt[i], p) = fetchbe8(p) ;; + std.slfree(data) -> f } |