SFM/tests/unit/test_mapping_lookup_cache.py
Andrey Epifancev 6668858b6f Pick report column values through a reverse path index
build_fixed_row_by_index evaluated ~2 400 candidate paths per report row
(7 million _pick_value calls per 13 800 rows). A reverse index
"path -> (rule, candidate, probe)" is built once at import; per row we
walk only the record's own fields and keep the best hit per rule, with
the same candidate/probe ordering as _pick_value. Differential test
compares the index with _pick_value on random and parsed payloads.

Also: merged lookup reuses the operation lookup when the participant
payload is empty, and index-free paths skip the regex normalisation.
scripts/bench_report.py reproduces the measurement (0.42 -> 0.26 ms/row).

Refs #1

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 19:14:43 +04:00

52 lines
2.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Переиспользование lookup операции между строками одной операции.
Все строки одной операции (участники, continuation) приходят с одним и тем
же словарём operation_fields. Его lookup можно не пересобирать, но только
если результат не зависит от того, кешировался словарь или нет: изменение
содержимого словаря между вызовами обязано отражаться в строке.
"""
from __future__ import annotations
from app.pipeline.mapping import build_fixed_row
_OPERATION_CODE_COLUMN = "Код вида операции"
def _row(operation_fields: dict[str, str], participant_fields: dict[str, str]):
return build_fixed_row(
file_name="f.xml",
record_id="R1",
operation_index=1,
operation_fields=operation_fields,
participant_fields=participant_fields,
)
def test_same_operation_dict_across_rows_gives_same_values_as_fresh_dict() -> None:
shared = {"КодОперации": "5007", "СумОперации": "10.00"}
first = _row(shared, {"ИННФЛ": "111111111111", "Тип": "01"})
second = _row(shared, {"ИННФЛ": "222222222222", "Тип": "01"})
fresh = _row(dict(shared), {"ИННФЛ": "222222222222", "Тип": "01"})
assert first[_OPERATION_CODE_COLUMN] == "5007"
assert second == fresh
def test_mutating_operation_dict_between_rows_is_reflected() -> None:
operation = {"КодОперации": "5007"}
assert _row(operation, {})[_OPERATION_CODE_COLUMN] == "5007"
operation["КодОперации"] = "6001"
assert _row(operation, {})[_OPERATION_CODE_COLUMN] == "6001"
del operation["КодОперации"]
assert _row(operation, {})[_OPERATION_CODE_COLUMN] == ""
def test_empty_participant_row_equals_row_built_without_participant_data() -> None:
operation = {"КодОперации": "5007", "ИННФЛ": "333333333333"}
with_empty = _row(operation, {})
fresh = _row(dict(operation), dict())
assert with_empty == fresh