| ... | ... | @@ -70,11 +70,15 @@ pub fn StaticStringMapWithEql( |
| 70 | 70 | /// (only keys) tuples if `V` is `void`. |
| 71 | 71 | pub inline fn initComptime(comptime kvs_list: anytype) Self { |
| 72 | 72 | comptime { |
| 73 | | @setEvalBranchQuota(30 * kvs_list.len); |
| 74 | 73 | var self = Self{}; |
| 75 | 74 | if (kvs_list.len == 0) |
| 76 | 75 | return self; |
| 77 | 76 | |
| 77 | // Since the KVs are sorted, a linearly-growing bound will never |
| 78 | // be sufficient for extreme cases. So we grow proportional to |
| 79 | // N*log2(N). |
| 80 | @setEvalBranchQuota(10 * kvs_list.len * std.math.log2_int_ceil(usize, kvs_list.len)); |
| 81 | |
| 78 | 82 | var sorted_keys: [kvs_list.len][]const u8 = undefined; |
| 79 | 83 | var sorted_vals: [kvs_list.len]V = undefined; |
| 80 | 84 | |
| ... | ... | @@ -212,8 +216,12 @@ pub fn StaticStringMapWithEql( |
| 212 | 216 | } |
| 213 | 217 | } |
| 214 | 218 | |
| 215 | | /// Returns the longest key, value pair where key is a prefix of `str` |
| 219 | /// Returns the key-value pair where key is the longest prefix of `str` |
| 216 | 220 | /// else null. |
| 221 | /// |
| 222 | /// This is effectively an O(N) algorithm which loops from `max_len` to |
| 223 | /// `min_len` and calls `getIndex()` to check all keys with the given |
| 224 | /// len. |
| 217 | 225 | pub fn getLongestPrefix(self: Self, str: []const u8) ?KV { |
| 218 | 226 | if (self.kvs.len == 0) |
| 219 | 227 | return null; |
| ... | ... | @@ -497,6 +505,33 @@ test "getLongestPrefix2" { |
| 497 | 505 | try testing.expectEqual(null, map.getLongestPrefix("xxx")); |
| 498 | 506 | } |
| 499 | 507 | |
| 500 | | test "long kvs_list doesn't exceed @setEvalBranchQuota" { |
| 501 | | _ = TestMapVoid.initComptime([1]TestKVVoid{.{"x"}} ** 1_000); |
| 508 | test "sorting kvs doesn't exceed eval branch quota" { |
| 509 | // from https://github.com/ziglang/zig/issues/19803 |
| 510 | const TypeToByteSizeLUT = std.StaticStringMap(u32).initComptime(.{ |
| 511 | .{ "bool", 0 }, |
| 512 | .{ "c_int", 0 }, |
| 513 | .{ "c_long", 0 }, |
| 514 | .{ "c_longdouble", 0 }, |
| 515 | .{ "t20", 0 }, |
| 516 | .{ "t19", 0 }, |
| 517 | .{ "t18", 0 }, |
| 518 | .{ "t17", 0 }, |
| 519 | .{ "t16", 0 }, |
| 520 | .{ "t15", 0 }, |
| 521 | .{ "t14", 0 }, |
| 522 | .{ "t13", 0 }, |
| 523 | .{ "t12", 0 }, |
| 524 | .{ "t11", 0 }, |
| 525 | .{ "t10", 0 }, |
| 526 | .{ "t9", 0 }, |
| 527 | .{ "t8", 0 }, |
| 528 | .{ "t7", 0 }, |
| 529 | .{ "t6", 0 }, |
| 530 | .{ "t5", 0 }, |
| 531 | .{ "t4", 0 }, |
| 532 | .{ "t3", 0 }, |
| 533 | .{ "t2", 0 }, |
| 534 | .{ "t1", 1 }, |
| 535 | }); |
| 536 | try testing.expectEqual(1, TypeToByteSizeLUT.get("t1")); |
| 502 | 537 | } |