Merge branch 'master' of github.com:ClickHouse/ClickHouse into polygon-dict-grids

This commit is contained in:
Andrey Chulkov 2020-05-18 02:36:26 +03:00
commit b64c9a09a5
12198 changed files with 495630 additions and 204962 deletions

View File

@ -52,7 +52,7 @@ IncludeCategories:
ReflowComments: false ReflowComments: false
AlignEscapedNewlinesLeft: false AlignEscapedNewlinesLeft: false
AlignEscapedNewlines: DontAlign AlignEscapedNewlines: DontAlign
AlignTrailingComments: true AlignTrailingComments: false
# Not changed: # Not changed:
AccessModifierOffset: -4 AccessModifierOffset: -4

205
.clang-tidy Normal file
View File

@ -0,0 +1,205 @@
Checks: '-*,
misc-throw-by-value-catch-by-reference,
misc-misplaced-const,
misc-unconventional-assign-operator,
misc-redundant-expression,
misc-static-assert,
misc-unconventional-assign-operator,
misc-uniqueptr-reset-release,
misc-unused-alias-decls,
misc-unused-parameters,
misc-unused-using-decls,
modernize-avoid-bind,
modernize-loop-convert,
modernize-make-shared,
modernize-make-unique,
modernize-raw-string-literal,
modernize-redundant-void-arg,
modernize-replace-auto-ptr,
modernize-replace-random-shuffle,
modernize-use-bool-literals,
modernize-use-nullptr,
modernize-use-using,
modernize-use-equals-default,
modernize-use-equals-delete,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-algorithm,
performance-inefficient-vector-operation,
performance-move-constructor-init,
performance-no-automatic-move,
performance-trivially-destructible,
performance-unnecessary-copy-initialization,
readability-avoid-const-params-in-decls,
readability-const-return-type,
readability-container-size-empty,
readability-convert-member-functions-to-static,
readability-delete-null-pointer,
readability-deleted-default,
readability-make-member-function-const,
readability-misplaced-array-index,
readability-non-const-parameter,
readability-qualified-auto,
readability-redundant-access-specifiers,
readability-redundant-control-flow,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
readability-redundant-string-init,
readability-static-definition-in-anonymous-namespace,
readability-string-compare,
readability-uniqueptr-delete-release,
readability-redundant-member-init,
readability-simplify-subscript-expr,
readability-simplify-boolean-expr,
readability-inconsistent-declaration-parameter-name,
readability-identifier-naming,
bugprone-undelegated-constructor,
bugprone-argument-comment,
bugprone-bad-signal-to-kill-thread,
bugprone-bool-pointer-implicit-conversion,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-forward-declaration-namespace,
bugprone-fold-init-type,
bugprone-inaccurate-erase,
bugprone-incorrect-roundings,
bugprone-infinite-loop,
bugprone-integer-division,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-artithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multiple-statement-macro,
bugprone-parent-virtual-call,
bugprone-posix-return,
bugprone-reserved-identifier,
bugprone-signed-char-misuse,
bugprone-sizeof-container,
bugprone-sizeof-expression,
bugprone-string-constructor,
bugprone-string-integer-assignment,
bugprone-string-literal-with-embedded-nul,
bugprone-suspicious-enum-usage,
bugprone-suspicious-include,
bugprone-suspicious-memset-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-string-compare,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
bugprone-undefined-memory-manipulation,
bugprone-unhandled-self-assignment,
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-use-after-move,
bugprone-virtual-near-miss,
cert-dcl21-cpp,
cert-dcl50-cpp,
cert-env33-c,
cert-err34-c,
cert-err52-cpp,
cert-flp30-c,
cert-mem57-cpp,
cert-msc50-cpp,
cert-oop58-cpp,
google-build-explicit-make-pair,
google-build-namespaces,
google-default-arguments,
google-explicit-constructor,
google-readability-casting,
google-readability-avoid-underscore-in-googletest-name,
google-runtime-int,
google-runtime-operator,
hicpp-exception-baseclass,
clang-analyzer-core.CallAndMessage,
clang-analyzer-core.DivideZero,
clang-analyzer-core.NonNullParamChecker,
clang-analyzer-core.NullDereference,
clang-analyzer-core.StackAddressEscape,
clang-analyzer-core.UndefinedBinaryOperatorResult,
clang-analyzer-core.VLASize,
clang-analyzer-core.uninitialized.ArraySubscript,
clang-analyzer-core.uninitialized.Assign,
clang-analyzer-core.uninitialized.Branch,
clang-analyzer-core.uninitialized.CapturedBlockVariable,
clang-analyzer-core.uninitialized.UndefReturn,
clang-analyzer-cplusplus.InnerPointer,
clang-analyzer-cplusplus.NewDelete,
clang-analyzer-cplusplus.NewDeleteLeaks,
clang-analyzer-cplusplus.PlacementNewChecker,
clang-analyzer-cplusplus.SelfAssignment,
clang-analyzer-deadcode.DeadStores,
clang-analyzer-optin.cplusplus.VirtualCall,
clang-analyzer-security.insecureAPI.UncheckedReturn,
clang-analyzer-security.insecureAPI.bcmp,
clang-analyzer-security.insecureAPI.bcopy,
clang-analyzer-security.insecureAPI.bzero,
clang-analyzer-security.insecureAPI.getpw,
clang-analyzer-security.insecureAPI.gets,
clang-analyzer-security.insecureAPI.mkstemp,
clang-analyzer-security.insecureAPI.mktemp,
clang-analyzer-security.insecureAPI.rand,
clang-analyzer-security.insecureAPI.strcpy,
clang-analyzer-unix.Malloc,
clang-analyzer-unix.MallocSizeof,
clang-analyzer-unix.MismatchedDeallocator,
clang-analyzer-unix.Vfork,
clang-analyzer-unix.cstring.BadSizeArg,
clang-analyzer-unix.cstring.NullArg,
boost-use-to-string,
'
WarningsAsErrors: '*'
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.LocalVariableCase
value: lower_case
- key: readability-identifier-naming.StaticConstantCase
value: aNy_CasE
- key: readability-identifier-naming.MemberCase
value: lower_case
- key: readability-identifier-naming.PrivateMemberPrefix
value: ''
- key: readability-identifier-naming.ProtectedMemberPrefix
value: ''
- key: readability-identifier-naming.PublicMemberCase
value: lower_case
- key: readability-identifier-naming.MethodCase
value: camelBack
- key: readability-identifier-naming.PrivateMethodPrefix
value: ''
- key: readability-identifier-naming.ProtectedMethodPrefix
value: ''
- key: readability-identifier-naming.ParameterPackCase
value: lower_case
- key: readability-identifier-naming.StructCase
value: CamelCase
- key: readability-identifier-naming.TemplateTemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.TemplateUsingCase
value: lower_case
- key: readability-identifier-naming.TypeTemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.TypedefCase
value: CamelCase
- key: readability-identifier-naming.UnionCase
value: CamelCase
- key: readability-identifier-naming.UsingCase
value: CamelCase

1
.github/CODEOWNERS vendored
View File

@ -1,2 +1,3 @@
docs/* @ClickHouse/docs docs/* @ClickHouse/docs
docs/zh/* @ClickHouse/docs-zh docs/zh/* @ClickHouse/docs-zh
website/* @ClickHouse/docs

View File

@ -0,0 +1,27 @@
---
name: Backward compatibility issue
about: Create a report to help us improve ClickHouse
title: ''
labels: backward compatibility
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the issue**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server versions are incompatible
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary
* Queries to run that lead to unexpected result
**Error message and/or stacktrace**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -1,30 +0,0 @@
---
name: Bug report or unexpected behaviour
about: Create a report to help us improve ClickHouse
title: ''
labels: bug
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the bug or unexpected behaviour**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server version to use
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/dbms/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary
* Queries to run that lead to unexpected result
**Expected behavior**
A clear and concise description of what you expected to happen.
**Error message and/or stacktrace**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

30
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@ -0,0 +1,30 @@
---
name: Bug report
about: Create a report to help us improve ClickHouse
title: ''
labels: bug
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the bug**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server version to use
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary
* Queries to run that lead to unexpected result
**Expected behavior**
A clear and concise description of what you expected to happen.
**Error message and/or stacktrace**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -17,7 +17,7 @@ What exactly works slower than expected?
* Which interface to use, if matters * Which interface to use, if matters
* Non-default settings, if any * Non-default settings, if any
* `CREATE TABLE` statements for all tables involved * `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/dbms/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary * Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary
* Queries to run that lead to slow performance * Queries to run that lead to slow performance
**Expected performance** **Expected performance**

View File

@ -0,0 +1,30 @@
---
name: Unexpected behaviour
about: Create a report to help us improve ClickHouse
title: ''
labels: unexpected behaviour
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the unexpected behaviour**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server version to use
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary
* Queries to run that lead to unexpected result
**Expected behavior**
A clear and concise description of what you expected to happen.
**Error message and/or stacktrace**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,30 @@
---
name: Usability issue
about: Create a report to help us improve ClickHouse
title: ''
labels: usability
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the issue**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server version to use
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/programs/obfuscator/Obfuscator.cpp#L42-L80) if necessary
* Queries to run that lead to unexpected result
**Expected behavior**
A clear and concise description of what you expected to happen.
**Error message and/or stacktrace**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

143
.gitignore vendored
View File

@ -12,11 +12,15 @@
/build /build
/build_* /build_*
/build-* /build-*
/docs/build /docs/build
/docs/publish /docs/publish
/docs/edit /docs/edit
/docs/website /docs/website
/docs/tools/venv/ /docs/venv
/docs/tools/venv
/docs/tools/translate/venv
/docs/tools/translate/output.md
/docs/en/single.md /docs/en/single.md
/docs/ru/single.md /docs/ru/single.md
/docs/zh/single.md /docs/zh/single.md
@ -54,143 +58,9 @@ cmake-build-*
__pycache__ __pycache__
*.pytest_cache *.pytest_cache
# ignore generated files
*-metrika-yandex
test.cpp test.cpp
utils/compressor/compressor
utils/corrector_utf8/corrector_utf8
utils/iotest/iotest
utils/iotest/iotest_aio
utils/iotest/iotest_nonblock
utils/config-processor/config-processor
CPackConfig.cmake CPackConfig.cmake
CPackSourceConfig.cmake CPackSourceConfig.cmake
contrib/libpoco/Poco/
contrib/libpoco/bin/
contrib/libpoco/cmake_uninstall.cmake
contrib/libre2/re2_st/
dbms/src/Client/clickhouse-benchmark
dbms/src/Client/clickhouse-client
dbms/src/Client/tests/test-connect
dbms/src/Common/tests/arena_with_free_lists
dbms/src/Common/tests/auto_array
dbms/src/Common/tests/compact_array
dbms/src/Common/tests/hash_table
dbms/src/Common/tests/hashes_test
dbms/src/Common/tests/int_hashes_perf
dbms/src/Common/tests/lru_cache
dbms/src/Common/tests/parallel_aggregation
dbms/src/Common/tests/parallel_aggregation2
dbms/src/Common/tests/radix_sort
dbms/src/Common/tests/shell_command_test
dbms/src/Common/tests/simple_cache
dbms/src/Common/tests/sip_hash
dbms/src/Common/tests/sip_hash_perf
dbms/src/Common/tests/small_table
dbms/src/Core/tests/exception
dbms/src/Core/tests/field
dbms/src/Core/tests/rvo_test
dbms/src/Core/tests/string_pool
dbms/src/DataStreams/tests/aggregating_stream
dbms/src/DataStreams/tests/block_tab_separated_streams
dbms/src/DataStreams/tests/collapsing_sorted_stream
dbms/src/DataStreams/tests/expression_stream
dbms/src/DataStreams/tests/filter_stream
dbms/src/DataStreams/tests/filter_stream_hitlog
dbms/src/DataStreams/tests/fork_streams
dbms/src/DataStreams/tests/glue_streams
dbms/src/DataStreams/tests/json_streams
dbms/src/DataStreams/tests/native_streams
dbms/src/DataStreams/tests/sorting_stream
dbms/src/DataStreams/tests/tab_separated_streams
dbms/src/DataStreams/tests/union_stream
dbms/src/DataStreams/tests/union_stream2
dbms/src/DataTypes/tests/data_type_string
dbms/src/DataTypes/tests/data_types_number_fixed
dbms/src/Functions/tests/functions_arithmetic
dbms/src/Functions/tests/logical_functions_performance
dbms/src/Functions/tests/number_traits
dbms/src/IO/tests/async_write
dbms/src/IO/tests/cached_compressed_read_buffer
dbms/src/IO/tests/compressed_buffer
dbms/src/IO/tests/hashing_read_buffer
dbms/src/IO/tests/hashing_write_buffer
dbms/src/IO/tests/io_and_exceptions
dbms/src/IO/tests/io_operators
dbms/src/IO/tests/mempbrk
dbms/src/IO/tests/o_direct_and_dirty_pages
dbms/src/IO/tests/parse_int_perf
dbms/src/IO/tests/parse_int_perf2
dbms/src/IO/tests/read_buffer
dbms/src/IO/tests/read_buffer_aio
dbms/src/IO/tests/read_buffer_perf
dbms/src/IO/tests/read_escaped_string
dbms/src/IO/tests/read_float_perf
dbms/src/IO/tests/read_write_int
dbms/src/IO/tests/valid_utf8
dbms/src/IO/tests/valid_utf8_perf
dbms/src/IO/tests/var_uint
dbms/src/IO/tests/write_buffer
dbms/src/IO/tests/write_buffer_aio
dbms/src/IO/tests/write_buffer_perf
dbms/src/Interpreters/tests/address_patterns
dbms/src/Interpreters/tests/aggregate
dbms/src/Interpreters/tests/compiler_test
dbms/src/Interpreters/tests/create_query
dbms/src/Interpreters/tests/expression
dbms/src/Interpreters/tests/expression_analyzer
dbms/src/Interpreters/tests/hash_map
dbms/src/Interpreters/tests/hash_map2
dbms/src/Interpreters/tests/hash_map3
dbms/src/Interpreters/tests/hash_map_string
dbms/src/Interpreters/tests/hash_map_string_2
dbms/src/Interpreters/tests/hash_map_string_3
dbms/src/Interpreters/tests/hash_map_string_small
dbms/src/Interpreters/tests/in_join_subqueries_preprocessor
dbms/src/Interpreters/tests/logical_expressions_optimizer
dbms/src/Interpreters/tests/select_query
dbms/src/Interpreters/tests/two_level_hash_map
dbms/src/Interpreters/tests/users
dbms/src/Parsers/tests/create_parser
dbms/src/Parsers/tests/select_parser
dbms/src/Server/clickhouse-server
dbms/src/Server/clickhouse-server.init
dbms/src/Storages/tests/hit_log
dbms/src/Storages/tests/merge_tree
dbms/src/Storages/tests/part_checker
dbms/src/Storages/tests/part_name
dbms/src/Storages/tests/pk_condition
dbms/src/Storages/tests/seek_speed_test
dbms/src/Storages/tests/storage_log
dbms/src/Storages/tests/system_numbers
libs/libcommon/src/revision.h
libs/libcommon/src/tests/date_lut2
libs/libcommon/src/tests/date_lut3
libs/libcommon/src/tests/date_lut4
libs/libcommon/src/tests/date_lut_init
libs/libcommon/src/tests/multi_version
libs/libmysqlxx/src/tests/failover
libs/libmysqlxx/src/tests/mysqlxx_test
libs/libzkutil/src/tests/zkutil_expiration_test
libs/libzkutil/src/tests/zkutil_test
libs/libzkutil/src/tests/zkutil_test_async
libs/libzkutil/src/tests/zkutil_test_commands
libs/libzkutil/src/tests/zkutil_test_lock
libs/libzkutil/src/tests/zkutil_zookeeper_holder
utils/zookeeper-create-entry-to-download-part/zookeeper-create-entry-to-download-part
utils/zookeeper-dump-tree/zookeeper-dump-tree
utils/zookeeper-remove-by-list/zookeeper-remove-by-list
dbms/src/Storages/tests/remove_symlink_directory
libs/libcommon/src/tests/json_test
utils/compressor/zstd_test
utils/wikistat-loader/wikistat-loader
dbms/src/Common/tests/pod_array
dbms/src/Server/data/*
dbms/src/Server/metadata/*
dbms/src/Server/status
config-9001.xml
*-preprocessed.xml *-preprocessed.xml
@ -238,9 +108,6 @@ website/package-lock.json
.DS_Store .DS_Store
*/.DS_Store */.DS_Store
# Ignore files for locally disabled tests
/dbms/tests/queries/**/*.disabled
# cquery cache # cquery cache
/.cquery-cache /.cquery-cache

View File

@ -1,41 +0,0 @@
stages:
- builder
- build
variables:
GIT_SUBMODULE_STRATEGY: recursive
builder:
stage: builder
when: manual
services:
- docker:dind
script:
- docker info
- apk add --no-cache git curl binutils ca-certificates
- docker login -u gitlab -p nopasswd $CI_REGISTRY
- docker build -t yandex/clickhouse-builder ./docker/builder
- docker tag yandex/clickhouse-builder $CI_REGISTRY/yandex/clickhouse-builder
- docker push $CI_REGISTRY/yandex/clickhouse-builder
tags:
- docker
build:
stage: build
when: manual
services:
- docker:dind
script:
- apk add --no-cache git curl binutils ca-certificates
- git submodule sync --recursive
- git submodule update --init --recursive
- docker info
- docker login -u gitlab -p nopasswd $CI_REGISTRY
- docker pull $CI_REGISTRY/yandex/clickhouse-builder
- docker run --rm --volumes-from "${HOSTNAME}-build" --workdir "${CI_PROJECT_DIR}" --env CI_PROJECT_DIR=${CI_PROJECT_DIR} $CI_REGISTRY/yandex/clickhouse-builder /build_gitlab_ci.sh
# You can upload your binary to nexus
- curl -v --keepalive-time 60 --keepalive --user "$NEXUS_USER:$NEXUS_PASSWORD" -XPUT "http://$NEXUS_HOST/repository/binaries/$CI_PROJECT_NAME" --upload-file ./dbms/src/Server/clickhouse
# Or download artifacts from gitlab
artifacts:
paths:
- ./dbms/src/Server/clickhouse
expire_in: 1 day
tags:
- docker

19
.gitmodules vendored
View File

@ -13,7 +13,7 @@
url = https://github.com/edenhill/librdkafka.git url = https://github.com/edenhill/librdkafka.git
[submodule "contrib/cctz"] [submodule "contrib/cctz"]
path = contrib/cctz path = contrib/cctz
url = https://github.com/google/cctz.git url = https://github.com/ClickHouse-Extras/cctz.git
[submodule "contrib/zlib-ng"] [submodule "contrib/zlib-ng"]
path = contrib/zlib-ng path = contrib/zlib-ng
url = https://github.com/ClickHouse-Extras/zlib-ng.git url = https://github.com/ClickHouse-Extras/zlib-ng.git
@ -110,16 +110,16 @@
branch = v1.25.0 branch = v1.25.0
[submodule "contrib/aws"] [submodule "contrib/aws"]
path = contrib/aws path = contrib/aws
url = https://github.com/aws/aws-sdk-cpp.git url = https://github.com/ClickHouse-Extras/aws-sdk-cpp.git
[submodule "aws-c-event-stream"] [submodule "aws-c-event-stream"]
path = contrib/aws-c-event-stream path = contrib/aws-c-event-stream
url = https://github.com/awslabs/aws-c-event-stream.git url = https://github.com/ClickHouse-Extras/aws-c-event-stream.git
[submodule "aws-c-common"] [submodule "aws-c-common"]
path = contrib/aws-c-common path = contrib/aws-c-common
url = https://github.com/awslabs/aws-c-common.git url = https://github.com/ClickHouse-Extras/aws-c-common.git
[submodule "aws-checksums"] [submodule "aws-checksums"]
path = contrib/aws-checksums path = contrib/aws-checksums
url = https://github.com/awslabs/aws-checksums.git url = https://github.com/ClickHouse-Extras/aws-checksums.git
[submodule "contrib/curl"] [submodule "contrib/curl"]
path = contrib/curl path = contrib/curl
url = https://github.com/curl/curl.git url = https://github.com/curl/curl.git
@ -148,3 +148,12 @@
path = contrib/avro path = contrib/avro
url = https://github.com/ClickHouse-Extras/avro.git url = https://github.com/ClickHouse-Extras/avro.git
ignore = untracked ignore = untracked
[submodule "contrib/msgpack-c"]
path = contrib/msgpack-c
url = https://github.com/msgpack/msgpack-c
[submodule "contrib/libcpuid"]
path = contrib/libcpuid
url = https://github.com/ClickHouse-Extras/libcpuid.git
[submodule "contrib/openldap"]
path = contrib/openldap
url = https://github.com/openldap/openldap.git

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@ project(ClickHouse)
include (cmake/arch.cmake) include (cmake/arch.cmake)
include (cmake/target.cmake) include (cmake/target.cmake)
include (cmake/tools.cmake) include (cmake/tools.cmake)
include (cmake/analysis.cmake)
# Ignore export() since we don't use it, # Ignore export() since we don't use it,
# but it gets broken with a global targets via link_libraries() # but it gets broken with a global targets via link_libraries()
@ -29,7 +30,11 @@ set(CMAKE_LINK_DEPENDS_NO_SHARED 1) # Do not relink all depended targets on .so
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Debug;Release;MinSizeRel" CACHE STRING "" FORCE) set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Debug;Release;MinSizeRel" CACHE STRING "" FORCE)
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Generate debug library name with a postfix.") # To be consistent with CMakeLists from contrib libs. set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Generate debug library name with a postfix.") # To be consistent with CMakeLists from contrib libs.
option(ENABLE_IPO "Enable inter-procedural optimization (aka LTO)" OFF) # need cmake 3.9+ # Enable the ability to organize targets into hierarchies of "folders" for capable GUI-based IDEs.
# For more info see https://cmake.org/cmake/help/latest/prop_gbl/USE_FOLDERS.html
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
option(ENABLE_IPO "Enable full link time optimization (it's usually impractical; see also ENABLE_THINLTO)" OFF) # need cmake 3.9+
if(ENABLE_IPO) if(ENABLE_IPO)
cmake_policy(SET CMP0069 NEW) cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported) include(CheckIPOSupported)
@ -52,12 +57,12 @@ endif ()
include (cmake/find/ccache.cmake) include (cmake/find/ccache.cmake)
if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None") if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None")
message (STATUS "CMAKE_BUILD_TYPE is not set, set to default = RELWITHDEBINFO") set (CMAKE_BUILD_TYPE "RelWithDebInfo")
set (CMAKE_BUILD_TYPE "RELWITHDEBINFO") message (STATUS "CMAKE_BUILD_TYPE is not set, set to default = ${CMAKE_BUILD_TYPE}")
endif () endif ()
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
option (USE_STATIC_LIBRARIES "Set to FALSE to use shared libraries" ON) option (USE_STATIC_LIBRARIES "Set to FALSE to use shared libraries" ON)
option (MAKE_STATIC_LIBRARIES "Set to FALSE to make shared libraries" ${USE_STATIC_LIBRARIES}) option (MAKE_STATIC_LIBRARIES "Set to FALSE to make shared libraries" ${USE_STATIC_LIBRARIES})
@ -83,9 +88,10 @@ option (ENABLE_FUZZING "Enables fuzzing instrumentation" OFF)
if (ENABLE_FUZZING) if (ENABLE_FUZZING)
message (STATUS "Fuzzing instrumentation enabled") message (STATUS "Fuzzing instrumentation enabled")
set (WITH_COVERAGE ON) set (WITH_COVERAGE ON)
set (SANITIZE "libfuzzer") set (FUZZER "libfuzzer")
endif() endif()
include (cmake/fuzzer.cmake)
include (cmake/sanitize.cmake) include (cmake/sanitize.cmake)
if (CMAKE_GENERATOR STREQUAL "Ninja" AND NOT DISABLE_COLORED_BUILD) if (CMAKE_GENERATOR STREQUAL "Ninja" AND NOT DISABLE_COLORED_BUILD)
@ -97,16 +103,7 @@ endif ()
include (cmake/add_warning.cmake) include (cmake/add_warning.cmake)
if (NOT MSVC) if (NOT MSVC)
set (COMMON_WARNING_FLAGS "${COMMON_WARNING_FLAGS} -Wall") # -Werror is also added inside directories with our own code. set (COMMON_WARNING_FLAGS "${COMMON_WARNING_FLAGS} -Wall") # -Werror and many more is also added inside cmake/warnings.cmake
endif ()
if (COMPILER_GCC OR COMPILER_CLANG)
set (CXX_WARNING_FLAGS "${CXX_WARNING_FLAGS} -Wnon-virtual-dtor")
endif ()
if (COMPILER_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "8.3.0")
# Warnings in protobuf generating
set (CXX_WARNING_FLAGS "${CXX_WARNING_FLAGS} -Wno-array-bounds")
endif () endif ()
if (COMPILER_CLANG) if (COMPILER_CLANG)
@ -120,12 +117,8 @@ endif ()
option (ENABLE_TESTS "Enables tests" ON) option (ENABLE_TESTS "Enables tests" ON)
if (ARCH_AMD64)
option (USE_INTERNAL_MEMCPY "Use internal implementation of 'memcpy' function instead of provided by libc. Only for x86_64." ON)
endif ()
if (OS_LINUX AND NOT UNBUNDLED AND MAKE_STATIC_LIBRARIES AND NOT SPLIT_SHARED_LIBRARIES AND CMAKE_VERSION VERSION_GREATER "3.9.0") if (OS_LINUX AND NOT UNBUNDLED AND MAKE_STATIC_LIBRARIES AND NOT SPLIT_SHARED_LIBRARIES AND CMAKE_VERSION VERSION_GREATER "3.9.0")
option (GLIBC_COMPATIBILITY "Set to TRUE to enable compatibility with older glibc libraries. Only for x86_64, Linux. Implies USE_INTERNAL_MEMCPY." ON) option (GLIBC_COMPATIBILITY "Set to TRUE to enable compatibility with older glibc libraries. Only for x86_64, Linux. Implies ENABLE_FASTMEMCPY." ON)
endif () endif ()
if (NOT CMAKE_VERSION VERSION_GREATER "3.9.0") if (NOT CMAKE_VERSION VERSION_GREATER "3.9.0")
@ -189,12 +182,14 @@ if (COMPILER_GCC OR COMPILER_CLANG)
endif () endif ()
option(WITH_COVERAGE "Build with coverage." 0) option(WITH_COVERAGE "Build with coverage." 0)
if(WITH_COVERAGE AND COMPILER_CLANG)
if (WITH_COVERAGE AND COMPILER_CLANG)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fprofile-instr-generate -fcoverage-mapping") set(COMPILER_FLAGS "${COMPILER_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
# If we want to disable coverage for specific translation units # If we want to disable coverage for specific translation units
set(WITHOUT_COVERAGE "-fno-profile-instr-generate -fno-coverage-mapping") set(WITHOUT_COVERAGE "-fno-profile-instr-generate -fno-coverage-mapping")
endif() endif()
if(WITH_COVERAGE AND COMPILER_GCC)
if (WITH_COVERAGE AND COMPILER_GCC)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fprofile-arcs -ftest-coverage") set(COMPILER_FLAGS "${COMPILER_FLAGS} -fprofile-arcs -ftest-coverage")
set(COVERAGE_OPTION "-lgcov") set(COVERAGE_OPTION "-lgcov")
set(WITHOUT_COVERAGE "-fno-profile-arcs -fno-test-coverage") set(WITHOUT_COVERAGE "-fno-profile-arcs -fno-test-coverage")
@ -210,10 +205,44 @@ set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 ${
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline ${CMAKE_C_FLAGS_ADD}") set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline ${CMAKE_C_FLAGS_ADD}")
if (COMPILER_CLANG) if (COMPILER_CLANG)
# Exception unwinding doesn't work in clang release build without this option if (OS_DARWIN)
# TODO investigate that set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-U,_inside_main")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer") endif()
# Display absolute paths in error messages. Otherwise KDevelop fails to navigate to correct file and opens a new file instead.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-absolute-paths")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-absolute-paths")
option(ENABLE_THINLTO "Enable Thin LTO. Only applicable for clang. It's also suppressed when building with tests or sanitizers." ON)
# We cannot afford to use LTO when compiling unitests, and it's not enough
# to only supply -fno-lto at the final linking stage. So we disable it
# completely.
if (ENABLE_THINLTO AND NOT ENABLE_TESTS AND NOT SANITIZE)
# Link time optimization
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -flto=thin")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -flto=thin")
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -flto=thin")
endif ()
# Always prefer llvm tools when using clang. For instance, we cannot use GNU ar when llvm LTO is enabled
find_program (LLVM_AR_PATH NAMES "llvm-ar" "llvm-ar-10" "llvm-ar-9" "llvm-ar-8")
if (LLVM_AR_PATH)
message(STATUS "Using llvm-ar: ${LLVM_AR_PATH}.")
set (CMAKE_AR ${LLVM_AR_PATH})
else ()
message(WARNING "Cannot find llvm-ar. System ar will be used instead. It does not work with ThinLTO.")
endif ()
find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-10" "llvm-ranlib-9" "llvm-ranlib-8")
if (LLVM_RANLIB_PATH)
message(STATUS "Using llvm-ranlib: ${LLVM_RANLIB_PATH}.")
set (CMAKE_RANLIB ${LLVM_RANLIB_PATH})
else ()
message(WARNING "Cannot find llvm-ranlib. System ranlib will be used instead. It does not work with ThinLTO.")
endif ()
endif () endif ()
option (ENABLE_LIBRARIES "Enable all libraries (Global default switch)" ON) option (ENABLE_LIBRARIES "Enable all libraries (Global default switch)" ON)
@ -225,7 +254,7 @@ else ()
set(NOT_UNBUNDLED 1) set(NOT_UNBUNDLED 1)
endif () endif ()
if (UNBUNDLED OR NOT (OS_LINUX OR OS_DARWIN) OR ARCH_32) if (UNBUNDLED OR NOT (OS_LINUX OR OS_DARWIN))
# Using system libs can cause a lot of warnings in includes (on macro expansion). # Using system libs can cause a lot of warnings in includes (on macro expansion).
option (WERROR "Enable -Werror compiler option" OFF) option (WERROR "Enable -Werror compiler option" OFF)
else () else ()
@ -239,7 +268,7 @@ endif ()
# Make this extra-checks for correct library dependencies. # Make this extra-checks for correct library dependencies.
if (OS_LINUX AND NOT SANITIZE) if (OS_LINUX AND NOT SANITIZE)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
endif () endif ()
include(cmake/dbms_glob_sources.cmake) include(cmake/dbms_glob_sources.cmake)
@ -248,13 +277,14 @@ if (OS_LINUX)
include(cmake/linux/default_libs.cmake) include(cmake/linux/default_libs.cmake)
elseif (OS_DARWIN) elseif (OS_DARWIN)
include(cmake/darwin/default_libs.cmake) include(cmake/darwin/default_libs.cmake)
elseif (OS_FREEBSD)
include(cmake/freebsd/default_libs.cmake)
endif () endif ()
###################################### ######################################
### Add targets below this comment ### ### Add targets below this comment ###
###################################### ######################################
string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
set (CMAKE_POSTFIX_VARIABLE "CMAKE_${CMAKE_BUILD_TYPE_UC}_POSTFIX") set (CMAKE_POSTFIX_VARIABLE "CMAKE_${CMAKE_BUILD_TYPE_UC}_POSTFIX")
if (MAKE_STATIC_LIBRARIES) if (MAKE_STATIC_LIBRARIES)
@ -281,24 +311,6 @@ if (USE_INCLUDE_WHAT_YOU_USE)
endif() endif()
endif () endif ()
# Using clang-tidy static analyzer http://mariobadr.com/using-clang-tidy-with-cmake-36.html https://cmake.org/cmake/help/v3.6/prop_tgt/LANG_CLANG_TIDY.html
option (ENABLE_CLANG_TIDY "Use 'clang-tidy' static analyzer" OFF)
if (ENABLE_CLANG_TIDY)
if (${CMAKE_VERSION} VERSION_LESS "3.6.0")
message(FATAL_ERROR "clang-tidy requires CMake version at least 3.6.")
endif()
find_program (CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable")
if (NOT CLANG_TIDY_EXE)
set (USE_CLANG_TIDY 0)
message (STATUS "clang-tidy not found.")
else ()
set (USE_CLANG_TIDY 1)
message (STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set (DO_CLANG_TIDY "${CLANG_TIDY_EXE}" "-checks=*,-clang-analyzer-alpha.*")
# You can enable it within a directory by: set (CMAKE_CXX_CLANG_TIDY "${DO_CLANG_TIDY}")
endif ()
endif ()
if (ENABLE_TESTS) if (ENABLE_TESTS)
message (STATUS "Tests are enabled") message (STATUS "Tests are enabled")
endif () endif ()
@ -313,35 +325,30 @@ endif ()
message (STATUS "Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_LIBRARY_ARCHITECTURE} ; USE_STATIC_LIBRARIES=${USE_STATIC_LIBRARIES} MAKE_STATIC_LIBRARIES=${MAKE_STATIC_LIBRARIES} SPLIT_SHARED=${SPLIT_SHARED_LIBRARIES} UNBUNDLED=${UNBUNDLED} CCACHE=${CCACHE_FOUND} ${CCACHE_VERSION}") message (STATUS "Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_LIBRARY_ARCHITECTURE} ; USE_STATIC_LIBRARIES=${USE_STATIC_LIBRARIES} MAKE_STATIC_LIBRARIES=${MAKE_STATIC_LIBRARIES} SPLIT_SHARED=${SPLIT_SHARED_LIBRARIES} UNBUNDLED=${UNBUNDLED} CCACHE=${CCACHE_FOUND} ${CCACHE_VERSION}")
include(GNUInstallDirs) include (GNUInstallDirs)
include (cmake/contrib_finder.cmake) include (cmake/contrib_finder.cmake)
include (cmake/lib_name.cmake) include (cmake/lib_name.cmake)
find_contrib_lib(double-conversion) # Must be before parquet find_contrib_lib(double-conversion) # Must be before parquet
include (cmake/find/ssl.cmake) include (cmake/find/ssl.cmake)
include (cmake/find/ldap.cmake) # after ssl
include (cmake/find/icu.cmake) include (cmake/find/icu.cmake)
include (cmake/find/boost.cmake) include (cmake/find/boost.cmake)
include (cmake/find/zlib.cmake) include (cmake/find/zlib.cmake)
include (cmake/find/zstd.cmake) include (cmake/find/zstd.cmake)
include (cmake/find/ltdl.cmake) # for odbc include (cmake/find/ltdl.cmake) # for odbc
include (cmake/find/termcap.cmake) include (cmake/find/termcap.cmake)
include (cmake/find/odbc.cmake) # openssl, zlib before poco
# openssl, zlib, odbc before poco
include (cmake/find/poco.cmake)
include (cmake/find/lz4.cmake) include (cmake/find/lz4.cmake)
include (cmake/find/xxhash.cmake) include (cmake/find/xxhash.cmake)
include (cmake/find/sparsehash.cmake) include (cmake/find/sparsehash.cmake)
include (cmake/find/execinfo.cmake)
include (cmake/find/re2.cmake) include (cmake/find/re2.cmake)
include (cmake/find/libgsasl.cmake) include (cmake/find/libgsasl.cmake)
include (cmake/find/rdkafka.cmake) include (cmake/find/rdkafka.cmake)
include (cmake/find/capnp.cmake) include (cmake/find/capnp.cmake)
include (cmake/find/llvm.cmake) include (cmake/find/llvm.cmake)
include (cmake/find/opencl.cmake)
include (cmake/find/h3.cmake) include (cmake/find/h3.cmake)
include (cmake/find/cpuid.cmake) # Freebsd, bundled
if (NOT USE_CPUID)
include (cmake/find/cpuinfo.cmake) # Debian
endif()
include (cmake/find/libxml2.cmake) include (cmake/find/libxml2.cmake)
include (cmake/find/brotli.cmake) include (cmake/find/brotli.cmake)
include (cmake/find/protobuf.cmake) include (cmake/find/protobuf.cmake)
@ -349,7 +356,6 @@ include (cmake/find/grpc.cmake)
include (cmake/find/pdqsort.cmake) include (cmake/find/pdqsort.cmake)
include (cmake/find/hdfs3.cmake) # uses protobuf include (cmake/find/hdfs3.cmake) # uses protobuf
include (cmake/find/s3.cmake) include (cmake/find/s3.cmake)
include (cmake/find/consistent-hashing.cmake)
include (cmake/find/base64.cmake) include (cmake/find/base64.cmake)
include (cmake/find/parquet.cmake) include (cmake/find/parquet.cmake)
include (cmake/find/hyperscan.cmake) include (cmake/find/hyperscan.cmake)
@ -358,6 +364,7 @@ include (cmake/find/rapidjson.cmake)
include (cmake/find/fastops.cmake) include (cmake/find/fastops.cmake)
include (cmake/find/orc.cmake) include (cmake/find/orc.cmake)
include (cmake/find/avro.cmake) include (cmake/find/avro.cmake)
include (cmake/find/msgpack.cmake)
find_contrib_lib(cityhash) find_contrib_lib(cityhash)
find_contrib_lib(farmhash) find_contrib_lib(farmhash)
@ -369,21 +376,24 @@ if (ENABLE_TESTS)
endif () endif ()
# Need to process before "contrib" dir: # Need to process before "contrib" dir:
include (cmake/find/jemalloc.cmake)
include (cmake/find/cctz.cmake)
include (cmake/find/mysqlclient.cmake) include (cmake/find/mysqlclient.cmake)
# When testing for memory leaks with Valgrind, don't link tcmalloc or jemalloc. # When testing for memory leaks with Valgrind, don't link tcmalloc or jemalloc.
if (USE_JEMALLOC) if (OS_LINUX AND NOT ENABLE_JEMALLOC)
message (STATUS "Link jemalloc: ${JEMALLOC_LIBRARIES}")
set (MALLOC_LIBRARIES ${JEMALLOC_LIBRARIES})
elseif (SANITIZE)
message (STATUS "Will use ${SANITIZE} sanitizer.")
elseif (OS_LINUX)
message (WARNING "Non default allocator is disabled. This is not recommended for production Linux builds.") message (WARNING "Non default allocator is disabled. This is not recommended for production Linux builds.")
endif () endif ()
if (USE_OPENCL)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_OPENCL=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_OPENCL=1")
if (OS_DARWIN)
set(OPENCL_LINKER_FLAGS "-framework OpenCL")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCL_LINKER_FLAGS}")
endif ()
endif ()
include (cmake/print_flags.cmake) include (cmake/print_flags.cmake)
if (TARGET global-group) if (TARGET global-group)
@ -403,8 +413,16 @@ macro (add_executable target)
endif() endif()
endmacro() endmacro()
set(ConfigIncludePath ${CMAKE_CURRENT_BINARY_DIR}/includes/configs CACHE INTERNAL "Path to generated configuration files.")
include_directories(${ConfigIncludePath})
# Add as many warnings as possible for our own code.
include (cmake/warnings.cmake)
add_subdirectory (base) add_subdirectory (base)
add_subdirectory (programs)
add_subdirectory (src)
add_subdirectory (tests)
add_subdirectory (utils) add_subdirectory (utils)
add_subdirectory (dbms)
include (cmake/print_include_directories.cmake) include (cmake/print_include_directories.cmake)

1
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1 @@
We welcome everyone to contribute to our product, see CONTRIBUTING.md.

View File

@ -8,10 +8,12 @@ ClickHouse is an open-source column-oriented database management system that all
* [Tutorial](https://clickhouse.tech/docs/en/getting_started/tutorial/) shows how to set up and query small ClickHouse cluster. * [Tutorial](https://clickhouse.tech/docs/en/getting_started/tutorial/) shows how to set up and query small ClickHouse cluster.
* [Documentation](https://clickhouse.tech/docs/en/) provides more in-depth information. * [Documentation](https://clickhouse.tech/docs/en/) provides more in-depth information.
* [YouTube channel](https://www.youtube.com/c/ClickHouseDB) has a lot of content about ClickHouse in video format. * [YouTube channel](https://www.youtube.com/c/ClickHouseDB) has a lot of content about ClickHouse in video format.
* [Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-d2zxkf9e-XyxDa_ucfPxzuH4SJIm~Ng) and [Telegram](https://telegram.me/clickhouse_en) allow to chat with ClickHouse users in real-time.
* [Blog](https://clickhouse.yandex/blog/en/) contains various ClickHouse-related articles, as well as announces and reports about events. * [Blog](https://clickhouse.yandex/blog/en/) contains various ClickHouse-related articles, as well as announces and reports about events.
* [Contacts](https://clickhouse.tech/#contacts) can help to get your questions answered if there are any. * [Contacts](https://clickhouse.tech/#contacts) can help to get your questions answered if there are any.
* You can also [fill this form](https://forms.yandex.com/surveys/meet-yandex-clickhouse-team/) to meet Yandex ClickHouse team in person. * You can also [fill this form](https://clickhouse.tech/#meet) to meet Yandex ClickHouse team in person.
## Upcoming Events ## Upcoming Events
* [ClickHouse Meetup in Athens](https://www.meetup.com/Athens-Big-Data/events/268379195/) on March 5. * [ClickHouse Workshop in Novosibirsk](https://2020.codefest.ru/lecture/1628) on TBD date.
* [Yandex C++ Open-Source Sprints in Moscow](https://events.yandex.ru/events/otkrytyj-kod-v-yandek-28-03-2020) on TBD date.

View File

@ -9,6 +9,7 @@ currently being supported with security updates:
| ------- | ------------------ | | ------- | ------------------ |
| 1.x | :x: | | 1.x | :x: |
| 18.x | :x: | | 18.x | :x: |
| 19.x | :x: |
| 19.14 | :white_check_mark: | | 19.14 | :white_check_mark: |
| 20.x | :white_check_mark: | | 20.x | :white_check_mark: |

View File

@ -1,17 +1,13 @@
add_subdirectory (common) if (USE_CLANG_TIDY)
add_subdirectory (loggers) set (CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_PATH}")
add_subdirectory (daemon) endif ()
if (USE_INTERNAL_MEMCPY) add_subdirectory (common)
add_subdirectory (memcpy) add_subdirectory (daemon)
endif() add_subdirectory (loggers)
add_subdirectory (pcg-random)
add_subdirectory (widechar_width)
if (USE_MYSQL) if (USE_MYSQL)
add_subdirectory (mysqlxx) add_subdirectory (mysqlxx)
endif () endif ()
if (USE_INTERNAL_CONSISTENT_HASHING_LIBRARY)
add_subdirectory (consistent-hashing)
endif ()
add_subdirectory (consistent-hashing-sumbur)
add_subdirectory (widechar_width)

View File

@ -1,18 +1,17 @@
configure_file (config_common.h.in config_common.h)
set (SRCS set (SRCS
argsToConfig.cpp argsToConfig.cpp
coverage.cpp coverage.cpp
DateLUT.cpp DateLUT.cpp
DateLUTImpl.cpp DateLUTImpl.cpp
demangle.cpp demangle.cpp
getFQDNOrHostName.cpp
getMemoryAmount.cpp getMemoryAmount.cpp
getThreadId.cpp getThreadId.cpp
JSON.cpp JSON.cpp
LineReader.cpp LineReader.cpp
mremap.cpp mremap.cpp
phdr_cache.cpp phdr_cache.cpp
preciseExp10.c preciseExp10.cpp
setTerminalEcho.cpp setTerminalEcho.cpp
shift10.cpp shift10.cpp
sleep.cpp sleep.cpp
@ -20,15 +19,9 @@ set (SRCS
) )
if (ENABLE_REPLXX) if (ENABLE_REPLXX)
set (SRCS ${SRCS} list (APPEND SRCS ReplxxLineReader.cpp)
ReplxxLineReader.cpp
ReplxxLineReader.h
)
elseif (ENABLE_READLINE) elseif (ENABLE_READLINE)
set (SRCS ${SRCS} list (APPEND SRCS ReadlineLineReader.cpp)
ReadlineLineReader.cpp
ReadlineLineReader.h
)
endif () endif ()
if (USE_DEBUG_HELPERS) if (USE_DEBUG_HELPERS)
@ -38,31 +31,23 @@ endif ()
add_library (common ${SRCS}) add_library (common ${SRCS})
target_include_directories(common PUBLIC .. ${CMAKE_CURRENT_BINARY_DIR}/..) if (WITH_COVERAGE)
target_compile_definitions(common PUBLIC WITH_COVERAGE=1)
if (USE_INTERNAL_MEMCPY) else ()
target_link_libraries (common PRIVATE memcpy) target_compile_definitions(common PUBLIC WITH_COVERAGE=0)
endif () endif ()
if(CCTZ_INCLUDE_DIR) if (USE_INTERNAL_CCTZ)
target_include_directories(common BEFORE PRIVATE ${CCTZ_INCLUDE_DIR}) set_source_files_properties(DateLUTImpl.cpp PROPERTIES COMPILE_DEFINITIONS USE_INTERNAL_CCTZ)
endif() endif()
target_include_directories(common PUBLIC .. ${CMAKE_CURRENT_BINARY_DIR}/..)
if (NOT USE_INTERNAL_BOOST_LIBRARY) if (NOT USE_INTERNAL_BOOST_LIBRARY)
target_include_directories (common SYSTEM BEFORE PUBLIC ${Boost_INCLUDE_DIRS}) target_include_directories (common SYSTEM BEFORE PUBLIC ${Boost_INCLUDE_DIRS})
endif () endif ()
if(NOT USE_INTERNAL_POCO_LIBRARY) # Allow explicit fallback to readline
target_include_directories (common SYSTEM BEFORE PUBLIC ${Poco_Foundation_INCLUDE_DIR})
endif()
if(CCTZ_LIBRARY)
target_link_libraries(common PRIVATE ${CCTZ_LIBRARY})
endif()
target_link_libraries(common PUBLIC replxx)
# allow explicitly fallback to readline
if (NOT ENABLE_REPLXX AND ENABLE_READLINE) if (NOT ENABLE_REPLXX AND ENABLE_READLINE)
message (STATUS "Attempt to fallback to readline explicitly") message (STATUS "Attempt to fallback to readline explicitly")
set (READLINE_PATHS "/usr/local/opt/readline/lib") set (READLINE_PATHS "/usr/local/opt/readline/lib")
@ -86,10 +71,17 @@ endif ()
target_link_libraries (common target_link_libraries (common
PUBLIC PUBLIC
${Poco_Util_LIBRARY}
${Poco_Foundation_LIBRARY}
${CITYHASH_LIBRARIES} ${CITYHASH_LIBRARIES}
${Boost_SYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}
FastMemcpy
Poco::Net
Poco::Net::SSL
Poco::Util
Poco::Foundation
replxx
PRIVATE
cctz
) )
if (ENABLE_TESTS) if (ENABLE_TESTS)

View File

@ -1,9 +1,10 @@
#include <common/DateLUT.h> #include "DateLUT.h"
#include <filesystem> #include <Poco/DigestStream.h>
#include <Poco/Exception.h> #include <Poco/Exception.h>
#include <Poco/SHA1Engine.h> #include <Poco/SHA1Engine.h>
#include <Poco/DigestStream.h>
#include <filesystem>
#include <fstream> #include <fstream>

View File

@ -1,20 +1,15 @@
#pragma once #pragma once
#include "DateLUTImpl.h" #include "DateLUTImpl.h"
#include <unordered_map>
#include <atomic> #include "defines.h"
#include <mutex>
#include <memory>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
// Also defined in Core/Defines.h #include <atomic>
#if !defined(ALWAYS_INLINE) #include <memory>
#if defined(_MSC_VER) #include <mutex>
#define ALWAYS_INLINE __forceinline #include <unordered_map>
#else
#define ALWAYS_INLINE __attribute__((__always_inline__))
#endif
#endif
/// This class provides lazy initialization and lookup of singleton DateLUTImpl objects for a given timezone. /// This class provides lazy initialization and lookup of singleton DateLUTImpl objects for a given timezone.

View File

@ -1,25 +1,19 @@
#if __has_include(<cctz/civil_time.h>) #include "DateLUTImpl.h"
#include <cctz/civil_time.h> // bundled, debian
#else
#include <civil_time.h> // freebsd
#endif
#if __has_include(<cctz/time_zone.h>) #include <cctz/civil_time.h>
#include <cctz/time_zone.h> #include <cctz/time_zone.h>
#else #include <cctz/zone_info_source.h>
#include <time_zone.h> #include <common/unaligned.h>
#endif
#include <common/DateLUTImpl.h>
#include <Poco/Exception.h> #include <Poco/Exception.h>
#include <memory> #include <dlfcn.h>
#include <algorithm>
#include <cassert>
#include <chrono> #include <chrono>
#include <cstring> #include <cstring>
#include <cassert>
#include <iostream> #include <iostream>
#include <memory>
#define DATE_LUT_MIN 0
namespace namespace
@ -37,9 +31,8 @@ UInt8 getDayOfWeek(const cctz::civil_day & date)
case cctz::weekday::friday: return 5; case cctz::weekday::friday: return 5;
case cctz::weekday::saturday: return 6; case cctz::weekday::saturday: return 6;
case cctz::weekday::sunday: return 7; case cctz::weekday::sunday: return 7;
default:
throw Poco::Exception("Logical error: incorrect week day.");
} }
__builtin_unreachable();
} }
} }
@ -56,10 +49,10 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
assert(inside_main); assert(inside_main);
size_t i = 0; size_t i = 0;
time_t start_of_day = DATE_LUT_MIN; time_t start_of_day = 0;
cctz::time_zone cctz_time_zone; cctz::time_zone cctz_time_zone;
if (!cctz::load_time_zone(time_zone.data(), &cctz_time_zone)) if (!cctz::load_time_zone(time_zone, &cctz_time_zone))
throw Poco::Exception("Cannot load time zone " + time_zone_); throw Poco::Exception("Cannot load time zone " + time_zone_);
cctz::time_zone::absolute_lookup start_of_epoch_lookup = cctz_time_zone.lookup(std::chrono::system_clock::from_time_t(start_of_day)); cctz::time_zone::absolute_lookup start_of_epoch_lookup = cctz_time_zone.lookup(std::chrono::system_clock::from_time_t(start_of_day));
@ -81,6 +74,11 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
values.day_of_week = getDayOfWeek(date); values.day_of_week = getDayOfWeek(date);
values.date = start_of_day; values.date = start_of_day;
assert(values.year >= DATE_LUT_MIN_YEAR && values.year <= DATE_LUT_MAX_YEAR);
assert(values.month >= 1 && values.month <= 12);
assert(values.day_of_month >= 1 && values.day_of_month <= 31);
assert(values.day_of_week >= 1 && values.day_of_week <= 7);
if (values.day_of_month == 1) if (values.day_of_month == 1)
{ {
cctz::civil_month month(date); cctz::civil_month month(date);
@ -137,12 +135,15 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
/// Fill excessive part of lookup table. This is needed only to simplify handling of overflow cases. /// Fill excessive part of lookup table. This is needed only to simplify handling of overflow cases.
while (i < DATE_LUT_SIZE) while (i < DATE_LUT_SIZE)
{ {
lut[i] = lut[DATE_LUT_MAX_DAY_NUM]; lut[i] = lut[i - 1];
++i; ++i;
} }
/// Fill lookup table for years and months. /// Fill lookup table for years and months.
for (size_t day = 0; day < DATE_LUT_SIZE && lut[day].year <= DATE_LUT_MAX_YEAR; ++day) size_t year_months_lut_index = 0;
size_t first_day_of_last_month = 0;
for (size_t day = 0; day < DATE_LUT_SIZE; ++day)
{ {
const Values & values = lut[day]; const Values & values = lut[day];
@ -150,7 +151,87 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
{ {
if (values.month == 1) if (values.month == 1)
years_lut[values.year - DATE_LUT_MIN_YEAR] = day; years_lut[values.year - DATE_LUT_MIN_YEAR] = day;
years_months_lut[(values.year - DATE_LUT_MIN_YEAR) * 12 + values.month - 1] = day;
year_months_lut_index = (values.year - DATE_LUT_MIN_YEAR) * 12 + values.month - 1;
years_months_lut[year_months_lut_index] = day;
first_day_of_last_month = day;
} }
} }
/// Fill the rest of lookup table with the same last month (2106-02-01).
for (; year_months_lut_index < DATE_LUT_YEARS * 12; ++year_months_lut_index)
{
years_months_lut[year_months_lut_index] = first_day_of_last_month;
}
} }
#if !defined(ARCADIA_BUILD) /// Arcadia's variant of CCTZ already has the same implementation.
/// Prefer to load timezones from blobs linked to the binary.
/// The blobs are provided by "tzdata" library.
/// This allows to avoid dependency on system tzdata.
namespace cctz_extension
{
namespace
{
class Source : public cctz::ZoneInfoSource
{
public:
Source(const char * data_, size_t size_) : data(data_), size(size_) {}
size_t Read(void * buf, size_t bytes) override
{
if (bytes > size)
bytes = size;
memcpy(buf, data, bytes);
data += bytes;
size -= bytes;
return bytes;
}
int Skip(size_t offset) override
{
if (offset <= size)
{
data += offset;
size -= offset;
return 0;
}
else
{
errno = EINVAL;
return -1;
}
}
private:
const char * data;
size_t size;
};
std::unique_ptr<cctz::ZoneInfoSource> custom_factory(
const std::string & name,
const std::function<std::unique_ptr<cctz::ZoneInfoSource>(const std::string & name)> & fallback)
{
std::string name_replaced = name;
std::replace(name_replaced.begin(), name_replaced.end(), '/', '_');
std::replace(name_replaced.begin(), name_replaced.end(), '-', '_');
/// These are the names that are generated by "ld -r -b binary"
std::string symbol_name_data = "_binary_" + name_replaced + "_start";
std::string symbol_name_size = "_binary_" + name_replaced + "_size";
const void * sym_data = dlsym(RTLD_DEFAULT, symbol_name_data.c_str());
const void * sym_size = dlsym(RTLD_DEFAULT, symbol_name_size.c_str());
if (sym_data && sym_size)
return std::make_unique<Source>(static_cast<const char *>(sym_data), unalignedLoad<size_t>(&sym_size));
return fallback(name);
}
}
ZoneInfoSourceFactory zone_info_source_factory = custom_factory;
}
#endif

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#include "Types.h"
#include "DayNum.h" #include "DayNum.h"
#include "likely.h" #include "defines.h"
#include "types.h"
#include <ctime> #include <ctime>
#include <string> #include <string>
@ -11,7 +12,7 @@
/// Table size is bigger than DATE_LUT_MAX_DAY_NUM to fill all indices within UInt16 range: this allows to remove extra check. /// Table size is bigger than DATE_LUT_MAX_DAY_NUM to fill all indices within UInt16 range: this allows to remove extra check.
#define DATE_LUT_SIZE 0x10000 #define DATE_LUT_SIZE 0x10000
#define DATE_LUT_MIN_YEAR 1970 #define DATE_LUT_MIN_YEAR 1970
#define DATE_LUT_MAX_YEAR 2105 /// Last supported year #define DATE_LUT_MAX_YEAR 2106 /// Last supported year (incomplete)
#define DATE_LUT_YEARS (1 + DATE_LUT_MAX_YEAR - DATE_LUT_MIN_YEAR) /// Number of years in lookup table #define DATE_LUT_YEARS (1 + DATE_LUT_MAX_YEAR - DATE_LUT_MIN_YEAR) /// Number of years in lookup table
#if defined(__PPC__) #if defined(__PPC__)
@ -36,7 +37,12 @@ using YearWeek = std::pair<UInt16, UInt8>;
class DateLUTImpl class DateLUTImpl
{ {
public: public:
DateLUTImpl(const std::string & time_zone); explicit DateLUTImpl(const std::string & time_zone);
DateLUTImpl(const DateLUTImpl &) = delete;
DateLUTImpl & operator=(const DateLUTImpl &) = delete;
DateLUTImpl(const DateLUTImpl &&) = delete;
DateLUTImpl & operator=(const DateLUTImpl &&) = delete;
public: public:
/// The order of fields matters for alignment and sizeof. /// The order of fields matters for alignment and sizeof.
@ -98,7 +104,7 @@ private:
return guess; return guess;
/// Time zones that have offset 0 from UTC do daylight saving time change (if any) towards increasing UTC offset (example: British Standard Time). /// Time zones that have offset 0 from UTC do daylight saving time change (if any) towards increasing UTC offset (example: British Standard Time).
if (offset_at_start_of_epoch >= 0) if (t >= lut[DayNum(guess + 1)].date)
return DayNum(guess + 1); return DayNum(guess + 1);
return DayNum(guess - 1); return DayNum(guess - 1);
@ -286,8 +292,8 @@ public:
if (offset_is_whole_number_of_hours_everytime) if (offset_is_whole_number_of_hours_everytime)
return (t / 60) % 60; return (t / 60) % 60;
time_t date = find(t).date; UInt32 date = find(t).date;
return (t - date) / 60 % 60; return (UInt32(t) - date) / 60 % 60;
} }
inline time_t toStartOfMinute(time_t t) const { return t / 60 * 60; } inline time_t toStartOfMinute(time_t t) const { return t / 60 * 60; }
@ -300,9 +306,8 @@ public:
if (offset_is_whole_number_of_hours_everytime) if (offset_is_whole_number_of_hours_everytime)
return t / 3600 * 3600; return t / 3600 * 3600;
time_t date = find(t).date; UInt32 date = find(t).date;
/// Still can return wrong values for time at 1970-01-01 if the UTC offset was non-whole number of hours. return date + (UInt32(t) - date) / 3600 * 3600;
return date + (t - date) / 3600 * 3600;
} }
/** Number of calendar day since the beginning of UNIX epoch (1970-01-01 is zero) /** Number of calendar day since the beginning of UNIX epoch (1970-01-01 is zero)
@ -578,7 +583,7 @@ public:
return t / 3600; return t / 3600;
/// Assume that if offset was fractional, then the fraction is the same as at the beginning of epoch. /// Assume that if offset was fractional, then the fraction is the same as at the beginning of epoch.
/// NOTE This assumption is false for "Pacific/Pitcairn" time zone. /// NOTE This assumption is false for "Pacific/Pitcairn" and "Pacific/Kiritimati" time zones.
return (t + 86400 - offset_at_start_of_epoch) / 3600; return (t + 86400 - offset_at_start_of_epoch) / 3600;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <common/Types.h> #include <common/types.h>
#include <common/strong_typedef.h> #include <common/strong_typedef.h>
/** Represents number of days since 1970-01-01. /** Represents number of days since 1970-01-01.

View File

@ -215,7 +215,7 @@ JSON::ElementType JSON::getType() const
void JSON::checkPos(Pos pos) const void JSON::checkPos(Pos pos) const
{ {
if (pos >= ptr_end) if (pos >= ptr_end || ptr_begin == nullptr)
throw JSONException("JSON: unexpected end of data."); throw JSONException("JSON: unexpected end of data.");
} }
@ -341,7 +341,7 @@ JSON::Pos JSON::skipArray() const
if (*pos == ']') if (*pos == ']')
return ++pos; return ++pos;
while (1) while (true)
{ {
pos = JSON(pos, ptr_end, level + 1).skipElement(); pos = JSON(pos, ptr_end, level + 1).skipElement();
@ -373,7 +373,7 @@ JSON::Pos JSON::skipObject() const
if (*pos == '}') if (*pos == '}')
return ++pos; return ++pos;
while (1) while (true)
{ {
pos = JSON(pos, ptr_end, level + 1).skipNameValuePair(); pos = JSON(pos, ptr_end, level + 1).skipNameValuePair();
@ -451,7 +451,10 @@ JSON JSON::operator[] (size_t n) const
size_t i = 0; size_t i = 0;
const_iterator it = begin(); const_iterator it = begin();
while (i < n && it != end()) while (i < n && it != end())
++it, ++i; {
++it;
++i;
}
if (i != n) if (i != n)
throw JSONException("JSON: array index " + std::to_string(n) + " out of bounds."); throw JSONException("JSON: array index " + std::to_string(n) + " out of bounds.");
@ -626,7 +629,7 @@ std::string JSON::getString() const
{ {
unicode = Poco::NumberParser::parseHex(hex); unicode = Poco::NumberParser::parseHex(hex);
} }
catch (const Poco::SyntaxException & e) catch (const Poco::SyntaxException &)
{ {
throw JSONException("JSON: incorrect syntax: incorrect HEX code."); throw JSONException("JSON: incorrect syntax: incorrect HEX code.");
} }
@ -776,7 +779,7 @@ JSON::iterator & JSON::iterator::operator++()
return *this; return *this;
} }
JSON::iterator JSON::iterator::operator++(int) JSON::iterator JSON::iterator::operator++(int) // NOLINT
{ {
iterator copy(*this); iterator copy(*this);
++*this; ++*this;

View File

@ -3,7 +3,7 @@
#include <typeinfo> #include <typeinfo>
#include <Poco/Exception.h> #include <Poco/Exception.h>
#include <common/StringRef.h> #include <common/StringRef.h>
#include <common/Types.h> #include <common/types.h>
/** Очень простой класс для чтения JSON (или его кусочков). /** Очень простой класс для чтения JSON (или его кусочков).

View File

@ -30,7 +30,7 @@ void trim(String & s)
bool hasInputData() bool hasInputData()
{ {
timeval timeout = {0, 0}; timeval timeout = {0, 0};
fd_set fds; fd_set fds{};
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); FD_SET(STDIN_FILENO, &fds);
return select(1, &fds, nullptr, nullptr, &timeout) == 1; return select(1, &fds, nullptr, nullptr, &timeout) == 1;
@ -53,15 +53,15 @@ LineReader::Suggest::WordsRange LineReader::Suggest::getCompletions(const String
/// last_word can be empty. /// last_word can be empty.
if (case_insensitive) /// Only perform case sensitive completion when the prefix string contains any uppercase characters
if (std::none_of(prefix.begin(), prefix.end(), [&](auto c) { return c >= 'A' && c <= 'Z'; }))
return std::equal_range( return std::equal_range(
words.begin(), words.end(), last_word, [prefix_length](std::string_view s, std::string_view prefix_searched) words_no_case.begin(), words_no_case.end(), last_word, [prefix_length](std::string_view s, std::string_view prefix_searched)
{ {
return strncasecmp(s.data(), prefix_searched.data(), prefix_length) < 0; return strncasecmp(s.data(), prefix_searched.data(), prefix_length) < 0;
}); });
else else
return std::equal_range( return std::equal_range(words.begin(), words.end(), last_word, [prefix_length](std::string_view s, std::string_view prefix_searched)
words.begin(), words.end(), last_word, [prefix_length](std::string_view s, std::string_view prefix_searched)
{ {
return strncmp(s.data(), prefix_searched.data(), prefix_length) < 0; return strncmp(s.data(), prefix_searched.data(), prefix_length) < 0;
}); });
@ -127,7 +127,7 @@ LineReader::InputStatus LineReader::readOneLine(const String & prompt)
#ifdef OS_LINUX #ifdef OS_LINUX
if (!readline_ptr) if (!readline_ptr)
{ {
for (auto name : {"libreadline.so", "libreadline.so.0", "libeditline.so", "libeditline.so.0"}) for (const auto * name : {"libreadline.so", "libreadline.so.0", "libeditline.so", "libeditline.so.0"})
{ {
void * dl_handle = dlopen(name, RTLD_LAZY); void * dl_handle = dlopen(name, RTLD_LAZY);
if (dl_handle) if (dl_handle)

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <common/Types.h> #include <common/types.h>
#include <atomic> #include <atomic>
#include <vector> #include <vector>
@ -14,13 +14,11 @@ public:
using WordsRange = std::pair<Words::const_iterator, Words::const_iterator>; using WordsRange = std::pair<Words::const_iterator, Words::const_iterator>;
Words words; Words words;
Words words_no_case;
std::atomic<bool> ready{false}; std::atomic<bool> ready{false};
/// Get iterators for the matched range of words if any. /// Get iterators for the matched range of words if any.
WordsRange getCompletions(const String & prefix, size_t prefix_length) const; WordsRange getCompletions(const String & prefix, size_t prefix_length) const;
/// case sensitive suggestion
bool case_insensitive = false;
}; };
LineReader(const String & history_file_path, char extender, char delimiter = 0); /// if delimiter != 0, then it's multiline mode LineReader(const String & history_file_path, char extender, char delimiter = 0); /// if delimiter != 0, then it's multiline mode

View File

@ -104,6 +104,8 @@ ReadlineLineReader::ReadlineLineReader(const Suggest & suggest_, const String &
if (signal(SIGINT, clear_prompt_or_exit) == SIG_ERR) if (signal(SIGINT, clear_prompt_or_exit) == SIG_ERR)
throw std::runtime_error(std::string("Cannot set signal handler for readline: ") + strerror(errno)); throw std::runtime_error(std::string("Cannot set signal handler for readline: ") + strerror(errno));
rl_variable_bind("completion-ignore-case", "on");
} }
ReadlineLineReader::~ReadlineLineReader() ReadlineLineReader::~ReadlineLineReader()

View File

@ -3,6 +3,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <functional>
namespace namespace
{ {
@ -18,18 +19,31 @@ void trim(String & s)
ReplxxLineReader::ReplxxLineReader(const Suggest & suggest, const String & history_file_path_, char extender_, char delimiter_) ReplxxLineReader::ReplxxLineReader(const Suggest & suggest, const String & history_file_path_, char extender_, char delimiter_)
: LineReader(history_file_path_, extender_, delimiter_) : LineReader(history_file_path_, extender_, delimiter_)
{ {
using namespace std::placeholders;
using Replxx = replxx::Replxx;
if (!history_file_path.empty()) if (!history_file_path.empty())
rx.history_load(history_file_path); rx.history_load(history_file_path);
auto callback = [&suggest] (const String & context, size_t context_size) auto callback = [&suggest] (const String & context, size_t context_size)
{ {
auto range = suggest.getCompletions(context, context_size); auto range = suggest.getCompletions(context, context_size);
return replxx::Replxx::completions_t(range.first, range.second); return Replxx::completions_t(range.first, range.second);
}; };
rx.set_completion_callback(callback); rx.set_completion_callback(callback);
rx.set_complete_on_empty(false); rx.set_complete_on_empty(false);
rx.set_word_break_characters(word_break_characters); rx.set_word_break_characters(word_break_characters);
/// By default C-p/C-n binded to COMPLETE_NEXT/COMPLETE_PREV,
/// bind C-p/C-n to history-previous/history-next like readline.
rx.bind_key(Replxx::KEY::control('N'), [this](char32_t code) { return rx.invoke(Replxx::ACTION::HISTORY_NEXT, code); });
rx.bind_key(Replxx::KEY::control('P'), [this](char32_t code) { return rx.invoke(Replxx::ACTION::HISTORY_PREVIOUS, code); });
/// By default COMPLETE_NEXT/COMPLETE_PREV was binded to C-p/C-n, re-bind
/// to M-P/M-N (that was used for HISTORY_COMMON_PREFIX_SEARCH before, but
/// it also binded to M-p/M-n).
rx.bind_key(Replxx::KEY::meta('N'), [this](char32_t code) { return rx.invoke(Replxx::ACTION::COMPLETE_NEXT, code); });
rx.bind_key(Replxx::KEY::meta('P'), [this](char32_t code) { return rx.invoke(Replxx::ACTION::COMPLETE_PREVIOUS, code); });
} }
ReplxxLineReader::~ReplxxLineReader() ReplxxLineReader::~ReplxxLineReader()

View File

@ -5,7 +5,7 @@
#include <functional> #include <functional>
#include <ostream> #include <ostream>
#include <common/Types.h> #include <common/types.h>
#include <common/unaligned.h> #include <common/unaligned.h>
#include <city.h> #include <city.h>
@ -27,17 +27,17 @@ struct StringRef
size_t size = 0; size_t size = 0;
template <typename CharT, typename = std::enable_if_t<sizeof(CharT) == 1>> template <typename CharT, typename = std::enable_if_t<sizeof(CharT) == 1>>
StringRef(const CharT * data_, size_t size_) : data(reinterpret_cast<const char *>(data_)), size(size_) {} constexpr StringRef(const CharT * data_, size_t size_) : data(reinterpret_cast<const char *>(data_)), size(size_) {}
StringRef(const std::string & s) : data(s.data()), size(s.size()) {} StringRef(const std::string & s) : data(s.data()), size(s.size()) {}
StringRef(const std::string_view & s) : data(s.data()), size(s.size()) {} constexpr StringRef(const std::string_view & s) : data(s.data()), size(s.size()) {}
explicit StringRef(const char * data_) : data(data_), size(strlen(data_)) {} constexpr StringRef(const char * data_) : StringRef(std::string_view{data_}) {}
StringRef() = default; constexpr StringRef() = default;
std::string toString() const { return std::string(data, size); } std::string toString() const { return std::string(data, size); }
explicit operator std::string() const { return toString(); } explicit operator std::string() const { return toString(); }
explicit operator std::string_view() const { return {data, size}; } constexpr explicit operator std::string_view() const { return {data, size}; }
}; };
using StringRefs = std::vector<StringRef>; using StringRefs = std::vector<StringRef>;

View File

@ -1,58 +0,0 @@
#pragma once
#include <algorithm>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <type_traits>
using Int8 = int8_t;
using Int16 = int16_t;
using Int32 = int32_t;
using Int64 = int64_t;
using UInt8 = char8_t;
using UInt16 = uint16_t;
using UInt32 = uint32_t;
using UInt64 = uint64_t;
using String = std::string;
/// The standard library type traits, such as std::is_arithmetic, with one exception
/// (std::common_type), are "set in stone". Attempting to specialize them causes undefined behavior.
/// So instead of using the std type_traits, we use our own version which allows extension.
template <typename T>
struct is_signed
{
static constexpr bool value = std::is_signed_v<T>;
};
template <typename T>
inline constexpr bool is_signed_v = is_signed<T>::value;
template <typename T>
struct is_unsigned
{
static constexpr bool value = std::is_unsigned_v<T>;
};
template <typename T>
inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
template <typename T>
struct is_integral
{
static constexpr bool value = std::is_integral_v<T>;
};
template <typename T>
inline constexpr bool is_integral_v = is_integral<T>::value;
template <typename T>
struct is_arithmetic
{
static constexpr bool value = std::is_arithmetic_v<T>;
};
template <typename T>
inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;

View File

@ -1,6 +1,5 @@
#include <common/argsToConfig.h> #include "argsToConfig.h"
#include <Poco/Util/Application.h>
#include <Poco/Util/LayeredConfiguration.h> #include <Poco/Util/LayeredConfiguration.h>
#include <Poco/Util/MapConfiguration.h> #include <Poco/Util/MapConfiguration.h>
@ -11,7 +10,7 @@ void argsToConfig(const Poco::Util::Application::ArgVec & argv, Poco::Util::Laye
/// Test: -- --1=1 --1=2 --3 5 7 8 -9 10 -11=12 14= 15== --16==17 --=18 --19= --20 21 22 --23 --24 25 --26 -27 28 ---29=30 -- ----31 32 --33 3-4 /// Test: -- --1=1 --1=2 --3 5 7 8 -9 10 -11=12 14= 15== --16==17 --=18 --19= --20 21 22 --23 --24 25 --26 -27 28 ---29=30 -- ----31 32 --33 3-4
Poco::AutoPtr<Poco::Util::MapConfiguration> map_config = new Poco::Util::MapConfiguration; Poco::AutoPtr<Poco::Util::MapConfiguration> map_config = new Poco::Util::MapConfiguration;
std::string key; std::string key;
for (auto & arg : argv) for (const auto & arg : argv)
{ {
auto key_start = arg.find_first_not_of('-'); auto key_start = arg.find_first_not_of('-');
auto pos_minus = arg.find('-'); auto pos_minus = arg.find('-');

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <Poco/Util/Application.h> #include <Poco/Util/Application.h>
namespace Poco::Util namespace Poco::Util

View File

@ -1,7 +0,0 @@
#pragma once
// .h autogenerated by cmake !
#cmakedefine01 USE_JEMALLOC
#cmakedefine01 UNBUNDLED
#cmakedefine01 WITH_COVERAGE

View File

@ -1,16 +1,17 @@
#include <common/coverage.h> #include "coverage.h"
#include <common/config_common.h>
#if WITH_COVERAGE #if WITH_COVERAGE
#include <unistd.h> # include <mutex>
#include <mutex>
#if defined(__clang__) # include <unistd.h>
# if defined(__clang__)
extern "C" void __llvm_profile_dump(); extern "C" void __llvm_profile_dump();
#elif defined(__GNUC__) || defined(__GNUG__) # elif defined(__GNUC__) || defined(__GNUG__)
extern "C" void __gcov_exit(); extern "C" void __gcov_exit();
#endif # endif
#endif #endif
@ -21,11 +22,11 @@ void dumpCoverageReportIfPossible()
static std::mutex mutex; static std::mutex mutex;
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
#if defined(__clang__) # if defined(__clang__)
__llvm_profile_dump(); __llvm_profile_dump();
#elif defined(__GNUC__) || defined(__GNUG__) # elif defined(__GNUC__) || defined(__GNUG__)
__gcov_exit(); __gcov_exit();
#endif # endif
#endif #endif
} }

87
base/common/defines.h Normal file
View File

@ -0,0 +1,87 @@
#pragma once
#if defined(_MSC_VER)
# if !defined(likely)
# define likely(x) (x)
# endif
# if !defined(unlikely)
# define unlikely(x) (x)
# endif
#else
# if !defined(likely)
# define likely(x) (__builtin_expect(!!(x), 1))
# endif
# if !defined(unlikely)
# define unlikely(x) (__builtin_expect(!!(x), 0))
# endif
#endif
#if defined(_MSC_VER)
# define ALWAYS_INLINE __forceinline
# define NO_INLINE static __declspec(noinline)
# define MAY_ALIAS
#else
# define ALWAYS_INLINE __attribute__((__always_inline__))
# define NO_INLINE __attribute__((__noinline__))
# define MAY_ALIAS __attribute__((__may_alias__))
#endif
#if !defined(__x86_64__) && !defined(__aarch64__) && !defined(__PPC__)
# error "The only supported platforms are x86_64 and AArch64, PowerPC (work in progress)"
#endif
/// Check for presence of address sanitizer
#if !defined(ADDRESS_SANITIZER)
# if defined(__has_feature)
# if __has_feature(address_sanitizer)
# define ADDRESS_SANITIZER 1
# endif
# elif defined(__SANITIZE_ADDRESS__)
# define ADDRESS_SANITIZER 1
# endif
#endif
#if !defined(THREAD_SANITIZER)
# if defined(__has_feature)
# if __has_feature(thread_sanitizer)
# define THREAD_SANITIZER 1
# endif
# elif defined(__SANITIZE_THREAD__)
# define THREAD_SANITIZER 1
# endif
#endif
#if !defined(MEMORY_SANITIZER)
# if defined(__has_feature)
# if __has_feature(memory_sanitizer)
# define MEMORY_SANITIZER 1
# endif
# elif defined(__MEMORY_SANITIZER__)
# define MEMORY_SANITIZER 1
# endif
#endif
/// TODO: Strange enough, there is no way to detect UB sanitizer.
/// Explicitly allow undefined behaviour for certain functions. Use it as a function attribute.
/// It is useful in case when compiler cannot see (and exploit) it, but UBSan can.
/// Example: multiplication of signed integers with possibility of overflow when both sides are from user input.
#if defined(__clang__)
# define NO_SANITIZE_UNDEFINED __attribute__((__no_sanitize__("undefined")))
# define NO_SANITIZE_ADDRESS __attribute__((__no_sanitize__("address")))
# define NO_SANITIZE_THREAD __attribute__((__no_sanitize__("thread")))
#else /// It does not work in GCC. GCC 7 cannot recognize this attribute and GCC 8 simply ignores it.
# define NO_SANITIZE_UNDEFINED
# define NO_SANITIZE_ADDRESS
# define NO_SANITIZE_THREAD
#endif
#if defined __GNUC__ && !defined __clang__
# define OPTIMIZE(x) __attribute__((__optimize__(x)))
#else
# define OPTIMIZE(x)
#endif
/// A macro for suppressing warnings about unused variables or function results.
/// Useful for structured bindings which have no standard way to declare this.
#define UNUSED(...) (void)(__VA_ARGS__)

View File

@ -1,16 +1,8 @@
#include <common/demangle.h> #include <common/demangle.h>
#if defined(__has_feature) #if defined(_MSC_VER)
#if __has_feature(memory_sanitizer)
#define MEMORY_SANITIZER 1
#endif
#elif defined(__MEMORY_SANITIZER__)
#define MEMORY_SANITIZER 1
#endif
#if _MSC_VER || MEMORY_SANITIZER DemangleResult tryDemangle(const char *)
DemangleResult tryDemangle(const char * name)
{ {
return DemangleResult{}; return DemangleResult{};
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <string>
#if defined(__SSE2__) #if defined(__SSE2__)
#include <emmintrin.h> #include <emmintrin.h>
@ -292,3 +293,26 @@ inline char * find_last_not_symbols_or_null(char * begin, char * end)
{ {
return const_cast<char *>(detail::find_last_symbols_sse2<false, detail::ReturnMode::Nullptr, symbols...>(begin, end)); return const_cast<char *>(detail::find_last_symbols_sse2<false, detail::ReturnMode::Nullptr, symbols...>(begin, end));
} }
/// Slightly resembles boost::split. The drawback of boost::split is that it fires a false positive in clang static analyzer.
/// See https://github.com/boostorg/algorithm/issues/63
/// And https://bugs.llvm.org/show_bug.cgi?id=41141
template <char... symbols, typename To>
inline void splitInto(To & to, const std::string & what, bool token_compress = false)
{
const char * pos = what.data();
const char * end = pos + what.size();
while (pos < end)
{
const char * delimiter_or_end = find_first_symbols<symbols...>(pos, end);
if (!token_compress || pos < delimiter_or_end)
to.emplace_back(pos, delimiter_or_end);
if (delimiter_or_end < end)
pos = delimiter_or_end + 1;
else
pos = delimiter_or_end;
}
}

View File

@ -1,5 +1,5 @@
#include <Poco/Net/DNS.h> #include <Poco/Net/DNS.h>
#include <Common/getFQDNOrHostName.h> #include <common/getFQDNOrHostName.h>
namespace namespace

View File

@ -58,7 +58,7 @@ uint64_t getMemoryAmountOrZero()
#endif #endif
uint64_t size = 0; /* 64-bit */ uint64_t size = 0; /* 64-bit */
size_t len = sizeof(size); size_t len = sizeof(size);
if (sysctl(mib, 2, &size, &len, NULL, 0) == 0) if (sysctl(mib, 2, &size, &len, nullptr, 0) == 0)
return size; return size;
return 0; /* Failed? */ return 0; /* Failed? */
@ -69,13 +69,13 @@ uint64_t getMemoryAmountOrZero()
#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
/* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */ /* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */
return (uint64_t)sysconf(_SC_PHYS_PAGES) return uint64_t(sysconf(_SC_PHYS_PAGES))
* (uint64_t)sysconf(_SC_PAGESIZE); *uint64_t(sysconf(_SC_PAGESIZE));
#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE) #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE)
/* Legacy. -------------------------------------------------- */ /* Legacy. -------------------------------------------------- */
return (uint64_t)sysconf(_SC_PHYS_PAGES) return uint64_t(sysconf(_SC_PHYS_PAGES))
* (uint64_t)sysconf(_SC_PAGE_SIZE); * uint64_t(sysconf(_SC_PAGE_SIZE));
#elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM)) #elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM))
/* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */ /* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */
@ -88,7 +88,7 @@ uint64_t getMemoryAmountOrZero()
#endif #endif
unsigned int size = 0; /* 32-bit */ unsigned int size = 0; /* 32-bit */
size_t len = sizeof(size); size_t len = sizeof(size);
if (sysctl(mib, 2, &size, &len, NULL, 0) == 0) if (sysctl(mib, 2, &size, &len, nullptr, 0) == 0)
return size; return size;
return 0; /* Failed? */ return 0; /* Failed? */

View File

@ -1,9 +1,9 @@
#include <common/getThreadId.h> #include <common/getThreadId.h>
#if OS_LINUX #if defined(OS_LINUX)
#include <unistd.h> #include <unistd.h>
#include <syscall.h> #include <syscall.h>
#elif OS_FREEBSD #elif defined(OS_FREEBSD)
#include <pthread_np.h> #include <pthread_np.h>
#else #else
#include <pthread.h> #include <pthread.h>
@ -16,9 +16,9 @@ uint64_t getThreadId()
{ {
if (!current_tid) if (!current_tid)
{ {
#if OS_LINUX #if defined(OS_LINUX)
current_tid = syscall(SYS_gettid); /// This call is always successful. - man gettid current_tid = syscall(SYS_gettid); /// This call is always successful. - man gettid
#elif OS_FREEBSD #elif defined(OS_FREEBSD)
current_tid = pthread_getthreadid_np(); current_tid = pthread_getthreadid_np();
#else #else
if (0 != pthread_threadid_np(nullptr, &current_tid)) if (0 != pthread_threadid_np(nullptr, &current_tid))

View File

@ -80,7 +80,6 @@ dumpImpl(Out & out, T && x)
} }
/// Tuple, pair /// Tuple, pair
template <size_t N, typename Out, typename T> template <size_t N, typename Out, typename T>
Out & dumpTupleImpl(Out & out, T && x) Out & dumpTupleImpl(Out & out, T && x)

View File

@ -30,7 +30,6 @@
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <type_traits> #include <type_traits>
#include "likely.h"
using int128_t = __int128; using int128_t = __int128;
using uint128_t = unsigned __int128; using uint128_t = unsigned __int128;

View File

@ -1,15 +0,0 @@
#if defined(_MSC_VER)
# if !defined(likely)
# define likely(x) (x)
# endif
# if !defined(unlikely)
# define unlikely(x) (x)
# endif
#else
# if !defined(likely)
# define likely(x) (__builtin_expect(!!(x), 1))
# endif
# if !defined(unlikely)
# define unlikely(x) (__builtin_expect(!!(x), 0))
# endif
#endif

View File

@ -1,45 +1,21 @@
#pragma once #pragma once
#include <new> #include <new>
#include "likely.h" #include "defines.h"
#if __has_include(<common/config_common.h>)
#include <common/config_common.h>
#endif
#if USE_JEMALLOC #if USE_JEMALLOC
#include <jemalloc/jemalloc.h> # include <jemalloc/jemalloc.h>
#if JEMALLOC_VERSION_MAJOR < 4
#undef USE_JEMALLOC
#define USE_JEMALLOC 0
#include <cstdlib>
#endif
#else
#include <cstdlib>
#endif #endif
// Also defined in Core/Defines.h #if !USE_JEMALLOC || JEMALLOC_VERSION_MAJOR < 4
#if !defined(ALWAYS_INLINE) # include <cstdlib>
#if defined(_MSC_VER)
#define ALWAYS_INLINE inline __forceinline
#else
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
#endif
#endif #endif
#if !defined(NO_INLINE)
#if defined(_MSC_VER)
#define NO_INLINE static __declspec(noinline)
#else
#define NO_INLINE __attribute__((__noinline__))
#endif
#endif
namespace Memory namespace Memory
{ {
ALWAYS_INLINE void * newImpl(std::size_t size) inline ALWAYS_INLINE void * newImpl(std::size_t size)
{ {
auto * ptr = malloc(size); auto * ptr = malloc(size);
if (likely(ptr != nullptr)) if (likely(ptr != nullptr))
@ -49,19 +25,19 @@ ALWAYS_INLINE void * newImpl(std::size_t size)
throw std::bad_alloc{}; throw std::bad_alloc{};
} }
ALWAYS_INLINE void * newNoExept(std::size_t size) noexcept inline ALWAYS_INLINE void * newNoExept(std::size_t size) noexcept
{ {
return malloc(size); return malloc(size);
} }
ALWAYS_INLINE void deleteImpl(void * ptr) noexcept inline ALWAYS_INLINE void deleteImpl(void * ptr) noexcept
{ {
free(ptr); free(ptr);
} }
#if USE_JEMALLOC #if USE_JEMALLOC && JEMALLOC_VERSION_MAJOR >= 4
ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size) noexcept inline ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size) noexcept
{ {
if (unlikely(ptr == nullptr)) if (unlikely(ptr == nullptr))
return; return;
@ -71,7 +47,7 @@ ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size) noexcept
#else #else
ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size [[maybe_unused]]) noexcept inline ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size [[maybe_unused]]) noexcept
{ {
free(ptr); free(ptr);
} }

View File

@ -19,7 +19,7 @@ void * mremap_fallback(
return MAP_FAILED; return MAP_FAILED;
} }
#if _MSC_VER #if defined(_MSC_VER)
void * new_address = ::operator new(new_size); void * new_address = ::operator new(new_size);
#else #else
void * new_address = mmap(nullptr, new_size, mmap_prot, mmap_flags, mmap_fd, mmap_offset); void * new_address = mmap(nullptr, new_size, mmap_prot, mmap_flags, mmap_fd, mmap_offset);
@ -29,7 +29,7 @@ void * mremap_fallback(
memcpy(new_address, old_address, old_size); memcpy(new_address, old_address, old_size);
#if _MSC_VER #if defined(_MSC_VER)
delete old_address; delete old_address;
#else #else
if (munmap(old_address, old_size)) if (munmap(old_address, old_size))

View File

@ -20,6 +20,14 @@
#define USE_PHDR_CACHE 1 #define USE_PHDR_CACHE 1
#endif #endif
/// Thread Sanitizer uses dl_iterate_phdr function on initialization and fails if we provide our own.
#ifdef USE_PHDR_CACHE
#if defined(__clang__)
# pragma clang diagnostic ignored "-Wreserved-id-macro"
# pragma clang diagnostic ignored "-Wunused-macros"
#endif
#define __msan_unpoison(X, Y) #define __msan_unpoison(X, Y)
#if defined(__has_feature) #if defined(__has_feature)
# if __has_feature(memory_sanitizer) # if __has_feature(memory_sanitizer)
@ -28,9 +36,6 @@
# endif # endif
#endif #endif
/// Thread Sanitizer uses dl_iterate_phdr function on initialization and fails if we provide our own.
#ifdef USE_PHDR_CACHE
#include <link.h> #include <link.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <vector> #include <vector>
@ -70,7 +75,7 @@ extern "C"
#endif #endif
int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data) int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data)
{ {
auto current_phdr_cache = phdr_cache.load(); auto * current_phdr_cache = phdr_cache.load();
if (!current_phdr_cache) if (!current_phdr_cache)
{ {
// Cache is not yet populated, pass through to the original function. // Cache is not yet populated, pass through to the original function.

View File

@ -1,227 +0,0 @@
/*
https://www.musl-libc.org/
http://git.musl-libc.org/cgit/musl/tree/src/math/exp10.c
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2014 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
Alex Dowad
Alexander Monakov
Anthony G. Basile
Arvid Picciani
Bobby Bingham
Boris Brezillon
Brent Cook
Chris Spiegel
Clément Vasseur
Daniel Micay
Denys Vlasenko
Emil Renner Berthing
Felix Fietkau
Felix Janda
Gianluca Anzolin
Hauke Mehrtens
Hiltjo Posthuma
Isaac Dunham
Jaydeep Patil
Jens Gustedt
Jeremy Huntwork
Jo-Philipp Wich
Joakim Sindholt
John Spencer
Josiah Worcester
Justin Cormack
Khem Raj
Kylie McClain
Luca Barbato
Luka Perkov
M Farkas-Dyck (Strake)
Mahesh Bodapati
Michael Forney
Natanael Copa
Nicholas J. Kain
orc
Pascal Cuoq
Petr Hosek
Pierre Carrier
Rich Felker
Richard Pennington
Shiz
sin
Solar Designer
Stefan Kristiansson
Szabolcs Nagy
Timo Teräs
Trutz Behn
Valentin Ochs
William Haddon
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/ * and src/complex/ *) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The implementation of DES for crypt (src/crypt/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Valentin Ochs and is licensed under an MIT-style license.
The BSD PRNG implementation (src/prng/random.c) and XSI search API
(src/search/ *.c) functions are Copyright © 2011 Szabolcs Nagy and
licensed under following terms: "Permission to use, copy, modify,
and/or distribute this code for any purpose with or without fee is
hereby granted. There is no warranty."
The x86_64 port was written by Nicholas J. Kain and is licensed under
the standard MIT terms.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The mips64 port was contributed by Imagination Technologies and is
licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
In addition, permission is hereby granted for all public header files
(include/ * and arch/ * /bits/ *) and crt files intended to be linked into
applications (crt/ *, ldso/dlstart.c, and arch/ * /crt_arch.h) to omit
the copyright notice and permission notice otherwise required by the
license, and to use these files without any requirement of
attribution. These files include substantial contributions from:
Bobby Bingham
John Spencer
Nicholas J. Kain
Rich Felker
Richard Pennington
Stefan Kristiansson
Szabolcs Nagy
all of whom have explicitly granted such permission.
This file previously contained text expressing a belief that most of
the files covered by the above exception were sufficiently trivial not
to be subject to copyright, resulting in confusion over whether it
negated the permissions granted in the license. In the spirit of
permissive licensing, and of not having licensing issues being an
obstacle to adoption, that text has been removed.
*/
#include <math.h>
#include <stdint.h>
#include <stdio.h>
double preciseExp10(double x)
{
if (isnan(x)) return NAN;
// ranging between DBL_TRUE_MIN and DBL_MAX. Outsiders are treated as zeros or infinities
static const double p10[]
= {1e-323, 1e-322, 1e-321, 1e-320, 1e-319, 1e-318, 1e-317, 1e-316, 1e-315, 1e-314, 1e-313, 1e-312, 1e-311, 1e-310, 1e-309, 1e-308, 1e-307,
1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 1e-290,
1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273,
1e-272, 1e-271, 1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261, 1e-260, 1e-259, 1e-258, 1e-257, 1e-256,
1e-255, 1e-254, 1e-253, 1e-252, 1e-251, 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241, 1e-240, 1e-239,
1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231, 1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222,
1e-221, 1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205,
1e-204, 1e-203, 1e-202, 1e-201, 1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 1e-190, 1e-189, 1e-188,
1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181, 1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171,
1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161, 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154,
1e-153, 1e-152, 1e-151, 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141, 1e-140, 1e-139, 1e-138, 1e-137,
1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120,
1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103,
1e-102, 1e-101, 1e-100, 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86,
1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69,
1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52,
1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35,
1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18,
1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
1e0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16,
1e+17, 1e+18, 1e+19, 1e+20, 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33,
1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50,
1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67,
1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 1e+81, 1e+82, 1e+83, 1e+84,
1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 1e+101,
1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109, 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118,
1e+119, 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, 1e+128, 1e+129, 1e+130, 1e+131, 1e+132, 1e+133, 1e+134, 1e+135,
1e+136, 1e+137, 1e+138, 1e+139, 1e+140, 1e+141, 1e+142, 1e+143, 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, 1e+150, 1e+151, 1e+152,
1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, 1e+160, 1e+161, 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169,
1e+170, 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179, 1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186,
1e+187, 1e+188, 1e+189, 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199, 1e+200, 1e+201, 1e+202, 1e+203,
1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209, 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, 1e+216, 1e+217, 1e+218, 1e+219, 1e+220,
1e+221, 1e+222, 1e+223, 1e+224, 1e+225, 1e+226, 1e+227, 1e+228, 1e+229, 1e+230, 1e+231, 1e+232, 1e+233, 1e+234, 1e+235, 1e+236, 1e+237,
1e+238, 1e+239, 1e+240, 1e+241, 1e+242, 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, 1e+250, 1e+251, 1e+252, 1e+253, 1e+254,
1e+255, 1e+256, 1e+257, 1e+258, 1e+259, 1e+260, 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269, 1e+270, 1e+271,
1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, 1e+279, 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, 1e+288,
1e+289, 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299, 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305,
1e+306, 1e+307, 1e+308};
double n, y = modf(x, &n);
if (n > 308) return INFINITY;
if (n < -323) return 0;
// Using lookup table based formula to get accurate results for integer arguments.
return exp2(3.32192809488736234787031942948939 * y) * p10[(int)n + 323];
}

View File

@ -0,0 +1,227 @@
/*
https://www.musl-libc.org/
http://git.musl-libc.org/cgit/musl/tree/src/math/exp10.c
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2014 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
Alex Dowad
Alexander Monakov
Anthony G. Basile
Arvid Picciani
Bobby Bingham
Boris Brezillon
Brent Cook
Chris Spiegel
Clément Vasseur
Daniel Micay
Denys Vlasenko
Emil Renner Berthing
Felix Fietkau
Felix Janda
Gianluca Anzolin
Hauke Mehrtens
Hiltjo Posthuma
Isaac Dunham
Jaydeep Patil
Jens Gustedt
Jeremy Huntwork
Jo-Philipp Wich
Joakim Sindholt
John Spencer
Josiah Worcester
Justin Cormack
Khem Raj
Kylie McClain
Luca Barbato
Luka Perkov
M Farkas-Dyck (Strake)
Mahesh Bodapati
Michael Forney
Natanael Copa
Nicholas J. Kain
orc
Pascal Cuoq
Petr Hosek
Pierre Carrier
Rich Felker
Richard Pennington
Shiz
sin
Solar Designer
Stefan Kristiansson
Szabolcs Nagy
Timo Teräs
Trutz Behn
Valentin Ochs
William Haddon
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/ * and src/complex/ *) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The implementation of DES for crypt (src/crypt/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Valentin Ochs and is licensed under an MIT-style license.
The BSD PRNG implementation (src/prng/random.c) and XSI search API
(src/search/ *.c) functions are Copyright © 2011 Szabolcs Nagy and
licensed under following terms: "Permission to use, copy, modify,
and/or distribute this code for any purpose with or without fee is
hereby granted. There is no warranty."
The x86_64 port was written by Nicholas J. Kain and is licensed under
the standard MIT terms.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The mips64 port was contributed by Imagination Technologies and is
licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
In addition, permission is hereby granted for all public header files
(include/ * and arch/ * /bits/ *) and crt files intended to be linked into
applications (crt/ *, ldso/dlstart.c, and arch/ * /crt_arch.h) to omit
the copyright notice and permission notice otherwise required by the
license, and to use these files without any requirement of
attribution. These files include substantial contributions from:
Bobby Bingham
John Spencer
Nicholas J. Kain
Rich Felker
Richard Pennington
Stefan Kristiansson
Szabolcs Nagy
all of whom have explicitly granted such permission.
This file previously contained text expressing a belief that most of
the files covered by the above exception were sufficiently trivial not
to be subject to copyright, resulting in confusion over whether it
negated the permissions granted in the license. In the spirit of
permissive licensing, and of not having licensing issues being an
obstacle to adoption, that text has been removed.
*/
#include <math.h>
#include <stdint.h>
#include <stdio.h>
double preciseExp10(double x)
{
if (isnan(x)) return NAN;
// ranging between DBL_TRUE_MIN and DBL_MAX. Outsiders are treated as zeros or infinities
static const double p10[]
= {1e-323, 1e-322, 1e-321, 1e-320, 1e-319, 1e-318, 1e-317, 1e-316, 1e-315, 1e-314, 1e-313, 1e-312, 1e-311, 1e-310, 1e-309, 1e-308, 1e-307,
1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 1e-290,
1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273,
1e-272, 1e-271, 1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261, 1e-260, 1e-259, 1e-258, 1e-257, 1e-256,
1e-255, 1e-254, 1e-253, 1e-252, 1e-251, 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241, 1e-240, 1e-239,
1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231, 1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222,
1e-221, 1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205,
1e-204, 1e-203, 1e-202, 1e-201, 1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 1e-190, 1e-189, 1e-188,
1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181, 1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171,
1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161, 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154,
1e-153, 1e-152, 1e-151, 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141, 1e-140, 1e-139, 1e-138, 1e-137,
1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120,
1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103,
1e-102, 1e-101, 1e-100, 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86,
1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69,
1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52,
1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35,
1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18,
1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
1e0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16,
1e+17, 1e+18, 1e+19, 1e+20, 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33,
1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50,
1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67,
1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 1e+81, 1e+82, 1e+83, 1e+84,
1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 1e+101,
1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109, 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118,
1e+119, 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, 1e+128, 1e+129, 1e+130, 1e+131, 1e+132, 1e+133, 1e+134, 1e+135,
1e+136, 1e+137, 1e+138, 1e+139, 1e+140, 1e+141, 1e+142, 1e+143, 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, 1e+150, 1e+151, 1e+152,
1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, 1e+160, 1e+161, 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169,
1e+170, 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179, 1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186,
1e+187, 1e+188, 1e+189, 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199, 1e+200, 1e+201, 1e+202, 1e+203,
1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209, 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, 1e+216, 1e+217, 1e+218, 1e+219, 1e+220,
1e+221, 1e+222, 1e+223, 1e+224, 1e+225, 1e+226, 1e+227, 1e+228, 1e+229, 1e+230, 1e+231, 1e+232, 1e+233, 1e+234, 1e+235, 1e+236, 1e+237,
1e+238, 1e+239, 1e+240, 1e+241, 1e+242, 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, 1e+250, 1e+251, 1e+252, 1e+253, 1e+254,
1e+255, 1e+256, 1e+257, 1e+258, 1e+259, 1e+260, 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269, 1e+270, 1e+271,
1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, 1e+279, 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, 1e+288,
1e+289, 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299, 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305,
1e+306, 1e+307, 1e+308};
double n, y = modf(x, &n);
if (n > 308) return INFINITY;
if (n < -323) return 0;
// Using lookup table based formula to get accurate results for integer arguments.
return exp2(3.32192809488736234787031942948939 * y) * p10[static_cast<int>(n) + 323];
}

View File

@ -8,9 +8,4 @@
* Note: the function names are different to avoid confusion with symbols from the system libm. * Note: the function names are different to avoid confusion with symbols from the system libm.
*/ */
extern "C"
{
double preciseExp10(double x); double preciseExp10(double x);
}

View File

@ -1,6 +1,6 @@
#include <common/shift10.h> #include <common/shift10.h>
#include <common/likely.h> #include "defines.h"
#include <limits> #include <limits>
@ -8,8 +8,8 @@
template <typename T> template <typename T>
static T shift10Impl(T x, int exponent) static T shift10Impl(T x, int exponent)
{ {
static constexpr ssize_t MIN_EXPONENT = -323; static constexpr ssize_t min_exponent = -323;
static constexpr ssize_t MAX_EXPONENT = 308; static constexpr ssize_t max_exponent = 308;
static const long double powers10[] = static const long double powers10[] =
{ {
@ -47,12 +47,12 @@ static T shift10Impl(T x, int exponent)
1e291L,1e292L,1e293L,1e294L,1e295L,1e296L,1e297L,1e298L,1e299L,1e300L,1e301L,1e302L,1e303L,1e304L,1e305L,1e306L,1e307L,1e308L 1e291L,1e292L,1e293L,1e294L,1e295L,1e296L,1e297L,1e298L,1e299L,1e300L,1e301L,1e302L,1e303L,1e304L,1e305L,1e306L,1e307L,1e308L
}; };
if (unlikely(exponent < MIN_EXPONENT)) /// Note: there are some values below MIN_EXPONENT that is greater than zero. if (unlikely(exponent < min_exponent)) /// Note: there are some values below MIN_EXPONENT that is greater than zero.
x *= 0; /// Multiplying to keep the sign of zero. x *= 0; /// Multiplying to keep the sign of zero.
else if (unlikely(exponent > MAX_EXPONENT)) else if (unlikely(exponent > max_exponent))
x *= std::numeric_limits<T>::infinity(); /// Multiplying to keep the sign of infinity. x *= std::numeric_limits<T>::infinity(); /// Multiplying to keep the sign of infinity.
else else
x *= powers10[exponent - MIN_EXPONENT]; x *= powers10[exponent - min_exponent];
return x; return x;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <common/Types.h> #include <common/types.h>
/** Almost the same as x = x * exp10(exponent), but gives more accurate result. /** Almost the same as x = x * exp10(exponent), but gives more accurate result.
* Example: * Example:

View File

@ -22,7 +22,7 @@ void sleepForNanoseconds(uint64_t nanoseconds)
#if defined(OS_DARWIN) #if defined(OS_DARWIN)
//https://developer.apple.com/library/archive/technotes/tn2169/_index.html //https://developer.apple.com/library/archive/technotes/tn2169/_index.html
//https://dshil.github.io/blog/missed-os-x-clock-guide/ //https://dshil.github.io/blog/missed-os-x-clock-guide/
static mach_timebase_info_data_t timebase_info = {0}; static mach_timebase_info_data_t timebase_info{};
if (timebase_info.denom == 0) if (timebase_info.denom == 0)
mach_timebase_info(&timebase_info); mach_timebase_info(&timebase_info);

View File

@ -1,15 +1,9 @@
#pragma once #pragma once
#include <boost/operators.hpp>
#include <type_traits> #include <type_traits>
/** https://svn.boost.org/trac/boost/ticket/5182
*/
template <class T, class Tag> template <class T, class Tag>
struct StrongTypedef struct StrongTypedef
: boost::totally_ordered1< StrongTypedef<T, Tag>
, boost::totally_ordered2< StrongTypedef<T, Tag>, T> >
{ {
private: private:
using Self = StrongTypedef; using Self = StrongTypedef;

View File

@ -1,5 +1,5 @@
#include <string> #include <string>
#include <common/Types.h> #include <common/types.h>
/** Set color in terminal based on 64-bit hash value. /** Set color in terminal based on 64-bit hash value.

View File

@ -43,7 +43,7 @@ void loop(time_t begin, time_t end, int step)
} }
int main(int argc, char ** argv) int main(int, char **)
{ {
loop(orderedIdentifierToDate(20101031), orderedIdentifierToDate(20101101), 15 * 60); loop(orderedIdentifierToDate(20101031), orderedIdentifierToDate(20101101), 15 * 60);
loop(orderedIdentifierToDate(20100328), orderedIdentifierToDate(20100330), 15 * 60); loop(orderedIdentifierToDate(20100328), orderedIdentifierToDate(20100330), 15 * 60);

View File

@ -53,7 +53,7 @@ void loop(time_t begin, time_t end, int step)
} }
int main(int argc, char ** argv) int main(int, char **)
{ {
loop(orderedIdentifierToDate(20101031), orderedIdentifierToDate(20101101), 15 * 60); loop(orderedIdentifierToDate(20101031), orderedIdentifierToDate(20101101), 15 * 60);
loop(orderedIdentifierToDate(20100328), orderedIdentifierToDate(20100330), 15 * 60); loop(orderedIdentifierToDate(20100328), orderedIdentifierToDate(20100330), 15 * 60);

View File

@ -2,15 +2,15 @@
#include <common/DateLUT.h> #include <common/DateLUT.h>
int main(int argc, char ** argv) int main(int, char **)
{ {
/** В DateLUT был глюк - для времён из дня 1970-01-01, возвращался номер часа больше 23. */ /** В DateLUT был глюк - для времён из дня 1970-01-01, возвращался номер часа больше 23. */
static const time_t TIME = 66130; static const time_t time = 66130;
const auto & date_lut = DateLUT::instance(); const auto & date_lut = DateLUT::instance();
std::cerr << date_lut.toHour(TIME) << std::endl; std::cerr << date_lut.toHour(time) << std::endl;
std::cerr << date_lut.toDayNum(TIME) << std::endl; std::cerr << date_lut.toDayNum(time) << std::endl;
const auto * values = reinterpret_cast<const DateLUTImpl::Values *>(&date_lut); const auto * values = reinterpret_cast<const DateLUTImpl::Values *>(&date_lut);

View File

@ -2,13 +2,13 @@
#include <common/DateLUT.h> #include <common/DateLUT.h>
#include <Poco/Exception.h> #include <Poco/Exception.h>
int main(int argc, char ** argv) int main(int, char **)
{ {
try try
{ {
const auto & date_lut = DateLUT::instance(); const auto & date_lut = DateLUT::instance();
std::cout << "Detected default timezone: `" << date_lut.getTimeZone() << "'" << std::endl; std::cout << "Detected default timezone: `" << date_lut.getTimeZone() << "'" << std::endl;
time_t now = time(NULL); time_t now = time(nullptr);
std::cout << "Current time: " << date_lut.timeToString(now) std::cout << "Current time: " << date_lut.timeToString(now)
<< ", UTC: " << DateLUT::instance("UTC").timeToString(now) << std::endl; << ", UTC: " << DateLUT::instance("UTC").timeToString(now) << std::endl;
} }

View File

@ -1,7 +1,7 @@
#include <common/DateLUT.h> #include <common/DateLUT.h>
/// Позволяет проверить время инициализации DateLUT. /// Позволяет проверить время инициализации DateLUT.
int main(int argc, char ** argv) int main(int, char **)
{ {
DateLUT::instance(); DateLUT::instance();
return 0; return 0;

View File

@ -1,9 +1,10 @@
#include <string> #include <string>
#include <vector>
#include <common/find_symbols.h> #include <common/find_symbols.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
TEST(find_symbols, SimpleTest) TEST(FindSymbols, SimpleTest)
{ {
std::string s = "Hello, world! Goodbye..."; std::string s = "Hello, world! Goodbye...";
const char * begin = s.data(); const char * begin = s.data();
@ -22,4 +23,16 @@ TEST(find_symbols, SimpleTest)
ASSERT_EQ(find_last_symbols_or_null<' '>(begin, end), end - 11); ASSERT_EQ(find_last_symbols_or_null<' '>(begin, end), end - 11);
ASSERT_EQ(find_last_symbols_or_null<'H'>(begin, end), begin); ASSERT_EQ(find_last_symbols_or_null<'H'>(begin, end), begin);
ASSERT_EQ((find_last_symbols_or_null<'a', 'e'>(begin, end)), end - 4); ASSERT_EQ((find_last_symbols_or_null<'a', 'e'>(begin, end)), end - 4);
{
std::vector<std::string> vals;
splitInto<' ', ','>(vals, "hello, world", true);
ASSERT_EQ(vals, (std::vector<std::string>{"hello", "world"}));
}
{
std::vector<std::string> vals;
splitInto<' ', ','>(vals, "s String", true);
ASSERT_EQ(vals, (std::vector<std::string>{"s", "String"}));
}
} }

View File

@ -22,484 +22,484 @@ struct GetStringTestRecord
std::string result; std::string result;
}; };
TEST(JSON_Suite, SimpleTest) TEST(JSONSuite, SimpleTest)
{ {
std::vector<GetStringTestRecord> test_data = std::vector<GetStringTestRecord> test_data =
{ {
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Вафельница Vitek WX-1102 FL\""s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s }, { R"("Вафельница Vitek WX-1102 FL")"s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"184509\""s, ResultType::Return, "184509"s }, { R"("184509")"s, ResultType::Return, "184509"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"Все для детей/Детская техника/Vitek\""s, ResultType::Return, "Все для детей/Детская техника/Vitek"s }, { R"("Все для детей/Детская техника/Vitek")"s, ResultType::Return, "Все для детей/Детская техника/Vitek"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"В наличии\""s, ResultType::Return, "В наличии"s }, { R"("В наличии")"s, ResultType::Return, "В наличии"s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"2390.00\""s, ResultType::Return, "2390.00"s }, { R"("2390.00")"s, ResultType::Return, "2390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"Карточка\""s, ResultType::Return, "Карточка"s }, { R"("Карточка")"s, ResultType::Return, "Карточка"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"detail\""s, ResultType::Return, "detail"s }, { R"("detail")"s, ResultType::Return, "detail"s },
{ "\"actionField\""s, ResultType::Return, "actionField"s }, { R"("actionField")"s, ResultType::Return, "actionField"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"http://www.techport.ru/q/?t=вафельница&sort=price&sdim=asc\""s, ResultType::Return, "http://www.techport.ru/q/?t=вафельница&sort=price&sdim=asc"s }, { R"("http://www.techport.ru/q/?t=вафельница&sort=price&sdim=asc")"s, ResultType::Return, "http://www.techport.ru/q/?t=вафельница&sort=price&sdim=asc"s },
{ "\"action\""s, ResultType::Return, "action"s }, { R"("action")"s, ResultType::Return, "action"s },
{ "\"detail\""s, ResultType::Return, "detail"s }, { R"("detail")"s, ResultType::Return, "detail"s },
{ "\"products\""s, ResultType::Return, "products"s }, { R"("products")"s, ResultType::Return, "products"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Вафельница Vitek WX-1102 FL\""s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s }, { R"("Вафельница Vitek WX-1102 FL")"s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"184509\""s, ResultType::Return, "184509"s }, { R"("184509")"s, ResultType::Return, "184509"s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"2390.00\""s, ResultType::Return, "2390.00"s }, { R"("2390.00")"s, ResultType::Return, "2390.00"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"Vitek\""s, ResultType::Return, "Vitek"s }, { R"("Vitek")"s, ResultType::Return, "Vitek"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"Все для детей/Детская техника/Vitek\""s, ResultType::Return, "Все для детей/Детская техника/Vitek"s }, { R"("Все для детей/Детская техника/Vitek")"s, ResultType::Return, "Все для детей/Детская техника/Vitek"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"В наличии\""s, ResultType::Return, "В наличии"s }, { R"("В наличии")"s, ResultType::Return, "В наличии"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"isAuthorized\""s, ResultType::Return, "isAuthorized"s }, { R"("isAuthorized")"s, ResultType::Return, "isAuthorized"s },
{ "\"isSubscriber\""s, ResultType::Return, "isSubscriber"s }, { R"("isSubscriber")"s, ResultType::Return, "isSubscriber"s },
{ "\"postType\""s, ResultType::Return, "postType"s }, { R"("postType")"s, ResultType::Return, "postType"s },
{ "\"Новости\""s, ResultType::Return, "Новости"s }, { R"("Новости")"s, ResultType::Return, "Новости"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"Электроплита GEFEST Брест ЭПНД 5140-01 0001\""s, ResultType::Return, "Электроплита GEFEST Брест ЭПНД 5140-01 0001"s }, { R"("Электроплита GEFEST Брест ЭПНД 5140-01 0001")"s, ResultType::Return, "Электроплита GEFEST Брест ЭПНД 5140-01 0001"s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"currencyCode\""s, ResultType::Return, "currencyCode"s }, { R"("currencyCode")"s, ResultType::Return, "currencyCode"s },
{ "\"RUB\""s, ResultType::Return, "RUB"s }, { R"("RUB")"s, ResultType::Return, "RUB"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"trash_login\""s, ResultType::Return, "trash_login"s }, { R"("trash_login")"s, ResultType::Return, "trash_login"s },
{ "\"novikoff\""s, ResultType::Return, "novikoff"s }, { R"("novikoff")"s, ResultType::Return, "novikoff"s },
{ "\"trash_cat_link\""s, ResultType::Return, "trash_cat_link"s }, { R"("trash_cat_link")"s, ResultType::Return, "trash_cat_link"s },
{ "\"progs\""s, ResultType::Return, "progs"s }, { R"("progs")"s, ResultType::Return, "progs"s },
{ "\"trash_parent_link\""s, ResultType::Return, "trash_parent_link"s }, { R"("trash_parent_link")"s, ResultType::Return, "trash_parent_link"s },
{ "\"content\""s, ResultType::Return, "content"s }, { R"("content")"s, ResultType::Return, "content"s },
{ "\"trash_posted_parent\""s, ResultType::Return, "trash_posted_parent"s }, { R"("trash_posted_parent")"s, ResultType::Return, "trash_posted_parent"s },
{ "\"content.01.2016\""s, ResultType::Return, "content.01.2016"s }, { R"("content.01.2016")"s, ResultType::Return, "content.01.2016"s },
{ "\"trash_posted_cat\""s, ResultType::Return, "trash_posted_cat"s }, { R"("trash_posted_cat")"s, ResultType::Return, "trash_posted_cat"s },
{ "\"progs.01.2016\""s, ResultType::Return, "progs.01.2016"s }, { R"("progs.01.2016")"s, ResultType::Return, "progs.01.2016"s },
{ "\"trash_virus_count\""s, ResultType::Return, "trash_virus_count"s }, { R"("trash_virus_count")"s, ResultType::Return, "trash_virus_count"s },
{ "\"trash_is_android\""s, ResultType::Return, "trash_is_android"s }, { R"("trash_is_android")"s, ResultType::Return, "trash_is_android"s },
{ "\"trash_is_wp8\""s, ResultType::Return, "trash_is_wp8"s }, { R"("trash_is_wp8")"s, ResultType::Return, "trash_is_wp8"s },
{ "\"trash_is_ios\""s, ResultType::Return, "trash_is_ios"s }, { R"("trash_is_ios")"s, ResultType::Return, "trash_is_ios"s },
{ "\"trash_posted\""s, ResultType::Return, "trash_posted"s }, { R"("trash_posted")"s, ResultType::Return, "trash_posted"s },
{ "\"01.2016\""s, ResultType::Return, "01.2016"s }, { R"("01.2016")"s, ResultType::Return, "01.2016"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"merchantId\""s, ResultType::Return, "merchantId"s }, { R"("merchantId")"s, ResultType::Return, "merchantId"s },
{ "\"13694_49246\""s, ResultType::Return, "13694_49246"s }, { R"("13694_49246")"s, ResultType::Return, "13694_49246"s },
{ "\"cps-source\""s, ResultType::Return, "cps-source"s }, { R"("cps-source")"s, ResultType::Return, "cps-source"s },
{ "\"wargaming\""s, ResultType::Return, "wargaming"s }, { R"("wargaming")"s, ResultType::Return, "wargaming"s },
{ "\"cps_provider\""s, ResultType::Return, "cps_provider"s }, { R"("cps_provider")"s, ResultType::Return, "cps_provider"s },
{ "\"default\""s, ResultType::Return, "default"s }, { R"("default")"s, ResultType::Return, "default"s },
{ "\"errorReason\""s, ResultType::Return, "errorReason"s }, { R"("errorReason")"s, ResultType::Return, "errorReason"s },
{ "\"no errors\""s, ResultType::Return, "no errors"s }, { R"("no errors")"s, ResultType::Return, "no errors"s },
{ "\"scid\""s, ResultType::Return, "scid"s }, { R"("scid")"s, ResultType::Return, "scid"s },
{ "\"isAuthPayment\""s, ResultType::Return, "isAuthPayment"s }, { R"("isAuthPayment")"s, ResultType::Return, "isAuthPayment"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"rubric\""s, ResultType::Return, "rubric"s }, { R"("rubric")"s, ResultType::Return, "rubric"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"rubric\""s, ResultType::Return, "rubric"s }, { R"("rubric")"s, ResultType::Return, "rubric"s },
{ "\"Мир\""s, ResultType::Return, "Мир"s }, { R"("Мир")"s, ResultType::Return, "Мир"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"__ym\""s, ResultType::Return, "__ym"s }, { R"("__ym")"s, ResultType::Return, "__ym"s },
{ "\"ecommerce\""s, ResultType::Return, "ecommerce"s }, { R"("ecommerce")"s, ResultType::Return, "ecommerce"s },
{ "\"impressions\""s, ResultType::Return, "impressions"s }, { R"("impressions")"s, ResultType::Return, "impressions"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"863813\""s, ResultType::Return, "863813"s }, { R"("863813")"s, ResultType::Return, "863813"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Happy, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Happy, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Happy, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Happy, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"863839\""s, ResultType::Return, "863839"s }, { R"("863839")"s, ResultType::Return, "863839"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"863847\""s, ResultType::Return, "863847"s }, { R"("863847")"s, ResultType::Return, "863847"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911480\""s, ResultType::Return, "911480"s }, { R"("911480")"s, ResultType::Return, "911480"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Puppy, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Puppy, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Puppy, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Puppy, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911484\""s, ResultType::Return, "911484"s }, { R"("911484")"s, ResultType::Return, "911484"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Little bears, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Little bears, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Little bears, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Little bears, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911489\""s, ResultType::Return, "911489"s }, { R"("911489")"s, ResultType::Return, "911489"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж"s }, { R"("Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911496\""s, ResultType::Return, "911496"s }, { R"("911496")"s, ResultType::Return, "911496"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Pretty, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Pretty, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Pretty, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Pretty, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911504\""s, ResultType::Return, "911504"s }, { R"("911504")"s, ResultType::Return, "911504"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911508\""s, ResultType::Return, "911508"s }, { R"("911508")"s, ResultType::Return, "911508"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Kittens, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Kittens, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Kittens, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Kittens, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911512\""s, ResultType::Return, "911512"s }, { R"("911512")"s, ResultType::Return, "911512"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911516\""s, ResultType::Return, "911516"s }, { R"("911516")"s, ResultType::Return, "911516"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911520\""s, ResultType::Return, "911520"s }, { R"("911520")"s, ResultType::Return, "911520"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911524\""s, ResultType::Return, "911524"s }, { R"("911524")"s, ResultType::Return, "911524"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"911528\""s, ResultType::Return, "911528"s }, { R"("911528")"s, ResultType::Return, "911528"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Футболка детская 3D Turtle, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Turtle, возраст 1-2 года, трикотаж"s }, { R"("Футболка детская 3D Turtle, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Turtle, возраст 1-2 года, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"390.00\""s, ResultType::Return, "390.00"s }, { R"("390.00")"s, ResultType::Return, "390.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"888616\""s, ResultType::Return, "888616"s }, { R"("888616")"s, ResultType::Return, "888616"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"3Д Футболка мужская \\\"Collorista\\\" Светлое завтра р-р XL(52-54), 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка мужская \"Collorista\" Светлое завтра р-р XL(52-54), 100% хлопок, трикотаж"s }, { "\"3Д Футболка мужская \\\"Collorista\\\" Светлое завтра р-р XL(52-54), 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка мужская \"Collorista\" Светлое завтра р-р XL(52-54), 100% хлопок, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Одежда и обувь/Мужская одежда/Футболки/\""s, ResultType::Return, "/Одежда и обувь/Мужская одежда/Футболки/"s }, { R"("/Одежда и обувь/Мужская одежда/Футболки/")"s, ResultType::Return, "/Одежда и обувь/Мужская одежда/Футболки/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"406.60\""s, ResultType::Return, "406.60"s }, { R"("406.60")"s, ResultType::Return, "406.60"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"913361\""s, ResultType::Return, "913361"s }, { R"("913361")"s, ResultType::Return, "913361"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж"s }, { R"("3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"470.00\""s, ResultType::Return, "470.00"s }, { R"("470.00")"s, ResultType::Return, "470.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"913364\""s, ResultType::Return, "913364"s }, { R"("913364")"s, ResultType::Return, "913364"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж"s }, { R"("3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"470.00\""s, ResultType::Return, "470.00"s }, { R"("470.00")"s, ResultType::Return, "470.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"913367\""s, ResultType::Return, "913367"s }, { R"("913367")"s, ResultType::Return, "913367"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж"s }, { R"("3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"470.00\""s, ResultType::Return, "470.00"s }, { R"("470.00")"s, ResultType::Return, "470.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"913385\""s, ResultType::Return, "913385"s }, { R"("913385")"s, ResultType::Return, "913385"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж"s }, { R"("3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"470.00\""s, ResultType::Return, "470.00"s }, { R"("470.00")"s, ResultType::Return, "470.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"913391\""s, ResultType::Return, "913391"s }, { R"("913391")"s, ResultType::Return, "913391"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж"s }, { R"("3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s }, { R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"\""s, ResultType::Return, ""s }, { R"("")"s, ResultType::Return, ""s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"470.00\""s, ResultType::Return, "470.00"s }, { R"("470.00")"s, ResultType::Return, "470.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s }, { R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/\""s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s }, { R"("/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/")"s, ResultType::Return, "/911488/futbolka-detskaya-3d-dolphin-vozrast-1-2-goda-trikotazh/"s },
{ "\"usertype\""s, ResultType::Return, "usertype"s }, { R"("usertype")"s, ResultType::Return, "usertype"s },
{ "\"visitor\""s, ResultType::Return, "visitor"s }, { R"("visitor")"s, ResultType::Return, "visitor"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"__ym\""s, ResultType::Return, "__ym"s }, { R"("__ym")"s, ResultType::Return, "__ym"s },
{ "\"ecommerce\""s, ResultType::Return, "ecommerce"s }, { R"("ecommerce")"s, ResultType::Return, "ecommerce"s },
{ "\"impressions\""s, ResultType::Return, "impressions"s }, { R"("impressions")"s, ResultType::Return, "impressions"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"experiments\""s, ResultType::Return, "experiments"s }, { R"("experiments")"s, ResultType::Return, "experiments"s },
{ "\"lang\""s, ResultType::Return, "lang"s }, { R"("lang")"s, ResultType::Return, "lang"s },
{ "\"ru\""s, ResultType::Return, "ru"s }, { R"("ru")"s, ResultType::Return, "ru"s },
{ "\"los_portal\""s, ResultType::Return, "los_portal"s }, { R"("los_portal")"s, ResultType::Return, "los_portal"s },
{ "\"los_level\""s, ResultType::Return, "los_level"s }, { R"("los_level")"s, ResultType::Return, "los_level"s },
{ "\"none\""s, ResultType::Return, "none"s }, { R"("none")"s, ResultType::Return, "none"s },
{ "\"__ym\""s, ResultType::Return, "__ym"s }, { R"("__ym")"s, ResultType::Return, "__ym"s },
{ "\"ecommerce\""s, ResultType::Return, "ecommerce"s }, { R"("ecommerce")"s, ResultType::Return, "ecommerce"s },
{ "\"currencyCode\""s, ResultType::Return, "currencyCode"s }, { R"("currencyCode")"s, ResultType::Return, "currencyCode"s },
{ "\"RUR\""s, ResultType::Return, "RUR"s }, { R"("RUR")"s, ResultType::Return, "RUR"s },
{ "\"impressions\""s, ResultType::Return, "impressions"s }, { R"("impressions")"s, ResultType::Return, "impressions"s },
{ "\"name\""s, ResultType::Return, "name"s }, { R"("name")"s, ResultType::Return, "name"s },
{ "\"Чайник электрический Mystery MEK-1627, белый\""s, ResultType::Return, "Чайник электрический Mystery MEK-1627, белый"s }, { R"("Чайник электрический Mystery MEK-1627, белый")"s, ResultType::Return, "Чайник электрический Mystery MEK-1627, белый"s },
{ "\"brand\""s, ResultType::Return, "brand"s }, { R"("brand")"s, ResultType::Return, "brand"s },
{ "\"Mystery\""s, ResultType::Return, "Mystery"s }, { R"("Mystery")"s, ResultType::Return, "Mystery"s },
{ "\"id\""s, ResultType::Return, "id"s }, { R"("id")"s, ResultType::Return, "id"s },
{ "\"187180\""s, ResultType::Return, "187180"s }, { R"("187180")"s, ResultType::Return, "187180"s },
{ "\"category\""s, ResultType::Return, "category"s }, { R"("category")"s, ResultType::Return, "category"s },
{ "\"Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery\""s, ResultType::Return, "Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery"s }, { R"("Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery")"s, ResultType::Return, "Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery"s },
{ "\"variant\""s, ResultType::Return, "variant"s }, { R"("variant")"s, ResultType::Return, "variant"s },
{ "\"В наличии\""s, ResultType::Return, "В наличии"s }, { R"("В наличии")"s, ResultType::Return, "В наличии"s },
{ "\"price\""s, ResultType::Return, "price"s }, { R"("price")"s, ResultType::Return, "price"s },
{ "\"1630.00\""s, ResultType::Return, "1630.00"s }, { R"("1630.00")"s, ResultType::Return, "1630.00"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\"Карточка\""s, ResultType::Return, "Карточка"s }, { R"("Карточка")"s, ResultType::Return, "Карточка"s },
{ "\"position\""s, ResultType::Return, "position"s }, { R"("position")"s, ResultType::Return, "position"s },
{ "\"detail\""s, ResultType::Return, "detail"s }, { R"("detail")"s, ResultType::Return, "detail"s },
{ "\"actionField\""s, ResultType::Return, "actionField"s }, { R"("actionField")"s, ResultType::Return, "actionField"s },
{ "\"list\""s, ResultType::Return, "list"s }, { R"("list")"s, ResultType::Return, "list"s },
{ "\0\""s, ResultType::Throw, "JSON: expected \", got \0"s }, { "\0\""s, ResultType::Throw, "JSON: expected \", got \0"s },
{ "\"/igrushki/konstruktory\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, { "\"/igrushki/konstruktory\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/1290414/komplekt-zhenskiy-dzhemper-plusbryuki-m-254-09-malina-plustemno-siniy-\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, { "\"/1290414/komplekt-zhenskiy-dzhemper-plusbryuki-m-254-09-malina-plustemno-siniy-\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },

View File

@ -1,5 +1,3 @@
#define BOOST_TEST_MODULE StrongTypedef
#include <common/strong_typedef.h> #include <common/strong_typedef.h>
#include <set> #include <set>
#include <unordered_set> #include <unordered_set>
@ -12,15 +10,15 @@
TEST(StrongTypedefSuite, TypedefsOfTheSameType) TEST(StrongTypedefSuite, TypedefsOfTheSameType)
{ {
/// check that strong typedefs of same type differ /// check that strong typedefs of same type differ
STRONG_TYPEDEF(int, Int); STRONG_TYPEDEF(int, Int)
STRONG_TYPEDEF(int, AnotherInt); STRONG_TYPEDEF(int, AnotherInt)
EXPECT_TRUE(!(std::is_same<Int, AnotherInt>::value)); EXPECT_TRUE(!(std::is_same<Int, AnotherInt>::value));
} }
TEST(StrongTypedefSuite, Map) TEST(StrongTypedefSuite, Map)
{ {
STRONG_TYPEDEF(int, Int); STRONG_TYPEDEF(int, Int)
/// check that this code compiles /// check that this code compiles
std::set<Int> int_set; std::set<Int> int_set;
@ -31,13 +29,13 @@ TEST(StrongTypedefSuite, Map)
TEST(StrongTypedefSuite, CopyAndMoveCtor) TEST(StrongTypedefSuite, CopyAndMoveCtor)
{ {
STRONG_TYPEDEF(int, Int); STRONG_TYPEDEF(int, Int)
Int a(1); Int a(1);
Int b(2); Int b(2);
a = b; a = b;
EXPECT_EQ(a.toUnderType(), 2); EXPECT_EQ(a.toUnderType(), 2);
STRONG_TYPEDEF(std::unique_ptr<int>, IntPtr); STRONG_TYPEDEF(std::unique_ptr<int>, IntPtr)
{ {
IntPtr ptr; IntPtr ptr;
ptr = IntPtr(std::make_unique<int>(3)); ptr = IntPtr(std::make_unique<int>(3));
@ -54,9 +52,9 @@ TEST(StrongTypedefSuite, NoDefaultCtor)
{ {
struct NoDefaultCtor struct NoDefaultCtor
{ {
NoDefaultCtor(int i) {} NoDefaultCtor(int) {} // NOLINT
}; };
STRONG_TYPEDEF(NoDefaultCtor, MyStruct); STRONG_TYPEDEF(NoDefaultCtor, MyStruct)
MyStruct m(1); MyStruct m(1);
} }

View File

@ -4,4 +4,6 @@
#if defined (OS_DARWIN) #if defined (OS_DARWIN)
# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC # define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
#elif defined (OS_FREEBSD)
# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
#endif #endif

62
base/common/types.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include <algorithm>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <type_traits>
using Int8 = int8_t;
using Int16 = int16_t;
using Int32 = int32_t;
using Int64 = int64_t;
#if __cplusplus <= 201703L
using char8_t = unsigned char;
#endif
using UInt8 = char8_t;
using UInt16 = uint16_t;
using UInt32 = uint32_t;
using UInt64 = uint64_t;
using String = std::string;
/// The standard library type traits, such as std::is_arithmetic, with one exception
/// (std::common_type), are "set in stone". Attempting to specialize them causes undefined behavior.
/// So instead of using the std type_traits, we use our own version which allows extension.
template <typename T>
struct is_signed
{
static constexpr bool value = std::is_signed_v<T>;
};
template <typename T>
inline constexpr bool is_signed_v = is_signed<T>::value;
template <typename T>
struct is_unsigned
{
static constexpr bool value = std::is_unsigned_v<T>;
};
template <typename T>
inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
template <typename T>
struct is_integral
{
static constexpr bool value = std::is_integral_v<T>;
};
template <typename T>
inline constexpr bool is_integral_v = is_integral<T>::value;
template <typename T>
struct is_arithmetic
{
static constexpr bool value = std::is_arithmetic_v<T>;
};
template <typename T>
inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;

51
base/common/ya.make Normal file
View File

@ -0,0 +1,51 @@
LIBRARY()
ADDINCL(
GLOBAL clickhouse/base
contrib/libs/cctz/include
)
CFLAGS (GLOBAL -DARCADIA_BUILD)
CFLAGS (GLOBAL -DUSE_CPUID=1)
CFLAGS (GLOBAL -DUSE_JEMALLOC=0)
CFLAGS (GLOBAL -DUSE_RAPIDJSON=1)
IF (OS_DARWIN)
CFLAGS (GLOBAL -DOS_DARWIN)
ELSEIF (OS_FREEBSD)
CFLAGS (GLOBAL -DOS_FREEBSD)
ELSEIF (OS_LINUX)
CFLAGS (GLOBAL -DOS_LINUX)
ENDIF ()
PEERDIR(
contrib/libs/cctz/src
contrib/libs/cxxsupp/libcxx-filesystem
contrib/libs/poco/Net
contrib/libs/poco/Util
contrib/restricted/boost
contrib/restricted/cityhash-1.0.2
)
SRCS(
argsToConfig.cpp
coverage.cpp
DateLUT.cpp
DateLUTImpl.cpp
demangle.cpp
getFQDNOrHostName.cpp
getMemoryAmount.cpp
getThreadId.cpp
JSON.cpp
LineReader.cpp
mremap.cpp
phdr_cache.cpp
preciseExp10.cpp
setTerminalEcho.cpp
shift10.cpp
sleep.cpp
terminalColors.cpp
)
END()

View File

@ -12,7 +12,6 @@
#include <unistd.h> #include <unistd.h>
#include <typeinfo> #include <typeinfo>
#include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -51,11 +50,14 @@
#include <Common/getMultipleKeysFromConfig.h> #include <Common/getMultipleKeysFromConfig.h>
#include <Common/ClickHouseRevision.h> #include <Common/ClickHouseRevision.h>
#include <Common/Config/ConfigProcessor.h> #include <Common/Config/ConfigProcessor.h>
#include <Common/config_version.h>
#ifdef __APPLE__ #if !defined(ARCADIA_BUILD)
// ucontext is not available without _XOPEN_SOURCE # include <Common/config_version.h>
#define _XOPEN_SOURCE 700 #endif
#if defined(OS_DARWIN)
# pragma GCC diagnostic ignored "-Wunused-macros"
# define _XOPEN_SOURCE 700 // ucontext is not available without _XOPEN_SOURCE
#endif #endif
#include <ucontext.h> #include <ucontext.h>
@ -75,7 +77,7 @@ static void call_default_signal_handler(int sig)
static constexpr size_t max_query_id_size = 127; static constexpr size_t max_query_id_size = 127;
static const size_t buf_size = static const size_t signal_pipe_buf_size =
sizeof(int) sizeof(int)
+ sizeof(siginfo_t) + sizeof(siginfo_t)
+ sizeof(ucontext_t) + sizeof(ucontext_t)
@ -88,19 +90,23 @@ using signal_function = void(int, siginfo_t*, void*);
static void writeSignalIDtoSignalPipe(int sig) static void writeSignalIDtoSignalPipe(int sig)
{ {
char buf[buf_size]; auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
DB::WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], buf_size, buf);
char buf[signal_pipe_buf_size];
DB::WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf);
DB::writeBinary(sig, out); DB::writeBinary(sig, out);
out.next(); out.next();
errno = saved_errno;
} }
/** Signal handler for HUP / USR1 */ /** Signal handler for HUP / USR1 */
static void closeLogsSignalHandler(int sig, siginfo_t * info, void * context) static void closeLogsSignalHandler(int sig, siginfo_t *, void *)
{ {
writeSignalIDtoSignalPipe(sig); writeSignalIDtoSignalPipe(sig);
} }
static void terminateRequestedSignalHandler(int sig, siginfo_t * info, void * context) static void terminateRequestedSignalHandler(int sig, siginfo_t *, void *)
{ {
writeSignalIDtoSignalPipe(sig); writeSignalIDtoSignalPipe(sig);
} }
@ -110,8 +116,10 @@ static void terminateRequestedSignalHandler(int sig, siginfo_t * info, void * co
*/ */
static void signalHandler(int sig, siginfo_t * info, void * context) static void signalHandler(int sig, siginfo_t * info, void * context)
{ {
char buf[buf_size]; auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], buf_size, buf);
char buf[signal_pipe_buf_size];
DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf);
const ucontext_t signal_context = *reinterpret_cast<ucontext_t *>(context); const ucontext_t signal_context = *reinterpret_cast<ucontext_t *>(context);
const StackTrace stack_trace(signal_context); const StackTrace stack_trace(signal_context);
@ -134,6 +142,8 @@ static void signalHandler(int sig, siginfo_t * info, void * context)
::sleep(10); ::sleep(10);
call_default_signal_handler(sig); call_default_signal_handler(sig);
} }
errno = saved_errno;
} }
@ -157,15 +167,20 @@ public:
{ {
} }
void run() void run() override
{ {
char buf[buf_size]; char buf[signal_pipe_buf_size];
DB::ReadBufferFromFileDescriptor in(signal_pipe.fds_rw[0], buf_size, buf); DB::ReadBufferFromFileDescriptor in(signal_pipe.fds_rw[0], signal_pipe_buf_size, buf);
while (!in.eof()) while (!in.eof())
{ {
int sig = 0; int sig = 0;
DB::readBinary(sig, in); DB::readBinary(sig, in);
// We may log some specific signals afterwards, with different log
// levels and more info, but for completeness we log all signals
// here at trace level.
// Don't use strsignal here, because it's not thread-safe.
LOG_TRACE(log, "Received signal " << sig);
if (sig == Signals::StopThread) if (sig == Signals::StopThread)
{ {
@ -219,7 +234,6 @@ private:
Logger * log; Logger * log;
BaseDaemon & daemon; BaseDaemon & daemon;
private:
void onTerminate(const std::string & message, UInt32 thread_num) const void onTerminate(const std::string & message, UInt32 thread_num) const
{ {
LOG_FATAL(log, "(version " << VERSION_STRING << VERSION_OFFICIAL << ") (from thread " << thread_num << ") " << message); LOG_FATAL(log, "(version " << VERSION_STRING << VERSION_OFFICIAL << ") (from thread " << thread_num << ") " << message);
@ -269,19 +283,56 @@ private:
}; };
#if defined(SANITIZER)
extern "C" void __sanitizer_set_death_callback(void (*)());
static void sanitizerDeathCallback()
{
Logger * log = &Logger::get("BaseDaemon");
StringRef query_id = CurrentThread::getQueryId(); /// This is signal safe.
{
std::stringstream message;
message << "(version " << VERSION_STRING << VERSION_OFFICIAL << ")";
message << " (from thread " << getThreadId() << ")";
if (query_id.size == 0)
message << " (no query)";
else
message << " (query_id: " << query_id << ")";
message << " Sanitizer trap.";
LOG_FATAL(log, message.rdbuf());
}
/// Just in case print our own stack trace. In case when llvm-symbolizer does not work.
StackTrace stack_trace;
if (stack_trace.getSize())
{
std::stringstream bare_stacktrace;
bare_stacktrace << "Stack trace:";
for (size_t i = stack_trace.getOffset(); i < stack_trace.getSize(); ++i)
bare_stacktrace << ' ' << stack_trace.getFrames()[i];
LOG_FATAL(log, bare_stacktrace.rdbuf());
}
/// Write symbolized stack trace line by line for better grep-ability.
stack_trace.toStringEveryLine([&](const std::string & s) { LOG_FATAL(log, s); });
}
#endif
/** To use with std::set_terminate. /** To use with std::set_terminate.
* Collects slightly more info than __gnu_cxx::__verbose_terminate_handler, * Collects slightly more info than __gnu_cxx::__verbose_terminate_handler,
* and send it to pipe. Other thread will read this info from pipe and asynchronously write it to log. * and send it to pipe. Other thread will read this info from pipe and asynchronously write it to log.
* Look at libstdc++-v3/libsupc++/vterminate.cc for example. * Look at libstdc++-v3/libsupc++/vterminate.cc for example.
*/ */
static void terminate_handler() [[noreturn]] static void terminate_handler()
{ {
static thread_local bool terminating = false; static thread_local bool terminating = false;
if (terminating) if (terminating)
{
abort(); abort();
return; /// Just for convenience.
}
terminating = true; terminating = true;
@ -354,10 +405,7 @@ void BaseDaemon::reloadConfiguration()
} }
BaseDaemon::BaseDaemon() BaseDaemon::BaseDaemon() = default;
{
checkRequiredInstructions();
}
BaseDaemon::~BaseDaemon() BaseDaemon::~BaseDaemon()
@ -368,127 +416,6 @@ BaseDaemon::~BaseDaemon()
} }
enum class InstructionFail
{
NONE = 0,
SSE3 = 1,
SSSE3 = 2,
SSE4_1 = 3,
SSE4_2 = 4,
AVX = 5,
AVX2 = 6,
AVX512 = 7
};
static std::string instructionFailToString(InstructionFail fail)
{
switch (fail)
{
case InstructionFail::NONE:
return "NONE";
case InstructionFail::SSE3:
return "SSE3";
case InstructionFail::SSSE3:
return "SSSE3";
case InstructionFail::SSE4_1:
return "SSE4.1";
case InstructionFail::SSE4_2:
return "SSE4.2";
case InstructionFail::AVX:
return "AVX";
case InstructionFail::AVX2:
return "AVX2";
case InstructionFail::AVX512:
return "AVX512";
}
__builtin_unreachable();
}
static sigjmp_buf jmpbuf;
static void sigIllCheckHandler(int sig, siginfo_t * info, void * context)
{
siglongjmp(jmpbuf, 1);
}
/// Check if necessary sse extensions are available by trying to execute some sse instructions.
/// If instruction is unavailable, SIGILL will be sent by kernel.
static void checkRequiredInstructions(volatile InstructionFail & fail)
{
#if __SSE3__
fail = InstructionFail::SSE3;
__asm__ volatile ("addsubpd %%xmm0, %%xmm0" : : : "xmm0");
#endif
#if __SSSE3__
fail = InstructionFail::SSSE3;
__asm__ volatile ("pabsw %%xmm0, %%xmm0" : : : "xmm0");
#endif
#if __SSE4_1__
fail = InstructionFail::SSE4_1;
__asm__ volatile ("pmaxud %%xmm0, %%xmm0" : : : "xmm0");
#endif
#if __SSE4_2__
fail = InstructionFail::SSE4_2;
__asm__ volatile ("pcmpgtq %%xmm0, %%xmm0" : : : "xmm0");
#endif
#if __AVX__
fail = InstructionFail::AVX;
__asm__ volatile ("vaddpd %%ymm0, %%ymm0, %%ymm0" : : : "ymm0");
#endif
#if __AVX2__
fail = InstructionFail::AVX2;
__asm__ volatile ("vpabsw %%ymm0, %%ymm0" : : : "ymm0");
#endif
#if __AVX512__
fail = InstructionFail::AVX512;
__asm__ volatile ("vpabsw %%zmm0, %%zmm0" : : : "zmm0");
#endif
fail = InstructionFail::NONE;
}
void BaseDaemon::checkRequiredInstructions()
{
struct sigaction sa{};
struct sigaction sa_old{};
sa.sa_sigaction = sigIllCheckHandler;
sa.sa_flags = SA_SIGINFO;
auto signal = SIGILL;
if (sigemptyset(&sa.sa_mask) != 0
|| sigaddset(&sa.sa_mask, signal) != 0
|| sigaction(signal, &sa, &sa_old) != 0)
{
std::cerr << "Can not set signal handler\n";
exit(1);
}
volatile InstructionFail fail = InstructionFail::NONE;
if (sigsetjmp(jmpbuf, 1))
{
std::cerr << "Instruction check fail. There is no " << instructionFailToString(fail) << " instruction set\n";
exit(1);
}
::checkRequiredInstructions(fail);
if (sigaction(signal, &sa_old, nullptr))
{
std::cerr << "Can not set signal handler\n";
exit(1);
}
}
void BaseDaemon::terminate() void BaseDaemon::terminate()
{ {
getTaskManager().cancelAll(); getTaskManager().cancelAll();
@ -522,7 +449,7 @@ std::string BaseDaemon::getDefaultCorePath() const
void BaseDaemon::closeFDs() void BaseDaemon::closeFDs()
{ {
#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__)) #if defined(OS_FREEBSD) || defined(OS_DARWIN)
Poco::File proc_path{"/dev/fd"}; Poco::File proc_path{"/dev/fd"};
#else #else
Poco::File proc_path{"/proc/self/fd"}; Poco::File proc_path{"/proc/self/fd"};
@ -542,7 +469,7 @@ void BaseDaemon::closeFDs()
else else
{ {
int max_fd = -1; int max_fd = -1;
#ifdef _SC_OPEN_MAX #if defined(_SC_OPEN_MAX)
max_fd = sysconf(_SC_OPEN_MAX); max_fd = sysconf(_SC_OPEN_MAX);
if (max_fd == -1) if (max_fd == -1)
#endif #endif
@ -560,7 +487,7 @@ namespace
/// the maximum is 1000, and chromium uses 300 for its tab processes. Ignore /// the maximum is 1000, and chromium uses 300 for its tab processes. Ignore
/// whatever errors that occur, because it's just a debugging aid and we don't /// whatever errors that occur, because it's just a debugging aid and we don't
/// care if it breaks. /// care if it breaks.
#if defined(__linux__) && !defined(NDEBUG) #if defined(OS_LINUX) && !defined(NDEBUG)
void debugIncreaseOOMScore() void debugIncreaseOOMScore()
{ {
const std::string new_score = "555"; const std::string new_score = "555";
@ -585,7 +512,7 @@ void debugIncreaseOOMScore() {}
void BaseDaemon::initialize(Application & self) void BaseDaemon::initialize(Application & self)
{ {
closeFDs(); closeFDs();
task_manager.reset(new Poco::TaskManager); task_manager = std::make_unique<Poco::TaskManager>();
ServerApplication::initialize(self); ServerApplication::initialize(self);
/// now highest priority (lowest value) is PRIO_APPLICATION = -100, we want higher! /// now highest priority (lowest value) is PRIO_APPLICATION = -100, we want higher!
@ -635,12 +562,12 @@ void BaseDaemon::initialize(Application & self)
/// This must be done before any usage of DateLUT. In particular, before any logging. /// This must be done before any usage of DateLUT. In particular, before any logging.
if (config().has("timezone")) if (config().has("timezone"))
{ {
const std::string timezone = config().getString("timezone"); const std::string config_timezone = config().getString("timezone");
if (0 != setenv("TZ", timezone.data(), 1)) if (0 != setenv("TZ", config_timezone.data(), 1))
throw Poco::Exception("Cannot setenv TZ variable"); throw Poco::Exception("Cannot setenv TZ variable");
tzset(); tzset();
DateLUT::setDefaultTimezone(timezone); DateLUT::setDefaultTimezone(config_timezone);
} }
std::string log_path = config().getString("logger.log", ""); std::string log_path = config().getString("logger.log", "");
@ -658,6 +585,9 @@ void BaseDaemon::initialize(Application & self)
std::string stderr_path = config().getString("logger.stderr", log_path + "/stderr.log"); std::string stderr_path = config().getString("logger.stderr", log_path + "/stderr.log");
if (!freopen(stderr_path.c_str(), "a+", stderr)) if (!freopen(stderr_path.c_str(), "a+", stderr))
throw Poco::OpenFileException("Cannot attach stderr to " + stderr_path); throw Poco::OpenFileException("Cannot attach stderr to " + stderr_path);
/// Disable buffering for stderr
setbuf(stderr, nullptr);
} }
if ((!log_path.empty() && is_daemon) || config().has("logger.stdout")) if ((!log_path.empty() && is_daemon) || config().has("logger.stdout"))
@ -744,12 +674,18 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
{ {
#if defined(OS_DARWIN)
sigemptyset(&sa.sa_mask);
for (auto signal : signals)
sigaddset(&sa.sa_mask, signal);
#else
if (sigemptyset(&sa.sa_mask)) if (sigemptyset(&sa.sa_mask))
throw Poco::Exception("Cannot set signal handler."); throw Poco::Exception("Cannot set signal handler.");
for (auto signal : signals) for (auto signal : signals)
if (sigaddset(&sa.sa_mask, signal)) if (sigaddset(&sa.sa_mask, signal))
throw Poco::Exception("Cannot set signal handler."); throw Poco::Exception("Cannot set signal handler.");
#endif
for (auto signal : signals) for (auto signal : signals)
if (sigaction(signal, &sa, nullptr)) if (sigaction(signal, &sa, nullptr))
@ -763,6 +699,10 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
add_signal_handler({SIGHUP, SIGUSR1}, closeLogsSignalHandler); add_signal_handler({SIGHUP, SIGUSR1}, closeLogsSignalHandler);
add_signal_handler({SIGINT, SIGQUIT, SIGTERM}, terminateRequestedSignalHandler); add_signal_handler({SIGINT, SIGQUIT, SIGTERM}, terminateRequestedSignalHandler);
#if defined(SANITIZER)
__sanitizer_set_death_callback(sanitizerDeathCallback);
#endif
/// Set up Poco ErrorHandler for Poco Threads. /// Set up Poco ErrorHandler for Poco Threads.
static KillingErrorHandler killing_error_handler; static KillingErrorHandler killing_error_handler;
Poco::ErrorHandler::set(&killing_error_handler); Poco::ErrorHandler::set(&killing_error_handler);
@ -770,13 +710,15 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
signal_pipe.setNonBlocking(); signal_pipe.setNonBlocking();
signal_pipe.tryIncreaseSize(1 << 20); signal_pipe.tryIncreaseSize(1 << 20);
signal_listener.reset(new SignalListener(*this)); signal_listener = std::make_unique<SignalListener>(*this);
signal_listener_thread.start(*signal_listener); signal_listener_thread.start(*signal_listener);
} }
void BaseDaemon::logRevision() const void BaseDaemon::logRevision() const
{ {
Logger::root().information("Starting " + std::string{VERSION_FULL} + " with revision " + std::to_string(ClickHouseRevision::get())); Logger::root().information("Starting " + std::string{VERSION_FULL}
+ " with revision " + std::to_string(ClickHouseRevision::get())
+ ", PID " + std::to_string(getpid()));
} }
/// Makes server shutdown if at least one Poco::Task have failed. /// Makes server shutdown if at least one Poco::Task have failed.
@ -796,44 +738,42 @@ void BaseDaemon::handleNotification(Poco::TaskFailedNotification *_tfn)
ServerApplication::terminate(); ServerApplication::terminate();
} }
void BaseDaemon::defineOptions(Poco::Util::OptionSet& _options) void BaseDaemon::defineOptions(Poco::Util::OptionSet & new_options)
{ {
Poco::Util::ServerApplication::defineOptions (_options); new_options.addOption(
_options.addOption(
Poco::Util::Option("config-file", "C", "load configuration from a given file") Poco::Util::Option("config-file", "C", "load configuration from a given file")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("<file>") .argument("<file>")
.binding("config-file")); .binding("config-file"));
_options.addOption( new_options.addOption(
Poco::Util::Option("log-file", "L", "use given log file") Poco::Util::Option("log-file", "L", "use given log file")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("<file>") .argument("<file>")
.binding("logger.log")); .binding("logger.log"));
_options.addOption( new_options.addOption(
Poco::Util::Option("errorlog-file", "E", "use given log file for errors only") Poco::Util::Option("errorlog-file", "E", "use given log file for errors only")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("<file>") .argument("<file>")
.binding("logger.errorlog")); .binding("logger.errorlog"));
_options.addOption( new_options.addOption(
Poco::Util::Option("pid-file", "P", "use given pidfile") Poco::Util::Option("pid-file", "P", "use given pidfile")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("<file>") .argument("<file>")
.binding("pid")); .binding("pid"));
Poco::Util::ServerApplication::defineOptions(new_options);
} }
bool isPidRunning(pid_t pid) bool isPidRunning(pid_t pid)
{ {
if (getpgid(pid) >= 0) return getpgid(pid) >= 0;
return 1;
return 0;
} }
BaseDaemon::PID::PID(const std::string & file_) BaseDaemon::PID::PID(const std::string & file_)

View File

@ -17,7 +17,7 @@
#include <Poco/Util/ServerApplication.h> #include <Poco/Util/ServerApplication.h>
#include <Poco/Net/SocketAddress.h> #include <Poco/Net/SocketAddress.h>
#include <Poco/Version.h> #include <Poco/Version.h>
#include <common/Types.h> #include <common/types.h>
#include <common/logger_useful.h> #include <common/logger_useful.h>
#include <common/getThreadId.h> #include <common/getThreadId.h>
#include <daemon/GraphiteWriter.h> #include <daemon/GraphiteWriter.h>
@ -58,7 +58,7 @@ public:
void reloadConfiguration(); void reloadConfiguration();
/// Определяет параметр командной строки /// Определяет параметр командной строки
void defineOptions(Poco::Util::OptionSet & _options) override; void defineOptions(Poco::Util::OptionSet & new_options) override;
/// Заставляет демон завершаться, если хотя бы одна задача завершилась неудачно /// Заставляет демон завершаться, если хотя бы одна задача завершилась неудачно
void exitOnTaskError(); void exitOnTaskError();
@ -128,7 +128,7 @@ public:
/// close all process FDs except /// close all process FDs except
/// 0-2 -- stdin, stdout, stderr /// 0-2 -- stdin, stdout, stderr
/// also doesn't close global internal pipes for signal handling /// also doesn't close global internal pipes for signal handling
void closeFDs(); static void closeFDs();
protected: protected:
/// Возвращает TaskManager приложения /// Возвращает TaskManager приложения
@ -198,12 +198,6 @@ protected:
std::string config_path; std::string config_path;
DB::ConfigProcessor::LoadedConfig loaded_config; DB::ConfigProcessor::LoadedConfig loaded_config;
Poco::Util::AbstractConfiguration * last_configuration = nullptr; Poco::Util::AbstractConfiguration * last_configuration = nullptr;
private:
/// Check SSE and others instructions availability
/// Calls exit on fail
void checkRequiredInstructions();
}; };

View File

@ -1,11 +1,7 @@
add_library (daemon add_library (daemon
src/BaseDaemon.cpp BaseDaemon.cpp
src/GraphiteWriter.cpp GraphiteWriter.cpp
include/daemon/BaseDaemon.h
include/daemon/GraphiteWriter.h
) )
target_include_directories (daemon PUBLIC include) target_include_directories (daemon PUBLIC ..)
target_link_libraries (daemon PUBLIC loggers PRIVATE clickhouse_common_io clickhouse_common_config common ${EXECINFO_LIBRARIES})
target_link_libraries (daemon PUBLIC loggers PRIVATE clickhouse_common_io clickhouse_common_config common ${Poco_Net_LIBRARY} ${Poco_Util_LIBRARY} ${EXECINFO_LIBRARIES})

View File

@ -2,7 +2,7 @@
#include <daemon/BaseDaemon.h> #include <daemon/BaseDaemon.h>
#include <Poco/Util/LayeredConfiguration.h> #include <Poco/Util/LayeredConfiguration.h>
#include <Poco/Util/Application.h> #include <Poco/Util/Application.h>
#include <Common/getFQDNOrHostName.h> #include <common/getFQDNOrHostName.h>
#include <mutex> #include <mutex>
#include <iomanip> #include <iomanip>
@ -30,7 +30,7 @@ GraphiteWriter::GraphiteWriter(const std::string & config_name, const std::strin
root_path += hostname_in_path; root_path += hostname_in_path;
} }
if (sub_path.size()) if (!sub_path.empty())
{ {
if (!root_path.empty()) if (!root_path.empty())
root_path += "."; root_path += ".";

14
base/daemon/ya.make Normal file
View File

@ -0,0 +1,14 @@
LIBRARY()
NO_COMPILER_WARNINGS()
PEERDIR(
clickhouse/src/Common
)
SRCS(
BaseDaemon.cpp
GraphiteWriter.cpp
)
END()

View File

@ -1,16 +1,30 @@
#pragma once #pragma once
#include <chrono> #include <chrono>
#include <ctime>
#include <string> #include <string>
#include <common/DateLUT.h> #include <iomanip>
namespace ext namespace ext
{ {
inline std::string to_string(const std::time_t & time)
{
std::stringstream ss;
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %X");
return ss.str();
}
template <typename Clock, typename Duration = typename Clock::duration> template <typename Clock, typename Duration = typename Clock::duration>
std::string to_string(const std::chrono::time_point<Clock, Duration> & tp) std::string to_string(const std::chrono::time_point<Clock, Duration> & tp)
{ {
return DateLUT::instance().timeToString(std::chrono::system_clock::to_time_t(tp)); // Don't use DateLUT because it shows weird characters for
// TimePoint::max(). I wish we could use C++20 format, but it's not
// there yet.
// return DateLUT::instance().timeToString(std::chrono::system_clock::to_time_t(tp));
auto in_time_t = std::chrono::system_clock::to_time_t(tp);
return to_string(in_time_t);
} }
template <typename Rep, typename Period = std::ratio<1>> template <typename Rep, typename Period = std::ratio<1>>

View File

@ -1,42 +1,62 @@
#pragma once #pragma once
#include <type_traits>
#include <boost/range/counting_range.hpp> #include <boost/range/counting_range.hpp>
#include <boost/range/adaptor/transformed.hpp> #include <boost/range/adaptor/transformed.hpp>
#include <type_traits>
namespace ext namespace ext
{ {
/// For loop adaptor which is used to iterate through a half-closed interval [begin, end). namespace internal
template <typename BeginType, typename EndType> {
inline auto range(BeginType begin, EndType end) template <typename ResultType, typename CountingType, typename BeginType, typename EndType>
auto rangeImpl(BeginType begin, EndType end)
{ {
using CommonType = typename std::common_type<BeginType, EndType>::type; if constexpr (std::is_same_v<ResultType, CountingType>)
return boost::counting_range<CommonType>(begin, end); return boost::counting_range<CountingType>(static_cast<CountingType>(begin), static_cast<CountingType>(end));
}
template <typename Type>
inline auto range(Type end)
{
return range<Type, Type>(static_cast<Type>(0), end);
}
/// The same as range(), but every value is casted statically to a specified `ValueType`.
/// This is useful to iterate through all constants of a enum.
template <typename ValueType, typename BeginType, typename EndType>
inline auto range_with_static_cast(BeginType begin, EndType end)
{
using CommonType = typename std::common_type<BeginType, EndType>::type;
if constexpr (std::is_same_v<ValueType, CommonType>)
return boost::counting_range<CommonType>(begin, end);
else else
return boost::counting_range<CommonType>(begin, end) return boost::counting_range<CountingType>(static_cast<CountingType>(begin), static_cast<CountingType>(end))
| boost::adaptors::transformed([](CommonType x) -> ValueType { return static_cast<ValueType>(x); }); | boost::adaptors::transformed([](CountingType x) { return static_cast<ResultType>(x); });
}
template <typename ValueType, typename EndType>
inline auto range_with_static_cast(EndType end)
{
return range_with_static_cast<ValueType, EndType, EndType>(static_cast<EndType>(0), end);
} }
} }
/// For loop adaptor which is used to iterate through a half-closed interval [begin, end).
/// The parameters `begin` and `end` can have any integral or enum types.
template <typename BeginType,
typename EndType,
typename = std::enable_if_t<
(std::is_integral_v<BeginType> || std::is_enum_v<BeginType>) &&
(std::is_integral_v<EndType> || std::is_enum_v<EndType>) &&
(!std::is_enum_v<BeginType> || !std::is_enum_v<EndType> || std::is_same_v<BeginType, EndType>), void>>
inline auto range(BeginType begin, EndType end)
{
if constexpr (std::is_integral_v<BeginType> && std::is_integral_v<EndType>)
{
using CommonType = std::common_type_t<BeginType, EndType>;
return internal::rangeImpl<CommonType, CommonType>(begin, end);
}
else if constexpr (std::is_enum_v<BeginType>)
{
return internal::rangeImpl<BeginType, std::underlying_type_t<BeginType>>(begin, end);
}
else
{
return internal::rangeImpl<EndType, std::underlying_type_t<EndType>>(begin, end);
}
}
/// For loop adaptor which is used to iterate through a half-closed interval [0, end).
/// The parameter `end` can have any integral or enum type.
/// The same as range(0, end).
template <typename Type,
typename = std::enable_if_t<std::is_integral_v<Type> || std::is_enum_v<Type>, void>>
inline auto range(Type end)
{
if constexpr (std::is_integral_v<Type>)
return internal::rangeImpl<Type, Type>(0, end);
else
return internal::rangeImpl<Type, std::underlying_type_t<Type>>(0, end);
}
}

View File

@ -12,20 +12,20 @@ class [[nodiscard]] basic_scope_guard
{ {
public: public:
constexpr basic_scope_guard() = default; constexpr basic_scope_guard() = default;
constexpr basic_scope_guard(basic_scope_guard && src) : function{std::exchange(src.function, {})} {} constexpr basic_scope_guard(basic_scope_guard && src) : function{src.release()} {}
constexpr basic_scope_guard & operator=(basic_scope_guard && src) constexpr basic_scope_guard & operator=(basic_scope_guard && src)
{ {
if (this != &src) if (this != &src)
{ {
invoke(); invoke();
function = std::exchange(src.function, {}); function = src.release();
} }
return *this; return *this;
} }
template <typename G, typename = std::enable_if_t<std::is_convertible_v<G, F>, void>> template <typename G, typename = std::enable_if_t<std::is_convertible_v<G, F>, void>>
constexpr basic_scope_guard(basic_scope_guard<G> && src) : function{std::exchange(src.function, {})} {} constexpr basic_scope_guard(basic_scope_guard<G> && src) : function{src.release()} {}
template <typename G, typename = std::enable_if_t<std::is_convertible_v<G, F>, void>> template <typename G, typename = std::enable_if_t<std::is_convertible_v<G, F>, void>>
constexpr basic_scope_guard & operator=(basic_scope_guard<G> && src) constexpr basic_scope_guard & operator=(basic_scope_guard<G> && src)
@ -33,7 +33,7 @@ public:
if (this != &src) if (this != &src)
{ {
invoke(); invoke();
function = std::exchange(src.function, {}); function = src.release();
} }
return *this; return *this;
} }
@ -46,14 +46,26 @@ public:
~basic_scope_guard() { invoke(); } ~basic_scope_guard() { invoke(); }
static constexpr bool is_nullable = std::is_constructible_v<bool, F>;
explicit operator bool() const explicit operator bool() const
{ {
if constexpr (std::is_constructible_v<bool, F>) if constexpr (is_nullable)
return static_cast<bool>(function); return static_cast<bool>(function);
return true; return true;
} }
void reset() { function = {}; } void reset()
{
invoke();
release();
}
F release()
{
static_assert(is_nullable);
return std::exchange(function, {});
}
template <typename G, typename = std::enable_if_t<std::is_convertible_v<G, F>, void>> template <typename G, typename = std::enable_if_t<std::is_convertible_v<G, F>, void>>
basic_scope_guard<F> & join(basic_scope_guard<G> && other) basic_scope_guard<F> & join(basic_scope_guard<G> && other)
@ -62,14 +74,14 @@ public:
{ {
if (function) if (function)
{ {
function = [x = std::make_shared<std::pair<F, G>>(std::move(function), std::exchange(other.function, {}))]() function = [x = std::make_shared<std::pair<F, G>>(std::move(function), other.release())]()
{ {
std::move(x->first)(); std::move(x->first)();
std::move(x->second)(); std::move(x->second)();
}; };
} }
else else
function = std::exchange(other.function, {}); function = other.release();
} }
return *this; return *this;
} }
@ -77,7 +89,7 @@ public:
private: private:
void invoke() void invoke()
{ {
if constexpr (std::is_constructible_v<bool, F>) if constexpr (is_nullable)
{ {
if (!function) if (!function)
return; return;

View File

@ -1,44 +0,0 @@
#pragma once
#include <memory>
namespace ext
{
/** Thread-unsafe singleton. It works simply like a global variable.
* Supports deinitialization.
*
* In most of the cases, you don't need this class.
* Use "Meyers Singleton" instead: static T & instance() { static T x; return x; }
*/
template <class T>
class Singleton
{
public:
Singleton()
{
if (!instance)
instance = std::make_unique<T>();
}
T * operator->()
{
return instance.get();
}
static bool isInitialized()
{
return !!instance;
}
static void reset()
{
instance.reset();
}
private:
inline static std::unique_ptr<T> instance{};
};
}

View File

@ -1,5 +1,5 @@
if (GLIBC_COMPATIBILITY) if (GLIBC_COMPATIBILITY)
set (USE_INTERNAL_MEMCPY ON) set (ENABLE_FASTMEMCPY ON)
enable_language(ASM) enable_language(ASM)
include(CheckIncludeFile) include(CheckIncludeFile)

View File

@ -0,0 +1,22 @@
#include <time.h>
#include <unistd.h>
#include "syscall.h"
int clock_getres(clockid_t clk, struct timespec *ts)
{
#ifdef SYS_clock_getres_time64
/* On a 32-bit arch, use the old syscall if it exists. */
if (SYS_clock_getres != SYS_clock_getres_time64) {
long ts32[2];
int r = __syscall(SYS_clock_getres, clk, ts32);
if (!r && ts) {
ts->tv_sec = ts32[0];
ts->tv_nsec = ts32[1];
}
return __syscall_ret(r);
}
#endif
/* If reaching this point, it's a 64-bit arch or time64-only
* 32-bit arch and we can get result directly into timespec. */
return syscall(SYS_clock_getres, clk, ts);
}

View File

@ -2,7 +2,6 @@
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <time.h>
#include "atomic.h" #include "atomic.h"
#include "musl_features.h"
#include "syscall.h" #include "syscall.h"
#ifdef VDSO_CGT_SYM #ifdef VDSO_CGT_SYM
@ -54,7 +53,7 @@ static void *volatile vdso_func = (void *)cgt_init;
#endif #endif
int __clock_gettime(clockid_t clk, struct timespec *ts) int clock_gettime(clockid_t clk, struct timespec *ts)
{ {
int r; int r;
@ -104,5 +103,3 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
return __syscall_ret(r); return __syscall_ret(r);
#endif #endif
} }
weak_alias(__clock_gettime, clock_gettime);

View File

@ -1,10 +1,9 @@
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#include "musl_features.h"
#include "syscall.h" #include "syscall.h"
int __clock_nanosleep(clockid_t clk, int flags, const struct timespec * req, struct timespec * rem) int clock_nanosleep(clockid_t clk, int flags, const struct timespec * req, struct timespec * rem)
{ {
if (clk == CLOCK_THREAD_CPUTIME_ID) if (clk == CLOCK_THREAD_CPUTIME_ID)
return EINVAL; return EINVAL;
@ -23,5 +22,3 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec * req, str
pthread_setcanceltype(old_cancel_type, NULL); pthread_setcanceltype(old_cancel_type, NULL);
return status; return status;
} }
weak_alias(__clock_nanosleep, clock_nanosleep);

View File

@ -2,7 +2,4 @@
#define weak __attribute__((__weak__)) #define weak __attribute__((__weak__))
#define hidden __attribute__((__visibility__("hidden"))) #define hidden __attribute__((__visibility__("hidden")))
#define weak_alias(old, new) \
extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))
#define predict_false(x) __builtin_expect(x, 0) #define predict_false(x) __builtin_expect(x, 0)

View File

@ -2,6 +2,7 @@
.hidden __syscall .hidden __syscall
.type __syscall,@function .type __syscall,@function
__syscall: __syscall:
.cfi_startproc
movq %rdi,%rax movq %rdi,%rax
movq %rsi,%rdi movq %rsi,%rdi
movq %rdx,%rsi movq %rdx,%rsi
@ -11,3 +12,4 @@ __syscall:
movq 8(%rsp),%r9 movq 8(%rsp),%r9
syscall syscall
ret ret
.cfi_endproc

View File

@ -1 +1,5 @@
add_subdirectory(loggers) include(${ClickHouse_SOURCE_DIR}/cmake/dbms_glob_sources.cmake)
add_headers_and_sources(loggers .)
add_library(loggers ${loggers_sources} ${loggers_headers})
target_link_libraries(loggers PRIVATE dbms clickhouse_common_io)
target_include_directories(loggers PUBLIC ..)

View File

@ -166,12 +166,29 @@ void Loggers::buildLoggers(Poco::Util::AbstractConfiguration & config, Poco::Log
logger.root().setChannel(logger.getChannel()); logger.root().setChannel(logger.getChannel());
// Explicitly specified log levels for specific loggers. // Explicitly specified log levels for specific loggers.
Poco::Util::AbstractConfiguration::Keys levels; {
config.keys("logger.levels", levels); Poco::Util::AbstractConfiguration::Keys loggers_level;
config.keys("logger.levels", loggers_level);
if (!levels.empty()) if (!loggers_level.empty())
for (const auto & level : levels) {
logger.root().get(level).setLevel(config.getString("logger.levels." + level, "trace")); for (const auto & key : loggers_level)
{
if (key == "logger" || key.starts_with("logger["))
{
const std::string name(config.getString("logger.levels." + key + ".name"));
const std::string level(config.getString("logger.levels." + key + ".level"));
logger.root().get(name).setLevel(level);
}
else
{
// Legacy syntax
const std::string level(config.getString("logger.levels." + key, "trace"));
logger.root().get(key).setLevel(level);
}
}
}
}
} }
void Loggers::closeLogs(Poco::Logger & logger) void Loggers::closeLogs(Poco::Logger & logger)

View File

@ -75,7 +75,11 @@ void OwnPatternFormatter::formatExtended(const DB::ExtendedLogMessage & msg_ext,
if (color) if (color)
writeCString(resetColor(), wb); writeCString(resetColor(), wb);
writeCString("> ", wb); writeCString("> ", wb);
if (color)
writeString(setColor(std::hash<std::string>()(msg.getSource())), wb);
DB::writeString(msg.getSource(), wb); DB::writeString(msg.getSource(), wb);
if (color)
writeCString(resetColor(), wb);
writeCString(": ", wb); writeCString(": ", wb);
DB::writeString(msg.getText(), wb); DB::writeString(msg.getText(), wb);
} }

View File

@ -20,7 +20,7 @@ void OwnSplitChannel::log(const Poco::Message & msg)
if (channels.empty() && (logs_queue == nullptr || msg.getPriority() > logs_queue->max_priority)) if (channels.empty() && (logs_queue == nullptr || msg.getPriority() > logs_queue->max_priority))
return; return;
if (auto masker = SensitiveDataMasker::getInstance()) if (auto * masker = SensitiveDataMasker::getInstance())
{ {
auto message_text = msg.getText(); auto message_text = msg.getText();
auto matches = masker->wipeSensitiveData(message_text); auto matches = masker->wipeSensitiveData(message_text);
@ -71,7 +71,8 @@ void OwnSplitChannel::logSplit(const Poco::Message & msg)
/// Also log to system.text_log table, if message is not too noisy /// Also log to system.text_log table, if message is not too noisy
if (text_log_max_priority && msg.getPriority() <= text_log_max_priority) auto text_log_max_priority_loaded = text_log_max_priority.load(std::memory_order_relaxed);
if (text_log_max_priority_loaded && msg.getPriority() <= text_log_max_priority_loaded)
{ {
TextLogElement elem; TextLogElement elem;
@ -108,7 +109,7 @@ void OwnSplitChannel::addTextLog(std::shared_ptr<DB::TextLog> log, int max_prior
{ {
std::lock_guard<std::mutex> lock(text_log_mutex); std::lock_guard<std::mutex> lock(text_log_mutex);
text_log = log; text_log = log;
text_log_max_priority = max_priority; text_log_max_priority.store(max_priority, std::memory_order_relaxed);
} }
} }

View File

@ -33,7 +33,7 @@ private:
std::mutex text_log_mutex; std::mutex text_log_mutex;
std::weak_ptr<DB::TextLog> text_log; std::weak_ptr<DB::TextLog> text_log;
int text_log_max_priority = -1; std::atomic<int> text_log_max_priority = -1;
}; };
} }

View File

@ -1,5 +0,0 @@
include(${ClickHouse_SOURCE_DIR}/cmake/dbms_glob_sources.cmake)
add_headers_and_sources(loggers .)
add_library(loggers ${loggers_sources} ${loggers_headers})
target_link_libraries(loggers PRIVATE dbms clickhouse_common_io ${Poco_Foundation_LIBRARY})
target_include_directories(loggers PUBLIC ..)

15
base/loggers/ya.make Normal file
View File

@ -0,0 +1,15 @@
LIBRARY()
PEERDIR(
clickhouse/src/Common
)
SRCS(
ExtendedLogChannel.cpp
Loggers.cpp
OwnFormattingChannel.cpp
OwnPatternFormatter.cpp
OwnSplitChannel.cpp
)
END()

View File

@ -1 +0,0 @@
add_library(memcpy memcpy.c)

View File

@ -1,697 +0,0 @@
//=====================================================================
//
// FastMemcpy.c - skywind3000@163.com, 2015
//
// feature:
// 50% speed up in avg. vs standard memcpy (tested in vc2012/gcc5.1)
//
//=====================================================================
#ifndef __FAST_MEMCPY_H__
#define __FAST_MEMCPY_H__
#include <stddef.h>
#include <stdint.h>
#include <emmintrin.h>
//---------------------------------------------------------------------
// force inline for compilers
//---------------------------------------------------------------------
#ifndef INLINE
#ifdef __GNUC__
#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
#define INLINE __inline__ __attribute__((always_inline))
#else
#define INLINE __inline__
#endif
#elif defined(_MSC_VER)
#define INLINE __forceinline
#elif (defined(__BORLANDC__) || defined(__WATCOMC__))
#define INLINE __inline
#else
#define INLINE
#endif
#endif
typedef __attribute__((__aligned__(1))) uint16_t uint16_unaligned_t;
typedef __attribute__((__aligned__(1))) uint32_t uint32_unaligned_t;
typedef __attribute__((__aligned__(1))) uint64_t uint64_unaligned_t;
//---------------------------------------------------------------------
// fast copy for different sizes
//---------------------------------------------------------------------
static INLINE void memcpy_sse2_16(void *dst, const void *src) {
__m128i m0 = _mm_loadu_si128(((const __m128i*)src) + 0);
_mm_storeu_si128(((__m128i*)dst) + 0, m0);
}
static INLINE void memcpy_sse2_32(void *dst, const void *src) {
__m128i m0 = _mm_loadu_si128(((const __m128i*)src) + 0);
__m128i m1 = _mm_loadu_si128(((const __m128i*)src) + 1);
_mm_storeu_si128(((__m128i*)dst) + 0, m0);
_mm_storeu_si128(((__m128i*)dst) + 1, m1);
}
static INLINE void memcpy_sse2_64(void *dst, const void *src) {
__m128i m0 = _mm_loadu_si128(((const __m128i*)src) + 0);
__m128i m1 = _mm_loadu_si128(((const __m128i*)src) + 1);
__m128i m2 = _mm_loadu_si128(((const __m128i*)src) + 2);
__m128i m3 = _mm_loadu_si128(((const __m128i*)src) + 3);
_mm_storeu_si128(((__m128i*)dst) + 0, m0);
_mm_storeu_si128(((__m128i*)dst) + 1, m1);
_mm_storeu_si128(((__m128i*)dst) + 2, m2);
_mm_storeu_si128(((__m128i*)dst) + 3, m3);
}
static INLINE void memcpy_sse2_128(void *dst, const void *src) {
__m128i m0 = _mm_loadu_si128(((const __m128i*)src) + 0);
__m128i m1 = _mm_loadu_si128(((const __m128i*)src) + 1);
__m128i m2 = _mm_loadu_si128(((const __m128i*)src) + 2);
__m128i m3 = _mm_loadu_si128(((const __m128i*)src) + 3);
__m128i m4 = _mm_loadu_si128(((const __m128i*)src) + 4);
__m128i m5 = _mm_loadu_si128(((const __m128i*)src) + 5);
__m128i m6 = _mm_loadu_si128(((const __m128i*)src) + 6);
__m128i m7 = _mm_loadu_si128(((const __m128i*)src) + 7);
_mm_storeu_si128(((__m128i*)dst) + 0, m0);
_mm_storeu_si128(((__m128i*)dst) + 1, m1);
_mm_storeu_si128(((__m128i*)dst) + 2, m2);
_mm_storeu_si128(((__m128i*)dst) + 3, m3);
_mm_storeu_si128(((__m128i*)dst) + 4, m4);
_mm_storeu_si128(((__m128i*)dst) + 5, m5);
_mm_storeu_si128(((__m128i*)dst) + 6, m6);
_mm_storeu_si128(((__m128i*)dst) + 7, m7);
}
//---------------------------------------------------------------------
// tiny memory copy with jump table optimized
//---------------------------------------------------------------------
static INLINE void *memcpy_tiny(void *dst, const void *src, size_t size) {
unsigned char *dd = ((unsigned char*)dst) + size;
const unsigned char *ss = ((const unsigned char*)src) + size;
switch (size) {
case 64:
memcpy_sse2_64(dd - 64, ss - 64);
case 0:
break;
case 65:
memcpy_sse2_64(dd - 65, ss - 65);
case 1:
dd[-1] = ss[-1];
break;
case 66:
memcpy_sse2_64(dd - 66, ss - 66);
case 2:
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 67:
memcpy_sse2_64(dd - 67, ss - 67);
case 3:
*((uint16_unaligned_t*)(dd - 3)) = *((uint16_unaligned_t*)(ss - 3));
dd[-1] = ss[-1];
break;
case 68:
memcpy_sse2_64(dd - 68, ss - 68);
case 4:
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 69:
memcpy_sse2_64(dd - 69, ss - 69);
case 5:
*((uint32_unaligned_t*)(dd - 5)) = *((uint32_unaligned_t*)(ss - 5));
dd[-1] = ss[-1];
break;
case 70:
memcpy_sse2_64(dd - 70, ss - 70);
case 6:
*((uint32_unaligned_t*)(dd - 6)) = *((uint32_unaligned_t*)(ss - 6));
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 71:
memcpy_sse2_64(dd - 71, ss - 71);
case 7:
*((uint32_unaligned_t*)(dd - 7)) = *((uint32_unaligned_t*)(ss - 7));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 72:
memcpy_sse2_64(dd - 72, ss - 72);
case 8:
*((uint64_unaligned_t*)(dd - 8)) = *((uint64_unaligned_t*)(ss - 8));
break;
case 73:
memcpy_sse2_64(dd - 73, ss - 73);
case 9:
*((uint64_unaligned_t*)(dd - 9)) = *((uint64_unaligned_t*)(ss - 9));
dd[-1] = ss[-1];
break;
case 74:
memcpy_sse2_64(dd - 74, ss - 74);
case 10:
*((uint64_unaligned_t*)(dd - 10)) = *((uint64_unaligned_t*)(ss - 10));
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 75:
memcpy_sse2_64(dd - 75, ss - 75);
case 11:
*((uint64_unaligned_t*)(dd - 11)) = *((uint64_unaligned_t*)(ss - 11));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 76:
memcpy_sse2_64(dd - 76, ss - 76);
case 12:
*((uint64_unaligned_t*)(dd - 12)) = *((uint64_unaligned_t*)(ss - 12));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 77:
memcpy_sse2_64(dd - 77, ss - 77);
case 13:
*((uint64_unaligned_t*)(dd - 13)) = *((uint64_unaligned_t*)(ss - 13));
*((uint32_unaligned_t*)(dd - 5)) = *((uint32_unaligned_t*)(ss - 5));
dd[-1] = ss[-1];
break;
case 78:
memcpy_sse2_64(dd - 78, ss - 78);
case 14:
*((uint64_unaligned_t*)(dd - 14)) = *((uint64_unaligned_t*)(ss - 14));
*((uint64_unaligned_t*)(dd - 8)) = *((uint64_unaligned_t*)(ss - 8));
break;
case 79:
memcpy_sse2_64(dd - 79, ss - 79);
case 15:
*((uint64_unaligned_t*)(dd - 15)) = *((uint64_unaligned_t*)(ss - 15));
*((uint64_unaligned_t*)(dd - 8)) = *((uint64_unaligned_t*)(ss - 8));
break;
case 80:
memcpy_sse2_64(dd - 80, ss - 80);
case 16:
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 81:
memcpy_sse2_64(dd - 81, ss - 81);
case 17:
memcpy_sse2_16(dd - 17, ss - 17);
dd[-1] = ss[-1];
break;
case 82:
memcpy_sse2_64(dd - 82, ss - 82);
case 18:
memcpy_sse2_16(dd - 18, ss - 18);
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 83:
memcpy_sse2_64(dd - 83, ss - 83);
case 19:
memcpy_sse2_16(dd - 19, ss - 19);
*((uint16_unaligned_t*)(dd - 3)) = *((uint16_unaligned_t*)(ss - 3));
dd[-1] = ss[-1];
break;
case 84:
memcpy_sse2_64(dd - 84, ss - 84);
case 20:
memcpy_sse2_16(dd - 20, ss - 20);
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 85:
memcpy_sse2_64(dd - 85, ss - 85);
case 21:
memcpy_sse2_16(dd - 21, ss - 21);
*((uint32_unaligned_t*)(dd - 5)) = *((uint32_unaligned_t*)(ss - 5));
dd[-1] = ss[-1];
break;
case 86:
memcpy_sse2_64(dd - 86, ss - 86);
case 22:
memcpy_sse2_16(dd - 22, ss - 22);
*((uint32_unaligned_t*)(dd - 6)) = *((uint32_unaligned_t*)(ss - 6));
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 87:
memcpy_sse2_64(dd - 87, ss - 87);
case 23:
memcpy_sse2_16(dd - 23, ss - 23);
*((uint32_unaligned_t*)(dd - 7)) = *((uint32_unaligned_t*)(ss - 7));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 88:
memcpy_sse2_64(dd - 88, ss - 88);
case 24:
memcpy_sse2_16(dd - 24, ss - 24);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 89:
memcpy_sse2_64(dd - 89, ss - 89);
case 25:
memcpy_sse2_16(dd - 25, ss - 25);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 90:
memcpy_sse2_64(dd - 90, ss - 90);
case 26:
memcpy_sse2_16(dd - 26, ss - 26);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 91:
memcpy_sse2_64(dd - 91, ss - 91);
case 27:
memcpy_sse2_16(dd - 27, ss - 27);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 92:
memcpy_sse2_64(dd - 92, ss - 92);
case 28:
memcpy_sse2_16(dd - 28, ss - 28);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 93:
memcpy_sse2_64(dd - 93, ss - 93);
case 29:
memcpy_sse2_16(dd - 29, ss - 29);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 94:
memcpy_sse2_64(dd - 94, ss - 94);
case 30:
memcpy_sse2_16(dd - 30, ss - 30);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 95:
memcpy_sse2_64(dd - 95, ss - 95);
case 31:
memcpy_sse2_16(dd - 31, ss - 31);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 96:
memcpy_sse2_64(dd - 96, ss - 96);
case 32:
memcpy_sse2_32(dd - 32, ss - 32);
break;
case 97:
memcpy_sse2_64(dd - 97, ss - 97);
case 33:
memcpy_sse2_32(dd - 33, ss - 33);
dd[-1] = ss[-1];
break;
case 98:
memcpy_sse2_64(dd - 98, ss - 98);
case 34:
memcpy_sse2_32(dd - 34, ss - 34);
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 99:
memcpy_sse2_64(dd - 99, ss - 99);
case 35:
memcpy_sse2_32(dd - 35, ss - 35);
*((uint16_unaligned_t*)(dd - 3)) = *((uint16_unaligned_t*)(ss - 3));
dd[-1] = ss[-1];
break;
case 100:
memcpy_sse2_64(dd - 100, ss - 100);
case 36:
memcpy_sse2_32(dd - 36, ss - 36);
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 101:
memcpy_sse2_64(dd - 101, ss - 101);
case 37:
memcpy_sse2_32(dd - 37, ss - 37);
*((uint32_unaligned_t*)(dd - 5)) = *((uint32_unaligned_t*)(ss - 5));
dd[-1] = ss[-1];
break;
case 102:
memcpy_sse2_64(dd - 102, ss - 102);
case 38:
memcpy_sse2_32(dd - 38, ss - 38);
*((uint32_unaligned_t*)(dd - 6)) = *((uint32_unaligned_t*)(ss - 6));
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 103:
memcpy_sse2_64(dd - 103, ss - 103);
case 39:
memcpy_sse2_32(dd - 39, ss - 39);
*((uint32_unaligned_t*)(dd - 7)) = *((uint32_unaligned_t*)(ss - 7));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 104:
memcpy_sse2_64(dd - 104, ss - 104);
case 40:
memcpy_sse2_32(dd - 40, ss - 40);
*((uint64_unaligned_t*)(dd - 8)) = *((uint64_unaligned_t*)(ss - 8));
break;
case 105:
memcpy_sse2_64(dd - 105, ss - 105);
case 41:
memcpy_sse2_32(dd - 41, ss - 41);
*((uint64_unaligned_t*)(dd - 9)) = *((uint64_unaligned_t*)(ss - 9));
dd[-1] = ss[-1];
break;
case 106:
memcpy_sse2_64(dd - 106, ss - 106);
case 42:
memcpy_sse2_32(dd - 42, ss - 42);
*((uint64_unaligned_t*)(dd - 10)) = *((uint64_unaligned_t*)(ss - 10));
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 107:
memcpy_sse2_64(dd - 107, ss - 107);
case 43:
memcpy_sse2_32(dd - 43, ss - 43);
*((uint64_unaligned_t*)(dd - 11)) = *((uint64_unaligned_t*)(ss - 11));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 108:
memcpy_sse2_64(dd - 108, ss - 108);
case 44:
memcpy_sse2_32(dd - 44, ss - 44);
*((uint64_unaligned_t*)(dd - 12)) = *((uint64_unaligned_t*)(ss - 12));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 109:
memcpy_sse2_64(dd - 109, ss - 109);
case 45:
memcpy_sse2_32(dd - 45, ss - 45);
*((uint64_unaligned_t*)(dd - 13)) = *((uint64_unaligned_t*)(ss - 13));
*((uint32_unaligned_t*)(dd - 5)) = *((uint32_unaligned_t*)(ss - 5));
dd[-1] = ss[-1];
break;
case 110:
memcpy_sse2_64(dd - 110, ss - 110);
case 46:
memcpy_sse2_32(dd - 46, ss - 46);
*((uint64_unaligned_t*)(dd - 14)) = *((uint64_unaligned_t*)(ss - 14));
*((uint64_unaligned_t*)(dd - 8)) = *((uint64_unaligned_t*)(ss - 8));
break;
case 111:
memcpy_sse2_64(dd - 111, ss - 111);
case 47:
memcpy_sse2_32(dd - 47, ss - 47);
*((uint64_unaligned_t*)(dd - 15)) = *((uint64_unaligned_t*)(ss - 15));
*((uint64_unaligned_t*)(dd - 8)) = *((uint64_unaligned_t*)(ss - 8));
break;
case 112:
memcpy_sse2_64(dd - 112, ss - 112);
case 48:
memcpy_sse2_32(dd - 48, ss - 48);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 113:
memcpy_sse2_64(dd - 113, ss - 113);
case 49:
memcpy_sse2_32(dd - 49, ss - 49);
memcpy_sse2_16(dd - 17, ss - 17);
dd[-1] = ss[-1];
break;
case 114:
memcpy_sse2_64(dd - 114, ss - 114);
case 50:
memcpy_sse2_32(dd - 50, ss - 50);
memcpy_sse2_16(dd - 18, ss - 18);
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 115:
memcpy_sse2_64(dd - 115, ss - 115);
case 51:
memcpy_sse2_32(dd - 51, ss - 51);
memcpy_sse2_16(dd - 19, ss - 19);
*((uint16_unaligned_t*)(dd - 3)) = *((uint16_unaligned_t*)(ss - 3));
dd[-1] = ss[-1];
break;
case 116:
memcpy_sse2_64(dd - 116, ss - 116);
case 52:
memcpy_sse2_32(dd - 52, ss - 52);
memcpy_sse2_16(dd - 20, ss - 20);
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 117:
memcpy_sse2_64(dd - 117, ss - 117);
case 53:
memcpy_sse2_32(dd - 53, ss - 53);
memcpy_sse2_16(dd - 21, ss - 21);
*((uint32_unaligned_t*)(dd - 5)) = *((uint32_unaligned_t*)(ss - 5));
dd[-1] = ss[-1];
break;
case 118:
memcpy_sse2_64(dd - 118, ss - 118);
case 54:
memcpy_sse2_32(dd - 54, ss - 54);
memcpy_sse2_16(dd - 22, ss - 22);
*((uint32_unaligned_t*)(dd - 6)) = *((uint32_unaligned_t*)(ss - 6));
*((uint16_unaligned_t*)(dd - 2)) = *((uint16_unaligned_t*)(ss - 2));
break;
case 119:
memcpy_sse2_64(dd - 119, ss - 119);
case 55:
memcpy_sse2_32(dd - 55, ss - 55);
memcpy_sse2_16(dd - 23, ss - 23);
*((uint32_unaligned_t*)(dd - 7)) = *((uint32_unaligned_t*)(ss - 7));
*((uint32_unaligned_t*)(dd - 4)) = *((uint32_unaligned_t*)(ss - 4));
break;
case 120:
memcpy_sse2_64(dd - 120, ss - 120);
case 56:
memcpy_sse2_32(dd - 56, ss - 56);
memcpy_sse2_16(dd - 24, ss - 24);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 121:
memcpy_sse2_64(dd - 121, ss - 121);
case 57:
memcpy_sse2_32(dd - 57, ss - 57);
memcpy_sse2_16(dd - 25, ss - 25);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 122:
memcpy_sse2_64(dd - 122, ss - 122);
case 58:
memcpy_sse2_32(dd - 58, ss - 58);
memcpy_sse2_16(dd - 26, ss - 26);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 123:
memcpy_sse2_64(dd - 123, ss - 123);
case 59:
memcpy_sse2_32(dd - 59, ss - 59);
memcpy_sse2_16(dd - 27, ss - 27);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 124:
memcpy_sse2_64(dd - 124, ss - 124);
case 60:
memcpy_sse2_32(dd - 60, ss - 60);
memcpy_sse2_16(dd - 28, ss - 28);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 125:
memcpy_sse2_64(dd - 125, ss - 125);
case 61:
memcpy_sse2_32(dd - 61, ss - 61);
memcpy_sse2_16(dd - 29, ss - 29);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 126:
memcpy_sse2_64(dd - 126, ss - 126);
case 62:
memcpy_sse2_32(dd - 62, ss - 62);
memcpy_sse2_16(dd - 30, ss - 30);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 127:
memcpy_sse2_64(dd - 127, ss - 127);
case 63:
memcpy_sse2_32(dd - 63, ss - 63);
memcpy_sse2_16(dd - 31, ss - 31);
memcpy_sse2_16(dd - 16, ss - 16);
break;
case 128:
memcpy_sse2_128(dd - 128, ss - 128);
break;
}
return dst;
}
//---------------------------------------------------------------------
// main routine
//---------------------------------------------------------------------
static INLINE void* memcpy_fast(void *destination, const void *source, size_t size)
{
unsigned char *dst = (unsigned char*)destination;
const unsigned char *src = (const unsigned char*)source;
size_t padding;
// small memory copy
if (size <= 128) {
return memcpy_tiny(dst, src, size);
}
// align destination to 16 bytes boundary
padding = (16 - (((size_t)dst) & 15)) & 15;
if (padding > 0) {
__m128i head = _mm_loadu_si128((const __m128i*)src);
_mm_storeu_si128((__m128i*)dst, head);
dst += padding;
src += padding;
size -= padding;
}
// medium size copy
if (size <= 0x200000) // something around half of LL-cache size
{
__m128i c0, c1, c2, c3, c4, c5, c6, c7;
for (; size >= 128; size -= 128) {
c0 = _mm_loadu_si128(((const __m128i*)src) + 0);
c1 = _mm_loadu_si128(((const __m128i*)src) + 1);
c2 = _mm_loadu_si128(((const __m128i*)src) + 2);
c3 = _mm_loadu_si128(((const __m128i*)src) + 3);
c4 = _mm_loadu_si128(((const __m128i*)src) + 4);
c5 = _mm_loadu_si128(((const __m128i*)src) + 5);
c6 = _mm_loadu_si128(((const __m128i*)src) + 6);
c7 = _mm_loadu_si128(((const __m128i*)src) + 7);
_mm_prefetch((const char*)(src + 256), _MM_HINT_NTA);
src += 128;
_mm_store_si128((((__m128i*)dst) + 0), c0);
_mm_store_si128((((__m128i*)dst) + 1), c1);
_mm_store_si128((((__m128i*)dst) + 2), c2);
_mm_store_si128((((__m128i*)dst) + 3), c3);
_mm_store_si128((((__m128i*)dst) + 4), c4);
_mm_store_si128((((__m128i*)dst) + 5), c5);
_mm_store_si128((((__m128i*)dst) + 6), c6);
_mm_store_si128((((__m128i*)dst) + 7), c7);
dst += 128;
}
}
else { // big memory copy
__m128i c0, c1, c2, c3, c4, c5, c6, c7;
_mm_prefetch((const char*)(src), _MM_HINT_NTA);
if ((((size_t)src) & 15) == 0) { // source aligned
for (; size >= 128; size -= 128) {
c0 = _mm_load_si128(((const __m128i*)src) + 0);
c1 = _mm_load_si128(((const __m128i*)src) + 1);
c2 = _mm_load_si128(((const __m128i*)src) + 2);
c3 = _mm_load_si128(((const __m128i*)src) + 3);
c4 = _mm_load_si128(((const __m128i*)src) + 4);
c5 = _mm_load_si128(((const __m128i*)src) + 5);
c6 = _mm_load_si128(((const __m128i*)src) + 6);
c7 = _mm_load_si128(((const __m128i*)src) + 7);
_mm_prefetch((const char*)(src + 256), _MM_HINT_NTA);
src += 128;
_mm_stream_si128((((__m128i*)dst) + 0), c0);
_mm_stream_si128((((__m128i*)dst) + 1), c1);
_mm_stream_si128((((__m128i*)dst) + 2), c2);
_mm_stream_si128((((__m128i*)dst) + 3), c3);
_mm_stream_si128((((__m128i*)dst) + 4), c4);
_mm_stream_si128((((__m128i*)dst) + 5), c5);
_mm_stream_si128((((__m128i*)dst) + 6), c6);
_mm_stream_si128((((__m128i*)dst) + 7), c7);
dst += 128;
}
}
else { // source unaligned
for (; size >= 128; size -= 128) {
c0 = _mm_loadu_si128(((const __m128i*)src) + 0);
c1 = _mm_loadu_si128(((const __m128i*)src) + 1);
c2 = _mm_loadu_si128(((const __m128i*)src) + 2);
c3 = _mm_loadu_si128(((const __m128i*)src) + 3);
c4 = _mm_loadu_si128(((const __m128i*)src) + 4);
c5 = _mm_loadu_si128(((const __m128i*)src) + 5);
c6 = _mm_loadu_si128(((const __m128i*)src) + 6);
c7 = _mm_loadu_si128(((const __m128i*)src) + 7);
_mm_prefetch((const char*)(src + 256), _MM_HINT_NTA);
src += 128;
_mm_stream_si128((((__m128i*)dst) + 0), c0);
_mm_stream_si128((((__m128i*)dst) + 1), c1);
_mm_stream_si128((((__m128i*)dst) + 2), c2);
_mm_stream_si128((((__m128i*)dst) + 3), c3);
_mm_stream_si128((((__m128i*)dst) + 4), c4);
_mm_stream_si128((((__m128i*)dst) + 5), c5);
_mm_stream_si128((((__m128i*)dst) + 6), c6);
_mm_stream_si128((((__m128i*)dst) + 7), c7);
dst += 128;
}
}
_mm_sfence();
}
memcpy_tiny(dst, src, size);
return destination;
}
#endif

Some files were not shown because too many files have changed in this diff Show More