2026-08-13 23:42:26 +03:00
2026-08-13 23:42:26 +03:00
2026-08-13 23:42:26 +03:00
2026-08-13 23:42:26 +03:00
2026-08-13 23:42:26 +03:00
2026-08-13 23:42:26 +03:00
2026-08-11 22:19:34 +03:00
2026-08-13 23:42:26 +03:00
2026-08-11 22:19:34 +03:00
2026-08-13 23:42:26 +03:00
2026-08-11 22:19:34 +03:00
2026-08-11 23:35:38 +03:00
2026-08-13 23:42:26 +03:00

Universal Container

Экспериментальный C++20-контейнер индексируемой последовательности с двумя представлениями. Текущая default-policy привязывает все автоматические перестройки к изменению логической вместимости:

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<T, true> использует flat hash. Число hash buckets рассчитывается из логической вместимости с запасом под worst-case load не выше 70% и пересматривается только на той же границе вместимости. Это исключает независимый rehash посреди обычной серии операций.

Старые многомерные benchmark-матрицы и сделанные по ним выводы сохранены только как historical / retired. Активная постановка и ограничения описаны в docs/benchmarking.md и docs/findings.md.

Быстрый старт

Из обычной командной строки Windows:

build.bat baseline test

Доступные профили:

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\<profile>\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.

Текущий воспроизводимый запуск:

benchmark.bat

Он собирает и тестирует только профиль baseline, создаёт timestamp-папку и один раз запускает uc_focused_bench с 100000 операций и 7 повторами. В benchmark сравниваются три варианта одного типа AdaptiveSequence<uint32_t, true>: 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\<timestamp>-focused\. Подтверждённая таблица публикуется вместе с результатами запуска, а не вшивается в документацию до завершения серии.

Следующие команды относятся к historical / retired benchmark matrix и не являются текущим способом калибровки:

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

#include <universal_container/adaptive_sequence.hpp>

uc::AdaptiveSequence<std::uint32_t> 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:

uc::AdaptiveSequence<std::uint32_t, true> indexed;
indexed.push_back(5);
indexed.push_back(5);
auto ids = indexed.find_all_ids(5);
indexed.erase_by_id(ids.front());

При включённом индексе запись через operator[] идёт через proxy и обновляет индекс. Сам индекс не хранит логические позиции как ключи дубликатов.

Каталоги

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.

S
Description
No description provided
Readme 2.1 MiB
Languages
C++ 82.7%
PowerShell 14.2%
Batchfile 1.6%
CMake 1.5%