0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

perf(headers): improve iterator complexity to O(2n) (#10526)

This commit is contained in:
Satya Rohith 2021-05-10 13:31:51 +05:30 committed by GitHub
parent 7a9ebd1585
commit c3c4a8e0f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -178,32 +178,42 @@
get [_iterableHeaders]() {
const list = this[_headerList];
const headers = [];
const headerNamesSet = new Set();
// The order of steps are not similar to the ones suggested by the
// spec but produce the same result.
const headers = {};
const cookies = [];
for (const entry of list) {
headerNamesSet.add(byteLowerCase(entry[0]));
}
const names = [...headerNamesSet].sort();
for (const name of names) {
// The following if statement, and if block of the following statement
// are not spec compliant. `set-cookie` is the only header that can not
// be concatentated, so must be given to the user as multiple headers.
const name = byteLowerCase(entry[0]);
const value = entry[1];
if (value === null) throw new TypeError("Unreachable");
// The following if statement is not spec compliant.
// `set-cookie` is the only header that can not be concatentated,
// so must be given to the user as multiple headers.
// The else block of the if statement is spec compliant again.
if (name == "set-cookie") {
const setCookie = list.filter((entry) =>
byteLowerCase(entry[0]) === "set-cookie"
);
if (setCookie.length === 0) throw new TypeError("Unreachable");
for (const entry of setCookie) {
headers.push([name, entry[1]]);
}
if (name === "set-cookie") {
cookies.push([name, value]);
} else {
const value = getHeader(list, name);
if (value === null) throw new TypeError("Unreachable");
headers.push([name, value]);
// The following code has the same behaviour as getHeader()
// at the end of loop. But it avoids looping through the entire
// list to combine multiple values with same header name. It
// instead gradually combines them as they are found.
let header = headers[name];
if (header && header.length > 0) {
header += "\x2C\x20" + value;
} else {
header = value;
}
headers[name] = header;
}
}
return headers;
return [...Object.entries(headers), ...cookies].sort((a, b) => {
const akey = a[0];
const bkey = b[0];
if (akey > bkey) return 1;
if (akey < bkey) return -1;
return 0;
});
}
/** @param {HeadersInit} [init] */