mirror of
https://github.com/openharmony/third_party_rust_http.git
synced 2026-07-19 22:53:59 -04:00
Fix HeaderMap seq -> hash map transition (#15)
The function that rebuilds the map with a new hasher did not correctly update the hash table. Also, fix mask values.
This commit is contained in:
+13
-6
@@ -1594,6 +1594,8 @@ impl<T> HeaderMap<T> {
|
||||
// Initialze the indices
|
||||
self.indices = vec![Pos::none(); cap];
|
||||
|
||||
self.mask = cap.wrapping_sub(1) as Size;
|
||||
|
||||
// Rebuild the table
|
||||
self.rebuild();
|
||||
}
|
||||
@@ -1604,32 +1606,37 @@ impl<T> HeaderMap<T> {
|
||||
debug_assert!(!self.is_scan());
|
||||
|
||||
// Loop over all entries and re-insert them into the map
|
||||
for entry in &mut self.entries {
|
||||
'outer:
|
||||
for (index, entry) in self.entries.iter_mut().enumerate() {
|
||||
let hash = hash_elem_using(&self.danger, &entry.key);
|
||||
let mut probe = desired_pos(self.mask, hash);
|
||||
let mut dist = 0;
|
||||
|
||||
// Update the entry's hash code
|
||||
entry.hash = hash;
|
||||
|
||||
probe_loop!(probe < self.indices.len() as Size, {
|
||||
if let Some((_, entry_hash)) = self.indices[probe as usize].resolve() {
|
||||
// if existing element probed less than us, swap
|
||||
let their_dist = probe_distance(self.mask, entry_hash, probe);
|
||||
|
||||
if their_dist < dist {
|
||||
// Robinhood
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
// Vaccant slot
|
||||
self.indices[probe as usize] = Pos::new(index as Size, hash);
|
||||
continue 'outer;
|
||||
}
|
||||
|
||||
dist += 1;
|
||||
});
|
||||
|
||||
entry.hash = hash;
|
||||
|
||||
do_insert_phase_two(
|
||||
&mut self.indices,
|
||||
probe as Size,
|
||||
Pos::new(probe as Size, hash));
|
||||
Pos::new(index as Size, hash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3015,7 +3022,7 @@ fn probe_distance(mask: Size, hash: HashValue, current: Size) -> Size {
|
||||
fn hash_elem_using<K: ?Sized>(danger: &Danger, k: &K) -> HashValue
|
||||
where K: FastHash
|
||||
{
|
||||
const MASK: u64 = MAX_SIZE as u64;
|
||||
const MASK: u64 = (MAX_SIZE as u64) - 1;
|
||||
|
||||
let hash = match *danger {
|
||||
// Safe hash
|
||||
|
||||
@@ -131,3 +131,129 @@ fn eq() {
|
||||
|
||||
assert_ne!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_all_std_headers() {
|
||||
let mut m = HeaderMap::new();
|
||||
|
||||
for (i, hdr) in STD.iter().enumerate() {
|
||||
m.insert(hdr.clone(), hdr.as_str().to_string());
|
||||
|
||||
for j in 0..(i+1) {
|
||||
assert_eq!(m[&STD[j]], STD[j].as_str());
|
||||
}
|
||||
|
||||
if i != 0 {
|
||||
for j in (i+1)..STD.len() {
|
||||
assert!(m.get(&STD[j]).is_none(), "contained {}; j={}", STD[j].as_str(), j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_79_custom_std_headers() {
|
||||
let mut h = HeaderMap::new();
|
||||
let hdrs = custom_std(79);
|
||||
|
||||
for (i, hdr) in hdrs.iter().enumerate() {
|
||||
h.insert(hdr.clone(), hdr.as_str().to_string());
|
||||
|
||||
for j in 0..(i+1) {
|
||||
assert_eq!(h[&hdrs[j]], hdrs[j].as_str());
|
||||
}
|
||||
|
||||
for j in (i+1)..hdrs.len() {
|
||||
assert!(h.get(&hdrs[j]).is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn custom_std(n: usize) -> Vec<HeaderName> {
|
||||
(0..n).map(|i| {
|
||||
let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
|
||||
s.parse().unwrap()
|
||||
}).collect()
|
||||
}
|
||||
|
||||
const STD: [HeaderName; 79] = [
|
||||
ACCEPT,
|
||||
ACCEPT_CHARSET,
|
||||
ACCEPT_ENCODING,
|
||||
ACCEPT_LANGUAGE,
|
||||
ACCEPT_PATCH,
|
||||
ACCEPT_RANGES,
|
||||
ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
||||
ACCESS_CONTROL_ALLOW_HEADERS,
|
||||
ACCESS_CONTROL_ALLOW_METHODS,
|
||||
ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||
ACCESS_CONTROL_EXPOSE_HEADERS,
|
||||
ACCESS_CONTROL_MAX_AGE,
|
||||
ACCESS_CONTROL_REQUEST_HEADERS,
|
||||
ACCESS_CONTROL_REQUEST_METHOD,
|
||||
AGE,
|
||||
ALLOW,
|
||||
ALT_SVC,
|
||||
AUTHORIZATION,
|
||||
CACHE_CONTROL,
|
||||
CONNECTION,
|
||||
CONTENT_DISPOSITION,
|
||||
CONTENT_ENCODING,
|
||||
CONTENT_LANGUAGE,
|
||||
CONTENT_LENGTH,
|
||||
CONTENT_LOCATION,
|
||||
CONTENT_MD5,
|
||||
CONTENT_RANGE,
|
||||
CONTENT_SECURITY_POLICY,
|
||||
CONTENT_SECURITY_POLICY_REPORT_ONLY,
|
||||
CONTENT_TYPE,
|
||||
COOKIE,
|
||||
DNT,
|
||||
DATE,
|
||||
ETAG,
|
||||
EXPECT,
|
||||
EXPIRES,
|
||||
FORWARDED,
|
||||
FROM,
|
||||
HOST,
|
||||
IF_MATCH,
|
||||
IF_MODIFIED_SINCE,
|
||||
IF_NONE_MATCH,
|
||||
IF_RANGE,
|
||||
IF_UNMODIFIED_SINCE,
|
||||
LAST_MODIFIED,
|
||||
KEEP_ALIVE,
|
||||
LINK,
|
||||
LOCATION,
|
||||
MAX_FORWARDS,
|
||||
ORIGIN,
|
||||
PRAGMA,
|
||||
PROXY_AUTHENTICATE,
|
||||
PROXY_AUTHORIZATION,
|
||||
PUBLIC_KEY_PINS,
|
||||
PUBLIC_KEY_PINS_REPORT_ONLY,
|
||||
RANGE,
|
||||
REFERER,
|
||||
REFERRER_POLICY,
|
||||
REFRESH,
|
||||
RETRY_AFTER,
|
||||
SERVER,
|
||||
SET_COOKIE,
|
||||
STRICT_TRANSPORT_SECURITY,
|
||||
TE,
|
||||
TK,
|
||||
TRAILER,
|
||||
TRANSFER_ENCODING,
|
||||
TSV,
|
||||
USER_AGENT,
|
||||
UPGRADE,
|
||||
UPGRADE_INSECURE_REQUESTS,
|
||||
VARY,
|
||||
VIA,
|
||||
WARNING,
|
||||
WWW_AUTHENTICATE,
|
||||
X_CONTENT_TYPE_OPTIONS,
|
||||
X_DNS_PREFETCH_CONTROL,
|
||||
X_FRAME_OPTIONS,
|
||||
X_XSS_PROTECTION,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user