Skip to content

Commit

Permalink
Replace 2d map with flat map
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Sep 26, 2023
1 parent 2ac056b commit 7d74cae
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 135 deletions.
34 changes: 17 additions & 17 deletions components/plurals/data/data/macros/plurals_ranges_v1.data.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 35 additions & 22 deletions components/plurals/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use crate::rules::runtime::ast::Rule;
use icu_provider::prelude::*;
use icu_provider::DataMarker;
use zerovec::ZeroMap2d;
use zerovec::ZeroMap;

#[cfg(feature = "compiled_data")]
#[derive(Debug)]
Expand Down Expand Up @@ -121,14 +121,6 @@ pub enum RawPluralCategory {
Many = 5,
}

impl RawPluralCategory {
#[inline]
/// Converts to an [`UnvalidatedPluralCategory`].
pub fn to_unvalidated(self) -> UnvalidatedPluralCategory {
UnvalidatedPluralCategory(self as u8)
}
}

impl From<PluralCategory> for RawPluralCategory {
fn from(value: PluralCategory) -> Self {
match value {
Expand All @@ -142,7 +134,7 @@ impl From<PluralCategory> for RawPluralCategory {
}
}

/// An `u8` that is expected to be a `PluralCategory` tag but does not enforce this variant.
/// An `u8` that is expected to be a plural range, but does not enforce this invariant.
///
/// <div class="stab unstable">
/// 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways,
Expand All @@ -155,30 +147,52 @@ impl From<PluralCategory> for RawPluralCategory {
derive(databake::Bake),
databake(path = icu_plurals::provider),
)]
#[zerovec::make_ule(UnvalidatedPluralCategoryULE)]
pub struct UnvalidatedPluralCategory(pub u8);
#[zerovec::make_ule(UnvalidatedPluralRangeULE)]
pub struct UnvalidatedPluralRange(pub u8);

impl UnvalidatedPluralRange {
/// Creates a new `UnvalidatedPluralRange` from a category range.
pub fn from_range(start: RawPluralCategory, end: RawPluralCategory) -> Self {
let start = start as u8;
let end = end as u8;

debug_assert!(start < 16);
debug_assert!(end < 16);

let range = (start << 4) | end;

Self(range)
}
}

#[cfg(feature = "datagen")]
impl serde::Serialize for UnvalidatedPluralCategory {
impl serde::Serialize for UnvalidatedPluralRange {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::Error;
RawPluralCategory::new_from_u8(self.0)
.ok_or_else(|| S::Error::custom("invalid tag in UnvalidatedPluralCategory"))?
.serialize(serializer)
if serializer.is_human_readable() {
let start = RawPluralCategory::new_from_u8(self.0 >> 4)
.ok_or_else(|| S::Error::custom("invalid tag in UnvalidatedPluralRange"))?;
let end = RawPluralCategory::new_from_u8(self.0 & 0x0F)
.ok_or_else(|| S::Error::custom("invalid tag in UnvalidatedPluralRange"))?;
(start, end).serialize(serializer)
} else {
self.0.serialize(serializer)
}
}
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for UnvalidatedPluralCategory {
impl<'de> serde::Deserialize<'de> for UnvalidatedPluralRange {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
Ok(RawPluralCategory::deserialize(deserializer)?.to_unvalidated())
let (start, end) = <(RawPluralCategory, RawPluralCategory)>::deserialize(deserializer)?;
Ok(UnvalidatedPluralRange::from_range(start, end))
} else {
Ok(Self(<u8>::deserialize(deserializer)?))
}
Expand Down Expand Up @@ -210,9 +224,8 @@ pub struct PluralRangesV1<'data> {
/// Map between the categories of the endpoints of a range and its corresponding
/// category.
///
/// - `key0` corresponds to the start category of the range.
/// - `key1` corresponds to the end category of the range.
/// This is roughly equivalent to a `BTreeMap<(PluralCategory, PluralCategory), PluralCategory>`,
/// where the key is `(start category, end category)`.
#[cfg_attr(feature = "serde", serde(borrow))]
pub ranges:
ZeroMap2d<'data, UnvalidatedPluralCategory, UnvalidatedPluralCategory, RawPluralCategory>,
pub ranges: ZeroMap<'data, UnvalidatedPluralRange, RawPluralCategory>,
}
64 changes: 34 additions & 30 deletions provider/datagen/src/transform/cldr/plurals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl From<&cldr_serde::plural_ranges::LocalePluralRanges> for PluralRangesV1<'st
.expect("category parsing failed.")
.into()
}
let mut map: BTreeMap<RawPluralCategory, BTreeMap<RawPluralCategory, RawPluralCategory>> =
let mut map: BTreeMap<(RawPluralCategory, RawPluralCategory), RawPluralCategory> =
BTreeMap::new();
for (range, result) in &other.0 {
let start = convert(&range.start);
Expand All @@ -144,17 +144,15 @@ impl From<&cldr_serde::plural_ranges::LocalePluralRanges> for PluralRangesV1<'st
// We can use that to save a lot of memory by not inserting the ranges that
// have end == result.
if end != result {
map.entry(start).or_default().insert(end, result);
map.insert((start, end), result);
}
}

PluralRangesV1 {
ranges: map
.into_iter()
.flat_map(|(start, rest)| {
rest.into_iter().map(move |(end, result)| {
(start.to_unvalidated(), end.to_unvalidated(), result)
})
.map(|((start, end), result)| {
(UnvalidatedPluralRange::from_range(start, end), result)
})
.collect(),
}
Expand Down Expand Up @@ -210,51 +208,57 @@ fn test_ranges() {
.unwrap();

assert_eq!(
plural_ranges.get().ranges.get_copied_2d(
&RawPluralCategory::Few.to_unvalidated(),
&RawPluralCategory::One.to_unvalidated()
),
plural_ranges
.get()
.ranges
.get_copied(&UnvalidatedPluralRange::from_range(
RawPluralCategory::Few,
RawPluralCategory::One
)),
Some(RawPluralCategory::Few)
);
assert_eq!(
plural_ranges.get().ranges.get_copied_2d(
&RawPluralCategory::Other.to_unvalidated(),
&RawPluralCategory::One.to_unvalidated()
),
plural_ranges
.get()
.ranges
.get_copied(&UnvalidatedPluralRange::from_range(
RawPluralCategory::Other,
RawPluralCategory::One
)),
Some(RawPluralCategory::Few)
);
assert!(plural_ranges
.get()
.ranges
.get_copied_2d(
&RawPluralCategory::Zero.to_unvalidated(),
&RawPluralCategory::One.to_unvalidated()
)
.get_copied(&UnvalidatedPluralRange::from_range(
RawPluralCategory::Zero,
RawPluralCategory::One
))
.is_none());
assert!(plural_ranges
.get()
.ranges
.get_copied_2d(
&RawPluralCategory::One.to_unvalidated(),
&RawPluralCategory::Zero.to_unvalidated()
)
.get_copied(&UnvalidatedPluralRange::from_range(
RawPluralCategory::One,
RawPluralCategory::Zero
))
.is_none());

// tests that the space optimization succeeds
assert!(plural_ranges
.get()
.ranges
.get_copied_2d(
&RawPluralCategory::One.to_unvalidated(),
&RawPluralCategory::Other.to_unvalidated()
)
.get_copied(&UnvalidatedPluralRange::from_range(
RawPluralCategory::One,
RawPluralCategory::Other
))
.is_none());
assert!(plural_ranges
.get()
.ranges
.get_copied_2d(
&RawPluralCategory::Few.to_unvalidated(),
&RawPluralCategory::Two.to_unvalidated()
)
.get_copied(&UnvalidatedPluralRange::from_range(
RawPluralCategory::Few,
RawPluralCategory::Two
))
.is_none());
}
50 changes: 37 additions & 13 deletions provider/datagen/tests/data/json/plurals/ranges@1/ar-EG.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7d74cae

Please sign in to comment.