The write compare was comparing two orderings of the same set
rega's L43 check: three of four pass — the row-click shader compile is 0 ms on both engines (was 3.8 s / 7.5 s), the tab visit is no worse, the highlight stays. The collapse did not: still nine setPaintProperty calls per row click instead of three. Their hypothesis is right, and I had the evidence before I wrote the code. The two callers build the same region from different lists — node.isoCodes and mapLayers.regionIsoMap[slug] — and they do not agree on ORDER. rega said so in the very first stack trace on this bug: "a case over ['IND',…]" from one path, "a case over ['MYS',…], a different literal order" from the other. I then wrote a JSON-string compare, which cannot match two orderings of one set. The pre-warm half worked because that expression is a shared constant; this half compared text that was never going to be equal. The list is now canonical before both the compare and the write — de-duplicated, upper-cased, sorted — so the expression is a function of the SET, which is the thing the two callers actually agree on. Order is irrelevant to `in` membership, and the case normalisation is a no-op on today's data (both lists come from the same regions dataset, and the highlight matches now, so they are already upper-case); it is there so a future source that ships lower-case cannot silently select nothing. ★ IT IS ALSO A TEST, and worth reading as one. If the count drops to 3, the two sources agree about which countries are in a region. If it does not, they disagree about the CONTENT — a data defect this compare would otherwise have hidden behind a last-writer-wins repaint, and the next thing to chase. Verified: gates:pre 13/13. Chained on f7a2f001 (same file). Needs rega: re-count with the same probe.
This commit is contained in:
parent
16c98acfe9
commit
c0c1a72851
1 changed files with 13 additions and 1 deletions
|
|
@ -1113,7 +1113,19 @@ const REGION_IDLE_COLOR = ['case', ['has', 'iso_3166_1_alpha_3'], 'rgba(60,60,80
|
|||
const REGION_IDLE_WIDTH = ['case', ['has', 'iso_3166_1_alpha_3'], 0.6, 0.6]
|
||||
function paintRegionScope(m, isoCodes) {
|
||||
if (!m || !m.getLayer('regions-fill')) return
|
||||
const list = Array.isArray(isoCodes) ? isoCodes.filter(Boolean) : []
|
||||
// ★ CANONICAL FIRST, OR THE COMPARE BELOW IS A LIE (rega, L43: still 9 writes per click, not 3).
|
||||
// The two sources build the same region from different lists — node.isoCodes and
|
||||
// mapLayers.regionIsoMap[slug] — and they do not agree on ORDER. rega had already told me that in
|
||||
// the very first stack trace ("a case over ['IND',…]" then "a case over ['MYS',…], a different
|
||||
// literal order") and I wrote a JSON-string compare anyway, which can never match two orderings of
|
||||
// the same set. Sorting and de-duplicating makes the expression a function of the SET, which is what
|
||||
// the two callers actually agree on.
|
||||
//
|
||||
// It is also a test: if the write count does not drop to 3, the two sources disagree about WHICH
|
||||
// countries are in the region, which is a data defect this compare would otherwise have hidden.
|
||||
const list = Array.isArray(isoCodes)
|
||||
? [...new Set(isoCodes.filter(Boolean).map((c) => String(c).toUpperCase()))].sort()
|
||||
: []
|
||||
const isoArr = ['literal', list]
|
||||
const fill = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 0.85, 0.15] : REGION_IDLE_FILL
|
||||
const color = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], '#111827', 'rgba(60,60,80,0.15)'] : REGION_IDLE_COLOR
|
||||
|
|
|
|||
Loading…
Reference in a new issue