- находки 48 и 49: единицы не менялись ни разу; настоящих столкновений 0.65%, несравнимых наборов полей нет, тай-брейк берёт меньшее в 96% случаев - edinicy-metriki-v-razreze закрыт: гипотеза не подтвердилась замером - тай-брейк отложен до каталога рода агрегации
5.1 KiB
Полнота точки — по множеству ключей, а не по их числу
Приоритет: высокий
Была блокером, вынутым ревью кода задачи razbor-metrik-v-obekty (профиль
deep, находка №7 триажа, severity major). Решение принято замером
(находка 49) — ниже задача на остаток.
Что не так сегодня
Полнота — это счётчик ключей, чьё значение не null, не "" и не пусто.
Поэтому {}, [], 0 и false считаются содержательными:
точка {"qty":0,"a":0,"b":0,"c":{},"d":[]} полнота 5
точка {"date":"…","qty":123.4} полнота 2
Вторая точка — настоящее измерение — проигрывает первой и стирается безвозвратно. Восстановить можно только из сырого архива, пока он жив.
Что решено и на каком основании
Замер по всем 99 доставкам (находка 49): настоящих столкновений 2 897 из 444 256 координат (0.65%), и среди них ноль несравнимых наборов полей.
Отсюда:
- Полнота — сравнение множеств ключей, побеждает надмножество. Ровно 981 случай из замера, и там правило уже работает верно — но работает случайно, через счётчик, который на другом входе даст обратное.
- Объединение полей при несравнимых наборах не нужно. Самая дорогая часть
обсуждавшегося варианта (1) на живом потоке не срабатывает ни разу. Вместо
реализации — счётчик: несравнимый набор считается и логируется
WARN. Если событие когда-нибудь наступит, оно будет видно, а не додумано заранее. - Тай-брейк при равной полноте в эту задачу не входит. Обоснование ниже.
Что делать
resolveвinternal/store/bucket.go: полнота — множество ключей с непустым значением; побеждает строгое надмножество.- Несравнимые множества — счётчик в
MergeStatsплюсWARNс координатами объекта (без значений). Точку выбирает тот же тай-брейк, что и при равной полноте. - Дельта-спека
openspec/specs/storage→ «Разрешение столкновений по полноте»: переформулировать с числа ключей на множество. - Тесты: «бедная точка с пятью пустыми полями не стирает измерение» (регрессия на приведённой выше паре), «надмножество побеждает», «несравнимые наборы считаются».
task verify:archiveобязан дать то же состояние — правило меняет исход только там, где сегодня он неверен.
Что отложено и почему
Тай-брейк при равной полноте. Сегодня это лексикографический порядок
канонических форм. Измерено (находка 49): в 1 847 случаях из 1 912 он выбирает
меньшее значение — 96%. Четыре из шести затронутых метрик накопительные,
там это систематический недосчёт; но крупнейшая группа, heart_rate (985
случаев), мгновенная, и там «большее» не правильнее.
То есть правильный тай-брейк зависит от рода метрики, а род по замыслу проекта измеряется сверкой слоёв между собой. Выбирать его сейчас — угадывать ровно то, что станет известно точно.
Зависимость: rod-agregacii-i-katalog. Тай-брейк доделывается после неё, отдельной задачей.
Что стоит без решения
Ничего. Правило работает и наблюдаемо: столкновение считается расхождением
канонических форм (а не байтов), даёт WARN с координатами объекта и счётчик
overwrites.