summaryrefslogtreecommitdiff
path: root/libs/libmdbx/src/test/config.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libmdbx/src/test/config.h')
-rw-r--r--libs/libmdbx/src/test/config.h337
1 files changed, 0 insertions, 337 deletions
diff --git a/libs/libmdbx/src/test/config.h b/libs/libmdbx/src/test/config.h
deleted file mode 100644
index 5f0331291b..0000000000
--- a/libs/libmdbx/src/test/config.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2017-2020 Leonid Yuriev <leo@yuriev.ru>
- * and other libmdbx authors: please see AUTHORS file.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#pragma once
-
-#include "base.h"
-#include "log.h"
-#include "utils.h"
-
-#define ACTOR_ID_MAX INT16_MAX
-
-enum actor_testcase {
- ac_none,
- ac_hill,
- ac_deadread,
- ac_deadwrite,
- ac_jitter,
- ac_try,
- ac_copy,
- ac_append,
- ac_ttl,
- ac_nested
-};
-
-enum actor_status {
- as_unknown,
- as_debugging,
- as_running,
- as_successful,
- as_killed,
- as_failed,
- as_coredump,
-};
-
-const char *testcase2str(const actor_testcase);
-const char *status2str(actor_status status);
-
-enum keygen_case {
- kc_random, /* [ 6.. 2.. 7.. 4.. 0.. 1.. 5.. 3.. ] */
- kc_dashes, /* [ 0123.. 4567.. ] */
- kc_custom,
- /* TODO: more cases */
-};
-
-const char *keygencase2str(const keygen_case);
-
-//-----------------------------------------------------------------------------
-
-namespace config {
-
-enum scale_mode { no_scale, decimal, binary, duration };
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- const char **value, const char *default_value = nullptr);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- std::string &value, bool allow_empty = false);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- std::string &value, bool allow_empty,
- const char *default_value);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- bool &value);
-
-struct option_verb {
- const char *const verb;
- unsigned mask;
-};
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- unsigned &mask, const option_verb *verbs);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- uint64_t &value, const scale_mode scale,
- const uint64_t minval = 0, const uint64_t maxval = INT64_MAX,
- const uint64_t default_value = 0);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- unsigned &value, const scale_mode scale,
- const unsigned minval = 0, const unsigned maxval = INT32_MAX,
- const unsigned default_value = 0);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- uint8_t &value, const uint8_t minval = 0,
- const uint8_t maxval = 255, const uint8_t default_value = 0);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- int64_t &value, const int64_t minval, const int64_t maxval,
- const int64_t default_value = -1);
-
-bool parse_option(int argc, char *const argv[], int &narg, const char *option,
- int32_t &value, const int32_t minval, const int32_t maxval,
- const int32_t default_value = -1);
-
-inline bool parse_option_intptr(int argc, char *const argv[], int &narg,
- const char *option, intptr_t &value,
- const intptr_t minval, const intptr_t maxval,
- const intptr_t default_value = -1) {
- static_assert(sizeof(intptr_t) == 4 || sizeof(intptr_t) == 8, "WTF?");
- if (sizeof(intptr_t) == 8)
- return parse_option(argc, argv, narg, option,
- *reinterpret_cast<int64_t *>(&value), int64_t(minval),
- int64_t(maxval), int64_t(default_value));
- else
- return parse_option(argc, argv, narg, option,
- *reinterpret_cast<int32_t *>(&value), int32_t(minval),
- int32_t(maxval), int32_t(default_value));
-}
-
-//-----------------------------------------------------------------------------
-
-#pragma pack(push, 1)
-
-struct keygen_params_pod {
- /* Параметры генератора пар key-value. Также может быть полезным описание
- * алгоритма генерации в keygen.h
- *
- * Ключи и значения генерируются по задаваемым параметрам на основе "плоской"
- * исходной координаты. При этом, в общем случае, в процессе тестов исходная
- * координата последовательно итерируется в заданном диапазоне, а необходимые
- * паттерны/последовательности/узоры получаются за счет преобразования
- * исходной координаты, согласно описанным ниже параметрам.
- *
- * Стоит отметить, что порядок описания параметров для удобства совпадает с
- * порядком их использования, т.е. с порядком соответствующих преобразований.
- *
- * Второе важное замечание касается ограничений одновременной координированной
- * генерации паттеров как для ключей, так и для значений. Суть в том, что
- * такая возможность не нужна по следующим причинам:
- * - libmdbx поддерживает два существенно различающихся вида таблиц,
- * "уникальные" (без дубликатов и без multi-value), и так называемые
- * "с дубликатами" (c multi-value).
- * - Для таблиц "без дубликатов" только размер связанных с ключами значений
- * (данных) оказывает влияния на работу движка, непосредственно содержимое
- * данных не анализируется движком и не оказывает влияния на его работу.
- * - Для таблиц "с дубликатами", при наличии более одного значения для
- * некоторого ключа, формируется дочернее btree-поддерево. Это дерево
- * формируется во вложенной странице или отдельном "кусте" страниц,
- * и обслуживается независимо от окружения родительского ключа.
- * - Таким образом, паттерн генерации значений имеет смысл только для
- * таблиц "с дубликатами" и только в контексте одного значения ключа.
- * Иначе говоря, не имеет смысла взаимная координация при генерации
- * значений для разных ключей. Поэтому генерацию значений следует
- * рассматривать только в контексте связки с одним значением ключа.
- * - Тем не менее, во всех случаях достаточно важным является равновероятное
- * распределение всех возможных сочетаний длин ключей и данных.
- *
- * width:
- * Большинство тестов предполагают создание или итерирование некоторого
- * количества записей. При этом требуется итерирование или генерация
- * значений и ключей из некоторого ограниченного пространства вариантов.
- *
- * Параметр width задает такую ширину пространства вариантов в битах.
- * Таким образом мощность пространства вариантов (пока) всегда равна
- * степени двойки. Это ограничение можно снять, но ценой увеличения
- * вычислительной сложности, включая потерю простоты и прозрачности.
- *
- * С другой стороны, не-n-битовый width может быть полезен:
- * - Позволит генерировать ключи/значения в точно задаваемом диапазоне.
- * Например, перебрать в псевдо-случайном порядке 10001 значение.
- * - Позволит поровну разделять заданное пространство (диапазон)
- * ключей/значений между количеством потоков некратным степени двойки.
- *
- * mesh и seed:
- * Позволяют получить псевдо-случайные последовательности ключей/значений.
- * Параметр mesh задает сколько младших бит исходной плоской координаты
- * будет "перемешано" (инъективно отображено), а параметр seed позволяет
- * выбрать конкретный вариант "перемешивания".
- *
- * Перемешивание выполняется при ненулевом значении mesh. Перемешивание
- * реализуется посредством применения двух инъективных функций для
- * заданного количества бит:
- * - применяется первая инъективная функция;
- * - к результату добавляется salt полученный из seed;
- * - применяется вторая инъективная функция;
- *
- * Следует отметить, что mesh умышленно позволяет перемешать только младшую
- * часть, что при ненулевом значении split (см далее) не позволяет получать
- * псевдо-случайные значений ключей без псевдо-случайности в значениях.
- *
- * Такое ограничение соответствуют внутренней алгоритмике libmdbx. Проще
- * говоря, мы можем проверить движок псевдо-случайной последовательностью
- * ключей на таблицах без дубликатов (без multi-value), а затем проверить
- * корректность работу псевдо-случайной последовательностью значений на
- * таблицах с дубликатами (с multi-value), опционально добавляя
- * псевдо-случайности к последовательности ключей. Однако, нет смысла
- * генерировать псевдо-случайные ключи, одновременно с формированием
- * какого-либо паттерна в значениях, так как содержимое в данных либо
- * не будет иметь значения (для таблиц без дубликатов), либо будет
- * обрабатываться в отдельных btree-поддеревьях.
- *
- * rotate и offset:
- * Для проверки слияния и разделения страниц внутри движка требуются
- * генерация ключей/значений в виде не-смежных последовательностей, как-бы
- * в виде "пунктира", который постепенно заполняет весь заданный диапазон.
- *
- * Параметры позволяют генерировать такой "пунктир". Соответственно rotate
- * задает циклический сдвиг вправо, а offset задает смещение, точнее говоря
- * сложение по модулю внутри диапазона заданного посредством width.
- *
- * Например, при rotate равном 1 (циклический сдвиг вправо на 1 бит),
- * четные и нечетные исходные значения сложатся в две линейные
- * последовательности, которые постепенно закроют старшую и младшую
- * половины диапазона.
- *
- * split:
- * Для таблиц без дубликатов (без multi-value ключей) фактически требуется
- * генерация только ключей, а данные могут быть постоянным. Но для таблиц с
- * дубликатами (с multi-value ключами) также требуется генерация значений.
- *
- * Ненулевое значение параметра split фактически включает генерацию значений,
- * при этом значение split определяет сколько бит исходного абстрактного
- * номера будет отрезано для генерации значения.
- */
-
- uint8_t width{0};
- uint8_t mesh{0};
- uint8_t rotate{0};
- uint8_t split{0};
- uint32_t seed{0};
- uint64_t offset{0};
- keygen_case keycase{kc_random};
- bool zero_fill{false};
-};
-
-struct actor_params_pod {
- unsigned mode_flags{0};
- unsigned table_flags{0};
- intptr_t size_lower{0};
- intptr_t size_now{0};
- intptr_t size_upper{0};
- int shrink_threshold{0};
- int growth_step{0};
- int pagesize{0};
-
- unsigned test_duration{0};
- unsigned test_nops{0};
- unsigned nrepeat{0};
- unsigned nthreads{0};
-
- unsigned keylen_min{0}, keylen_max{0};
- unsigned datalen_min{0}, datalen_max{0};
-
- unsigned batch_read{0};
- unsigned batch_write{0};
-
- unsigned delaystart{0};
- unsigned waitfor_nops{0};
- unsigned inject_writefaultn{0};
-
- unsigned max_readers{0};
- unsigned max_tables{0};
- keygen_params_pod keygen;
-
- uint8_t loglevel{0};
- bool drop_table{false};
- bool ignore_dbfull{false};
- bool speculum{false};
- bool random_writemap{true};
-};
-
-struct actor_config_pod {
- unsigned actor_id{0}, space_id{0};
- actor_testcase testcase{ac_none};
- unsigned wait4id{0};
- unsigned signal_nops{0};
-
- actor_config_pod() = default;
- actor_config_pod(unsigned actor_id, actor_testcase testcase,
- unsigned space_id, unsigned wait4id)
- : actor_id(actor_id), space_id(space_id), testcase(testcase),
- wait4id(wait4id) {}
-};
-
-#pragma pack(pop)
-
-extern const struct option_verb mode_bits[];
-extern const struct option_verb table_bits[];
-void dump(const char *title = "config-dump: ");
-
-} /* namespace config */
-
-struct actor_params : public config::actor_params_pod {
- std::string pathname_log;
- std::string pathname_db;
- actor_params() = default;
-
- void set_defaults(const std::string &tmpdir);
- unsigned mdbx_keylen_min() const;
- unsigned mdbx_keylen_max() const;
- unsigned mdbx_datalen_min() const;
- unsigned mdbx_datalen_max() const;
-};
-
-struct actor_config : public config::actor_config_pod {
- actor_params params;
-
- bool wanna_event4signalling() const { return true /* TODO ? */; }
-
- actor_config() = default;
- actor_config(actor_testcase testcase, const actor_params &params,
- unsigned space_id, unsigned wait4id);
-
- actor_config(const char *str) : actor_config() {
- if (!deserialize(str, *this))
- failure("Invalid internal parameter '%s'\n", str);
- }
-
- const std::string osal_serialize(simple_checksum &) const;
- bool osal_deserialize(const char *str, const char *end, simple_checksum &);
-
- const std::string serialize(const char *prefix) const;
- static bool deserialize(const char *str, actor_config &config);
-
- bool is_waitable(size_t nops) const {
- switch (testcase) {
- case ac_hill:
- if (!params.test_nops || params.test_nops >= nops)
- return true;
- __fallthrough;
- default:
- return false;
- }
- }
-};