ref: 2da5de43f610bfd33116a06631a4eaa85deb811d
parent: f637a3c144fe69410d7134cfe57b95258bfabe1f
author: Ori Bernstein <[email protected]>
date: Sun Nov 19 14:13:00 EST 2017
Cache timezone info. Loading and parsing zoneinfo files every time we print a date? eugh.
--- a/lib/date/zoneinfo+posixy.myr
+++ b/lib/date/zoneinfo+posixy.myr
@@ -32,6 +32,11 @@
"/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 @@
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 @@
/* 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 @@
for i = 0; i < nisgmt; i++
(f.isgmt[i], p) = fetchbe8(p)
;;
+ std.slfree(data)
-> f
}