moonchen opened a new pull request, #13559: URL: https://github.com/apache/trafficserver/pull/13559
`hdrtoken_init()` builds the well-known-string (WKS) table at startup in an `ats_calloc` heap, interning each string behind a `HdrTokenHeapPrefix` and then resolving initializer names to indexes to fill in token types, slot ids, presence masks and flags. This builds the whole table during translation instead. ### 1. Modernize the well-known-string initialization `_hdrtoken_strs` becomes a `constexpr std::array` of `std::string_view`, and a `constexpr` builder produces the same prefix-then-string layout in a read-only table. `hdrtoken_init()` no longer allocates, interns or resolves anything; it copies the hot fields into the parallel arrays and builds the hash table. `hdrtoken_wks_to_prefix()` still finds a prefix by stepping back `sizeof(HdrTokenHeapPrefix)` bytes, which a `static_assert` on `offsetof` now guarantees. The cooked Cache-Control masks move out of `mime_init_cache_control_cooking_masks()` into the same table, so that function is removed. It was the only writer to a prefix after startup. The table is read-only now, so `hdrtoken_wks_to_prefix()` and `hdrtoken_index_to_prefix()` return `const HdrTokenHeapPrefix *`, which resolves an existing `ToDo`. `hdrtoken_hash_table` also halves. `hash_to_slot()` masks a hash to 15 bits, but the table held 65536 buckets, so half of it was unreachable. The mask and the size now come from one constant. Sizes, measured on the `HdrToken.cc` object file: | | before | after | |---|---|---| | WKS table | ~15 KB, heap | 10,800 B, `.rodata` | | `hdrtoken_hash_table` | 1,052,904 B BSS | 528,616 B BSS | | `sizeof(HdrTokenHeapPrefix)` | 56 | 48 | ### 2. Add compile-time checks for WKS correctness `static_assert` replaces two startup checks. - Every initializer name must name an entry in `_hdrtoken_strs`, and no two rows of one table may claim the same entry. The old code used `ink_release_assert` on the index range, which a mis-resolution passes; it is also compiled out unless `DEBUG` is defined. - Every string must land in its own hash slot. The old code printed an error and called `abort()`. Resolution at compile time is an exact case-insensitive comparison, which is stronger than the case-folded hash-and-length match `hdrtoken_tokenize()` does at run time. ### 3. Remove the restriction that prevents a WKS from being added after its prefix Name resolution used a PCRE2 DFA over start-anchored patterns, so a name matched the first pattern it prefixed. The array therefore had to keep the longer entry of every case-insensitive prefix pair at the lower index. All 13 pairs satisfy that today, so this is not a live bug, but the rule contradicts the `WARNING` on the array: new strings must be **appended**, because their indexes are stored on disk for cached objects. Appending is what gives a new name the highest index, while the ordering rule wants the longer name lowest. Measured on master with `"Server-Timing"` appended to the array and to the field initializer table: it resolves to index 58, `"Server"`, and writes its own slot id, flags and mask onto `"Server"`. `"Server"` loses `MIME_PRESENCE_SERVER`, the process exits 0, and all 437064 assertions pass. Headers that would be shadowed the same way include `Accept-CH`, `Accept-Patch` and `Accept-Post`, and anything extending `Age`, `Via`, `Range`, `Host`, `Date`, `Allow`, `Vary` or `Warning`. With an exact comparison a prefix pair works in either order, so appending is now safe and the cache-format rule is the only one left to remember. ### Notes for review - `HdrTokenFieldInfo` is split in two. `HdrTokenFieldInit` keeps `name` and is the initializer row type, where the name is the lookup key. The version embedded in the prefix drops it: it held a pointer into the table, which a constant may not do, and nothing read it. That is also where the 8 bytes per prefix come from. - `hdrtoken_tokenize()` is unchanged and still matches on a case-folded hash plus a length. The type initializer for `public` is lowercase while the array entry is `Public`, and that still resolves. ### Testing `test_proxy_hdrs` passes with 437064 assertions in 52 test cases, unchanged from master. The emitted table was compared byte-for-byte across each refactoring step. Verified that a missing initializer name, a duplicate initializer row, and a name that is a strict prefix of an existing entry each fail the build. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
