Merge branch 'master' into new-nav

This commit is contained in:
Rich Raposa 2023-03-02 10:56:49 -07:00 committed by GitHub
commit 21996c377a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 122 additions and 117 deletions

View File

@ -26,6 +26,7 @@ ClickHouse Inc does **not** maintain the libraries listed below and hasnt don
- [one-ck](https://github.com/lizhichao/one-ck) - [one-ck](https://github.com/lizhichao/one-ck)
- [glushkovds/phpclickhouse-laravel](https://packagist.org/packages/glushkovds/phpclickhouse-laravel) - [glushkovds/phpclickhouse-laravel](https://packagist.org/packages/glushkovds/phpclickhouse-laravel)
- [kolya7k ClickHouse PHP extension](https://github.com//kolya7k/clickhouse-php) - [kolya7k ClickHouse PHP extension](https://github.com//kolya7k/clickhouse-php)
- [hyvor/clickhouse-php](https://github.com/hyvor/clickhouse-php)
- Go - Go
- [clickhouse](https://github.com/kshvakov/clickhouse/) - [clickhouse](https://github.com/kshvakov/clickhouse/)
- [go-clickhouse](https://github.com/roistat/go-clickhouse) - [go-clickhouse](https://github.com/roistat/go-clickhouse)

View File

@ -1231,8 +1231,8 @@ Using replacement fields, you can define a pattern for the resulting string. “
| %e | day of the month, space-padded (1-31) |   2 | | %e | day of the month, space-padded (1-31) |   2 |
| %f | fractional second from the fractional part of DateTime64 | 1234560 | | %f | fractional second from the fractional part of DateTime64 | 1234560 |
| %F | short YYYY-MM-DD date, equivalent to %Y-%m-%d | 2018-01-02 | | %F | short YYYY-MM-DD date, equivalent to %Y-%m-%d | 2018-01-02 |
| %G | four-digit year format for ISO week number, calculated from the week-based year [defined by the ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Week_dates) standard, normally useful only with %V | 2018 |
| %g | two-digit year format, aligned to ISO 8601, abbreviated from four-digit notation | 18 | | %g | two-digit year format, aligned to ISO 8601, abbreviated from four-digit notation | 18 |
| %G | four-digit year format for ISO week number, calculated from the week-based year [defined by the ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Week_dates) standard, normally useful only with %V | 2018 |
| %h | hour in 12h format (01-12) | 09 | | %h | hour in 12h format (01-12) | 09 |
| %H | hour in 24h format (00-23) | 22 | | %H | hour in 24h format (00-23) | 22 |
| %i | minute (00-59) | 33 | | %i | minute (00-59) | 33 |

View File

@ -24,6 +24,7 @@ sidebar_label: "Клиентские библиотеки от сторонни
- [SeasClick C++ client](https://github.com/SeasX/SeasClick) - [SeasClick C++ client](https://github.com/SeasX/SeasClick)
- [glushkovds/phpclickhouse-laravel](https://packagist.org/packages/glushkovds/phpclickhouse-laravel) - [glushkovds/phpclickhouse-laravel](https://packagist.org/packages/glushkovds/phpclickhouse-laravel)
- [kolya7k ClickHouse PHP extension](https://github.com//kolya7k/clickhouse-php) - [kolya7k ClickHouse PHP extension](https://github.com//kolya7k/clickhouse-php)
- [hyvor/clickhouse-php](https://github.com/hyvor/clickhouse-php)
- Go - Go
- [clickhouse](https://github.com/kshvakov/clickhouse/) - [clickhouse](https://github.com/kshvakov/clickhouse/)
- [go-clickhouse](https://github.com/roistat/go-clickhouse) - [go-clickhouse](https://github.com/roistat/go-clickhouse)

View File

@ -301,7 +301,7 @@ ClickHouse поддерживает временные таблицы со сл
- Временные таблицы исчезают после завершения сессии, в том числе при обрыве соединения. - Временные таблицы исчезают после завершения сессии, в том числе при обрыве соединения.
- Временная таблица использует только модуль памяти. - Временная таблица использует только модуль памяти.
- Невозможно указать базу данных для временной таблицы. Она создается вне баз данных. - Невозможно указать базу данных для временной таблицы. Она создается вне баз данных.
- Невозможно создать временную таблицу распределнным DDL запросом на всех серверах кластера (с опцией `ON CLUSTER`): такая таблица существует только в рамках существующей сессии. - Невозможно создать временную таблицу распределённым DDL запросом на всех серверах кластера (с опцией `ON CLUSTER`): такая таблица существует только в рамках существующей сессии.
- Если временная таблица имеет то же имя, что и некоторая другая, то, при упоминании в запросе без указания БД, будет использована временная таблица. - Если временная таблица имеет то же имя, что и некоторая другая, то, при упоминании в запросе без указания БД, будет использована временная таблица.
- При распределённой обработке запроса, используемые в запросе временные таблицы, передаются на удалённые серверы. - При распределённой обработке запроса, используемые в запросе временные таблицы, передаются на удалённые серверы.
@ -344,7 +344,9 @@ REPLACE TABLE myOldTable SELECT * FROM myOldTable WHERE CounterID <12345;
### Синтаксис ### Синтаксис
```sql
{CREATE [OR REPLACE]|REPLACE} TABLE [db.]table_name {CREATE [OR REPLACE]|REPLACE} TABLE [db.]table_name
```
Для данного запроса можно использовать любые варианты синтаксиса запроса `CREATE`. Запрос `REPLACE` для несуществующей таблицы вызовет ошибку. Для данного запроса можно использовать любые варианты синтаксиса запроса `CREATE`. Запрос `REPLACE` для несуществующей таблицы вызовет ошибку.

View File

@ -108,7 +108,7 @@ SELECT year, month, day, count(*) FROM t GROUP BY year, month, day WITH ROLLUP;
## Модификатор WITH CUBE {#with-cube-modifier} ## Модификатор WITH CUBE {#with-cube-modifier}
Модификатор `WITH CUBE` применятеся для расчета подытогов по всем комбинациям группировки ключевых выражений в списке `GROUP BY`. Модификатор `WITH CUBE` применяется для расчета подытогов по всем комбинациям группировки ключевых выражений в списке `GROUP BY`.
Строки с подытогами добавляются в конец результирующей таблицы. В колонках, по которым выполняется группировка, указывается значение `0` или пустая строка. Строки с подытогами добавляются в конец результирующей таблицы. В колонках, по которым выполняется группировка, указывается значение `0` или пустая строка.

View File

@ -16,7 +16,7 @@ FROM <left_table>
(ON <expr_list>)|(USING <column_list>) ... (ON <expr_list>)|(USING <column_list>) ...
``` ```
Выражения из секции `ON` и столбцы из секции `USING` называется «ключами соединения». Если не указано иное, при присоединение создаётся [Декартово произведение](https://en.wikipedia.org/wiki/Cartesian_product) из строк с совпадающими значениями ключей соединения, что может привести к получению результатов с гораздо большим количеством строк, чем исходные таблицы. Выражения из секции `ON` и столбцы из секции `USING` называются «ключами соединения». Если не указано иное, при присоединение создаётся [Декартово произведение](https://en.wikipedia.org/wiki/Cartesian_product) из строк с совпадающими значениями ключей соединения, что может привести к получению результатов с гораздо большим количеством строк, чем исходные таблицы.
## Поддерживаемые типы соединения {#select-join-types} ## Поддерживаемые типы соединения {#select-join-types}
@ -28,7 +28,7 @@ FROM <left_table>
- `FULL OUTER JOIN`, не совпадающие строки из обеих таблиц возвращаются в дополнение к совпадающим строкам. - `FULL OUTER JOIN`, не совпадающие строки из обеих таблиц возвращаются в дополнение к совпадающим строкам.
- `CROSS JOIN`, производит декартово произведение таблиц целиком, ключи соединения не указываются. - `CROSS JOIN`, производит декартово произведение таблиц целиком, ключи соединения не указываются.
Без указания типа `JOIN` подразумевается `INNER`. Ключевое слово `OUTER` можно опускать. Альтернативным синтаксисом для `CROSS JOIN` является ли указание нескольких таблиц, разделённых запятыми, в [секции FROM](from.md). Без указания типа `JOIN` подразумевается `INNER`. Ключевое слово `OUTER` можно опускать. Альтернативным синтаксисом для `CROSS JOIN` является указание нескольких таблиц, разделённых запятыми, в [секции FROM](from.md).
Дополнительные типы соединений, доступные в ClickHouse: Дополнительные типы соединений, доступные в ClickHouse:
@ -62,7 +62,7 @@ FROM <left_table>
Строки объединяются только тогда, когда всё составное условие выполнено. Если оно не выполнено, то строки могут попасть в результат в зависимости от типа `JOIN`. Обратите внимание, что если то же самое условие поместить в секцию `WHERE`, то строки, для которых оно не выполняется, никогда не попаду в результат. Строки объединяются только тогда, когда всё составное условие выполнено. Если оно не выполнено, то строки могут попасть в результат в зависимости от типа `JOIN`. Обратите внимание, что если то же самое условие поместить в секцию `WHERE`, то строки, для которых оно не выполняется, никогда не попаду в результат.
Оператор `OR` внутри секции `ON` работает, используя алгоритм хеш-соединения — на каждый агрумент `OR` с ключами соединений для `JOIN` создается отдельная хеш-таблица, поэтому потребление памяти и время выполнения запроса растет линейно при увеличении количества выражений `OR` секции `ON`. Оператор `OR` внутри секции `ON` работает, используя алгоритм хеш-соединения — на каждый аргумент `OR` с ключами соединений для `JOIN` создается отдельная хеш-таблица, поэтому потребление памяти и время выполнения запроса растет линейно при увеличении количества выражений `OR` секции `ON`.
:::note "Примечание" :::note "Примечание"
Если в условии использованы столбцы из разных таблиц, то пока поддерживается только оператор равенства (`=`). Если в условии использованы столбцы из разных таблиц, то пока поддерживается только оператор равенства (`=`).
@ -280,7 +280,7 @@ SELECT a, b, toTypeName(a), toTypeName(b) FROM t_1 FULL JOIN t_2 USING (a, b);
Каждый раз для выполнения запроса с одинаковым `JOIN`, подзапрос выполняется заново — результат не кэшируется. Это можно избежать, используя специальный движок таблиц [Join](../../../engines/table-engines/special/join.md), представляющий собой подготовленное множество для соединения, которое всегда находится в оперативке. Каждый раз для выполнения запроса с одинаковым `JOIN`, подзапрос выполняется заново — результат не кэшируется. Это можно избежать, используя специальный движок таблиц [Join](../../../engines/table-engines/special/join.md), представляющий собой подготовленное множество для соединения, которое всегда находится в оперативке.
В некоторых случаях это более эффективно использовать [IN](../../operators/in.md) вместо `JOIN`. В некоторых случаях более эффективно использовать [IN](../../operators/in.md) вместо `JOIN`.
Если `JOIN` необходим для соединения с таблицами измерений (dimension tables - сравнительно небольшие таблицы, которые содержат свойства измерений - например, имена для рекламных кампаний), то использование `JOIN` может быть не очень удобным из-за громоздкости синтаксиса, а также из-за того, что правая таблица читается заново при каждом запросе. Специально для таких случаев существует функциональность «Внешние словари», которую следует использовать вместо `JOIN`. Дополнительные сведения смотрите в разделе «Внешние словари». Если `JOIN` необходим для соединения с таблицами измерений (dimension tables - сравнительно небольшие таблицы, которые содержат свойства измерений - например, имена для рекламных кампаний), то использование `JOIN` может быть не очень удобным из-за громоздкости синтаксиса, а также из-за того, что правая таблица читается заново при каждом запросе. Специально для таких случаев существует функциональность «Внешние словари», которую следует использовать вместо `JOIN`. Дополнительные сведения смотрите в разделе «Внешние словари».

View File

@ -67,7 +67,7 @@ sidebar_label: ORDER BY
## Примеры с использованием сравнения {#collation-examples} ## Примеры с использованием сравнения {#collation-examples}
Пример с значениями типа [String](../../../sql-reference/data-types/string.md): Пример со значениями типа [String](../../../sql-reference/data-types/string.md):
Входная таблица: Входная таблица:
@ -241,13 +241,13 @@ SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
└───┴─────────┘ └───┴─────────┘
``` ```
## Деталь реализации {#implementation-details} ## Детали реализации {#implementation-details}
Если кроме `ORDER BY` указан также не слишком большой [LIMIT](limit.md), то расходуется меньше оперативки. Иначе расходуется количество памяти, пропорциональное количеству данных для сортировки. При распределённой обработке запроса, если отсутствует [GROUP BY](group-by.md), сортировка частично делается на удалённых серверах, а на сервере-инициаторе запроса производится слияние результатов. Таким образом, при распределённой сортировке, может сортироваться объём данных, превышающий размер памяти на одном сервере. Если кроме `ORDER BY` указан также не слишком большой [LIMIT](limit.md), то расходуется меньше оперативки. Иначе расходуется количество памяти, пропорциональное количеству данных для сортировки. При распределённой обработке запроса, если отсутствует [GROUP BY](group-by.md), сортировка частично делается на удалённых серверах, а на сервере-инициаторе запроса производится слияние результатов. Таким образом, при распределённой сортировке, может сортироваться объём данных, превышающий размер памяти на одном сервере.
Существует возможность выполнять сортировку во внешней памяти (с созданием временных файлов на диске), если оперативной памяти не хватает. Для этого предназначена настройка `max_bytes_before_external_sort`. Если она выставлена в 0 (по умолчанию), то внешняя сортировка выключена. Если она включена, то при достижении объёмом данных для сортировки указанного количества байт, накопленные данные будут отсортированы и сброшены во временный файл. После того, как все данные будут прочитаны, будет произведено слияние всех сортированных файлов и выдача результата. Файлы записываются в директорию `/var/lib/clickhouse/tmp/` (по умолчанию, может быть изменено с помощью параметра `tmp_path`) в конфиге. Существует возможность выполнять сортировку во внешней памяти (с созданием временных файлов на диске), если оперативной памяти не хватает. Для этого предназначена настройка `max_bytes_before_external_sort`. Если она выставлена в 0 (по умолчанию), то внешняя сортировка выключена. Если она включена, то при достижении объёмом данных для сортировки указанного количества байт, накопленные данные будут отсортированы и сброшены во временный файл. После того, как все данные будут прочитаны, будет произведено слияние всех сортированных файлов и выдача результата. Файлы записываются в директорию `/var/lib/clickhouse/tmp/` (по умолчанию, может быть изменено с помощью параметра `tmp_path`) в конфиге.
На выполнение запроса может расходоваться больше памяти, чем `max_bytes_before_external_sort`. Поэтому, значение этой настройки должно быть существенно меньше, чем `max_memory_usage`. Для примера, если на вашем сервере 128 GB оперативки, и вам нужно выполнить один запрос, то выставите `max_memory_usage` в 100 GB, а `max_bytes_before_external_sort` в 80 GB. На выполнение запроса может расходоваться больше памяти, чем `max_bytes_before_external_sort`. Поэтому значение этой настройки должно быть существенно меньше, чем `max_memory_usage`. Для примера, если на вашем сервере 128 GB оперативки, и вам нужно выполнить один запрос, то выставьте `max_memory_usage` в 100 GB, а `max_bytes_before_external_sort` в 80 GB.
Внешняя сортировка работает существенно менее эффективно, чем сортировка в оперативке. Внешняя сортировка работает существенно менее эффективно, чем сортировка в оперативке.
@ -366,9 +366,9 @@ ORDER BY
└────────────┴────────────┴──────────┘ └────────────┴────────────┴──────────┘
``` ```
Поле `d1` не заполняется и использует значение по умолчанию. Поскольку у нас нет повторяющихся значений для `d2`, мы не можем правильно рассчитать последователность заполнения для `d1`. Поле `d1` не заполняется и использует значение по умолчанию. Поскольку у нас нет повторяющихся значений для `d2`, мы не можем правильно рассчитать последовательность заполнения для `d1`.
едующий запрос (с измененым порядком в ORDER BY): едующий запрос (с измененным порядком в ORDER BY):
```sql ```sql
SELECT SELECT
toDate((number * 10) * 86400) AS d1, toDate((number * 10) * 86400) AS d1,

View File

@ -13,7 +13,7 @@ Prewhere — это оптимизация для более эффективн
`PREWHERE` имеет смысл использовать, если есть условия фильтрации, которые использует меньшинство столбцов из тех, что есть в запросе, но достаточно сильно фильтрует данные. Таким образом, сокращается количество читаемых данных. `PREWHERE` имеет смысл использовать, если есть условия фильтрации, которые использует меньшинство столбцов из тех, что есть в запросе, но достаточно сильно фильтрует данные. Таким образом, сокращается количество читаемых данных.
В запросе может быть одновременно указаны и `PREWHERE`, и `WHERE`. В этом случае `PREWHERE` предшествует `WHERE`. В запросе могут быть одновременно указаны и `PREWHERE`, и `WHERE`. В этом случае `PREWHERE` предшествует `WHERE`.
Если значение параметра [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) равно 0, эвристика по автоматическому перемещению части выражений из `WHERE` к `PREWHERE` отключается. Если значение параметра [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) равно 0, эвристика по автоматическому перемещению части выражений из `WHERE` к `PREWHERE` отключается.

View File

@ -10,7 +10,7 @@ sidebar_label: SAMPLE
Сэмплирование имеет смысл, когда: Сэмплирование имеет смысл, когда:
1. Точность результата не важна, например, для оценочных расчетов. 1. Точность результата не важна, например, для оценочных расчетов.
2. Возможности аппаратной части не позволяют соответствовать строгим критериям. Например, время ответа должно быть \&lt;100 мс. При этом точность расчета имеет более низкий приоритет. 2. Возможности аппаратной части не позволяют соответствовать строгим критериям. Например, время ответа должно быть &lt;100 мс. При этом точность расчета имеет более низкий приоритет.
3. Точность результата участвует в бизнес-модели сервиса. Например, пользователи с бесплатной подпиской на сервис могут получать отчеты с меньшей точностью, чем пользователи с премиум подпиской. 3. Точность результата участвует в бизнес-модели сервиса. Например, пользователи с бесплатной подпиской на сервис могут получать отчеты с меньшей точностью, чем пользователи с премиум подпиской.
:::note "Внимание" :::note "Внимание"

View File

@ -26,7 +26,7 @@ SELECT CounterID, 2 AS table, sum(Sign) AS c
Результирующие столбцы сопоставляются по их индексу (порядку внутри `SELECT`). Если имена столбцов не совпадают, то имена для конечного результата берутся из первого запроса. Результирующие столбцы сопоставляются по их индексу (порядку внутри `SELECT`). Если имена столбцов не совпадают, то имена для конечного результата берутся из первого запроса.
При объединении выполняет приведение типов. Например, если два запроса имеют одно и то же поле с не-`Nullable` и `Nullable` совместимыми типами, полученные в результате `UNION` данные будут иметь `Nullable` тип. При объединении выполняется приведение типов. Например, если два запроса имеют одно и то же поле с не-`Nullable` и `Nullable` совместимыми типами, полученные в результате `UNION` данные будут иметь `Nullable` тип.
Запросы, которые являются частью `UNION`, могут быть заключены в круглые скобки. [ORDER BY](order-by.md) и [LIMIT](limit.md) применяются к отдельным запросам, а не к конечному результату. Если вам нужно применить преобразование к конечному результату, вы можете разместить все объединенные с помощью `UNION` запросы в подзапрос в секции [FROM](from.md). Запросы, которые являются частью `UNION`, могут быть заключены в круглые скобки. [ORDER BY](order-by.md) и [LIMIT](limit.md) применяются к отдельным запросам, а не к конечному результату. Если вам нужно применить преобразование к конечному результату, вы можете разместить все объединенные с помощью `UNION` запросы в подзапрос в секции [FROM](from.md).

View File

@ -5,7 +5,7 @@ sidebar_label: WITH
# Секция WITH {#with-clause} # Секция WITH {#with-clause}
Clickhouse поддерживает [Общие табличные выражения](https://ru.wikipedia.org/wiki/Иерархические_и_рекурсивныеапросы_в_SQL), то есть позволяет использовать результаты выражений из секции `WITH` в остальной части `SELECT` запроса. Именованные подзапросы могут быть включены в текущий и дочерний контекст запроса в тех местах, где разрешены табличные объекты. Рекурсия предотвращается путем скрытия общего табличного выражения текущего уровня из выражения `WITH`. ClickHouse поддерживает [Общие табличные выражения](https://ru.wikipedia.org/wiki/Иерархические_и_рекурсивныеапросы_в_SQL), то есть позволяет использовать результаты выражений из секции `WITH` в остальной части `SELECT` запроса. Именованные подзапросы могут быть включены в текущий и дочерний контекст запроса в тех местах, где разрешены табличные объекты. Рекурсия предотвращается путем скрытия общего табличного выражения текущего уровня из выражения `WITH`.
## Синтаксис ## Синтаксис

View File

@ -24,6 +24,7 @@ Yandex**没有**维护下面列出的库,也没有做过任何广泛的测试
- [SeasClick C++ client](https://github.com/SeasX/SeasClick) - [SeasClick C++ client](https://github.com/SeasX/SeasClick)
- [one-ck](https://github.com/lizhichao/one-ck) - [one-ck](https://github.com/lizhichao/one-ck)
- [glushkovds/phpclickhouse-laravel](https://packagist.org/packages/glushkovds/phpclickhouse-laravel) - [glushkovds/phpclickhouse-laravel](https://packagist.org/packages/glushkovds/phpclickhouse-laravel)
- [hyvor/clickhouse-php](https://github.com/hyvor/clickhouse-php)
- Go - Go
- [clickhouse](https://github.com/kshvakov/clickhouse/) - [clickhouse](https://github.com/kshvakov/clickhouse/)
- [go-clickhouse](https://github.com/roistat/go-clickhouse) - [go-clickhouse](https://github.com/roistat/go-clickhouse)

View File

@ -35,26 +35,26 @@ namespace
void CancelToken::Registry::insert(CancelToken * token) void CancelToken::Registry::insert(CancelToken * token)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
threads[token->thread_id] = token; threads[token->thread_id] = token;
} }
void CancelToken::Registry::remove(CancelToken * token) void CancelToken::Registry::remove(CancelToken * token)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
threads.erase(token->thread_id); threads.erase(token->thread_id);
} }
void CancelToken::Registry::signal(UInt64 tid) void CancelToken::Registry::signal(UInt64 tid)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
if (auto it = threads.find(tid); it != threads.end()) if (auto it = threads.find(tid); it != threads.end())
it->second->signalImpl(); it->second->signalImpl();
} }
void CancelToken::Registry::signal(UInt64 tid, int code, const String & message) void CancelToken::Registry::signal(UInt64 tid, int code, const String & message)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
if (auto it = threads.find(tid); it != threads.end()) if (auto it = threads.find(tid); it != threads.end())
it->second->signalImpl(code, message); it->second->signalImpl(code, message);
} }

View File

@ -163,14 +163,14 @@ public:
/// Returns size of queue /// Returns size of queue
size_t size() const size_t size() const
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
return queue.size(); return queue.size();
} }
/// Returns if queue is empty /// Returns if queue is empty
bool empty() const bool empty() const
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
return queue.empty(); return queue.empty();
} }
@ -184,7 +184,7 @@ public:
bool was_finished_before = false; bool was_finished_before = false;
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
if (is_finished) if (is_finished)
return true; return true;
@ -202,14 +202,14 @@ public:
/// Returns if queue is finished /// Returns if queue is finished
bool isFinished() const bool isFinished() const
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
return is_finished; return is_finished;
} }
/// Returns if queue is finished and empty /// Returns if queue is finished and empty
bool isFinishedAndEmpty() const bool isFinishedAndEmpty() const
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
return is_finished && queue.empty(); return is_finished && queue.empty();
} }
@ -217,7 +217,7 @@ public:
void clear() void clear()
{ {
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
if (is_finished) if (is_finished)
return; return;
@ -233,7 +233,7 @@ public:
void clearAndFinish() void clearAndFinish()
{ {
{ {
std::lock_guard<std::mutex> lock(queue_mutex); std::lock_guard lock(queue_mutex);
std::queue<T> empty_queue; std::queue<T> empty_queue;
queue.swap(empty_queue); queue.swap(empty_queue);

View File

@ -149,7 +149,7 @@ DateLUT::DateLUT()
const DateLUTImpl & DateLUT::getImplementation(const std::string & time_zone) const const DateLUTImpl & DateLUT::getImplementation(const std::string & time_zone) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
auto it = impls.emplace(time_zone, nullptr).first; auto it = impls.emplace(time_zone, nullptr).first;
if (!it->second) if (!it->second)

View File

@ -26,13 +26,13 @@ namespace CurrentStatusInfo
inline void set(Status status, Key key, Int8 value) inline void set(Status status, Key key, Int8 value)
{ {
std::lock_guard<std::mutex> lock(locks[status]); std::lock_guard lock(locks[status]);
values[status][key] = value; values[status][key] = value;
} }
inline void unset(Status status, Key key) inline void unset(Status status, Key key)
{ {
std::lock_guard<std::mutex> lock(locks[status]); std::lock_guard lock(locks[status]);
values[status].erase(key); values[status].erase(key);
} }
} }

View File

@ -109,14 +109,14 @@ size_t TLDListsHolder::parseAndAddTldList(const std::string & name, const std::s
} }
size_t tld_list_size = tld_list.size(); size_t tld_list_size = tld_list.size();
std::lock_guard<std::mutex> lock(tld_lists_map_mutex); std::lock_guard lock(tld_lists_map_mutex);
tld_lists_map.insert(std::make_pair(name, std::move(tld_list))); tld_lists_map.insert(std::make_pair(name, std::move(tld_list)));
return tld_list_size; return tld_list_size;
} }
const TLDList & TLDListsHolder::getTldList(const std::string & name) const TLDList & TLDListsHolder::getTldList(const std::string & name)
{ {
std::lock_guard<std::mutex> lock(tld_lists_map_mutex); std::lock_guard lock(tld_lists_map_mutex);
auto it = tld_lists_map.find(name); auto it = tld_lists_map.find(name);
if (it == tld_lists_map.end()) if (it == tld_lists_map.end())
throw Exception(ErrorCodes::TLD_LIST_NOT_FOUND, "TLD list {} does not exist", name); throw Exception(ErrorCodes::TLD_LIST_NOT_FOUND, "TLD list {} does not exist", name);

View File

@ -130,7 +130,7 @@ Pool::Pool(const Poco::Util::AbstractConfiguration & cfg, const std::string & co
Pool::~Pool() Pool::~Pool()
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
for (auto & connection : connections) for (auto & connection : connections)
delete static_cast<Connection *>(connection); delete static_cast<Connection *>(connection);
@ -187,7 +187,7 @@ Pool::Entry Pool::get(uint64_t wait_timeout)
Pool::Entry Pool::tryGet() Pool::Entry Pool::tryGet()
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
initialize(); initialize();
@ -229,7 +229,7 @@ void Pool::removeConnection(Connection* connection)
{ {
logger.trace("(%s): Removing connection.", getDescription()); logger.trace("(%s): Removing connection.", getDescription());
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
if (connection) if (connection)
{ {
if (connection->ref_count > 0) if (connection->ref_count > 0)

View File

@ -76,7 +76,7 @@ PoolWithFailover PoolFactory::get(const Poco::Util::AbstractConfiguration & conf
const std::string & config_name, unsigned default_connections, unsigned max_connections, size_t max_tries) const std::string & config_name, unsigned default_connections, unsigned max_connections, size_t max_tries)
{ {
std::lock_guard<std::mutex> lock(impl->mutex); std::lock_guard lock(impl->mutex);
if (auto entry = impl->pools.find(config_name); entry != impl->pools.end()) if (auto entry = impl->pools.find(config_name); entry != impl->pools.end())
{ {
return *(entry->second); return *(entry->second);
@ -106,7 +106,7 @@ PoolWithFailover PoolFactory::get(const Poco::Util::AbstractConfiguration & conf
void PoolFactory::reset() void PoolFactory::reset()
{ {
std::lock_guard<std::mutex> lock(impl->mutex); std::lock_guard lock(impl->mutex);
impl->pools.clear(); impl->pools.clear();
impl->pools_by_ids.clear(); impl->pools_by_ids.clear();
} }

View File

@ -123,7 +123,7 @@ PoolWithFailover::PoolWithFailover(const PoolWithFailover & other)
PoolWithFailover::Entry PoolWithFailover::get() PoolWithFailover::Entry PoolWithFailover::get()
{ {
Poco::Util::Application & app = Poco::Util::Application::instance(); Poco::Util::Application & app = Poco::Util::Application::instance();
std::lock_guard<std::mutex> locker(mutex); std::lock_guard locker(mutex);
/// If we cannot connect to some replica due to pool overflow, than we will wait and connect. /// If we cannot connect to some replica due to pool overflow, than we will wait and connect.
PoolPtr * full_pool = nullptr; PoolPtr * full_pool = nullptr;

View File

@ -27,7 +27,7 @@ uint64_t InMemoryLogStore::start_index() const
uint64_t InMemoryLogStore::next_slot() const uint64_t InMemoryLogStore::next_slot() const
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
// Exclude the dummy entry. // Exclude the dummy entry.
return start_idx + logs.size() - 1; return start_idx + logs.size() - 1;
} }
@ -35,7 +35,7 @@ uint64_t InMemoryLogStore::next_slot() const
nuraft::ptr<nuraft::log_entry> InMemoryLogStore::last_entry() const nuraft::ptr<nuraft::log_entry> InMemoryLogStore::last_entry() const
{ {
uint64_t next_idx = next_slot(); uint64_t next_idx = next_slot();
std::lock_guard<std::mutex> lock(logs_lock); std::lock_guard lock(logs_lock);
auto entry = logs.find(next_idx - 1); auto entry = logs.find(next_idx - 1);
if (entry == logs.end()) if (entry == logs.end())
entry = logs.find(0); entry = logs.find(0);
@ -47,7 +47,7 @@ uint64_t InMemoryLogStore::append(nuraft::ptr<nuraft::log_entry> & entry)
{ {
ptr<log_entry> clone = makeClone(entry); ptr<log_entry> clone = makeClone(entry);
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
uint64_t idx = start_idx + logs.size() - 1; uint64_t idx = start_idx + logs.size() - 1;
logs[idx] = clone; logs[idx] = clone;
return idx; return idx;
@ -58,7 +58,7 @@ void InMemoryLogStore::write_at(uint64_t index, nuraft::ptr<nuraft::log_entry> &
nuraft::ptr<log_entry> clone = makeClone(entry); nuraft::ptr<log_entry> clone = makeClone(entry);
// Discard all logs equal to or greater than `index. // Discard all logs equal to or greater than `index.
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
auto itr = logs.lower_bound(index); auto itr = logs.lower_bound(index);
while (itr != logs.end()) while (itr != logs.end())
itr = logs.erase(itr); itr = logs.erase(itr);
@ -76,7 +76,7 @@ nuraft::ptr<std::vector<nuraft::ptr<nuraft::log_entry>>> InMemoryLogStore::log_e
{ {
nuraft::ptr<nuraft::log_entry> src = nullptr; nuraft::ptr<nuraft::log_entry> src = nullptr;
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
auto entry = logs.find(i); auto entry = logs.find(i);
if (entry == logs.end()) if (entry == logs.end())
{ {
@ -94,7 +94,7 @@ nuraft::ptr<nuraft::log_entry> InMemoryLogStore::entry_at(uint64_t index)
{ {
nuraft::ptr<nuraft::log_entry> src = nullptr; nuraft::ptr<nuraft::log_entry> src = nullptr;
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
auto entry = logs.find(index); auto entry = logs.find(index);
if (entry == logs.end()) if (entry == logs.end())
entry = logs.find(0); entry = logs.find(0);
@ -107,7 +107,7 @@ uint64_t InMemoryLogStore::term_at(uint64_t index)
{ {
uint64_t term = 0; uint64_t term = 0;
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
auto entry = logs.find(index); auto entry = logs.find(index);
if (entry == logs.end()) if (entry == logs.end())
entry = logs.find(0); entry = logs.find(0);
@ -125,7 +125,7 @@ nuraft::ptr<nuraft::buffer> InMemoryLogStore::pack(uint64_t index, Int32 cnt)
{ {
ptr<log_entry> le = nullptr; ptr<log_entry> le = nullptr;
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
le = logs[ii]; le = logs[ii];
} }
assert(le.get()); assert(le.get());
@ -162,13 +162,13 @@ void InMemoryLogStore::apply_pack(uint64_t index, nuraft::buffer & pack)
nuraft::ptr<nuraft::log_entry> le = nuraft::log_entry::deserialize(*buf_local); nuraft::ptr<nuraft::log_entry> le = nuraft::log_entry::deserialize(*buf_local);
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
logs[cur_idx] = le; logs[cur_idx] = le;
} }
} }
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
auto entry = logs.upper_bound(0); auto entry = logs.upper_bound(0);
if (entry != logs.end()) if (entry != logs.end())
start_idx = entry->first; start_idx = entry->first;
@ -179,7 +179,7 @@ void InMemoryLogStore::apply_pack(uint64_t index, nuraft::buffer & pack)
bool InMemoryLogStore::compact(uint64_t last_log_index) bool InMemoryLogStore::compact(uint64_t last_log_index)
{ {
std::lock_guard<std::mutex> l(logs_lock); std::lock_guard l(logs_lock);
for (uint64_t ii = start_idx; ii <= last_log_index; ++ii) for (uint64_t ii = start_idx; ii <= last_log_index; ++ii)
{ {
auto entry = logs.find(ii); auto entry = logs.find(ii);

View File

@ -341,7 +341,7 @@ void KeeperStateMachine::rollbackRequest(const KeeperStorage::RequestForSession
nuraft::ptr<nuraft::snapshot> KeeperStateMachine::last_snapshot() nuraft::ptr<nuraft::snapshot> KeeperStateMachine::last_snapshot()
{ {
/// Just return the latest snapshot. /// Just return the latest snapshot.
std::lock_guard<std::mutex> lock(snapshots_lock); std::lock_guard lock(snapshots_lock);
return latest_snapshot_meta; return latest_snapshot_meta;
} }

View File

@ -37,7 +37,7 @@ nuraft::ptr<nuraft::buffer> SummingStateMachine::commit(const uint64_t log_idx,
bool SummingStateMachine::apply_snapshot(nuraft::snapshot & s) bool SummingStateMachine::apply_snapshot(nuraft::snapshot & s)
{ {
std::lock_guard<std::mutex> ll(snapshots_lock); std::lock_guard ll(snapshots_lock);
auto entry = snapshots.find(s.get_last_log_idx()); auto entry = snapshots.find(s.get_last_log_idx());
if (entry == snapshots.end()) if (entry == snapshots.end())
return false; return false;
@ -50,7 +50,7 @@ bool SummingStateMachine::apply_snapshot(nuraft::snapshot & s)
nuraft::ptr<nuraft::snapshot> SummingStateMachine::last_snapshot() nuraft::ptr<nuraft::snapshot> SummingStateMachine::last_snapshot()
{ {
// Just return the latest snapshot. // Just return the latest snapshot.
std::lock_guard<std::mutex> ll(snapshots_lock); std::lock_guard ll(snapshots_lock);
auto entry = snapshots.rbegin(); auto entry = snapshots.rbegin();
if (entry == snapshots.rend()) if (entry == snapshots.rend())
return nullptr; return nullptr;
@ -100,7 +100,7 @@ void SummingStateMachine::save_logical_snp_obj(
nuraft::buffer_serializer bs(data); nuraft::buffer_serializer bs(data);
int64_t local_value = static_cast<int64_t>(bs.get_u64()); int64_t local_value = static_cast<int64_t>(bs.get_u64());
std::lock_guard<std::mutex> ll(snapshots_lock); std::lock_guard ll(snapshots_lock);
auto entry = snapshots.find(s.get_last_log_idx()); auto entry = snapshots.find(s.get_last_log_idx());
assert(entry != snapshots.end()); assert(entry != snapshots.end());
entry->second->value = local_value; entry->second->value = local_value;
@ -118,7 +118,7 @@ int SummingStateMachine::read_logical_snp_obj(
{ {
nuraft::ptr<SingleValueSnapshotContext> ctx = nullptr; nuraft::ptr<SingleValueSnapshotContext> ctx = nullptr;
{ {
std::lock_guard<std::mutex> ll(snapshots_lock); std::lock_guard ll(snapshots_lock);
auto entry = snapshots.find(s.get_last_log_idx()); auto entry = snapshots.find(s.get_last_log_idx());
if (entry == snapshots.end()) if (entry == snapshots.end())
{ {
@ -155,7 +155,7 @@ void SummingStateMachine::create_snapshot(
nuraft::async_result<bool>::handler_type & when_done) nuraft::async_result<bool>::handler_type & when_done)
{ {
{ {
std::lock_guard<std::mutex> ll(snapshots_lock); std::lock_guard ll(snapshots_lock);
createSnapshotInternal(s); createSnapshotInternal(s);
} }
nuraft::ptr<std::exception> except(nullptr); nuraft::ptr<std::exception> except(nullptr);

View File

@ -82,7 +82,7 @@ DatabaseMySQL::DatabaseMySQL(
bool DatabaseMySQL::empty() const bool DatabaseMySQL::empty() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
fetchTablesIntoLocalCache(getContext()); fetchTablesIntoLocalCache(getContext());
@ -99,7 +99,7 @@ bool DatabaseMySQL::empty() const
DatabaseTablesIteratorPtr DatabaseMySQL::getTablesIterator(ContextPtr local_context, const FilterByNameFunction & filter_by_table_name) const DatabaseTablesIteratorPtr DatabaseMySQL::getTablesIterator(ContextPtr local_context, const FilterByNameFunction & filter_by_table_name) const
{ {
Tables tables; Tables tables;
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
fetchTablesIntoLocalCache(local_context); fetchTablesIntoLocalCache(local_context);
@ -117,7 +117,7 @@ bool DatabaseMySQL::isTableExist(const String & name, ContextPtr local_context)
StoragePtr DatabaseMySQL::tryGetTable(const String & mysql_table_name, ContextPtr local_context) const StoragePtr DatabaseMySQL::tryGetTable(const String & mysql_table_name, ContextPtr local_context) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
fetchTablesIntoLocalCache(local_context); fetchTablesIntoLocalCache(local_context);
@ -129,7 +129,7 @@ StoragePtr DatabaseMySQL::tryGetTable(const String & mysql_table_name, ContextPt
ASTPtr DatabaseMySQL::getCreateTableQueryImpl(const String & table_name, ContextPtr local_context, bool throw_on_error) const ASTPtr DatabaseMySQL::getCreateTableQueryImpl(const String & table_name, ContextPtr local_context, bool throw_on_error) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
fetchTablesIntoLocalCache(local_context); fetchTablesIntoLocalCache(local_context);
@ -175,7 +175,7 @@ ASTPtr DatabaseMySQL::getCreateTableQueryImpl(const String & table_name, Context
time_t DatabaseMySQL::getObjectMetadataModificationTime(const String & table_name) const time_t DatabaseMySQL::getObjectMetadataModificationTime(const String & table_name) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
fetchTablesIntoLocalCache(getContext()); fetchTablesIntoLocalCache(getContext());
@ -360,7 +360,7 @@ void DatabaseMySQL::cleanOutdatedTables()
void DatabaseMySQL::attachTable(ContextPtr /* context_ */, const String & table_name, const StoragePtr & storage, const String &) void DatabaseMySQL::attachTable(ContextPtr /* context_ */, const String & table_name, const StoragePtr & storage, const String &)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
if (!local_tables_cache.contains(table_name)) if (!local_tables_cache.contains(table_name))
throw Exception(ErrorCodes::UNKNOWN_TABLE, "Cannot attach table {}.{} because it does not exist.", throw Exception(ErrorCodes::UNKNOWN_TABLE, "Cannot attach table {}.{} because it does not exist.",
@ -383,7 +383,7 @@ void DatabaseMySQL::attachTable(ContextPtr /* context_ */, const String & table_
StoragePtr DatabaseMySQL::detachTable(ContextPtr /* context */, const String & table_name) StoragePtr DatabaseMySQL::detachTable(ContextPtr /* context */, const String & table_name)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
if (remove_or_detach_tables.contains(table_name)) if (remove_or_detach_tables.contains(table_name))
throw Exception(ErrorCodes::TABLE_IS_DROPPED, "Table {}.{} is dropped", throw Exception(ErrorCodes::TABLE_IS_DROPPED, "Table {}.{} is dropped",
@ -405,7 +405,7 @@ String DatabaseMySQL::getMetadataPath() const
void DatabaseMySQL::loadStoredObjects(ContextMutablePtr, LoadingStrictnessLevel /*mode*/, bool /* skip_startup_tables */) void DatabaseMySQL::loadStoredObjects(ContextMutablePtr, LoadingStrictnessLevel /*mode*/, bool /* skip_startup_tables */)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
fs::directory_iterator iter(getMetadataPath()); fs::directory_iterator iter(getMetadataPath());
for (fs::directory_iterator end; iter != end; ++iter) for (fs::directory_iterator end; iter != end; ++iter)
@ -421,7 +421,7 @@ void DatabaseMySQL::loadStoredObjects(ContextMutablePtr, LoadingStrictnessLevel
void DatabaseMySQL::detachTablePermanently(ContextPtr, const String & table_name) void DatabaseMySQL::detachTablePermanently(ContextPtr, const String & table_name)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
fs::path remove_flag = fs::path(getMetadataPath()) / (escapeForFileName(table_name) + suffix); fs::path remove_flag = fs::path(getMetadataPath()) / (escapeForFileName(table_name) + suffix);

View File

@ -76,7 +76,7 @@ String DatabasePostgreSQL::formatTableName(const String & table_name, bool quote
bool DatabasePostgreSQL::empty() const bool DatabasePostgreSQL::empty() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
auto connection_holder = pool->get(); auto connection_holder = pool->get();
auto tables_list = fetchPostgreSQLTablesList(connection_holder->get(), configuration.schema); auto tables_list = fetchPostgreSQLTablesList(connection_holder->get(), configuration.schema);
@ -91,7 +91,7 @@ bool DatabasePostgreSQL::empty() const
DatabaseTablesIteratorPtr DatabasePostgreSQL::getTablesIterator(ContextPtr local_context, const FilterByNameFunction & /* filter_by_table_name */) const DatabaseTablesIteratorPtr DatabasePostgreSQL::getTablesIterator(ContextPtr local_context, const FilterByNameFunction & /* filter_by_table_name */) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
Tables tables; Tables tables;
/// Do not allow to throw here, because this might be, for example, a query to system.tables. /// Do not allow to throw here, because this might be, for example, a query to system.tables.
@ -154,7 +154,7 @@ bool DatabasePostgreSQL::checkPostgresTable(const String & table_name) const
bool DatabasePostgreSQL::isTableExist(const String & table_name, ContextPtr /* context */) const bool DatabasePostgreSQL::isTableExist(const String & table_name, ContextPtr /* context */) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
if (detached_or_dropped.contains(table_name)) if (detached_or_dropped.contains(table_name))
return false; return false;
@ -165,7 +165,7 @@ bool DatabasePostgreSQL::isTableExist(const String & table_name, ContextPtr /* c
StoragePtr DatabasePostgreSQL::tryGetTable(const String & table_name, ContextPtr local_context) const StoragePtr DatabasePostgreSQL::tryGetTable(const String & table_name, ContextPtr local_context) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
if (!detached_or_dropped.contains(table_name)) if (!detached_or_dropped.contains(table_name))
return fetchTable(table_name, local_context, false); return fetchTable(table_name, local_context, false);
@ -210,7 +210,7 @@ StoragePtr DatabasePostgreSQL::fetchTable(const String & table_name, ContextPtr,
void DatabasePostgreSQL::attachTable(ContextPtr /* context_ */, const String & table_name, const StoragePtr & storage, const String &) void DatabasePostgreSQL::attachTable(ContextPtr /* context_ */, const String & table_name, const StoragePtr & storage, const String &)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
if (!checkPostgresTable(table_name)) if (!checkPostgresTable(table_name))
throw Exception(ErrorCodes::UNKNOWN_TABLE, throw Exception(ErrorCodes::UNKNOWN_TABLE,
@ -235,7 +235,7 @@ void DatabasePostgreSQL::attachTable(ContextPtr /* context_ */, const String & t
StoragePtr DatabasePostgreSQL::detachTable(ContextPtr /* context_ */, const String & table_name) StoragePtr DatabasePostgreSQL::detachTable(ContextPtr /* context_ */, const String & table_name)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
if (detached_or_dropped.contains(table_name)) if (detached_or_dropped.contains(table_name))
throw Exception(ErrorCodes::TABLE_IS_DROPPED, "Cannot detach table {}. It is already dropped/detached", getTableNameForLogs(table_name)); throw Exception(ErrorCodes::TABLE_IS_DROPPED, "Cannot detach table {}. It is already dropped/detached", getTableNameForLogs(table_name));
@ -266,7 +266,7 @@ void DatabasePostgreSQL::createTable(ContextPtr local_context, const String & ta
void DatabasePostgreSQL::dropTable(ContextPtr, const String & table_name, bool /* sync */) void DatabasePostgreSQL::dropTable(ContextPtr, const String & table_name, bool /* sync */)
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
if (!checkPostgresTable(table_name)) if (!checkPostgresTable(table_name))
throw Exception(ErrorCodes::UNKNOWN_TABLE, "Cannot drop table {} because it does not exist", getTableNameForLogs(table_name)); throw Exception(ErrorCodes::UNKNOWN_TABLE, "Cannot drop table {} because it does not exist", getTableNameForLogs(table_name));
@ -293,7 +293,7 @@ void DatabasePostgreSQL::drop(ContextPtr /*context*/)
void DatabasePostgreSQL::loadStoredObjects(ContextMutablePtr /* context */, LoadingStrictnessLevel /*mode*/, bool /* skip_startup_tables */) void DatabasePostgreSQL::loadStoredObjects(ContextMutablePtr /* context */, LoadingStrictnessLevel /*mode*/, bool /* skip_startup_tables */)
{ {
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
fs::directory_iterator iter(getMetadataPath()); fs::directory_iterator iter(getMetadataPath());
/// Check for previously dropped tables /// Check for previously dropped tables
@ -314,7 +314,7 @@ void DatabasePostgreSQL::loadStoredObjects(ContextMutablePtr /* context */, Load
void DatabasePostgreSQL::removeOutdatedTables() void DatabasePostgreSQL::removeOutdatedTables()
{ {
std::lock_guard<std::mutex> lock{mutex}; std::lock_guard lock{mutex};
auto connection_holder = pool->get(); auto connection_holder = pool->get();
auto actual_tables = fetchPostgreSQLTablesList(connection_holder->get(), configuration.schema); auto actual_tables = fetchPostgreSQLTablesList(connection_holder->get(), configuration.schema);

View File

@ -40,14 +40,14 @@ DatabaseSQLite::DatabaseSQLite(
bool DatabaseSQLite::empty() const bool DatabaseSQLite::empty() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
return fetchTablesList().empty(); return fetchTablesList().empty();
} }
DatabaseTablesIteratorPtr DatabaseSQLite::getTablesIterator(ContextPtr local_context, const IDatabase::FilterByNameFunction &) const DatabaseTablesIteratorPtr DatabaseSQLite::getTablesIterator(ContextPtr local_context, const IDatabase::FilterByNameFunction &) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
Tables tables; Tables tables;
auto table_names = fetchTablesList(); auto table_names = fetchTablesList();
@ -120,14 +120,14 @@ bool DatabaseSQLite::checkSQLiteTable(const String & table_name) const
bool DatabaseSQLite::isTableExist(const String & table_name, ContextPtr) const bool DatabaseSQLite::isTableExist(const String & table_name, ContextPtr) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
return checkSQLiteTable(table_name); return checkSQLiteTable(table_name);
} }
StoragePtr DatabaseSQLite::tryGetTable(const String & table_name, ContextPtr local_context) const StoragePtr DatabaseSQLite::tryGetTable(const String & table_name, ContextPtr local_context) const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
return fetchTable(table_name, local_context, false); return fetchTable(table_name, local_context, false);
} }
@ -175,7 +175,7 @@ ASTPtr DatabaseSQLite::getCreateTableQueryImpl(const String & table_name, Contex
{ {
StoragePtr storage; StoragePtr storage;
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
storage = fetchTable(table_name, local_context, false); storage = fetchTable(table_name, local_context, false);
} }
if (!storage) if (!storage)

View File

@ -1289,7 +1289,7 @@ void Context::addQueryAccessInfo(
if (isGlobalContext()) if (isGlobalContext())
throw Exception(ErrorCodes::LOGICAL_ERROR, "Global context cannot have query access info"); throw Exception(ErrorCodes::LOGICAL_ERROR, "Global context cannot have query access info");
std::lock_guard<std::mutex> lock(query_access_info.mutex); std::lock_guard lock(query_access_info.mutex);
query_access_info.databases.emplace(quoted_database_name); query_access_info.databases.emplace(quoted_database_name);
query_access_info.tables.emplace(full_quoted_table_name); query_access_info.tables.emplace(full_quoted_table_name);
for (const auto & column_name : column_names) for (const auto & column_name : column_names)

View File

@ -34,7 +34,7 @@ std::set<std::string> ExternalLoaderXMLConfigRepository::getAllLoadablesDefiniti
std::unordered_set<std::string> patterns_copy; std::unordered_set<std::string> patterns_copy;
{ {
std::lock_guard<std::mutex> lock(patterns_mutex); std::lock_guard lock(patterns_mutex);
patterns_copy = patterns; patterns_copy = patterns;
} }
@ -71,7 +71,7 @@ std::set<std::string> ExternalLoaderXMLConfigRepository::getAllLoadablesDefiniti
void ExternalLoaderXMLConfigRepository::updatePatterns(const std::unordered_set<std::string> & patterns_) void ExternalLoaderXMLConfigRepository::updatePatterns(const std::unordered_set<std::string> & patterns_)
{ {
std::lock_guard<std::mutex> lock(patterns_mutex); std::lock_guard lock(patterns_mutex);
if (patterns == patterns_) if (patterns == patterns_)
return; return;

View File

@ -52,7 +52,7 @@ namespace
Block read() Block read()
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
if (eof) if (eof)
return {}; return {};

View File

@ -352,7 +352,7 @@ CHJIT::~CHJIT() = default;
CHJIT::CompiledModule CHJIT::compileModule(std::function<void (llvm::Module &)> compile_function) CHJIT::CompiledModule CHJIT::compileModule(std::function<void (llvm::Module &)> compile_function)
{ {
std::lock_guard<std::mutex> lock(jit_lock); std::lock_guard lock(jit_lock);
auto module = createModuleForCompilation(); auto module = createModuleForCompilation();
compile_function(*module); compile_function(*module);
@ -426,7 +426,7 @@ CHJIT::CompiledModule CHJIT::compileModule(std::unique_ptr<llvm::Module> module)
void CHJIT::deleteCompiledModule(const CHJIT::CompiledModule & module) void CHJIT::deleteCompiledModule(const CHJIT::CompiledModule & module)
{ {
std::lock_guard<std::mutex> lock(jit_lock); std::lock_guard lock(jit_lock);
auto module_it = module_identifier_to_memory_manager.find(module.identifier); auto module_it = module_identifier_to_memory_manager.find(module.identifier);
if (module_it == module_identifier_to_memory_manager.end()) if (module_it == module_identifier_to_memory_manager.end())
@ -438,7 +438,7 @@ void CHJIT::deleteCompiledModule(const CHJIT::CompiledModule & module)
void CHJIT::registerExternalSymbol(const std::string & symbol_name, void * address) void CHJIT::registerExternalSymbol(const std::string & symbol_name, void * address)
{ {
std::lock_guard<std::mutex> lock(jit_lock); std::lock_guard lock(jit_lock);
symbol_resolver->registerSymbol(symbol_name, address); symbol_resolver->registerSymbol(symbol_name, address);
} }

View File

@ -137,7 +137,7 @@ void OwnSplitChannel::logSplit(const Poco::Message & msg)
std::shared_ptr<TextLog> text_log_locked{}; std::shared_ptr<TextLog> text_log_locked{};
{ {
std::lock_guard<std::mutex> lock(text_log_mutex); std::lock_guard lock(text_log_mutex);
text_log_locked = text_log.lock(); text_log_locked = text_log.lock();
} }
if (text_log_locked) if (text_log_locked)
@ -155,7 +155,7 @@ void OwnSplitChannel::addChannel(Poco::AutoPtr<Poco::Channel> channel, const std
#ifndef WITHOUT_TEXT_LOG #ifndef WITHOUT_TEXT_LOG
void OwnSplitChannel::addTextLog(std::shared_ptr<DB::TextLog> log, int max_priority) void OwnSplitChannel::addTextLog(std::shared_ptr<DB::TextLog> log, int max_priority)
{ {
std::lock_guard<std::mutex> lock(text_log_mutex); std::lock_guard lock(text_log_mutex);
text_log = log; text_log = log;
text_log_max_priority.store(max_priority, std::memory_order_relaxed); text_log_max_priority.store(max_priority, std::memory_order_relaxed);
} }

View File

@ -15,7 +15,7 @@ namespace DB
collector_finished.wait(); collector_finished.wait();
{ {
std::lock_guard<std::mutex> lock(collector_thread_mutex); std::lock_guard lock(collector_thread_mutex);
if (collector_thread.joinable()) if (collector_thread.joinable())
collector_thread.join(); collector_thread.join();
} }
@ -80,7 +80,7 @@ namespace DB
} }
{ {
std::lock_guard<std::mutex> lock(collector_thread_mutex); std::lock_guard lock(collector_thread_mutex);
if (collector_thread.joinable()) if (collector_thread.joinable())
collector_thread.join(); collector_thread.join();
} }
@ -137,7 +137,7 @@ namespace DB
{ {
/// Notify other threads. /// Notify other threads.
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
unit.status = READY_TO_INSERT; unit.status = READY_TO_INSERT;
writer_condvar.notify_all(); writer_condvar.notify_all();
} }
@ -227,7 +227,7 @@ namespace DB
unit.actual_memory_size = out_buffer.getActualSize(); unit.actual_memory_size = out_buffer.getActualSize();
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
unit.status = READY_TO_READ; unit.status = READY_TO_READ;
collector_condvar.notify_all(); collector_condvar.notify_all();
} }

View File

@ -292,7 +292,7 @@ private:
{ {
/// Additionally notify condvars /// Additionally notify condvars
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
segmentator_condvar.notify_all(); segmentator_condvar.notify_all();
reader_condvar.notify_all(); reader_condvar.notify_all();
} }

View File

@ -62,7 +62,7 @@ public:
{ {
assert(!rhs_ports.first->isConnected() && !rhs_ports.second->isConnected()); assert(!rhs_ports.first->isConnected() && !rhs_ports.second->isConnected());
std::lock_guard<std::mutex> lock(mux); std::lock_guard lock(mux);
if (input_port || output_port) if (input_port || output_port)
{ {
assert(input_port && output_port); assert(input_port && output_port);

View File

@ -274,7 +274,7 @@ namespace
} }
catch (...) catch (...)
{ {
std::lock_guard<std::mutex> lock(send_data_lock); std::lock_guard lock(send_data_lock);
exception_during_send_data = std::current_exception(); exception_during_send_data = std::current_exception();
} }
}); });
@ -387,7 +387,7 @@ namespace
void rethrowExceptionDuringSendDataIfNeeded() void rethrowExceptionDuringSendDataIfNeeded()
{ {
std::lock_guard<std::mutex> lock(send_data_lock); std::lock_guard lock(send_data_lock);
if (exception_during_send_data) if (exception_during_send_data)
{ {
command_is_invalid = true; command_is_invalid = true;

View File

@ -125,7 +125,7 @@ void PrometheusMetricsWriter::write(WriteBuffer & wb) const
{ {
for (size_t i = 0, end = CurrentStatusInfo::end(); i < end; ++i) for (size_t i = 0, end = CurrentStatusInfo::end(); i < end; ++i)
{ {
std::lock_guard<std::mutex> lock(CurrentStatusInfo::locks[static_cast<CurrentStatusInfo::Status>(i)]); std::lock_guard lock(CurrentStatusInfo::locks[static_cast<CurrentStatusInfo::Status>(i)]);
std::string metric_name{CurrentStatusInfo::getName(static_cast<CurrentStatusInfo::Status>(i))}; std::string metric_name{CurrentStatusInfo::getName(static_cast<CurrentStatusInfo::Status>(i))};
std::string metric_doc{CurrentStatusInfo::getDocumentation(static_cast<CurrentStatusInfo::Status>(i))}; std::string metric_doc{CurrentStatusInfo::getDocumentation(static_cast<CurrentStatusInfo::Status>(i))};

View File

@ -12,7 +12,7 @@ FileLogDirectoryWatcher::FileLogDirectoryWatcher(const std::string & path_, Stor
FileLogDirectoryWatcher::Events FileLogDirectoryWatcher::getEventsAndReset() FileLogDirectoryWatcher::Events FileLogDirectoryWatcher::getEventsAndReset()
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
Events res; Events res;
res.swap(events); res.swap(events);
return res; return res;
@ -20,7 +20,7 @@ FileLogDirectoryWatcher::Events FileLogDirectoryWatcher::getEventsAndReset()
FileLogDirectoryWatcher::Error FileLogDirectoryWatcher::getErrorAndReset() FileLogDirectoryWatcher::Error FileLogDirectoryWatcher::getErrorAndReset()
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
Error old_error = error; Error old_error = error;
error = {}; error = {};
return old_error; return old_error;
@ -33,7 +33,7 @@ const std::string & FileLogDirectoryWatcher::getPath() const
void FileLogDirectoryWatcher::onItemAdded(DirectoryWatcherBase::DirectoryEvent ev) void FileLogDirectoryWatcher::onItemAdded(DirectoryWatcherBase::DirectoryEvent ev)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
EventInfo info{ev.event, "onItemAdded"}; EventInfo info{ev.event, "onItemAdded"};
std::string event_path = ev.path; std::string event_path = ev.path;
@ -51,7 +51,7 @@ void FileLogDirectoryWatcher::onItemAdded(DirectoryWatcherBase::DirectoryEvent e
void FileLogDirectoryWatcher::onItemRemoved(DirectoryWatcherBase::DirectoryEvent ev) void FileLogDirectoryWatcher::onItemRemoved(DirectoryWatcherBase::DirectoryEvent ev)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
EventInfo info{ev.event, "onItemRemoved"}; EventInfo info{ev.event, "onItemRemoved"};
std::string event_path = ev.path; std::string event_path = ev.path;
@ -74,7 +74,7 @@ void FileLogDirectoryWatcher::onItemRemoved(DirectoryWatcherBase::DirectoryEvent
/// because it is equal to just record and handle one MODIY event /// because it is equal to just record and handle one MODIY event
void FileLogDirectoryWatcher::onItemModified(DirectoryWatcherBase::DirectoryEvent ev) void FileLogDirectoryWatcher::onItemModified(DirectoryWatcherBase::DirectoryEvent ev)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
auto event_path = ev.path; auto event_path = ev.path;
EventInfo info{ev.event, "onItemModified"}; EventInfo info{ev.event, "onItemModified"};
@ -97,7 +97,7 @@ void FileLogDirectoryWatcher::onItemModified(DirectoryWatcherBase::DirectoryEven
void FileLogDirectoryWatcher::onItemMovedFrom(DirectoryWatcherBase::DirectoryEvent ev) void FileLogDirectoryWatcher::onItemMovedFrom(DirectoryWatcherBase::DirectoryEvent ev)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
EventInfo info{ev.event, "onItemMovedFrom"}; EventInfo info{ev.event, "onItemMovedFrom"};
std::string event_path = ev.path; std::string event_path = ev.path;
@ -114,7 +114,7 @@ void FileLogDirectoryWatcher::onItemMovedFrom(DirectoryWatcherBase::DirectoryEve
void FileLogDirectoryWatcher::onItemMovedTo(DirectoryWatcherBase::DirectoryEvent ev) void FileLogDirectoryWatcher::onItemMovedTo(DirectoryWatcherBase::DirectoryEvent ev)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
EventInfo info{ev.event, "onItemMovedTo"}; EventInfo info{ev.event, "onItemMovedTo"};
std::string event_path = ev.path; std::string event_path = ev.path;
@ -131,7 +131,7 @@ void FileLogDirectoryWatcher::onItemMovedTo(DirectoryWatcherBase::DirectoryEvent
void FileLogDirectoryWatcher::onError(Exception e) void FileLogDirectoryWatcher::onError(Exception e)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard lock(mutex);
LOG_ERROR(log, "Error happened during watching directory: {}", error.error_msg); LOG_ERROR(log, "Error happened during watching directory: {}", error.error_msg);
error.has_error = true; error.has_error = true;
error.error_msg = e.message(); error.error_msg = e.message();

View File

@ -312,7 +312,7 @@ Pipe StorageFileLog::read(
if (mv_attached) if (mv_attached)
throw Exception(ErrorCodes::QUERY_NOT_ALLOWED, "Cannot read from StorageFileLog with attached materialized views"); throw Exception(ErrorCodes::QUERY_NOT_ALLOWED, "Cannot read from StorageFileLog with attached materialized views");
std::lock_guard<std::mutex> lock(file_infos_mutex); std::lock_guard lock(file_infos_mutex);
if (running_streams) if (running_streams)
{ {
throw Exception(ErrorCodes::CANNOT_SELECT, "Another select query is running on this table, need to wait it finish."); throw Exception(ErrorCodes::CANNOT_SELECT, "Another select query is running on this table, need to wait it finish.");
@ -659,7 +659,7 @@ void StorageFileLog::threadFunc()
bool StorageFileLog::streamToViews() bool StorageFileLog::streamToViews()
{ {
std::lock_guard<std::mutex> lock(file_infos_mutex); std::lock_guard lock(file_infos_mutex);
if (running_streams) if (running_streams)
{ {
LOG_INFO(log, "Another select query is running on this table, need to wait it finish."); LOG_INFO(log, "Another select query is running on this table, need to wait it finish.");

View File

@ -856,7 +856,7 @@ HiveFiles StorageHive::collectHiveFiles(
= collectHiveFilesFromPartition(partition, query_info, hive_table_metadata, fs, context_, prune_level); = collectHiveFilesFromPartition(partition, query_info, hive_table_metadata, fs, context_, prune_level);
if (!hive_files_in_partition.empty()) if (!hive_files_in_partition.empty())
{ {
std::lock_guard<std::mutex> lock(hive_files_mutex); std::lock_guard lock(hive_files_mutex);
hit_parttions_num += 1; hit_parttions_num += 1;
if (hive_max_query_partitions > 0 && hit_parttions_num > hive_max_query_partitions) if (hive_max_query_partitions > 0 && hit_parttions_num > hive_max_query_partitions)
{ {
@ -882,7 +882,7 @@ HiveFiles StorageHive::collectHiveFiles(
auto hive_file = getHiveFileIfNeeded(file_info, {}, query_info, hive_table_metadata, context_, prune_level); auto hive_file = getHiveFileIfNeeded(file_info, {}, query_info, hive_table_metadata, context_, prune_level);
if (hive_file) if (hive_file)
{ {
std::lock_guard<std::mutex> lock(hive_files_mutex); std::lock_guard lock(hive_files_mutex);
hive_files.push_back(hive_file); hive_files.push_back(hive_file);
} }
}); });

View File

@ -2316,7 +2316,7 @@ bool ReplicatedMergeTreeMergePredicate::canMergeSinglePart(
return false; return false;
} }
std::lock_guard<std::mutex> lock(queue.state_mutex); std::lock_guard lock(queue.state_mutex);
/// We look for containing parts in queue.virtual_parts (and not in prev_virtual_parts) because queue.virtual_parts is newer /// We look for containing parts in queue.virtual_parts (and not in prev_virtual_parts) because queue.virtual_parts is newer
/// and it is guaranteed that it will contain all merges assigned before this object is constructed. /// and it is guaranteed that it will contain all merges assigned before this object is constructed.
@ -2334,7 +2334,7 @@ bool ReplicatedMergeTreeMergePredicate::canMergeSinglePart(
bool ReplicatedMergeTreeMergePredicate::partParticipatesInReplaceRange(const MergeTreeData::DataPartPtr & part, String * out_reason) const bool ReplicatedMergeTreeMergePredicate::partParticipatesInReplaceRange(const MergeTreeData::DataPartPtr & part, String * out_reason) const
{ {
std::lock_guard<std::mutex> lock(queue.state_mutex); std::lock_guard lock(queue.state_mutex);
for (const auto & entry : queue.queue) for (const auto & entry : queue.queue)
{ {
if (entry->type != ReplicatedMergeTreeLogEntry::REPLACE_RANGE) if (entry->type != ReplicatedMergeTreeLogEntry::REPLACE_RANGE)
@ -2457,7 +2457,7 @@ bool ReplicatedMergeTreeMergePredicate::isGoingToBeDropped(const MergeTreePartIn
String ReplicatedMergeTreeMergePredicate::getCoveringVirtualPart(const String & part_name) const String ReplicatedMergeTreeMergePredicate::getCoveringVirtualPart(const String & part_name) const
{ {
std::lock_guard<std::mutex> lock(queue.state_mutex); std::lock_guard lock(queue.state_mutex);
return queue.virtual_parts.getContainingPart(MergeTreePartInfo::fromPartName(part_name, queue.format_version)); return queue.virtual_parts.getContainingPart(MergeTreePartInfo::fromPartName(part_name, queue.format_version));
} }

View File

@ -208,13 +208,13 @@ void StorageDictionary::removeDictionaryConfigurationFromRepository()
Poco::Timestamp StorageDictionary::getUpdateTime() const Poco::Timestamp StorageDictionary::getUpdateTime() const
{ {
std::lock_guard<std::mutex> lock(dictionary_config_mutex); std::lock_guard lock(dictionary_config_mutex);
return update_time; return update_time;
} }
LoadablesConfigurationPtr StorageDictionary::getConfiguration() const LoadablesConfigurationPtr StorageDictionary::getConfiguration() const
{ {
std::lock_guard<std::mutex> lock(dictionary_config_mutex); std::lock_guard lock(dictionary_config_mutex);
return configuration; return configuration;
} }
@ -234,7 +234,7 @@ void StorageDictionary::renameInMemory(const StorageID & new_table_id)
assert(old_table_id.uuid == new_table_id.uuid || move_to_atomic || move_to_ordinary); assert(old_table_id.uuid == new_table_id.uuid || move_to_atomic || move_to_ordinary);
{ {
std::lock_guard<std::mutex> lock(dictionary_config_mutex); std::lock_guard lock(dictionary_config_mutex);
configuration->setString("dictionary.database", new_table_id.database_name); configuration->setString("dictionary.database", new_table_id.database_name);
configuration->setString("dictionary.name", new_table_id.table_name); configuration->setString("dictionary.name", new_table_id.table_name);
@ -301,7 +301,7 @@ void StorageDictionary::alter(const AlterCommands & params, ContextPtr alter_con
dictionary_non_const->setDictionaryComment(new_comment); dictionary_non_const->setDictionaryComment(new_comment);
} }
std::lock_guard<std::mutex> lock(dictionary_config_mutex); std::lock_guard lock(dictionary_config_mutex);
configuration->setString("dictionary.comment", new_comment); configuration->setString("dictionary.comment", new_comment);
} }

View File

@ -732,7 +732,7 @@ CancellationCode StorageMergeTree::killMutation(const String & mutation_id)
to_kill->removeFile(); to_kill->removeFile();
LOG_TRACE(log, "Cancelled part mutations and removed mutation file {}", mutation_id); LOG_TRACE(log, "Cancelled part mutations and removed mutation file {}", mutation_id);
{ {
std::lock_guard<std::mutex> lock(mutation_wait_mutex); std::lock_guard lock(mutation_wait_mutex);
mutation_wait_event.notify_all(); mutation_wait_event.notify_all();
} }
@ -1306,7 +1306,7 @@ size_t StorageMergeTree::clearOldMutations(bool truncate)
std::vector<MergeTreeMutationEntry> mutations_to_delete; std::vector<MergeTreeMutationEntry> mutations_to_delete;
{ {
std::lock_guard<std::mutex> lock(currently_processing_in_background_mutex); std::lock_guard lock(currently_processing_in_background_mutex);
if (current_mutations_by_version.size() <= finished_mutations_to_keep) if (current_mutations_by_version.size() <= finished_mutations_to_keep)
return 0; return 0;