Skip to content

Commit

Permalink
Use Vec instead of HashMap
Browse files Browse the repository at this point in the history
  • Loading branch information
zbraniecki committed Jul 10, 2020
1 parent 0e80b77 commit 3edd964
Show file tree
Hide file tree
Showing 18 changed files with 307 additions and 228 deletions.
14 changes: 8 additions & 6 deletions components/pluralrules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ include = [
]

[dependencies]
icu-locale = { path = "../locale", features=["serde"] }
icu-locale = { path = "../locale" }
serde = { version = "1.0", optional = true, features = ["derive"] }
serde_json = {version = "1.0", optional = true }
bincode = { version = "1.3", optional = true }
serde-tuple-vec-map = { version = "1.0", optional = true }

[dev-dependencies]
criterion = "0.3"
Expand All @@ -28,15 +29,16 @@ serde_json = {version = "1.0" }

[features]
default = []
compiled = []
inline = []
json = ["serde", "serde_json"]
binary = ["serde", "serde_json", "bincode"]

io = ["serde", "serde_json", "serde-tuple-vec-map"]
inline-source = ["inline"]
inline-rs = ["inline"]
io-json = ["io"]
io-bincode = ["io", "bincode"]

[[bin]]
name = "generate_res"
required-features = ["binary"]
required-features = ["io-json", "io-bincode"]

[[bench]]
name = "pluralrules"
Expand Down
13 changes: 8 additions & 5 deletions components/pluralrules/benches/pluralrules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use std::convert::TryInto;

use cldr_pluralrules_parser::parse_plural_condition;
use icu_locale::LanguageIdentifier;
use icu_pluralrules::data::DATA_TYPE;
#[cfg(feature = "inline-rs")]
use icu_pluralrules::data::inline::rs::DataProvider;
use icu_pluralrules::operands::PluralOperands;
use icu_pluralrules::rules::lexer::Lexer;
use icu_pluralrules::rules::parser::Parser;
Expand Down Expand Up @@ -49,9 +50,10 @@ fn plural_rules(c: &mut Criterion) {
}
})
});
c.bench_function(&format!("select/{}", DATA_TYPE), |b| {
c.bench_function("select/inline-rs", |b| {
let loc: LanguageIdentifier = "pl".parse().unwrap();
let pr = PluralRules::try_new(loc, PluralRuleType::Cardinal).unwrap();
let dtp = DataProvider {};
let pr = PluralRules::try_new(loc, PluralRuleType::Cardinal, &dtp).unwrap();
b.iter(|| {
for s in SAMPLES {
let op: PluralOperands = (*s).try_into().unwrap();
Expand All @@ -70,10 +72,11 @@ fn plural_rules(c: &mut Criterion) {
BenchmarkId::new("construct", langs.len()),
&langs,
|b, langs| {
let dtp = DataProvider {};
b.iter(|| {
for lang in langs {
PluralRules::try_new(lang.clone(), PluralRuleType::Ordinal).unwrap();
PluralRules::try_new(lang.clone(), PluralRuleType::Cardinal).unwrap();
PluralRules::try_new(lang.clone(), PluralRuleType::Ordinal, &dtp).unwrap();
PluralRules::try_new(lang.clone(), PluralRuleType::Cardinal, &dtp).unwrap();
}
});
},
Expand Down
Binary file modified components/pluralrules/data/ordinals.dat
Binary file not shown.
Binary file modified components/pluralrules/data/plurals.dat
Binary file not shown.
2 changes: 1 addition & 1 deletion components/pluralrules/src/bin/generate_res.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use icu_pluralrules::data::json::get_resource;
use icu_pluralrules::data::io::json::get_resource;
use icu_pluralrules::PluralRuleType;
use std::fs::File;
use std::io::prelude::*;
Expand Down
46 changes: 0 additions & 46 deletions components/pluralrules/src/data/inline.rs

This file was deleted.

5 changes: 5 additions & 0 deletions components/pluralrules/src/data/inline/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[cfg(feature = "inline-rs")]
pub mod rs;

#[cfg(feature = "inline-source")]
pub mod source;
33 changes: 33 additions & 0 deletions components/pluralrules/src/data/inline/rs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
mod rules;

use crate::DataProviderType;
use crate::PluralRuleEnum;
use crate::PluralRuleType;
use icu_locale::LanguageIdentifier;

#[derive(Default)]
pub struct DataProvider {}

impl DataProviderType for DataProvider {
fn get_rule(
&self,
locale: &LanguageIdentifier,
type_: PluralRuleType,
) -> Option<PluralRuleEnum> {
let rules = match type_ {
PluralRuleType::Cardinal => rules::PRS_CARDINAL,
PluralRuleType::Ordinal => rules::PRS_ORDINAL,
};
if let Ok(idx) = rules.binary_search_by(|(lsv, _)| {
lsv.language.cmp(&locale.language).then(
lsv.script
.cmp(&locale.script)
.then(lsv.region.cmp(&locale.region)),
)
}) {
Some(PluralRuleEnum::Function(rules[idx].1))
} else {
None
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,16 @@
#![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::nonminimal_bool))]
use icu_locale::subtags;

use crate::PluralCategory;
use crate::PluralRule;
use crate::PluralRuleEnum;
use crate::PluralRuleType;
use icu_locale::subtags;
use icu_locale::LanguageIdentifier;

pub const DATA_TYPE: &str = "compiled";

pub fn get_rule(locale: &LanguageIdentifier, type_: PluralRuleType) -> Option<PluralRuleEnum> {
let rules = match type_ {
PluralRuleType::Cardinal => PRS_CARDINAL,
PluralRuleType::Ordinal => PRS_ORDINAL,
};
if let Ok(idx) = rules.binary_search_by(|(lsv, _)| {
lsv.language.cmp(&locale.language).then(
lsv.script
.cmp(&locale.script)
.then(lsv.region.cmp(&locale.region)),
)
}) {
Some(PluralRuleEnum::FunPtr(PRS_CARDINAL[idx].1))
} else {
None
}
}

#[derive(PartialOrd, PartialEq, Ord, Eq)]
pub struct LSV {
language: subtags::Language,
script: Option<subtags::Script>,
region: Option<subtags::Region>,
pub language: subtags::Language,
pub script: Option<subtags::Script>,
pub region: Option<subtags::Region>,
}

macro_rules! langid {
Expand All @@ -48,7 +25,6 @@ macro_rules! langid {
}
}};
}

pub const PRS_CARDINAL: &[(LSV, PluralRule)] = &[
(
langid!(subtags::Language::from_raw_unchecked(26209u64), None, None),
Expand Down
55 changes: 55 additions & 0 deletions components/pluralrules/src/data/inline/source/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
mod rules;

use crate::rules::ast;
use crate::rules::parser::Parser;
use crate::DataProviderType;
use crate::PluralCategory;
use crate::PluralRuleEnum;
use crate::PluralRuleType;
use icu_locale::LanguageIdentifier;

#[derive(Default)]
pub struct DataProvider {}

impl DataProviderType for DataProvider {
fn get_rule(
&self,
locale: &LanguageIdentifier,
type_: PluralRuleType,
) -> Option<PluralRuleEnum> {
let rules = get_rules(locale, type_)?;
Some(PluralRuleEnum::Conditions(rules))
}
}

pub fn get_rules(
locale: &LanguageIdentifier,
type_: PluralRuleType,
) -> Option<Box<[(PluralCategory, ast::Condition)]>> {
let data = match type_ {
PluralRuleType::Cardinal => rules::DATA_CARDINAL,
PluralRuleType::Ordinal => rules::DATA_ORDINAL,
};
let r = if let Ok(idx) = data.binary_search_by(|(lsv, _)| {
lsv.language.cmp(&locale.language).then(
lsv.script
.cmp(&locale.script)
.then(lsv.region.cmp(&locale.region)),
)
}) {
Some(data[idx].1)
} else {
None
};

let mut rules = vec![];

for (category, input) in r? {
let p = Parser::new(input.as_bytes());
let ast = p
.parse()
.unwrap_or_else(|_| panic!("Failed to parse: {:#?}, {:#?}", locale, category));
rules.push((*category, ast));
}
Some(rules.into_boxed_slice())
}
43 changes: 43 additions & 0 deletions components/pluralrules/src/data/inline/source/rules.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use icu_locale::subtags;

use crate::PluralCategory;

#[derive(PartialOrd, PartialEq, Ord, Eq)]
pub struct LSV {
pub language: subtags::Language,
pub script: Option<subtags::Script>,
pub region: Option<subtags::Region>,
}

macro_rules! langid {
( $ lang : expr , $ script : expr , $ region : expr ) => {{
unsafe {
LSV {
language: $lang,
script: $script,
region: $region,
}
}
}};
}

pub const DATA_CARDINAL: &[(LSV, &[(PluralCategory, &str)])] = &[
(
langid!(subtags::Language::from_raw_unchecked(28261u64), None, None),
&[
(PluralCategory::One, "i = 1 and v = 0 @integer 1"),
(PluralCategory::Other, " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"),
]
),
(
langid!(subtags::Language::from_raw_unchecked(27760u64), None, None),
&[
(PluralCategory::One, "i = 1 and v = 0"),
(PluralCategory::Few, "v = 0 and i % 10 = 2..4 and i % 100 != 12..14"),
(PluralCategory::Many, "v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14"),
(PluralCategory::Other, ""),
]
)
];

pub const DATA_ORDINAL: &[(LSV, &[(PluralCategory, &str)])] = &[];
Loading

0 comments on commit 3edd964

Please sign in to comment.