# Universal Container Экспериментальный C++20-контейнер индексируемой последовательности с двумя представлениями. Текущая default-policy привязывает все автоматические перестройки к изменению логической вместимости: ```text capacity boundary |-- grow: capacity *= 2 when the current capacity is exhausted `-- shrink: capacity /= 2 at 12.5% occupancy | +-- small N: contiguous vector `-- large N: tiered storage, leaf = ceil(sqrt(N)) ``` Между изменениями вместимости контейнер не меняет ни представление, ни размер leaf. На границе вместимости auto-mode заново выбирает `vector` или tiered, поэтому обратный переход `tiered -> vector` также возможен. Focused cutoff равен 4096 элементов; он выбран по baseline focused-run 7 x 100000 для текущего `uint32_t` workload и остаётся калибруемой, а не универсальной константой. Поиск по значению не удалён: `AdaptiveSequence` использует flat hash. Число hash buckets рассчитывается из логической вместимости с запасом под worst-case load не выше 70% и пересматривается только на той же границе вместимости. Это исключает независимый rehash посреди обычной серии операций. Старые многомерные benchmark-матрицы и сделанные по ним выводы сохранены только как **historical / retired**. Активная постановка и ограничения описаны в [docs/benchmarking.md](docs/benchmarking.md) и [docs/findings.md](docs/findings.md). ## Быстрый старт Из обычной командной строки Windows: ```bat build.bat baseline test ``` Доступные профили: ```bat build.bat scalar test build.bat baseline test build.bat avx2 test build.bat all test ``` Проект проверен с Visual Studio 18 2026 и workload «Desktop development with C++». `build.bat` сам находит комплектный CMake из Visual Studio. Готовые программы находятся в `out\bin\\Release\`: - `uc_demo.exe` — минимальный пример; - `uc_tests.exe` — differential/property-тесты; - `uc_focused_bench.exe` — текущий focused benchmark runner; - `uc_bench.exe` — historical / retired matrix runner. Все Release-цели собираются с `/O2` и статическим MSVC runtime (`/MT`). Профиль `scalar` — проверенный для MSVC 19.51 режим `project-novec`: внутренний ключ `/d2Qvec-`, `/Oi-` и отключение vector algorithms STL. Это не универсальная гарантия отсутствия SIMD внутри ABI/CRT. `baseline` оставляет штатную автовекторизацию без AVX-флага, `avx2` добавляет `/arch:AVX2`. Перед запуском AVX2-тестов и benchmark выполняется проверка CPU/OS; неподдерживаемый профиль безопасно пропускается. Подробности приведены в [docs/benchmarking.md](docs/benchmarking.md). Текущий воспроизводимый запуск: ```bat benchmark.bat ``` Он собирает и тестирует только профиль `baseline`, создаёт timestamp-папку и один раз запускает `uc_focused_bench` с 100000 операций и 7 повторами. В benchmark сравниваются три варианта одного типа `AdaptiveSequence`: forced vector, forced tiered и auto-mode; flat hash включён у всех трёх. Mixed trace содержит 97% индексных чтений, 1% hash-поисков `find_one` (50% hit / 50% miss), 1% вставок и 1% удалений. Runner также печатает медианную пропускную способность каждого типа операций отдельно. Raw CSV, metadata и медианная таблица `summary.md` сохраняются в `results\benchmarks\-focused\`. Подтверждённая таблица публикуется вместе с результатами запуска, а не вшивается в документацию до завершения серии. Следующие команды относятся к **historical / retired benchmark matrix** и не являются текущим способом калибровки: ```bat large_benchmark.bat smoke 12 large_benchmark.bat full 12 3 large_benchmark.bat full 12 3 huge ``` Старые CSV оставлены для аудита истории, но напрямую не сравнимы с focused постановкой: в ней другой workload и hash обязателен у каждого кандидата. `out\` полностью игнорируется Git, результаты исследования — намеренно нет. ## API ```cpp #include uc::AdaptiveSequence values; values.push_back(10); values.insert(0, 5); values.erase(1); auto x = values[0]; values.force_vector_mode(); values.force_tiered_mode({256, 64, 4}); values.enable_auto_mode(); values.adapt_now(); // default-policy не меняет mode между resize ``` Опциональный flat hash index со stable IDs: ```cpp uc::AdaptiveSequence indexed; indexed.push_back(5); indexed.push_back(5); auto ids = indexed.find_all_ids(5); indexed.erase_by_id(ids.front()); ``` При включённом индексе запись через `operator[]` идёт через proxy и обновляет индекс. Сам индекс не хранит логические позиции как ключи дубликатов. ## Каталоги ```text include/universal_container/ публичные header-only компоненты src/ demo и benchmark runner tests/ correctness/differential tests tools/ анализ CSV, аудит флагов, AVX2 probe и metadata docs/ архитектура и выводы results/benchmarks/ сохранённые результаты out/build/ промежуточная сборка (ignored) out/bin/ exe по профилям (ignored) out/lib/ библиотеки (ignored) out/symbols/ PDB по профилям (ignored) ``` Архитектура и контракт инвалидирования описаны в [docs/architecture.md](docs/architecture.md).