Skip to content

Commit

Permalink
Add tzdb_data crate
Browse files Browse the repository at this point in the history
Splitting up the generated data makes maintenance easier.
  • Loading branch information
Kijewski committed Dec 30, 2023
1 parent ec2e0bc commit a1b854c
Show file tree
Hide file tree
Showing 22 changed files with 328 additions and 250 deletions.
84 changes: 11 additions & 73 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ jobs:
RUSTC_BOOTSTRAP: 1
run: cargo generate-lockfile ${{ matrix.versions }}

- run: cargo check --package tzdb --all-targets
- run: cargo clippy --package tzdb --all-targets -- -D warnings
- run: cargo check --workspace --all-targets
- run: cargo clippy --workspace --all-targets -- -D warnings

clippy-pedantic:
runs-on: ubuntu-20.04
Expand All @@ -85,7 +85,7 @@ jobs:
with:
components: clippy

- run: cargo clippy --package tzdb --all-targets -- -D clippy::pedantic
- run: cargo clippy --workspace --all-targets -- -D clippy::pedantic

test:
runs-on: ubuntu-20.04
Expand All @@ -100,9 +100,9 @@ jobs:
with:
components: clippy

- run: cargo check --package tzdb --all-targets
- run: cargo clippy --package tzdb --all-targets -- -D warnings
- run: cargo test --package tzdb --all-targets
- run: cargo check --workspace --all-targets
- run: cargo clippy --workspace --all-targets -- -D warnings
- run: cargo test --workspace --all-targets
- run: cargo run --package current-time
- run: cd testing && cargo test

Expand All @@ -122,10 +122,10 @@ jobs:
components: miri

- name: Test (tzdb)
run: cargo miri test --package tzdb --all-targets
run: cargo miri test --workspace --all-targets

- name: Test (testing)
run: cd testing && cargo miri test --package tzdb --all-targets
run: cd testing && cargo miri test --workspace --all-targets

cross-miri:
strategy:
Expand Down Expand Up @@ -153,7 +153,7 @@ jobs:
target: ${{ matrix.target }}

- name: Test
run: cargo miri test --package tzdb --target ${{ matrix.target }}
run: cargo miri test --workspace --target ${{ matrix.target }}

doc:
runs-on: ubuntu-20.04
Expand All @@ -169,7 +169,7 @@ jobs:
toolchain: nightly
components: rust-docs

- run: cargo doc --package tzdb --all-features --no-deps
- run: cargo doc --workspace --all-features --no-deps
env:
RUSTDOCFLAGS: -D warnings --cfg docsrs

Expand All @@ -189,68 +189,6 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}

build-cross:
strategy:
fail-fast: false
matrix:
target:
- x86_64-unknown-freebsd
- x86_64-unknown-illumos
- x86_64-unknown-netbsd
- x86_64-linux-android
- i686-linux-android
- arm-linux-androideabi
- aarch64-linux-android
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Rust
uses: ./.github/actions/setup-rust
with:
toolchain: stable
target: ${{ matrix.target }}
components: clippy

- name: Install "cross"
run: curl --location --silent --show-error --fail https://github.com/cargo-bins/cargo-quickinstall/releases/download/cross-0.2.5-x86_64-unknown-linux-gnu/cross-0.2.5-x86_64-unknown-linux-gnu.tar.gz | tar -xzvvf - -C $HOME/.cargo/bin
- run: cross check --target ${{ matrix.target }} --package tzdb --all-targets
- run: cross clippy --target ${{ matrix.target }} --package tzdb --all-targets -- -D warnings
- run: cross build --target ${{ matrix.target }} --package tzdb --lib
- run: cross build --target ${{ matrix.target }} --examples

build-cross-ios:
strategy:
fail-fast: false
matrix:
target:
- aarch64-apple-ios-sim
- aarch64-apple-ios
- x86_64-apple-ios
runs-on: macos-12
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Rust
uses: ./.github/actions/setup-rust
with:
toolchain: stable
target: ${{ matrix.target }}
components: clippy

- name: Install "cross"
run: curl --location --silent --show-error --fail https://github.com/cargo-bins/cargo-quickinstall/releases/download/cross-0.2.5-x86_64-apple-darwin/cross-0.2.5-x86_64-apple-darwin.tar.gz | tar -xzvvf - -C $HOME/.cargo/bin
- run: cross check --target ${{ matrix.target }} --package tzdb --all-targets
- run: cross clippy --target ${{ matrix.target }} --package tzdb --all-targets -- -D warnings
- run: cross build --target ${{ matrix.target }} --package tzdb --lib
- run: cross build --target ${{ matrix.target }} --examples

package:
runs-on: ubuntu-20.04
steps:
Expand All @@ -264,7 +202,7 @@ jobs:
with:
toolchain: stable

- run: cargo package --package tzdb
- run: cargo package --workspace

devskim:
name: DevSkim
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "src/generated"]
path = src/generated
path = tzdb_data/src/generated
url = ./
branch = generated
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tzdb"
version = "0.6.0"
version = "0.6.1-pre.1"
edition = "2018"
authors = ["René Kijewski <crates.io@k6i.de>"]
repository = "https://github.com/Kijewski/tzdb"
Expand All @@ -12,8 +12,9 @@ readme = "README.md"
# rust-version = "1.56"

[dependencies]
tz-rs = { version = "^0.6.14", default-features = false, features = ["const", "std"] }
iana-time-zone = { version = "^0.1.50", default-features = false, features = ["fallback"], optional = true }
tzdb_data = { version = "0.1.0-pre.1", default-features = false, path = "tzdb_data" }
tz-rs = { version = "^0.6.14", default-features = false, features = ["const", "std"] }

[features]
default = ["local"]
Expand All @@ -25,4 +26,8 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[workspace]
members = [".", "examples/current-time"]
members = [
".",
"examples/current-time",
"tzdb_data",
]
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
.DELETE_ON_ERROR:
#.DELETE_ON_ERROR:

TZDB_VERSION := tzdb-2023d

src/generated/mod.rs: tmp/${TZDB_VERSION}/usr/share/zoneinfo/ tzdb.tar.lz.sha
tzdb_data/src/generated/mod.rs: tmp/${TZDB_VERSION}/usr/share/zoneinfo/ tzdb.tar.lz.sha
cd make-tzdb && cargo r -- ../$(@D) ../$< ../tzdb.tar.lz.sha
cargo +nightly fmt -- $(@D)/mod.rs $(@D)/by_name.rs $(@D)/raw_tzdata.rs $(@D)/test_all_names.rs
cargo +nightly fmt -- \
$(@D)/by_name.rs \
$(@D)/mod.rs \
$(@D)/raw_tzdata.rs \
$(@D)/test_all_names.rs \
$(@D)/time_zone.rs \
$(@D)/tzdata.rs

tmp/${TZDB_VERSION}/usr/share/zoneinfo/: tmp/${TZDB_VERSION}/
cd tmp/${TZDB_VERSION}/ && make PACKRATDATA=backzone PACKRATLIST=zone.tab TOPDIR="." install
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ license = "Apache-2.0"
publish = false

[dependencies]
tzdb = { version = "0.6.0", path = ".." }
tzdb_data = { path = "../tzdb_data" }

[dev-dependencies]
criterion = { version = "0.5", default-features = false }
Expand Down
10 changes: 5 additions & 5 deletions benchmarks/benches/by-name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use std::time::{Duration, Instant};
use rand::seq::{IteratorRandom, SliceRandom};
use rand::SeedableRng;
use rand_xoshiro::Xoroshiro128PlusPlus;
use tzdb::{raw_tz_by_name, TZ_NAMES};
use tzdb_data::{find_raw, TZ_NAMES};

fn benchmark_by_name(c: &mut criterion::Criterion) {
// collect all names with "random" capitalization
let mut names: Vec<(String, usize)> = TZ_NAMES
.iter()
.flat_map(|&name| {
let raw_len = raw_tz_by_name(name).unwrap().len();
let raw_len = find_raw(name.as_bytes()).unwrap().len();
let upper = name.to_uppercase();
let lower = name.to_lowercase();
let inverted = name
Expand Down Expand Up @@ -75,12 +75,12 @@ fn benchmark_by_name(c: &mut criterion::Criterion) {
let city = std::str::from_utf8(city).unwrap();

let raw_name = format!("{}/{}", continent, city);
let raw_len = crate::raw_tz_by_name(&raw_name).unwrap_or_default().len();
let raw_len = crate::find_raw(raw_name.as_bytes()).unwrap_or_default().len();
names.push((raw_name, raw_len));
}

// benchmark per name lookup time
c.bench_function("tzdb::raw_tz_by_name", |b| {
c.bench_function("tzdb::find_raw", |b| {
b.iter_custom(|iters| {
let mut nanos = 0;
for i in 0..iters {
Expand All @@ -91,7 +91,7 @@ fn benchmark_by_name(c: &mut criterion::Criterion) {
for &(ref name, raw_len) in names {
assert_eq!(
raw_len,
crate::raw_tz_by_name(name).unwrap_or_default().len(),
crate::find_raw(name.as_bytes()).unwrap_or_default().len(),
);
}
nanos += start.elapsed().as_nanos();
Expand Down
4 changes: 3 additions & 1 deletion examples/current-time/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#![allow(clippy::pedantic)]

use std::env::args;
use std::process::exit;

use tzdb::{local_tz, now, time_zone, tz_by_name, TZ_NAMES};

pub fn main() -> Result<(), now::NowError> {
let mut args = args().into_iter().fuse();
let mut args = args().fuse();
let exe = args.next();
let exe = exe.as_deref().unwrap_or("current-time");
let argument = args.next();
Expand Down
2 changes: 1 addition & 1 deletion fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ edition = "2018"
cargo-fuzz = true

[dependencies]
tzdb = { version = "0.6.0", path = ".." }
tzdb_data = { path = "../tzdb_data" }

afl = { version = "0.15", optional = true }
honggfuzz = { version = "0.5", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion fuzz/bin/afl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() {
afl::fuzz!(|name: &[u8]| {
let _ = tzdb::tz_by_name(name);
let _ = tzdb_data::find_tz(name);
});
}
2 changes: 1 addition & 1 deletion fuzz/bin/honggfuzz.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
fn main() {
loop {
honggfuzz::fuzz!(|name: &[u8]| {
let _ = tzdb::tz_by_name(name);
let _ = tzdb_data::find_tz(name);
});
}
}
2 changes: 1 addition & 1 deletion fuzz/bin/libfuzzer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![no_main]

libfuzzer_sys::fuzz_target!(|name: &[u8]| {
let _ = tzdb::tz_by_name(name);
let _ = tzdb_data::find_tz(name);
});
27 changes: 10 additions & 17 deletions make-tzdb/generate_lookup_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ def convert(stdin, stdout):

print('use tz::TimeZoneRef;', file=stdout)
print(file=stdout)
print('use crate::eq_ignore_ascii_case;', file=stdout)
print('use super::raw_tzdata;', file=stdout)
print('use super::tzdata;', file=stdout)
print(file=stdout)

print('#[derive(Clone, Copy)]', file=stdout)
print('#[repr(u16)]', file=stdout)
print('enum Index {', file=stdout)
print('pub(crate) enum Index {', file=stdout)
idx = 0
for entry in table:
match entry:
Expand Down Expand Up @@ -174,15 +175,15 @@ def convert(stdin, stdout):
print('];', file=stdout)
print(file=stdout)

print(f'const TIME_ZONES: [&TimeZoneRef<\'static>; {entry_count}] = [', file=stdout)
print(f'pub(crate) const TIME_ZONES: [&TimeZoneRef<\'static>; {entry_count}] = [', file=stdout)
for entry in table:
match entry:
case (name, canon):
print(f' &tzdata::{canon},', file=stdout)
print('];', file=stdout)
print(file=stdout)

print(f'const RAW_TIME_ZONES: [&[u8]; {entry_count}] = [', file=stdout)
print(f'pub(crate) const RAW_TIME_ZONES: [&[u8]; {entry_count}] = [', file=stdout)
for entry in table:
match entry:
case (name, canon):
Expand All @@ -197,7 +198,7 @@ def convert(stdin, stdout):
print(f'{max_hash_value + 1}];', file=stdout)
print(file=stdout)

print('fn find_key(s: &[u8]) -> Option<Index> {', file=stdout)
print('pub(crate) const fn find_key(s: &[u8]) -> Option<Index> {', file=stdout)
print(' let len = s.len();', file=stdout)
print(f' if !matches!(len, {min_word_length}..={max_word_length}) {{', file=stdout)
print(' return None;', file=stdout)
Expand Down Expand Up @@ -239,26 +240,18 @@ def hash_add(idx, offs):
print(f' if key > {max_hash_value} {{', file=stdout)
print(' return None;', file=stdout)
print(' }', file=stdout)
print(' let key = WORDLIST[key]?;', file=stdout)
print(' if !NAMES[key as u16 as usize].eq_ignore_ascii_case(s) {', file=stdout)
print(' let key = match WORDLIST[key] {', file=stdout)
print(' Some(key) => key,', file=stdout)
print(' None => return None,', file=stdout)
print(' };', file=stdout)
print(' if !eq_ignore_ascii_case(s, NAMES[key as u16 as usize]) {', file=stdout)
print(' return None;', file=stdout)
print(' }', file=stdout)
print(file=stdout)
print(' Some(key)', file=stdout)
print('}', file=stdout)
print(file=stdout)

print('#[inline]')
print('pub(crate) fn find_tz(s: &[u8]) -> Option<TimeZoneRef<\'static>> {', file=stdout)
print(' Some(*TIME_ZONES[find_key(s)? as u16 as usize])', file=stdout)
print('}', file=stdout)
print(file=stdout)

print('#[inline]')
print('pub(crate) fn find_raw(s: &[u8]) -> Option<&\'static [u8]> {', file=stdout)
print(' Some(RAW_TIME_ZONES[find_key(s)? as u16 as usize])', file=stdout)
print('}', file=stdout)


if __name__ == '__main__':
basicConfig(level=INFO)
Expand Down
Loading

0 comments on commit a1b854c

Please sign in to comment.