Skip to content

Commit f0010be

Browse files
authored
Merge pull request #677 from djc/optimize-tables
Optimize IDNA tables
2 parents 74fd76f + d56b36d commit f0010be

File tree

3 files changed

+1671
-3346
lines changed

3 files changed

+1671
-3346
lines changed

idna/src/make_uts46_mapping_table.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -148,30 +148,22 @@ def merge_single_char_ranges(ranges):
148148

149149
optimized_ranges = list(merge_single_char_ranges(optimized_ranges))
150150

151-
152-
print("static TABLE: &[Range] = &[")
153-
154-
for ranges in optimized_ranges:
155-
first = ranges[0][0]
156-
last = ranges[-1][1]
157-
print(" Range { from: '%s', to: '%s', }," % (escape_char(char(first)),
158-
escape_char(char(last))))
159-
160-
print("];\n")
161-
162-
print("static INDEX_TABLE: &[u16] = &[")
163-
164151
SINGLE_MARKER = 1 << 15
165152

153+
print("static TABLE: &[(char, u16)] = &[")
154+
166155
offset = 0
167156
for ranges in optimized_ranges:
168157
assert offset < SINGLE_MARKER
169158

170159
block_len = len(ranges)
171160
single = SINGLE_MARKER if block_len == 1 else 0
172-
print(" %s," % (offset | single))
161+
index = offset | single
173162
offset += block_len
174163

164+
start = escape_char(char(ranges[0][0]))
165+
print(" ('%s', %s)," % (start, index))
166+
175167
print("];\n")
176168

177169
print("static MAPPING_TABLE: &[Mapping] = &[")

idna/src/uts46.rs

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
1212
use self::Mapping::*;
1313
use crate::punycode;
14-
use std::cmp::Ordering::{Equal, Greater, Less};
1514
use std::{error::Error as StdError, fmt};
1615
use unicode_bidi::{bidi_class, BidiClass};
1716
use unicode_normalization::char::is_combining_mark;
@@ -50,36 +49,23 @@ enum Mapping {
5049
DisallowedStd3Mapped(StringTableSlice),
5150
}
5251

53-
struct Range {
54-
from: char,
55-
to: char,
56-
}
57-
5852
fn find_char(codepoint: char) -> &'static Mapping {
59-
let r = TABLE.binary_search_by(|ref range| {
60-
if codepoint > range.to {
61-
Less
62-
} else if codepoint < range.from {
63-
Greater
64-
} else {
65-
Equal
66-
}
67-
});
68-
r.ok()
69-
.map(|i| {
70-
const SINGLE_MARKER: u16 = 1 << 15;
53+
let idx = match TABLE.binary_search_by_key(&codepoint, |&val| val.0) {
54+
Ok(idx) => idx,
55+
Err(idx) => idx - 1,
56+
};
7157

72-
let x = INDEX_TABLE[i];
73-
let single = (x & SINGLE_MARKER) != 0;
74-
let offset = !SINGLE_MARKER & x;
58+
const SINGLE_MARKER: u16 = 1 << 15;
7559

76-
if single {
77-
&MAPPING_TABLE[offset as usize]
78-
} else {
79-
&MAPPING_TABLE[(offset + (codepoint as u16 - TABLE[i].from as u16)) as usize]
80-
}
81-
})
82-
.unwrap()
60+
let (base, x) = TABLE[idx];
61+
let single = (x & SINGLE_MARKER) != 0;
62+
let offset = !SINGLE_MARKER & x;
63+
64+
if single {
65+
&MAPPING_TABLE[offset as usize]
66+
} else {
67+
&MAPPING_TABLE[(offset + (codepoint as u16 - base as u16)) as usize]
68+
}
8369
}
8470

8571
struct Mapper<'a> {

0 commit comments

Comments
 (0)