// Конфигурации под сценарии: шаблон выбора опций
// Раздел учебника: Том IV, глава 22, «Выбор конфигурации под сценарий».
// Что демонстрирует: шесть типовых конфигураций окружения (запись-heavy,
//   чтение-heavy, мобильное, аналитика, многопроцессное чтение, низкая
//   задержка) как функции, возвращающие operate_parameters; применение одной
//   из них и установка дополнительных runtime-опций на открытом окружении.
// Сборка: g++ -std=c++17 -I<libmdbx-include> -I../common 29-scenario-configs.c++ -lmdbx
// Запуск: ./29-scenario-configs
// Ожидаемый вывод:
//   write-heavy config applied; inserted 1000 keys
//   ok: scenario config template applied
// При сбое — сообщение в stderr и exit 1.
//
// SPDX-License-Identifier: Apache-2.0

#include <iostream>
#include <string>

#include "common.h++"
#include <mdbx.h++>

namespace {

using params = mdbx::env::operate_parameters;
using opt = mdbx::env::extra_runtime_option;

// Запись-heavy: ленивая синхронизация, достаточно именованных таблиц.
params write_heavy() { return params().lazy_weak_tail().set_max_maps(64); }

// Чтение-heavy: максимальная долговечность, много читательских слотов.
[[maybe_unused]] params read_heavy() { return params().robust_synchronous().set_max_readers(1024).set_max_maps(64); }

// Мобильное устройство: малый размер файла, бережное отношение к флеш-памяти.
[[maybe_unused]] params mobile() { return params().lazy_weak_tail().set_max_maps(64); }

// Аналитика: пакетная запись, не мелочиться с балансировкой.
[[maybe_unused]] params analytics() { return params().lazy_weak_tail().set_max_maps(64); }

// Многопроцессное чтение: много читательских слотов, стабильная геометрия.
[[maybe_unused]] params multi_process_read() { return params().set_max_readers(4096).set_max_maps(64); }

// Низкая задержка: NOMETASYNC (данные на диске, метаданные могут отставать).
[[maybe_unused]] params low_latency() { return params().half_synchronous_weak_last().set_max_maps(64); }

} // namespace

int main() {
  try {
    const std::string path = std::string(example::tmpdir()) + "/mdbx-29-scenario-configs.mdbx";
    mdbx::env::remove(path);

    // «Шаблон применения»: берём конфигурацию под сценарий и работаем.
    auto env = example::env_open(path, write_heavy());
    // Дополнительные runtime-опции выставляются на открытом окружении:
    env.set_extra_option(opt::prefault_write_enable, 1);
    // ~33% страницы
    env.set_extra_option(opt::merge_threshold_dot16, 65536 / 3);
    {
      auto txn = env.start_write();
      auto table = txn.open_map(nullptr);
      for (int i = 0; i < 1000; ++i)
        txn.insert(table, mdbx::slice("k" + std::to_string(i)), mdbx::slice("v"));
      txn.commit();
    }
    std::cout << "write-heavy config applied; inserted 1000 keys\n";

    std::cout << "ok: scenario config template applied\n";
    return EXIT_SUCCESS;
  } catch (const std::exception &ex) {
    std::cerr << "error: " << ex.what() << "\n";
    return EXIT_FAILURE;
  }
}