mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Merge branch 'master' of github.com:ClickHouse/ClickHouse into docs/CLICKHOUSEDOCS-138-regionToTopContinent
This commit is contained in:
commit
5adc5a51dc
@ -52,7 +52,7 @@ IncludeCategories:
|
||||
ReflowComments: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignTrailingComments: true
|
||||
AlignTrailingComments: false
|
||||
|
||||
# Not changed:
|
||||
AccessModifierOffset: -4
|
||||
|
205
.clang-tidy
Normal file
205
.clang-tidy
Normal 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
1
.github/CODEOWNERS
vendored
@ -1,2 +1,3 @@
|
||||
docs/* @ClickHouse/docs
|
||||
docs/zh/* @ClickHouse/docs-zh
|
||||
website/* @ClickHouse/docs
|
||||
|
27
.github/ISSUE_TEMPLATE/backward-compatibility.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/backward-compatibility.md
vendored
Normal 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/dbms/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.
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
name: Bug report or unexpected behaviour
|
||||
name: Bug report
|
||||
about: Create a report to help us improve ClickHouse
|
||||
title: ''
|
||||
labels: bug
|
||||
@ -9,7 +9,7 @@ assignees: ''
|
||||
|
||||
(you don't have to strictly follow this form)
|
||||
|
||||
**Describe the bug or unexpected behaviour**
|
||||
**Describe the bug**
|
||||
A clear and concise description of what works not as it is supposed to.
|
||||
|
||||
**How to reproduce**
|
30
.github/ISSUE_TEMPLATE/unexpected-behaviour.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/unexpected-behaviour.md
vendored
Normal 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/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/usability-issue.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/usability-issue.md
vendored
Normal 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/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.
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,7 +16,10 @@
|
||||
/docs/publish
|
||||
/docs/edit
|
||||
/docs/website
|
||||
/docs/venv/
|
||||
/docs/tools/venv/
|
||||
/docs/tools/translate/venv/
|
||||
/docs/tools/translate/output.md
|
||||
/docs/en/single.md
|
||||
/docs/ru/single.md
|
||||
/docs/zh/single.md
|
||||
|
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -140,7 +140,7 @@
|
||||
url = https://github.com/ClickHouse-Extras/libc-headers.git
|
||||
[submodule "contrib/replxx"]
|
||||
path = contrib/replxx
|
||||
url = https://github.com/AmokHuginnsson/replxx.git
|
||||
url = https://github.com/ClickHouse-Extras/replxx.git
|
||||
[submodule "contrib/ryu"]
|
||||
path = contrib/ryu
|
||||
url = https://github.com/ClickHouse-Extras/ryu.git
|
||||
@ -148,3 +148,6 @@
|
||||
path = contrib/avro
|
||||
url = https://github.com/ClickHouse-Extras/avro.git
|
||||
ignore = untracked
|
||||
[submodule "website/images/feathericons"]
|
||||
path = website/images/feathericons
|
||||
url = https://github.com/feathericons/feather
|
||||
|
3597
CHANGELOG.md
3597
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,7 @@ project(ClickHouse)
|
||||
include (cmake/arch.cmake)
|
||||
include (cmake/target.cmake)
|
||||
include (cmake/tools.cmake)
|
||||
include (cmake/analysis.cmake)
|
||||
|
||||
# Ignore export() since we don't use it,
|
||||
# but it gets broken with a global targets via link_libraries()
|
||||
@ -88,8 +89,7 @@ endif()
|
||||
|
||||
include (cmake/sanitize.cmake)
|
||||
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
if (CMAKE_GENERATOR STREQUAL "Ninja" AND NOT DISABLE_COLORED_BUILD)
|
||||
# Turn on colored output. https://github.com/ninja-build/ninja/wiki/FAQ
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
|
||||
@ -121,12 +121,8 @@ endif ()
|
||||
|
||||
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")
|
||||
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 ()
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_GREATER "3.9.0")
|
||||
@ -190,11 +186,13 @@ if (COMPILER_GCC OR COMPILER_CLANG)
|
||||
endif ()
|
||||
|
||||
option(WITH_COVERAGE "Build with coverage." 0)
|
||||
|
||||
if(WITH_COVERAGE AND COMPILER_CLANG)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
||||
# If we want to disable coverage for specific translation units
|
||||
set(WITHOUT_COVERAGE "-fno-profile-instr-generate -fno-coverage-mapping")
|
||||
endif()
|
||||
|
||||
if(WITH_COVERAGE AND COMPILER_GCC)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||
set(COVERAGE_OPTION "-lgcov")
|
||||
@ -215,6 +213,10 @@ if (COMPILER_CLANG)
|
||||
# TODO investigate that
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
|
||||
if (OS_DARWIN)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wl,-U,_inside_main")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-U,_inside_main")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
option (ENABLE_LIBRARIES "Enable all libraries (Global default switch)" ON)
|
||||
@ -226,13 +228,15 @@ else ()
|
||||
set(NOT_UNBUNDLED 1)
|
||||
endif ()
|
||||
|
||||
# Using system libs can cause a lot of warnings in includes (on macro expansion).
|
||||
if (UNBUNDLED OR NOT (OS_LINUX OR OS_DARWIN) OR ARCH_32)
|
||||
option (NO_WERROR "Disable -Werror compiler option" ON)
|
||||
# Using system libs can cause a lot of warnings in includes (on macro expansion).
|
||||
option (WERROR "Enable -Werror compiler option" OFF)
|
||||
else ()
|
||||
option (WERROR "Enable -Werror compiler option" ON)
|
||||
endif ()
|
||||
|
||||
if (NOT NO_WERROR)
|
||||
add_warning(error)
|
||||
endif ()
|
||||
if (WERROR)
|
||||
add_warning(error)
|
||||
endif ()
|
||||
|
||||
# Make this extra-checks for correct library dependencies.
|
||||
@ -280,24 +284,6 @@ if (USE_INCLUDE_WHAT_YOU_USE)
|
||||
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)
|
||||
message (STATUS "Tests are enabled")
|
||||
endif ()
|
||||
@ -348,7 +334,6 @@ include (cmake/find/grpc.cmake)
|
||||
include (cmake/find/pdqsort.cmake)
|
||||
include (cmake/find/hdfs3.cmake) # uses protobuf
|
||||
include (cmake/find/s3.cmake)
|
||||
include (cmake/find/consistent-hashing.cmake)
|
||||
include (cmake/find/base64.cmake)
|
||||
include (cmake/find/parquet.cmake)
|
||||
include (cmake/find/hyperscan.cmake)
|
||||
@ -369,7 +354,6 @@ endif ()
|
||||
|
||||
# Need to process before "contrib" dir:
|
||||
include (cmake/find/jemalloc.cmake)
|
||||
include (cmake/find/cctz.cmake)
|
||||
include (cmake/find/mysqlclient.cmake)
|
||||
|
||||
# When testing for memory leaks with Valgrind, don't link tcmalloc or jemalloc.
|
||||
|
1
CODE_OF_CONDUCT.md
Normal file
1
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1 @@
|
||||
We welcome everyone to contribute to our product, see CONTRIBUTING.md.
|
@ -8,10 +8,14 @@ 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.
|
||||
* [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.
|
||||
* [Slack](https://join.slack.com/t/clickhousedb/shared_invite/enQtOTUzMjM4ODQwNTc5LWJmMjE3Yjc2YmI1ZDBlZmI4ZTc3OWY3ZTIwYTljYzY4MzBlODM3YzBjZTc1YmYyODRlZTJkYTgzYzBiNTA2Yjk) 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.
|
||||
* [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.
|
||||
|
||||
## 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.
|
||||
* [Talks on Saint HighLoad++ in St. Petersburg](https://www.highload.ru/spb/2020/abstracts/6647) 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.
|
||||
* [ClickHouse in Avito (online in Russian)](https://avitotech.timepad.ru/event/1290051/) on April 9, 2020.
|
||||
|
@ -9,7 +9,9 @@ currently being supported with security updates:
|
||||
| ------- | ------------------ |
|
||||
| 1.x | :x: |
|
||||
| 18.x | :x: |
|
||||
| 19.x | :white_check_mark: |
|
||||
| 19.x | :x: |
|
||||
| 19.14 | :white_check_mark: |
|
||||
| 20.x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
@ -1,17 +1,11 @@
|
||||
if (USE_CLANG_TIDY)
|
||||
set (CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_PATH}")
|
||||
endif ()
|
||||
|
||||
add_subdirectory (common)
|
||||
add_subdirectory (loggers)
|
||||
add_subdirectory (daemon)
|
||||
|
||||
if (USE_INTERNAL_MEMCPY)
|
||||
add_subdirectory (memcpy)
|
||||
endif()
|
||||
|
||||
if (USE_MYSQL)
|
||||
add_subdirectory (mysqlxx)
|
||||
endif ()
|
||||
|
||||
if (USE_INTERNAL_CONSISTENT_HASHING_LIBRARY)
|
||||
add_subdirectory (consistent-hashing)
|
||||
endif ()
|
||||
add_subdirectory (consistent-hashing-sumbur)
|
||||
add_subdirectory (widechar_width)
|
||||
|
@ -6,6 +6,7 @@ set (SRCS
|
||||
DateLUT.cpp
|
||||
DateLUTImpl.cpp
|
||||
demangle.cpp
|
||||
getFQDNOrHostName.cpp
|
||||
getMemoryAmount.cpp
|
||||
getThreadId.cpp
|
||||
JSON.cpp
|
||||
@ -16,26 +17,29 @@ set (SRCS
|
||||
setTerminalEcho.cpp
|
||||
shift10.cpp
|
||||
sleep.cpp
|
||||
terminalColors.cpp
|
||||
)
|
||||
|
||||
if (ENABLE_REPLXX)
|
||||
set (SRCS ${SRCS}
|
||||
ReplxxLineReader.cpp
|
||||
ReplxxLineReader.h
|
||||
)
|
||||
list (APPEND SRCS ReplxxLineReader.cpp)
|
||||
elseif (ENABLE_READLINE)
|
||||
list (APPEND SRCS ReadlineLineReader.cpp)
|
||||
endif ()
|
||||
|
||||
if (USE_DEBUG_HELPERS)
|
||||
set (INCLUDE_DEBUG_HELPERS "-include ${ClickHouse_SOURCE_DIR}/base/common/iostream_debug_helpers.h")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${INCLUDE_DEBUG_HELPERS}")
|
||||
endif ()
|
||||
|
||||
add_library (common ${SRCS})
|
||||
|
||||
target_include_directories(common PUBLIC .. ${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
|
||||
if (USE_INTERNAL_MEMCPY)
|
||||
target_link_libraries (common PRIVATE memcpy)
|
||||
if (WITH_COVERAGE)
|
||||
target_compile_definitions(common PUBLIC WITH_COVERAGE=1)
|
||||
else ()
|
||||
target_compile_definitions(common PUBLIC WITH_COVERAGE=0)
|
||||
endif ()
|
||||
|
||||
if(CCTZ_INCLUDE_DIR)
|
||||
target_include_directories(common BEFORE PRIVATE ${CCTZ_INCLUDE_DIR})
|
||||
endif()
|
||||
target_include_directories(common PUBLIC .. ${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
|
||||
if (NOT USE_INTERNAL_BOOST_LIBRARY)
|
||||
target_include_directories (common SYSTEM BEFORE PUBLIC ${Boost_INCLUDE_DIRS})
|
||||
@ -45,18 +49,40 @@ if(NOT USE_INTERNAL_POCO_LIBRARY)
|
||||
target_include_directories (common SYSTEM BEFORE PUBLIC ${Poco_Foundation_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(CCTZ_LIBRARY)
|
||||
target_link_libraries(common PRIVATE ${CCTZ_LIBRARY})
|
||||
endif()
|
||||
# allow explicitly fallback to readline
|
||||
if (NOT ENABLE_REPLXX AND ENABLE_READLINE)
|
||||
message (STATUS "Attempt to fallback to readline explicitly")
|
||||
set (READLINE_PATHS "/usr/local/opt/readline/lib")
|
||||
# First try find custom lib for macos users (default lib without history support)
|
||||
find_library (READLINE_LIB NAMES readline PATHS ${READLINE_PATHS} NO_DEFAULT_PATH)
|
||||
if (NOT READLINE_LIB)
|
||||
find_library (READLINE_LIB NAMES readline PATHS ${READLINE_PATHS})
|
||||
endif ()
|
||||
|
||||
target_link_libraries(common PUBLIC replxx)
|
||||
set(READLINE_INCLUDE_PATHS "/usr/local/opt/readline/include")
|
||||
find_path (READLINE_INCLUDE_DIR NAMES readline/readline.h PATHS ${READLINE_INCLUDE_PATHS} NO_DEFAULT_PATH)
|
||||
if (NOT READLINE_INCLUDE_DIR)
|
||||
find_path (READLINE_INCLUDE_DIR NAMES readline/readline.h PATHS ${READLINE_INCLUDE_PATHS})
|
||||
endif ()
|
||||
if (READLINE_INCLUDE_DIR AND READLINE_LIB)
|
||||
target_link_libraries(common PUBLIC ${READLINE_LIB})
|
||||
target_compile_definitions(common PUBLIC USE_READLINE=1)
|
||||
message (STATUS "Using readline: ${READLINE_INCLUDE_DIR} : ${READLINE_LIB}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
target_link_libraries (common
|
||||
PUBLIC
|
||||
${Poco_Net_LIBRARY}
|
||||
${Poco_Util_LIBRARY}
|
||||
${Poco_Foundation_LIBRARY}
|
||||
${CITYHASH_LIBRARIES}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
FastMemcpy
|
||||
replxx
|
||||
|
||||
PRIVATE
|
||||
cctz
|
||||
)
|
||||
|
||||
if (ENABLE_TESTS)
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <common/DateLUT.h>
|
||||
#include "DateLUT.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <Poco/DigestStream.h>
|
||||
#include <Poco/Exception.h>
|
||||
#include <Poco/SHA1Engine.h>
|
||||
#include <Poco/DigestStream.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
|
@ -1,20 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "DateLUTImpl.h"
|
||||
#include <unordered_map>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
// Also defined in Core/Defines.h
|
||||
#if !defined(ALWAYS_INLINE)
|
||||
#if defined(_MSC_VER)
|
||||
#define ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
#define ALWAYS_INLINE __attribute__((__always_inline__))
|
||||
#endif
|
||||
#endif
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
/// This class provides lazy initialization and lookup of singleton DateLUTImpl objects for a given timezone.
|
||||
|
@ -1,23 +1,14 @@
|
||||
#if __has_include(<cctz/civil_time.h>)
|
||||
#include <cctz/civil_time.h> // bundled, debian
|
||||
#else
|
||||
#include <civil_time.h> // freebsd
|
||||
#endif
|
||||
#include "DateLUTImpl.h"
|
||||
|
||||
#if __has_include(<cctz/time_zone.h>)
|
||||
#include <cctz/civil_time.h>
|
||||
#include <cctz/time_zone.h>
|
||||
#else
|
||||
#include <time_zone.h>
|
||||
#endif
|
||||
|
||||
#include <common/DateLUTImpl.h>
|
||||
#include <Poco/Exception.h>
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#define DATE_LUT_MIN 0
|
||||
|
||||
@ -59,7 +50,7 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
|
||||
time_t start_of_day = DATE_LUT_MIN;
|
||||
|
||||
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_);
|
||||
|
||||
cctz::time_zone::absolute_lookup start_of_epoch_lookup = cctz_time_zone.lookup(std::chrono::system_clock::from_time_t(start_of_day));
|
||||
|
@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.h"
|
||||
#include "DayNum.h"
|
||||
#include "likely.h"
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/Types.h>
|
||||
#include <common/types.h>
|
||||
#include <common/strong_typedef.h>
|
||||
|
||||
/** Represents number of days since 1970-01-01.
|
||||
|
@ -215,7 +215,7 @@ JSON::ElementType JSON::getType() 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.");
|
||||
}
|
||||
|
||||
@ -341,7 +341,7 @@ JSON::Pos JSON::skipArray() const
|
||||
if (*pos == ']')
|
||||
return ++pos;
|
||||
|
||||
while (1)
|
||||
while (true)
|
||||
{
|
||||
pos = JSON(pos, ptr_end, level + 1).skipElement();
|
||||
|
||||
@ -373,7 +373,7 @@ JSON::Pos JSON::skipObject() const
|
||||
if (*pos == '}')
|
||||
return ++pos;
|
||||
|
||||
while (1)
|
||||
while (true)
|
||||
{
|
||||
pos = JSON(pos, ptr_end, level + 1).skipNameValuePair();
|
||||
|
||||
@ -776,7 +776,7 @@ JSON::iterator & JSON::iterator::operator++()
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSON::iterator JSON::iterator::operator++(int)
|
||||
JSON::iterator JSON::iterator::operator++(int) // NOLINT
|
||||
{
|
||||
iterator copy(*this);
|
||||
++*this;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <typeinfo>
|
||||
#include <Poco/Exception.h>
|
||||
#include <common/StringRef.h>
|
||||
#include <common/Types.h>
|
||||
#include <common/types.h>
|
||||
|
||||
|
||||
/** Очень простой класс для чтения JSON (или его кусочков).
|
||||
|
@ -30,7 +30,7 @@ void trim(String & s)
|
||||
bool hasInputData()
|
||||
{
|
||||
timeval timeout = {0, 0};
|
||||
fd_set fds;
|
||||
fd_set fds{};
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
return select(1, &fds, nullptr, nullptr, &timeout) == 1;
|
||||
@ -53,8 +53,15 @@ LineReader::Suggest::WordsRange LineReader::Suggest::getCompletions(const String
|
||||
|
||||
/// last_word can be empty.
|
||||
|
||||
return std::equal_range(
|
||||
words.begin(), words.end(), last_word, [prefix_length](std::string_view s, std::string_view prefix_searched)
|
||||
/// 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(
|
||||
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;
|
||||
});
|
||||
else
|
||||
return std::equal_range(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;
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/Types.h>
|
||||
#include <common/types.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
@ -8,16 +8,15 @@
|
||||
class LineReader
|
||||
{
|
||||
public:
|
||||
class Suggest
|
||||
struct Suggest
|
||||
{
|
||||
protected:
|
||||
using Words = std::vector<std::string>;
|
||||
using WordsRange = std::pair<Words::const_iterator, Words::const_iterator>;
|
||||
|
||||
Words words;
|
||||
Words words_no_case;
|
||||
std::atomic<bool> ready{false};
|
||||
|
||||
public:
|
||||
/// Get iterators for the matched range of words if any.
|
||||
WordsRange getCompletions(const String & prefix, size_t prefix_length) const;
|
||||
};
|
||||
@ -31,6 +30,13 @@ public:
|
||||
/// Typical delimiter is ';' (semicolon) and typical extender is '\' (backslash).
|
||||
String readLine(const String & first_prompt, const String & second_prompt);
|
||||
|
||||
/// When bracketed paste mode is set, pasted text is bracketed with control sequences so
|
||||
/// that the program can differentiate pasted text from typed-in text. This helps
|
||||
/// clickhouse-client so that without -m flag, one can still paste multiline queries, and
|
||||
/// possibly get better pasting performance. See https://cirw.in/blog/bracketed-paste for
|
||||
/// more details.
|
||||
virtual void enableBracketedPaste() {}
|
||||
|
||||
protected:
|
||||
enum InputStatus
|
||||
{
|
||||
|
175
base/common/ReadlineLineReader.cpp
Normal file
175
base/common/ReadlineLineReader.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include <common/ReadlineLineReader.h>
|
||||
#include <ext/scope_guard.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/// Trim ending whitespace inplace
|
||||
void trim(String & s)
|
||||
{
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }).base(), s.end());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const LineReader::Suggest * suggest;
|
||||
|
||||
/// Points to current word to suggest.
|
||||
static LineReader::Suggest::Words::const_iterator pos;
|
||||
/// Points after the last possible match.
|
||||
static LineReader::Suggest::Words::const_iterator end;
|
||||
|
||||
/// Set iterators to the matched range of words if any.
|
||||
static void findRange(const char * prefix, size_t prefix_length)
|
||||
{
|
||||
std::string prefix_str(prefix);
|
||||
std::tie(pos, end) = suggest->getCompletions(prefix_str, prefix_length);
|
||||
}
|
||||
|
||||
/// Iterates through matched range.
|
||||
static char * nextMatch()
|
||||
{
|
||||
if (pos >= end)
|
||||
return nullptr;
|
||||
|
||||
/// readline will free memory by itself.
|
||||
char * word = strdup(pos->c_str());
|
||||
++pos;
|
||||
return word;
|
||||
}
|
||||
|
||||
static char * generate(const char * text, int state)
|
||||
{
|
||||
if (!suggest->ready)
|
||||
return nullptr;
|
||||
if (state == 0)
|
||||
findRange(text, strlen(text));
|
||||
|
||||
/// Do not append whitespace after word. For unknown reason, rl_completion_append_character = '\0' does not work.
|
||||
rl_completion_suppress_append = 1;
|
||||
|
||||
return nextMatch();
|
||||
};
|
||||
|
||||
ReadlineLineReader::ReadlineLineReader(const Suggest & suggest_, const String & history_file_path_, char extender_, char delimiter_)
|
||||
: LineReader(history_file_path_, extender_, delimiter_)
|
||||
{
|
||||
suggest = &suggest_;
|
||||
|
||||
if (!history_file_path.empty())
|
||||
{
|
||||
int res = read_history(history_file_path.c_str());
|
||||
if (res)
|
||||
std::cerr << "Cannot read history from file " + history_file_path + ": "+ strerror(errno) << std::endl;
|
||||
}
|
||||
|
||||
/// Added '.' to the default list. Because it is used to separate database and table.
|
||||
rl_basic_word_break_characters = word_break_characters;
|
||||
|
||||
/// Not append whitespace after single suggestion. Because whitespace after function name is meaningless.
|
||||
rl_completion_append_character = '\0';
|
||||
|
||||
rl_completion_entry_function = generate;
|
||||
|
||||
/// Install Ctrl+C signal handler that will be used in interactive mode.
|
||||
|
||||
if (rl_initialize())
|
||||
throw std::runtime_error("Cannot initialize readline");
|
||||
|
||||
auto clear_prompt_or_exit = [](int)
|
||||
{
|
||||
/// This is signal safe.
|
||||
ssize_t res = write(STDOUT_FILENO, "\n", 1);
|
||||
|
||||
/// Allow to quit client while query is in progress by pressing Ctrl+C twice.
|
||||
/// (First press to Ctrl+C will try to cancel query by InterruptListener).
|
||||
if (res == 1 && rl_line_buffer[0] && !RL_ISSTATE(RL_STATE_DONE))
|
||||
{
|
||||
rl_replace_line("", 0);
|
||||
if (rl_forced_update_display())
|
||||
_exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// A little dirty, but we struggle to find better way to correctly
|
||||
/// force readline to exit after returning from the signal handler.
|
||||
_exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
if (signal(SIGINT, clear_prompt_or_exit) == SIG_ERR)
|
||||
throw std::runtime_error(std::string("Cannot set signal handler for readline: ") + strerror(errno));
|
||||
|
||||
rl_variable_bind("completion-ignore-case", "on");
|
||||
}
|
||||
|
||||
ReadlineLineReader::~ReadlineLineReader()
|
||||
{
|
||||
}
|
||||
|
||||
LineReader::InputStatus ReadlineLineReader::readOneLine(const String & prompt)
|
||||
{
|
||||
input.clear();
|
||||
|
||||
const char* cinput = readline(prompt.c_str());
|
||||
if (cinput == nullptr)
|
||||
return (errno != EAGAIN) ? ABORT : RESET_LINE;
|
||||
input = cinput;
|
||||
|
||||
trim(input);
|
||||
return INPUT_LINE;
|
||||
}
|
||||
|
||||
void ReadlineLineReader::addToHistory(const String & line)
|
||||
{
|
||||
add_history(line.c_str());
|
||||
}
|
||||
|
||||
#if RL_VERSION_MAJOR >= 7
|
||||
|
||||
#define BRACK_PASTE_PREF "\033[200~"
|
||||
#define BRACK_PASTE_SUFF "\033[201~"
|
||||
|
||||
#define BRACK_PASTE_LAST '~'
|
||||
#define BRACK_PASTE_SLEN 6
|
||||
|
||||
/// This handler bypasses some unused macro/event checkings and remove trailing newlines before insertion.
|
||||
static int clickhouse_rl_bracketed_paste_begin(int /* count */, int /* key */)
|
||||
{
|
||||
std::string buf;
|
||||
buf.reserve(128);
|
||||
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
SCOPE_EXIT(RL_UNSETSTATE(RL_STATE_MOREINPUT));
|
||||
int c;
|
||||
while ((c = rl_read_key()) >= 0)
|
||||
{
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
buf.push_back(c);
|
||||
if (buf.size() >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST && buf.substr(buf.size() - BRACK_PASTE_SLEN) == BRACK_PASTE_SUFF)
|
||||
{
|
||||
buf.resize(buf.size() - BRACK_PASTE_SLEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
trim(buf);
|
||||
return static_cast<size_t>(rl_insert_text(buf.c_str())) == buf.size() ? 0 : 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ReadlineLineReader::enableBracketedPaste()
|
||||
{
|
||||
#if RL_VERSION_MAJOR >= 7
|
||||
rl_variable_bind("enable-bracketed-paste", "on");
|
||||
|
||||
/// Use our bracketed paste handler to get better user experience. See comments above.
|
||||
rl_bind_keyseq(BRACK_PASTE_PREF, clickhouse_rl_bracketed_paste_begin);
|
||||
#endif
|
||||
};
|
19
base/common/ReadlineLineReader.h
Normal file
19
base/common/ReadlineLineReader.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "LineReader.h"
|
||||
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
class ReadlineLineReader : public LineReader
|
||||
{
|
||||
public:
|
||||
ReadlineLineReader(const Suggest & suggest, const String & history_file_path, char extender, char delimiter = 0);
|
||||
~ReadlineLineReader() override;
|
||||
|
||||
void enableBracketedPaste() override;
|
||||
|
||||
private:
|
||||
InputStatus readOneLine(const String & prompt) override;
|
||||
void addToHistory(const String & line) override;
|
||||
};
|
@ -3,6 +3,7 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <functional>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -18,18 +19,31 @@ void trim(String & s)
|
||||
ReplxxLineReader::ReplxxLineReader(const Suggest & suggest, const String & history_file_path_, char extender_, char delimiter_)
|
||||
: LineReader(history_file_path_, extender_, delimiter_)
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
using Replxx = replxx::Replxx;
|
||||
|
||||
if (!history_file_path.empty())
|
||||
rx.history_load(history_file_path);
|
||||
|
||||
auto callback = [&suggest] (const String & context, size_t 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_complete_on_empty(false);
|
||||
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'), std::bind(&Replxx::invoke, &rx, Replxx::ACTION::HISTORY_NEXT, _1));
|
||||
rx.bind_key(Replxx::KEY::control('P'), std::bind(&Replxx::invoke, &rx, Replxx::ACTION::HISTORY_PREVIOUS, _1));
|
||||
/// 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'), std::bind(&Replxx::invoke, &rx, Replxx::ACTION::COMPLETE_NEXT, _1));
|
||||
rx.bind_key(Replxx::KEY::meta('P'), std::bind(&Replxx::invoke, &rx, Replxx::ACTION::COMPLETE_PREVIOUS, _1));
|
||||
}
|
||||
|
||||
ReplxxLineReader::~ReplxxLineReader()
|
||||
@ -55,3 +69,8 @@ void ReplxxLineReader::addToHistory(const String & line)
|
||||
{
|
||||
rx.history_add(line);
|
||||
}
|
||||
|
||||
void ReplxxLineReader::enableBracketedPaste()
|
||||
{
|
||||
rx.enable_bracketed_paste();
|
||||
};
|
||||
|
@ -10,6 +10,8 @@ public:
|
||||
ReplxxLineReader(const Suggest & suggest, const String & history_file_path, char extender, char delimiter = 0);
|
||||
~ReplxxLineReader() override;
|
||||
|
||||
void enableBracketedPaste() override;
|
||||
|
||||
private:
|
||||
InputStatus readOneLine(const String & prompt) override;
|
||||
void addToHistory(const String & line) override;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <functional>
|
||||
#include <ostream>
|
||||
|
||||
#include <common/Types.h>
|
||||
#include <common/types.h>
|
||||
#include <common/unaligned.h>
|
||||
|
||||
#include <city.h>
|
||||
@ -26,17 +26,18 @@ struct StringRef
|
||||
const char * data = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
StringRef(const char * data_, size_t size_) : data(data_), size(size_) {}
|
||||
StringRef(const unsigned char * data_, size_t size_) : data(reinterpret_cast<const char *>(data_)), size(size_) {}
|
||||
template <typename CharT, typename = std::enable_if_t<sizeof(CharT) == 1>>
|
||||
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_view & s) : data(s.data()), size(s.size()) {}
|
||||
explicit StringRef(const char * data_) : data(data_), size(strlen(data_)) {}
|
||||
StringRef() = default;
|
||||
constexpr StringRef(const std::string_view & s) : data(s.data()), size(s.size()) {}
|
||||
constexpr StringRef(const char * data_) : StringRef(std::string_view{data_}) {}
|
||||
constexpr StringRef() = default;
|
||||
|
||||
std::string toString() const { return std::string(data, size); }
|
||||
|
||||
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>;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <common/argsToConfig.h>
|
||||
#include "argsToConfig.h"
|
||||
|
||||
#include <Poco/Util/Application.h>
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Poco/Util/Application.h>
|
||||
|
||||
namespace Poco::Util
|
||||
|
@ -4,4 +4,3 @@
|
||||
|
||||
#cmakedefine01 USE_JEMALLOC
|
||||
#cmakedefine01 UNBUNDLED
|
||||
#cmakedefine01 WITH_COVERAGE
|
||||
|
@ -1,16 +1,17 @@
|
||||
#include <common/coverage.h>
|
||||
#include <common/config_common.h>
|
||||
#include "coverage.h"
|
||||
|
||||
#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();
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
# elif defined(__GNUC__) || defined(__GNUG__)
|
||||
extern "C" void __gcov_exit();
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,11 +22,11 @@ void dumpCoverageReportIfPossible()
|
||||
static std::mutex mutex;
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
#if defined(__clang__)
|
||||
# if defined(__clang__)
|
||||
__llvm_profile_dump();
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
# elif defined(__GNUC__) || defined(__GNUG__)
|
||||
__gcov_exit();
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
87
base/common/defines.h
Normal file
87
base/common/defines.h
Normal 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__)
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#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));
|
||||
}
|
||||
|
||||
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <Poco/Net/DNS.h>
|
||||
#include <Common/getFQDNOrHostName.h>
|
||||
#include <common/getFQDNOrHostName.h>
|
||||
|
||||
|
||||
namespace
|
@ -58,7 +58,7 @@ uint64_t getMemoryAmountOrZero()
|
||||
#endif
|
||||
uint64_t size = 0; /* 64-bit */
|
||||
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 0; /* Failed? */
|
||||
@ -69,13 +69,13 @@ uint64_t getMemoryAmountOrZero()
|
||||
|
||||
#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
|
||||
/* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */
|
||||
return (uint64_t)sysconf(_SC_PHYS_PAGES)
|
||||
* (uint64_t)sysconf(_SC_PAGESIZE);
|
||||
return uint64_t(sysconf(_SC_PHYS_PAGES))
|
||||
*uint64_t(sysconf(_SC_PAGESIZE));
|
||||
|
||||
#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE)
|
||||
/* Legacy. -------------------------------------------------- */
|
||||
return (uint64_t)sysconf(_SC_PHYS_PAGES)
|
||||
* (uint64_t)sysconf(_SC_PAGE_SIZE);
|
||||
return uint64_t(sysconf(_SC_PHYS_PAGES))
|
||||
* uint64_t(sysconf(_SC_PAGE_SIZE));
|
||||
|
||||
#elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM))
|
||||
/* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */
|
||||
@ -88,7 +88,7 @@ uint64_t getMemoryAmountOrZero()
|
||||
#endif
|
||||
unsigned int size = 0; /* 32-bit */
|
||||
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 0; /* Failed? */
|
||||
|
@ -3,6 +3,8 @@
|
||||
#if OS_LINUX
|
||||
#include <unistd.h>
|
||||
#include <syscall.h>
|
||||
#elif OS_FREEBSD
|
||||
#include <pthread_np.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <stdexcept>
|
||||
@ -16,6 +18,8 @@ uint64_t getThreadId()
|
||||
{
|
||||
#if OS_LINUX
|
||||
current_tid = syscall(SYS_gettid); /// This call is always successful. - man gettid
|
||||
#elif OS_FREEBSD
|
||||
current_tid = pthread_getthreadid_np();
|
||||
#else
|
||||
if (0 != pthread_threadid_np(nullptr, ¤t_tid))
|
||||
throw std::logic_error("pthread_threadid_np returned error");
|
||||
|
@ -80,7 +80,6 @@ dumpImpl(Out & out, T && x)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Tuple, pair
|
||||
template <size_t N, typename Out, typename T>
|
||||
Out & dumpTupleImpl(Out & out, T && x)
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#include "likely.h"
|
||||
|
||||
using int128_t = __int128;
|
||||
using uint128_t = unsigned __int128;
|
||||
@ -397,6 +396,12 @@ char * itoa(I i, char * p)
|
||||
return impl::convert::itoa(i, p);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline char * itoa(char8_t i, char * p)
|
||||
{
|
||||
return impl::convert::itoa(uint8_t(i), p);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline char * itoa<uint128_t>(uint128_t i, char * p)
|
||||
{
|
||||
|
@ -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
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <new>
|
||||
#include "likely.h"
|
||||
#include "defines.h"
|
||||
|
||||
#if __has_include(<common/config_common.h>)
|
||||
#include <common/config_common.h>
|
||||
@ -19,27 +19,11 @@
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
// Also defined in Core/Defines.h
|
||||
#if !defined(ALWAYS_INLINE)
|
||||
#if defined(_MSC_VER)
|
||||
#define ALWAYS_INLINE inline __forceinline
|
||||
#else
|
||||
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
|
||||
#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
|
||||
{
|
||||
|
||||
ALWAYS_INLINE void * newImpl(std::size_t size)
|
||||
inline ALWAYS_INLINE void * newImpl(std::size_t size)
|
||||
{
|
||||
auto * ptr = malloc(size);
|
||||
if (likely(ptr != nullptr))
|
||||
@ -49,19 +33,19 @@ ALWAYS_INLINE void * newImpl(std::size_t size)
|
||||
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);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void deleteImpl(void * ptr) noexcept
|
||||
inline ALWAYS_INLINE void deleteImpl(void * ptr) noexcept
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#if USE_JEMALLOC
|
||||
|
||||
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))
|
||||
return;
|
||||
@ -71,7 +55,7 @@ ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size) noexcept
|
||||
|
||||
#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);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <common/shift10.h>
|
||||
|
||||
#include <common/likely.h>
|
||||
#include "defines.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
template <typename T>
|
||||
static T shift10Impl(T x, int exponent)
|
||||
{
|
||||
static constexpr ssize_t MIN_EXPONENT = -323;
|
||||
static constexpr ssize_t MAX_EXPONENT = 308;
|
||||
static constexpr ssize_t min_exponent = -323;
|
||||
static constexpr ssize_t max_exponent = 308;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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.
|
||||
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.
|
||||
else
|
||||
x *= powers10[exponent - MIN_EXPONENT];
|
||||
x *= powers10[exponent - min_exponent];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/Types.h>
|
||||
#include <common/types.h>
|
||||
|
||||
/** Almost the same as x = x * exp10(exponent), but gives more accurate result.
|
||||
* Example:
|
||||
|
49
base/common/terminalColors.cpp
Normal file
49
base/common/terminalColors.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <string>
|
||||
#include <common/terminalColors.h>
|
||||
|
||||
|
||||
std::string setColor(UInt64 hash)
|
||||
{
|
||||
/// Make a random RGB color that has constant brightness.
|
||||
/// https://en.wikipedia.org/wiki/YCbCr
|
||||
|
||||
/// Note that this is darker than the middle relative luminance, see "Gamma_correction" and "Luma_(video)".
|
||||
/// It still looks awesome.
|
||||
UInt8 y = 128;
|
||||
|
||||
UInt8 cb = hash % 256;
|
||||
UInt8 cr = hash / 256 % 256;
|
||||
|
||||
UInt8 r = std::max(0.0, std::min(255.0, y + 1.402 * (cr - 128)));
|
||||
UInt8 g = std::max(0.0, std::min(255.0, y - 0.344136 * (cb - 128) - 0.714136 * (cr - 128)));
|
||||
UInt8 b = std::max(0.0, std::min(255.0, y + 1.772 * (cb - 128)));
|
||||
|
||||
/// ANSI escape sequence to set 24-bit foreground font color in terminal.
|
||||
return "\033[38;2;" + std::to_string(r) + ";" + std::to_string(g) + ";" + std::to_string(b) + "m";
|
||||
}
|
||||
|
||||
const char * setColorForLogPriority(int priority)
|
||||
{
|
||||
if (priority < 1 || priority > 8)
|
||||
return "";
|
||||
|
||||
static const char * colors[] =
|
||||
{
|
||||
"",
|
||||
"\033[1;41m", /// Fatal
|
||||
"\033[7;31m", /// Critical
|
||||
"\033[1;31m", /// Error
|
||||
"\033[0;31m", /// Warning
|
||||
"\033[0;33m", /// Notice
|
||||
"\033[1m", /// Information
|
||||
"", /// Debug
|
||||
"\033[2m", /// Trace
|
||||
};
|
||||
|
||||
return colors[priority];
|
||||
}
|
||||
|
||||
const char * resetColor()
|
||||
{
|
||||
return "\033[0m";
|
||||
}
|
15
base/common/terminalColors.h
Normal file
15
base/common/terminalColors.h
Normal file
@ -0,0 +1,15 @@
|
||||
#include <string>
|
||||
#include <common/types.h>
|
||||
|
||||
|
||||
/** Set color in terminal based on 64-bit hash value.
|
||||
* It can be used to choose some random color deterministically based on some other value.
|
||||
* Hash value should be uniformly distributed.
|
||||
*/
|
||||
std::string setColor(UInt64 hash);
|
||||
|
||||
/** Set color for logger priority value. */
|
||||
const char * setColorForLogPriority(int priority);
|
||||
|
||||
/** Undo changes made by the functions above. */
|
||||
const char * resetColor();
|
@ -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(20100328), orderedIdentifierToDate(20100330), 15 * 60);
|
||||
|
@ -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(20100328), orderedIdentifierToDate(20100330), 15 * 60);
|
||||
|
@ -2,15 +2,15 @@
|
||||
#include <common/DateLUT.h>
|
||||
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
int main(int, char **)
|
||||
{
|
||||
/** В DateLUT был глюк - для времён из дня 1970-01-01, возвращался номер часа больше 23. */
|
||||
static const time_t TIME = 66130;
|
||||
static const time_t time = 66130;
|
||||
|
||||
const auto & date_lut = DateLUT::instance();
|
||||
|
||||
std::cerr << date_lut.toHour(TIME) << std::endl;
|
||||
std::cerr << date_lut.toDayNum(TIME) << std::endl;
|
||||
std::cerr << date_lut.toHour(time) << std::endl;
|
||||
std::cerr << date_lut.toDayNum(time) << std::endl;
|
||||
|
||||
const auto * values = reinterpret_cast<const DateLUTImpl::Values *>(&date_lut);
|
||||
|
||||
|
@ -2,13 +2,13 @@
|
||||
#include <common/DateLUT.h>
|
||||
#include <Poco/Exception.h>
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
int main(int, char **)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto & date_lut = DateLUT::instance();
|
||||
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)
|
||||
<< ", UTC: " << DateLUT::instance("UTC").timeToString(now) << std::endl;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <common/DateLUT.h>
|
||||
|
||||
/// Позволяет проверить время инициализации DateLUT.
|
||||
int main(int argc, char ** argv)
|
||||
int main(int, char **)
|
||||
{
|
||||
DateLUT::instance();
|
||||
return 0;
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <common/find_symbols.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
TEST(find_symbols, SimpleTest)
|
||||
TEST(FindSymbols, SimpleTest)
|
||||
{
|
||||
std::string s = "Hello, world! Goodbye...";
|
||||
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<'H'>(begin, end), begin);
|
||||
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"}));
|
||||
}
|
||||
}
|
||||
|
@ -22,484 +22,484 @@ struct GetStringTestRecord
|
||||
std::string result;
|
||||
};
|
||||
|
||||
TEST(JSON_Suite, SimpleTest)
|
||||
TEST(JSONSuite, SimpleTest)
|
||||
{
|
||||
std::vector<GetStringTestRecord> test_data =
|
||||
{
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Вафельница Vitek WX-1102 FL\""s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s },
|
||||
{ "\"brand\""s, ResultType::Return, "brand"s },
|
||||
{ "\"184509\""s, ResultType::Return, "184509"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"Все для детей/Детская техника/Vitek\""s, ResultType::Return, "Все для детей/Детская техника/Vitek"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"В наличии\""s, ResultType::Return, "В наличии"s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"2390.00\""s, ResultType::Return, "2390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"Карточка\""s, ResultType::Return, "Карточка"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"detail\""s, ResultType::Return, "detail"s },
|
||||
{ "\"actionField\""s, ResultType::Return, "actionField"s },
|
||||
{ "\"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 },
|
||||
{ "\"action\""s, ResultType::Return, "action"s },
|
||||
{ "\"detail\""s, ResultType::Return, "detail"s },
|
||||
{ "\"products\""s, ResultType::Return, "products"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Вафельница Vitek WX-1102 FL\""s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"184509\""s, ResultType::Return, "184509"s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"2390.00\""s, ResultType::Return, "2390.00"s },
|
||||
{ "\"brand\""s, ResultType::Return, "brand"s },
|
||||
{ "\"Vitek\""s, ResultType::Return, "Vitek"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"Все для детей/Детская техника/Vitek\""s, ResultType::Return, "Все для детей/Детская техника/Vitek"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"В наличии\""s, ResultType::Return, "В наличии"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"isAuthorized\""s, ResultType::Return, "isAuthorized"s },
|
||||
{ "\"isSubscriber\""s, ResultType::Return, "isSubscriber"s },
|
||||
{ "\"postType\""s, ResultType::Return, "postType"s },
|
||||
{ "\"Новости\""s, ResultType::Return, "Новости"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"Электроплита GEFEST Брест ЭПНД 5140-01 0001\""s, ResultType::Return, "Электроплита GEFEST Брест ЭПНД 5140-01 0001"s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"currencyCode\""s, ResultType::Return, "currencyCode"s },
|
||||
{ "\"RUB\""s, ResultType::Return, "RUB"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"trash_login\""s, ResultType::Return, "trash_login"s },
|
||||
{ "\"novikoff\""s, ResultType::Return, "novikoff"s },
|
||||
{ "\"trash_cat_link\""s, ResultType::Return, "trash_cat_link"s },
|
||||
{ "\"progs\""s, ResultType::Return, "progs"s },
|
||||
{ "\"trash_parent_link\""s, ResultType::Return, "trash_parent_link"s },
|
||||
{ "\"content\""s, ResultType::Return, "content"s },
|
||||
{ "\"trash_posted_parent\""s, ResultType::Return, "trash_posted_parent"s },
|
||||
{ "\"content.01.2016\""s, ResultType::Return, "content.01.2016"s },
|
||||
{ "\"trash_posted_cat\""s, ResultType::Return, "trash_posted_cat"s },
|
||||
{ "\"progs.01.2016\""s, ResultType::Return, "progs.01.2016"s },
|
||||
{ "\"trash_virus_count\""s, ResultType::Return, "trash_virus_count"s },
|
||||
{ "\"trash_is_android\""s, ResultType::Return, "trash_is_android"s },
|
||||
{ "\"trash_is_wp8\""s, ResultType::Return, "trash_is_wp8"s },
|
||||
{ "\"trash_is_ios\""s, ResultType::Return, "trash_is_ios"s },
|
||||
{ "\"trash_posted\""s, ResultType::Return, "trash_posted"s },
|
||||
{ "\"01.2016\""s, ResultType::Return, "01.2016"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"merchantId\""s, ResultType::Return, "merchantId"s },
|
||||
{ "\"13694_49246\""s, ResultType::Return, "13694_49246"s },
|
||||
{ "\"cps-source\""s, ResultType::Return, "cps-source"s },
|
||||
{ "\"wargaming\""s, ResultType::Return, "wargaming"s },
|
||||
{ "\"cps_provider\""s, ResultType::Return, "cps_provider"s },
|
||||
{ "\"default\""s, ResultType::Return, "default"s },
|
||||
{ "\"errorReason\""s, ResultType::Return, "errorReason"s },
|
||||
{ "\"no errors\""s, ResultType::Return, "no errors"s },
|
||||
{ "\"scid\""s, ResultType::Return, "scid"s },
|
||||
{ "\"isAuthPayment\""s, ResultType::Return, "isAuthPayment"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"rubric\""s, ResultType::Return, "rubric"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"rubric\""s, ResultType::Return, "rubric"s },
|
||||
{ "\"Мир\""s, ResultType::Return, "Мир"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"__ym\""s, ResultType::Return, "__ym"s },
|
||||
{ "\"ecommerce\""s, ResultType::Return, "ecommerce"s },
|
||||
{ "\"impressions\""s, ResultType::Return, "impressions"s },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"863813\""s, ResultType::Return, "863813"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Happy, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Happy, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"863839\""s, ResultType::Return, "863839"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"863847\""s, ResultType::Return, "863847"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911480\""s, ResultType::Return, "911480"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Puppy, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Puppy, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911484\""s, ResultType::Return, "911484"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Little bears, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Little bears, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911489\""s, ResultType::Return, "911489"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911496\""s, ResultType::Return, "911496"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Pretty, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Pretty, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911504\""s, ResultType::Return, "911504"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911508\""s, ResultType::Return, "911508"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Kittens, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Kittens, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911512\""s, ResultType::Return, "911512"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911516\""s, ResultType::Return, "911516"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911520\""s, ResultType::Return, "911520"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911524\""s, ResultType::Return, "911524"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"911528\""s, ResultType::Return, "911528"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Футболка детская 3D Turtle, возраст 1-2 года, трикотаж\""s, ResultType::Return, "Футболка детская 3D Turtle, возраст 1-2 года, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"390.00\""s, ResultType::Return, "390.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"888616\""s, ResultType::Return, "888616"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Вафельница Vitek WX-1102 FL")"s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"s },
|
||||
{ R"("184509")"s, ResultType::Return, "184509"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("Все для детей/Детская техника/Vitek")"s, ResultType::Return, "Все для детей/Детская техника/Vitek"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("В наличии")"s, ResultType::Return, "В наличии"s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("2390.00")"s, ResultType::Return, "2390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("Карточка")"s, ResultType::Return, "Карточка"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("detail")"s, ResultType::Return, "detail"s },
|
||||
{ R"("actionField")"s, ResultType::Return, "actionField"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"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 },
|
||||
{ R"("action")"s, ResultType::Return, "action"s },
|
||||
{ R"("detail")"s, ResultType::Return, "detail"s },
|
||||
{ R"("products")"s, ResultType::Return, "products"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Вафельница Vitek WX-1102 FL")"s, ResultType::Return, "Вафельница Vitek WX-1102 FL"s },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("184509")"s, ResultType::Return, "184509"s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("2390.00")"s, ResultType::Return, "2390.00"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"s },
|
||||
{ R"("Vitek")"s, ResultType::Return, "Vitek"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("Все для детей/Детская техника/Vitek")"s, ResultType::Return, "Все для детей/Детская техника/Vitek"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("В наличии")"s, ResultType::Return, "В наличии"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("isAuthorized")"s, ResultType::Return, "isAuthorized"s },
|
||||
{ R"("isSubscriber")"s, ResultType::Return, "isSubscriber"s },
|
||||
{ R"("postType")"s, ResultType::Return, "postType"s },
|
||||
{ R"("Новости")"s, ResultType::Return, "Новости"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("Электроплита GEFEST Брест ЭПНД 5140-01 0001")"s, ResultType::Return, "Электроплита GEFEST Брест ЭПНД 5140-01 0001"s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("currencyCode")"s, ResultType::Return, "currencyCode"s },
|
||||
{ R"("RUB")"s, ResultType::Return, "RUB"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("trash_login")"s, ResultType::Return, "trash_login"s },
|
||||
{ R"("novikoff")"s, ResultType::Return, "novikoff"s },
|
||||
{ R"("trash_cat_link")"s, ResultType::Return, "trash_cat_link"s },
|
||||
{ R"("progs")"s, ResultType::Return, "progs"s },
|
||||
{ R"("trash_parent_link")"s, ResultType::Return, "trash_parent_link"s },
|
||||
{ R"("content")"s, ResultType::Return, "content"s },
|
||||
{ R"("trash_posted_parent")"s, ResultType::Return, "trash_posted_parent"s },
|
||||
{ R"("content.01.2016")"s, ResultType::Return, "content.01.2016"s },
|
||||
{ R"("trash_posted_cat")"s, ResultType::Return, "trash_posted_cat"s },
|
||||
{ R"("progs.01.2016")"s, ResultType::Return, "progs.01.2016"s },
|
||||
{ R"("trash_virus_count")"s, ResultType::Return, "trash_virus_count"s },
|
||||
{ R"("trash_is_android")"s, ResultType::Return, "trash_is_android"s },
|
||||
{ R"("trash_is_wp8")"s, ResultType::Return, "trash_is_wp8"s },
|
||||
{ R"("trash_is_ios")"s, ResultType::Return, "trash_is_ios"s },
|
||||
{ R"("trash_posted")"s, ResultType::Return, "trash_posted"s },
|
||||
{ R"("01.2016")"s, ResultType::Return, "01.2016"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("merchantId")"s, ResultType::Return, "merchantId"s },
|
||||
{ R"("13694_49246")"s, ResultType::Return, "13694_49246"s },
|
||||
{ R"("cps-source")"s, ResultType::Return, "cps-source"s },
|
||||
{ R"("wargaming")"s, ResultType::Return, "wargaming"s },
|
||||
{ R"("cps_provider")"s, ResultType::Return, "cps_provider"s },
|
||||
{ R"("default")"s, ResultType::Return, "default"s },
|
||||
{ R"("errorReason")"s, ResultType::Return, "errorReason"s },
|
||||
{ R"("no errors")"s, ResultType::Return, "no errors"s },
|
||||
{ R"("scid")"s, ResultType::Return, "scid"s },
|
||||
{ R"("isAuthPayment")"s, ResultType::Return, "isAuthPayment"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("rubric")"s, ResultType::Return, "rubric"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("rubric")"s, ResultType::Return, "rubric"s },
|
||||
{ R"("Мир")"s, ResultType::Return, "Мир"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("__ym")"s, ResultType::Return, "__ym"s },
|
||||
{ R"("ecommerce")"s, ResultType::Return, "ecommerce"s },
|
||||
{ R"("impressions")"s, ResultType::Return, "impressions"s },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("863813")"s, ResultType::Return, "863813"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Happy, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Happy, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("863839")"s, ResultType::Return, "863839"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Pretty kitten, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("863847")"s, ResultType::Return, "863847"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Little tiger, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911480")"s, ResultType::Return, "911480"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Puppy, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Puppy, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911484")"s, ResultType::Return, "911484"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Little bears, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Little bears, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911489")"s, ResultType::Return, "911489"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Dolphin, возраст 2-4 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911496")"s, ResultType::Return, "911496"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Pretty, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Pretty, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911504")"s, ResultType::Return, "911504"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Fairytale, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911508")"s, ResultType::Return, "911508"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Kittens, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Kittens, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911512")"s, ResultType::Return, "911512"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Sunshine, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911516")"s, ResultType::Return, "911516"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Dog in bag, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911520")"s, ResultType::Return, "911520"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Cute puppy, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911524")"s, ResultType::Return, "911524"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Rabbit, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("911528")"s, ResultType::Return, "911528"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Футболка детская 3D Turtle, возраст 1-2 года, трикотаж")"s, ResultType::Return, "Футболка детская 3D Turtle, возраст 1-2 года, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("390.00")"s, ResultType::Return, "390.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("888616")"s, ResultType::Return, "888616"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ "\"3Д Футболка мужская \\\"Collorista\\\" Светлое завтра р-р XL(52-54), 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка мужская \"Collorista\" Светлое завтра р-р XL(52-54), 100% хлопок, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Одежда и обувь/Мужская одежда/Футболки/\""s, ResultType::Return, "/Одежда и обувь/Мужская одежда/Футболки/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"406.60\""s, ResultType::Return, "406.60"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"913361\""s, ResultType::Return, "913361"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"470.00\""s, ResultType::Return, "470.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"913364\""s, ResultType::Return, "913364"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"470.00\""s, ResultType::Return, "470.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"913367\""s, ResultType::Return, "913367"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"470.00\""s, ResultType::Return, "470.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"913385\""s, ResultType::Return, "913385"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"470.00\""s, ResultType::Return, "470.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"913391\""s, ResultType::Return, "913391"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж\""s, ResultType::Return, "3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"/Летние товары/Летний текстиль/\""s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"\""s, ResultType::Return, ""s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"470.00\""s, ResultType::Return, "470.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"/retailrocket/\""s, ResultType::Return, "/retailrocket/"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"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 },
|
||||
{ "\"usertype\""s, ResultType::Return, "usertype"s },
|
||||
{ "\"visitor\""s, ResultType::Return, "visitor"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"__ym\""s, ResultType::Return, "__ym"s },
|
||||
{ "\"ecommerce\""s, ResultType::Return, "ecommerce"s },
|
||||
{ "\"impressions\""s, ResultType::Return, "impressions"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"experiments\""s, ResultType::Return, "experiments"s },
|
||||
{ "\"lang\""s, ResultType::Return, "lang"s },
|
||||
{ "\"ru\""s, ResultType::Return, "ru"s },
|
||||
{ "\"los_portal\""s, ResultType::Return, "los_portal"s },
|
||||
{ "\"los_level\""s, ResultType::Return, "los_level"s },
|
||||
{ "\"none\""s, ResultType::Return, "none"s },
|
||||
{ "\"__ym\""s, ResultType::Return, "__ym"s },
|
||||
{ "\"ecommerce\""s, ResultType::Return, "ecommerce"s },
|
||||
{ "\"currencyCode\""s, ResultType::Return, "currencyCode"s },
|
||||
{ "\"RUR\""s, ResultType::Return, "RUR"s },
|
||||
{ "\"impressions\""s, ResultType::Return, "impressions"s },
|
||||
{ "\"name\""s, ResultType::Return, "name"s },
|
||||
{ "\"Чайник электрический Mystery MEK-1627, белый\""s, ResultType::Return, "Чайник электрический Mystery MEK-1627, белый"s },
|
||||
{ "\"brand\""s, ResultType::Return, "brand"s },
|
||||
{ "\"Mystery\""s, ResultType::Return, "Mystery"s },
|
||||
{ "\"id\""s, ResultType::Return, "id"s },
|
||||
{ "\"187180\""s, ResultType::Return, "187180"s },
|
||||
{ "\"category\""s, ResultType::Return, "category"s },
|
||||
{ "\"Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery\""s, ResultType::Return, "Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery"s },
|
||||
{ "\"variant\""s, ResultType::Return, "variant"s },
|
||||
{ "\"В наличии\""s, ResultType::Return, "В наличии"s },
|
||||
{ "\"price\""s, ResultType::Return, "price"s },
|
||||
{ "\"1630.00\""s, ResultType::Return, "1630.00"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ "\"Карточка\""s, ResultType::Return, "Карточка"s },
|
||||
{ "\"position\""s, ResultType::Return, "position"s },
|
||||
{ "\"detail\""s, ResultType::Return, "detail"s },
|
||||
{ "\"actionField\""s, ResultType::Return, "actionField"s },
|
||||
{ "\"list\""s, ResultType::Return, "list"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Одежда и обувь/Мужская одежда/Футболки/")"s, ResultType::Return, "/Одежда и обувь/Мужская одежда/Футболки/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("406.60")"s, ResultType::Return, "406.60"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("913361")"s, ResultType::Return, "913361"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская World р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("470.00")"s, ResultType::Return, "470.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("913364")"s, ResultType::Return, "913364"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Force р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("470.00")"s, ResultType::Return, "470.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("913367")"s, ResultType::Return, "913367"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Winter tale р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("470.00")"s, ResultType::Return, "470.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("913385")"s, ResultType::Return, "913385"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Moonshine р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("470.00")"s, ResultType::Return, "470.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("913391")"s, ResultType::Return, "913391"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж")"s, ResultType::Return, "3Д Футболка детская Shaman р-р 8-10, 100% хлопок, трикотаж"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("/Летние товары/Летний текстиль/")"s, ResultType::Return, "/Летние товары/Летний текстиль/"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("")"s, ResultType::Return, ""s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("470.00")"s, ResultType::Return, "470.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("/retailrocket/")"s, ResultType::Return, "/retailrocket/"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"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 },
|
||||
{ R"("usertype")"s, ResultType::Return, "usertype"s },
|
||||
{ R"("visitor")"s, ResultType::Return, "visitor"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("__ym")"s, ResultType::Return, "__ym"s },
|
||||
{ R"("ecommerce")"s, ResultType::Return, "ecommerce"s },
|
||||
{ R"("impressions")"s, ResultType::Return, "impressions"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("experiments")"s, ResultType::Return, "experiments"s },
|
||||
{ R"("lang")"s, ResultType::Return, "lang"s },
|
||||
{ R"("ru")"s, ResultType::Return, "ru"s },
|
||||
{ R"("los_portal")"s, ResultType::Return, "los_portal"s },
|
||||
{ R"("los_level")"s, ResultType::Return, "los_level"s },
|
||||
{ R"("none")"s, ResultType::Return, "none"s },
|
||||
{ R"("__ym")"s, ResultType::Return, "__ym"s },
|
||||
{ R"("ecommerce")"s, ResultType::Return, "ecommerce"s },
|
||||
{ R"("currencyCode")"s, ResultType::Return, "currencyCode"s },
|
||||
{ R"("RUR")"s, ResultType::Return, "RUR"s },
|
||||
{ R"("impressions")"s, ResultType::Return, "impressions"s },
|
||||
{ R"("name")"s, ResultType::Return, "name"s },
|
||||
{ R"("Чайник электрический Mystery MEK-1627, белый")"s, ResultType::Return, "Чайник электрический Mystery MEK-1627, белый"s },
|
||||
{ R"("brand")"s, ResultType::Return, "brand"s },
|
||||
{ R"("Mystery")"s, ResultType::Return, "Mystery"s },
|
||||
{ R"("id")"s, ResultType::Return, "id"s },
|
||||
{ R"("187180")"s, ResultType::Return, "187180"s },
|
||||
{ R"("category")"s, ResultType::Return, "category"s },
|
||||
{ R"("Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery")"s, ResultType::Return, "Мелкая бытовая техника/Мелкие кухонные приборы/Чайники электрические/Mystery"s },
|
||||
{ R"("variant")"s, ResultType::Return, "variant"s },
|
||||
{ R"("В наличии")"s, ResultType::Return, "В наличии"s },
|
||||
{ R"("price")"s, ResultType::Return, "price"s },
|
||||
{ R"("1630.00")"s, ResultType::Return, "1630.00"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"s },
|
||||
{ R"("Карточка")"s, ResultType::Return, "Карточка"s },
|
||||
{ R"("position")"s, ResultType::Return, "position"s },
|
||||
{ R"("detail")"s, ResultType::Return, "detail"s },
|
||||
{ R"("actionField")"s, ResultType::Return, "actionField"s },
|
||||
{ R"("list")"s, ResultType::Return, "list"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 },
|
||||
{ "\"/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 },
|
||||
|
@ -54,7 +54,7 @@ TEST(StrongTypedefSuite, NoDefaultCtor)
|
||||
{
|
||||
struct NoDefaultCtor
|
||||
{
|
||||
NoDefaultCtor(int i) {}
|
||||
NoDefaultCtor(int) {} // NOLINT
|
||||
};
|
||||
|
||||
STRONG_TYPEDEF(NoDefaultCtor, MyStruct);
|
||||
|
@ -11,7 +11,7 @@ using Int16 = int16_t;
|
||||
using Int32 = int32_t;
|
||||
using Int64 = int64_t;
|
||||
|
||||
using UInt8 = uint8_t;
|
||||
using UInt8 = char8_t;
|
||||
using UInt16 = uint16_t;
|
||||
using UInt32 = uint32_t;
|
||||
using UInt64 = uint64_t;
|
12
base/common/ya.make
Normal file
12
base/common/ya.make
Normal file
@ -0,0 +1,12 @@
|
||||
LIBRARY()
|
||||
|
||||
PEERDIR(
|
||||
contrib/libs/poco/Util
|
||||
)
|
||||
|
||||
SRCS(
|
||||
argsToConfig.cpp
|
||||
coverage.cpp
|
||||
)
|
||||
|
||||
END()
|
@ -88,19 +88,23 @@ using signal_function = void(int, siginfo_t*, void*);
|
||||
|
||||
static void writeSignalIDtoSignalPipe(int sig)
|
||||
{
|
||||
auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
|
||||
|
||||
char buf[buf_size];
|
||||
DB::WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], buf_size, buf);
|
||||
DB::writeBinary(sig, out);
|
||||
out.next();
|
||||
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
static void terminateRequestedSignalHandler(int sig, siginfo_t * info, void * context)
|
||||
static void terminateRequestedSignalHandler(int sig, siginfo_t *, void *)
|
||||
{
|
||||
writeSignalIDtoSignalPipe(sig);
|
||||
}
|
||||
@ -110,6 +114,8 @@ static void terminateRequestedSignalHandler(int sig, siginfo_t * info, void * co
|
||||
*/
|
||||
static void signalHandler(int sig, siginfo_t * info, void * context)
|
||||
{
|
||||
auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
|
||||
|
||||
char buf[buf_size];
|
||||
DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], buf_size, buf);
|
||||
|
||||
@ -134,6 +140,8 @@ static void signalHandler(int sig, siginfo_t * info, void * context)
|
||||
::sleep(10);
|
||||
call_default_signal_handler(sig);
|
||||
}
|
||||
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
|
||||
@ -166,6 +174,11 @@ public:
|
||||
{
|
||||
int sig = 0;
|
||||
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)
|
||||
{
|
||||
@ -354,10 +367,7 @@ void BaseDaemon::reloadConfiguration()
|
||||
}
|
||||
|
||||
|
||||
BaseDaemon::BaseDaemon()
|
||||
{
|
||||
checkRequiredInstructions();
|
||||
}
|
||||
BaseDaemon::BaseDaemon() = default;
|
||||
|
||||
|
||||
BaseDaemon::~BaseDaemon()
|
||||
@ -368,127 +378,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()
|
||||
{
|
||||
getTaskManager().cancelAll();
|
||||
@ -585,7 +474,7 @@ void debugIncreaseOOMScore() {}
|
||||
void BaseDaemon::initialize(Application & self)
|
||||
{
|
||||
closeFDs();
|
||||
task_manager.reset(new Poco::TaskManager);
|
||||
task_manager = std::make_unique<Poco::TaskManager>();
|
||||
ServerApplication::initialize(self);
|
||||
|
||||
/// now highest priority (lowest value) is PRIO_APPLICATION = -100, we want higher!
|
||||
@ -770,13 +659,15 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
|
||||
signal_pipe.setNonBlocking();
|
||||
signal_pipe.tryIncreaseSize(1 << 20);
|
||||
|
||||
signal_listener.reset(new SignalListener(*this));
|
||||
signal_listener = std::make_unique<SignalListener>(*this);
|
||||
signal_listener_thread.start(*signal_listener);
|
||||
}
|
||||
|
||||
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.
|
||||
@ -831,9 +722,7 @@ void BaseDaemon::defineOptions(Poco::Util::OptionSet& _options)
|
||||
|
||||
bool isPidRunning(pid_t pid)
|
||||
{
|
||||
if (getpgid(pid) >= 0)
|
||||
return 1;
|
||||
return 0;
|
||||
return getpgid(pid) >= 0;
|
||||
}
|
||||
|
||||
BaseDaemon::PID::PID(const std::string & file_)
|
@ -17,7 +17,7 @@
|
||||
#include <Poco/Util/ServerApplication.h>
|
||||
#include <Poco/Net/SocketAddress.h>
|
||||
#include <Poco/Version.h>
|
||||
#include <common/Types.h>
|
||||
#include <common/types.h>
|
||||
#include <common/logger_useful.h>
|
||||
#include <common/getThreadId.h>
|
||||
#include <daemon/GraphiteWriter.h>
|
||||
@ -128,7 +128,7 @@ public:
|
||||
/// close all process FDs except
|
||||
/// 0-2 -- stdin, stdout, stderr
|
||||
/// also doesn't close global internal pipes for signal handling
|
||||
void closeFDs();
|
||||
static void closeFDs();
|
||||
|
||||
protected:
|
||||
/// Возвращает TaskManager приложения
|
||||
@ -198,12 +198,6 @@ protected:
|
||||
std::string config_path;
|
||||
DB::ConfigProcessor::LoadedConfig loaded_config;
|
||||
Poco::Util::AbstractConfiguration * last_configuration = nullptr;
|
||||
|
||||
private:
|
||||
|
||||
/// Check SSE and others instructions availability
|
||||
/// Calls exit on fail
|
||||
void checkRequiredInstructions();
|
||||
};
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
add_library (daemon
|
||||
src/BaseDaemon.cpp
|
||||
src/GraphiteWriter.cpp
|
||||
|
||||
include/daemon/BaseDaemon.h
|
||||
include/daemon/GraphiteWriter.h
|
||||
BaseDaemon.cpp
|
||||
GraphiteWriter.cpp
|
||||
)
|
||||
|
||||
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 ${Poco_Net_LIBRARY} ${Poco_Util_LIBRARY} ${EXECINFO_LIBRARIES})
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <daemon/BaseDaemon.h>
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
#include <Poco/Util/Application.h>
|
||||
#include <Common/getFQDNOrHostName.h>
|
||||
#include <common/getFQDNOrHostName.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <iomanip>
|
||||
@ -30,7 +30,7 @@ GraphiteWriter::GraphiteWriter(const std::string & config_name, const std::strin
|
||||
root_path += hostname_in_path;
|
||||
}
|
||||
|
||||
if (sub_path.size())
|
||||
if (!sub_path.empty())
|
||||
{
|
||||
if (!root_path.empty())
|
||||
root_path += ".";
|
@ -1,16 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <common/DateLUT.h>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
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>
|
||||
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>>
|
||||
|
@ -12,20 +12,20 @@ class [[nodiscard]] basic_scope_guard
|
||||
{
|
||||
public:
|
||||
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)
|
||||
{
|
||||
if (this != &src)
|
||||
{
|
||||
invoke();
|
||||
function = std::exchange(src.function, {});
|
||||
function = src.release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
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>>
|
||||
constexpr basic_scope_guard & operator=(basic_scope_guard<G> && src)
|
||||
@ -33,7 +33,7 @@ public:
|
||||
if (this != &src)
|
||||
{
|
||||
invoke();
|
||||
function = std::exchange(src.function, {});
|
||||
function = src.release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -46,14 +46,26 @@ public:
|
||||
|
||||
~basic_scope_guard() { invoke(); }
|
||||
|
||||
static constexpr bool is_nullable = std::is_constructible_v<bool, F>;
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
if constexpr (std::is_constructible_v<bool, F>)
|
||||
if constexpr (is_nullable)
|
||||
return static_cast<bool>(function);
|
||||
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>>
|
||||
basic_scope_guard<F> & join(basic_scope_guard<G> && other)
|
||||
@ -62,14 +74,14 @@ public:
|
||||
{
|
||||
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->second)();
|
||||
};
|
||||
}
|
||||
else
|
||||
function = std::exchange(other.function, {});
|
||||
function = other.release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -77,7 +89,7 @@ public:
|
||||
private:
|
||||
void invoke()
|
||||
{
|
||||
if constexpr (std::is_constructible_v<bool, F>)
|
||||
if constexpr (is_nullable)
|
||||
{
|
||||
if (!function)
|
||||
return;
|
||||
|
@ -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{};
|
||||
};
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
if (GLIBC_COMPATIBILITY)
|
||||
set (USE_INTERNAL_MEMCPY ON)
|
||||
set (ENABLE_FASTMEMCPY ON)
|
||||
|
||||
enable_language(ASM)
|
||||
include(CheckIncludeFile)
|
||||
|
22
base/glibc-compatibility/musl/clock_getres.c
Normal file
22
base/glibc-compatibility/musl/clock_getres.c
Normal 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);
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "atomic.h"
|
||||
#include "musl_features.h"
|
||||
#include "syscall.h"
|
||||
|
||||
#ifdef VDSO_CGT_SYM
|
||||
@ -54,7 +53,7 @@ static void *volatile vdso_func = (void *)cgt_init;
|
||||
|
||||
#endif
|
||||
|
||||
int __clock_gettime(clockid_t clk, struct timespec *ts)
|
||||
int clock_gettime(clockid_t clk, struct timespec *ts)
|
||||
{
|
||||
int r;
|
||||
|
||||
@ -104,5 +103,3 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
|
||||
return __syscall_ret(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
weak_alias(__clock_gettime, clock_gettime);
|
||||
|
@ -1,10 +1,9 @@
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include "musl_features.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)
|
||||
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);
|
||||
return status;
|
||||
}
|
||||
|
||||
weak_alias(__clock_nanosleep, clock_nanosleep);
|
||||
|
@ -2,7 +2,4 @@
|
||||
|
||||
#define weak __attribute__((__weak__))
|
||||
#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)
|
||||
|
@ -2,6 +2,7 @@
|
||||
.hidden __syscall
|
||||
.type __syscall,@function
|
||||
__syscall:
|
||||
.cfi_startproc
|
||||
movq %rdi,%rax
|
||||
movq %rsi,%rdi
|
||||
movq %rdx,%rsi
|
||||
@ -11,3 +12,4 @@ __syscall:
|
||||
movq 8(%rsp),%r9
|
||||
syscall
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
@ -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 ${Poco_Foundation_LIBRARY})
|
||||
target_include_directories(loggers PUBLIC ..)
|
||||
|
@ -133,12 +133,13 @@ void Loggers::buildLoggers(Poco::Util::AbstractConfiguration & config, Poco::Log
|
||||
split->addChannel(log);
|
||||
}
|
||||
|
||||
bool is_tty = isatty(STDIN_FILENO) || isatty(STDERR_FILENO);
|
||||
bool should_log_to_console = isatty(STDIN_FILENO) || isatty(STDERR_FILENO);
|
||||
bool color_logs_by_default = isatty(STDERR_FILENO);
|
||||
|
||||
if (config.getBool("logger.console", false)
|
||||
|| (!config.hasProperty("logger.console") && !is_daemon && is_tty))
|
||||
|| (!config.hasProperty("logger.console") && !is_daemon && should_log_to_console))
|
||||
{
|
||||
bool color_enabled = config.getBool("logger.color_terminal", true) && is_tty;
|
||||
bool color_enabled = config.getBool("logger.color_terminal", color_logs_by_default);
|
||||
|
||||
Poco::AutoPtr<OwnPatternFormatter> pf = new OwnPatternFormatter(this, OwnPatternFormatter::ADD_NOTHING, color_enabled);
|
||||
Poco::AutoPtr<DB::OwnFormattingChannel> log = new DB::OwnFormattingChannel(pf, new Poco::ConsoleChannel);
|
@ -9,57 +9,10 @@
|
||||
#include <Interpreters/InternalTextLogsQueue.h>
|
||||
#include <Common/CurrentThread.h>
|
||||
#include <common/getThreadId.h>
|
||||
#include <common/terminalColors.h>
|
||||
#include "Loggers.h"
|
||||
|
||||
|
||||
static std::string setColor(UInt64 num)
|
||||
{
|
||||
/// Make a random RGB color that has constant brightness.
|
||||
/// https://en.wikipedia.org/wiki/YCbCr
|
||||
|
||||
/// Note that this is darker than the middle relative luminance, see "Gamma_correction" and "Luma_(video)".
|
||||
/// It still looks awesome.
|
||||
UInt8 y = 128;
|
||||
|
||||
UInt8 cb = num % 256;
|
||||
UInt8 cr = num / 256 % 256;
|
||||
|
||||
UInt8 r = std::max(0.0, std::min(255.0, y + 1.402 * (cr - 128)));
|
||||
UInt8 g = std::max(0.0, std::min(255.0, y - 0.344136 * (cb - 128) - 0.714136 * (cr - 128)));
|
||||
UInt8 b = std::max(0.0, std::min(255.0, y + 1.772 * (cb - 128)));
|
||||
|
||||
/// ANSI escape sequence to set 24-bit foreground font color in terminal.
|
||||
return "\033[38;2;" + DB::toString(r) + ";" + DB::toString(g) + ";" + DB::toString(b) + "m";
|
||||
}
|
||||
|
||||
static const char * setColorForLogPriority(int priority)
|
||||
{
|
||||
if (priority < 1 || priority > 8)
|
||||
return "";
|
||||
|
||||
static const char * colors[] =
|
||||
{
|
||||
"",
|
||||
"\033[1;41m", /// Fatal
|
||||
"\033[7;31m", /// Critical
|
||||
"\033[1;31m", /// Error
|
||||
"\033[0;31m", /// Warning
|
||||
"\033[0;33m", /// Notice
|
||||
"\033[1m", /// Information
|
||||
"", /// Debug
|
||||
"\033[2m", /// Trace
|
||||
};
|
||||
|
||||
return colors[priority];
|
||||
}
|
||||
|
||||
static const char * resetColor()
|
||||
{
|
||||
return "\033[0m";
|
||||
}
|
||||
|
||||
|
||||
|
||||
OwnPatternFormatter::OwnPatternFormatter(const Loggers * loggers_, OwnPatternFormatter::Options options_, bool color_)
|
||||
: Poco::PatternFormatter(""), loggers(loggers_), options(options_), color(color_)
|
||||
{
|
@ -71,7 +71,8 @@ void OwnSplitChannel::logSplit(const Poco::Message & msg)
|
||||
|
||||
|
||||
/// 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;
|
||||
|
||||
@ -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);
|
||||
text_log = log;
|
||||
text_log_max_priority = max_priority;
|
||||
text_log_max_priority.store(max_priority, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
}
|
@ -33,7 +33,7 @@ private:
|
||||
std::mutex text_log_mutex;
|
||||
|
||||
std::weak_ptr<DB::TextLog> text_log;
|
||||
int text_log_max_priority = -1;
|
||||
std::atomic<int> text_log_max_priority = -1;
|
||||
};
|
||||
|
||||
}
|
@ -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 ..)
|
@ -1 +0,0 @@
|
||||
add_library(memcpy memcpy.c)
|
@ -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
|
||||
|
||||
|
||||
|
@ -1,97 +0,0 @@
|
||||
Build
|
||||
=====
|
||||
|
||||
with gcc:
|
||||
> gcc -O3 -msse2 FastMemcpy.c -o FastMemcpy
|
||||
|
||||
with msvc:
|
||||
> cl -nologo -O2 FastMemcpy.c
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
* 50% speedup in avg. vs traditional memcpy in msvc 2012 or gcc 4.9
|
||||
* small size copy optimized with jump table
|
||||
* medium size copy optimized with sse2 vector copy
|
||||
* huge size copy optimized with cache prefetch & movntdq
|
||||
|
||||
Reference
|
||||
=========
|
||||
|
||||
[Using Block Prefetch for Optimized Memory Performance](http://files.rsdn.ru/23380/AMD_block_prefetch_paper.pdf)
|
||||
|
||||
The article only focused on aligned huge memory copy. You need handle other conditions by your self.
|
||||
|
||||
|
||||
Results
|
||||
=======
|
||||
|
||||
```
|
||||
result: gcc4.9 (msvc 2012 got a similar result):
|
||||
|
||||
benchmark(size=32 bytes, times=16777216):
|
||||
result(dst aligned, src aligned): memcpy_fast=81ms memcpy=281 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=88ms memcpy=254 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=87ms memcpy=245 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=81ms memcpy=258 ms
|
||||
|
||||
benchmark(size=64 bytes, times=16777216):
|
||||
result(dst aligned, src aligned): memcpy_fast=91ms memcpy=364 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=95ms memcpy=336 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=96ms memcpy=353 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=99ms memcpy=346 ms
|
||||
|
||||
benchmark(size=512 bytes, times=8388608):
|
||||
result(dst aligned, src aligned): memcpy_fast=124ms memcpy=242 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=166ms memcpy=555 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=168ms memcpy=602 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=174ms memcpy=614 ms
|
||||
|
||||
benchmark(size=1024 bytes, times=4194304):
|
||||
result(dst aligned, src aligned): memcpy_fast=119ms memcpy=171 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=182ms memcpy=442 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=163ms memcpy=466 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=168ms memcpy=472 ms
|
||||
|
||||
benchmark(size=4096 bytes, times=524288):
|
||||
result(dst aligned, src aligned): memcpy_fast=68ms memcpy=82 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=94ms memcpy=226 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=134ms memcpy=216 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=84ms memcpy=188 ms
|
||||
|
||||
benchmark(size=8192 bytes, times=262144):
|
||||
result(dst aligned, src aligned): memcpy_fast=55ms memcpy=70 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=75ms memcpy=192 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=79ms memcpy=223 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=91ms memcpy=219 ms
|
||||
|
||||
benchmark(size=1048576 bytes, times=2048):
|
||||
result(dst aligned, src aligned): memcpy_fast=181ms memcpy=165 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=192ms memcpy=303 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=218ms memcpy=310 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=183ms memcpy=307 ms
|
||||
|
||||
benchmark(size=4194304 bytes, times=512):
|
||||
result(dst aligned, src aligned): memcpy_fast=263ms memcpy=398 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=269ms memcpy=433 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=306ms memcpy=497 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=285ms memcpy=417 ms
|
||||
|
||||
benchmark(size=8388608 bytes, times=256):
|
||||
result(dst aligned, src aligned): memcpy_fast=287ms memcpy=421 ms
|
||||
result(dst aligned, src unalign): memcpy_fast=288ms memcpy=430 ms
|
||||
result(dst unalign, src aligned): memcpy_fast=285ms memcpy=510 ms
|
||||
result(dst unalign, src unalign): memcpy_fast=291ms memcpy=440 ms
|
||||
|
||||
benchmark random access:
|
||||
memcpy_fast=487ms memcpy=1000ms
|
||||
|
||||
```
|
||||
|
||||
|
||||
About
|
||||
=====
|
||||
|
||||
skywind
|
||||
|
||||
http://www.skywind.me
|
@ -1,3 +0,0 @@
|
||||
#include "memcpy.h"
|
||||
|
||||
/// This is needed to generate an object file for linking.
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "impl/FastMemcpy.h"
|
||||
|
||||
void * __attribute__((__weak__)) memcpy(void * __restrict destination, const void * __restrict source, size_t size)
|
||||
{
|
||||
return memcpy_fast(destination, source, size);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,32 +1,18 @@
|
||||
add_library (mysqlxx
|
||||
src/Connection.cpp
|
||||
src/Exception.cpp
|
||||
src/Query.cpp
|
||||
src/ResultBase.cpp
|
||||
src/StoreQueryResult.cpp
|
||||
src/UseQueryResult.cpp
|
||||
src/Row.cpp
|
||||
src/Value.cpp
|
||||
src/Pool.cpp
|
||||
src/PoolWithFailover.cpp
|
||||
|
||||
include/mysqlxx/Connection.h
|
||||
include/mysqlxx/Exception.h
|
||||
include/mysqlxx/mysqlxx.h
|
||||
include/mysqlxx/Null.h
|
||||
include/mysqlxx/Pool.h
|
||||
include/mysqlxx/PoolWithFailover.h
|
||||
include/mysqlxx/Query.h
|
||||
include/mysqlxx/ResultBase.h
|
||||
include/mysqlxx/Row.h
|
||||
include/mysqlxx/StoreQueryResult.h
|
||||
include/mysqlxx/Transaction.h
|
||||
include/mysqlxx/Types.h
|
||||
include/mysqlxx/UseQueryResult.h
|
||||
include/mysqlxx/Value.h
|
||||
Connection.cpp
|
||||
Exception.cpp
|
||||
Query.cpp
|
||||
ResultBase.cpp
|
||||
StoreQueryResult.cpp
|
||||
UseQueryResult.cpp
|
||||
Row.cpp
|
||||
Value.cpp
|
||||
Pool.cpp
|
||||
PoolFactory.cpp
|
||||
PoolWithFailover.cpp
|
||||
)
|
||||
|
||||
target_include_directories (mysqlxx PUBLIC include)
|
||||
target_include_directories (mysqlxx PUBLIC ..)
|
||||
|
||||
if (USE_INTERNAL_MYSQL_LIBRARY)
|
||||
target_include_directories (mysqlxx PUBLIC ${ClickHouse_SOURCE_DIR}/contrib/mariadb-connector-c/include)
|
||||
@ -57,5 +43,5 @@ if (NOT USE_INTERNAL_MYSQL_LIBRARY AND OPENSSL_INCLUDE_DIR)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory (src/tests)
|
||||
add_subdirectory (tests)
|
||||
endif ()
|
||||
|
@ -22,15 +22,20 @@ void Pool::Entry::incrementRefCount()
|
||||
if (!data)
|
||||
return;
|
||||
++data->ref_count;
|
||||
mysql_thread_init();
|
||||
if (data->ref_count == 1)
|
||||
mysql_thread_init();
|
||||
}
|
||||
|
||||
void Pool::Entry::decrementRefCount()
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
--data->ref_count;
|
||||
mysql_thread_end();
|
||||
if (data->ref_count > 0)
|
||||
{
|
||||
--data->ref_count;
|
||||
if (data->ref_count == 0)
|
||||
mysql_thread_end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +119,7 @@ Pool::~Pool()
|
||||
}
|
||||
|
||||
|
||||
Pool::Entry Pool::Get()
|
||||
Pool::Entry Pool::get()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
@ -169,14 +174,24 @@ Pool::Entry Pool::tryGet()
|
||||
return Entry();
|
||||
}
|
||||
|
||||
void Pool::removeConnection(Connection* connection)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
if (connection)
|
||||
{
|
||||
if (connection->ref_count > 0)
|
||||
{
|
||||
connection->conn.disconnect();
|
||||
connection->ref_count = 0;
|
||||
}
|
||||
connections.remove(connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Pool::Entry::disconnect()
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
decrementRefCount();
|
||||
data->conn.disconnect();
|
||||
}
|
||||
pool->removeConnection(data);
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ public:
|
||||
~Pool();
|
||||
|
||||
/// Allocates connection.
|
||||
Entry Get();
|
||||
Entry get();
|
||||
|
||||
/// Allocates connection.
|
||||
/// If database is not accessible, returns empty Entry object.
|
||||
@ -198,6 +198,8 @@ public:
|
||||
return description;
|
||||
}
|
||||
|
||||
void removeConnection(Connection * connection);
|
||||
|
||||
protected:
|
||||
/// Number of MySQL connections which are created at launch.
|
||||
unsigned default_connections;
|
122
base/mysqlxx/PoolFactory.cpp
Normal file
122
base/mysqlxx/PoolFactory.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include <mysqlxx/PoolFactory.h>
|
||||
#include <Poco/Util/Application.h>
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
|
||||
namespace mysqlxx
|
||||
{
|
||||
|
||||
struct PoolFactory::Impl
|
||||
{
|
||||
// Cache of already affected pools identified by their config name
|
||||
std::map<std::string, std::shared_ptr<PoolWithFailover>> pools;
|
||||
|
||||
// Cache of Pool ID (host + port + user +...) cibling already established shareable pool
|
||||
std::map<std::string, std::string> pools_by_ids;
|
||||
|
||||
/// Protect pools and pools_by_ids caches
|
||||
std::mutex mutex;
|
||||
};
|
||||
|
||||
PoolWithFailover PoolFactory::get(const std::string & config_name, unsigned default_connections,
|
||||
unsigned max_connections, size_t max_tries)
|
||||
{
|
||||
return get(Poco::Util::Application::instance().config(), config_name, default_connections, max_connections, max_tries);
|
||||
}
|
||||
|
||||
/// Duplicate of code from StringUtils.h. Copied here for less dependencies.
|
||||
static bool startsWith(const std::string & s, const char * prefix)
|
||||
{
|
||||
return s.size() >= strlen(prefix) && 0 == memcmp(s.data(), prefix, strlen(prefix));
|
||||
}
|
||||
|
||||
static std::string getPoolEntryName(const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_name)
|
||||
{
|
||||
bool shared = config.getBool(config_name + ".share_connection", false);
|
||||
|
||||
// Not shared no need to generate a name the pool won't be stored
|
||||
if (!shared)
|
||||
return "";
|
||||
|
||||
std::string entry_name;
|
||||
std::string host = config.getString(config_name + ".host", "");
|
||||
std::string port = config.getString(config_name + ".port", "");
|
||||
std::string user = config.getString(config_name + ".user", "");
|
||||
std::string db = config.getString(config_name + ".db", "");
|
||||
std::string table = config.getString(config_name + ".table", "");
|
||||
|
||||
Poco::Util::AbstractConfiguration::Keys keys;
|
||||
config.keys(config_name, keys);
|
||||
|
||||
if (config.has(config_name + ".replica"))
|
||||
{
|
||||
Poco::Util::AbstractConfiguration::Keys replica_keys;
|
||||
config.keys(config_name, replica_keys);
|
||||
for (const auto & replica_config_key : replica_keys)
|
||||
{
|
||||
/// There could be another elements in the same level in configuration file, like "user", "port"...
|
||||
if (startsWith(replica_config_key, "replica"))
|
||||
{
|
||||
std::string replica_name = config_name + "." + replica_config_key;
|
||||
std::string tmp_host = config.getString(replica_name + ".host", host);
|
||||
std::string tmp_port = config.getString(replica_name + ".port", port);
|
||||
std::string tmp_user = config.getString(replica_name + ".user", user);
|
||||
entry_name += (entry_name.empty() ? "" : "|") + tmp_user + "@" + tmp_host + ":" + tmp_port + "/" + db;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_name = user + "@" + host + ":" + port + "/" + db;
|
||||
}
|
||||
return entry_name;
|
||||
}
|
||||
|
||||
PoolWithFailover PoolFactory::get(const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_name, unsigned default_connections, unsigned max_connections, size_t max_tries)
|
||||
{
|
||||
|
||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
||||
if (auto entry = impl->pools.find(config_name); entry != impl->pools.end())
|
||||
{
|
||||
return *(entry->second.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string entry_name = getPoolEntryName(config, config_name);
|
||||
if (auto id = impl->pools_by_ids.find(entry_name); id != impl->pools_by_ids.end())
|
||||
{
|
||||
entry = impl->pools.find(id->second);
|
||||
std::shared_ptr<PoolWithFailover> pool = entry->second;
|
||||
impl->pools.insert_or_assign(config_name, pool);
|
||||
return *pool;
|
||||
}
|
||||
|
||||
auto pool = std::make_shared<PoolWithFailover>(config, config_name, default_connections, max_connections, max_tries);
|
||||
// Check the pool will be shared
|
||||
if (!entry_name.empty())
|
||||
{
|
||||
// Store shared pool
|
||||
impl->pools.insert_or_assign(config_name, pool);
|
||||
impl->pools_by_ids.insert_or_assign(entry_name, config_name);
|
||||
}
|
||||
return *(pool.get());
|
||||
}
|
||||
}
|
||||
|
||||
void PoolFactory::reset()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(impl->mutex);
|
||||
impl->pools.clear();
|
||||
impl->pools_by_ids.clear();
|
||||
}
|
||||
|
||||
PoolFactory::PoolFactory() : impl(std::make_unique<PoolFactory::Impl>()) {}
|
||||
|
||||
PoolFactory & PoolFactory::instance()
|
||||
{
|
||||
static PoolFactory ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
55
base/mysqlxx/PoolFactory.h
Normal file
55
base/mysqlxx/PoolFactory.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <mysqlxx/PoolWithFailover.h>
|
||||
|
||||
|
||||
#define MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS 1
|
||||
#define MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS 16
|
||||
#define MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES 3
|
||||
|
||||
|
||||
namespace mysqlxx
|
||||
{
|
||||
|
||||
/*
|
||||
* PoolFactory.h
|
||||
* This class is a helper singleton to mutualize connections to MySQL.
|
||||
*/
|
||||
class PoolFactory final : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
static PoolFactory & instance();
|
||||
|
||||
PoolFactory(const PoolFactory &) = delete;
|
||||
|
||||
/** Allocates a PoolWithFailover to connect to MySQL. */
|
||||
PoolWithFailover get(const std::string & config_name,
|
||||
unsigned default_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
|
||||
unsigned max_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS,
|
||||
size_t max_tries = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES);
|
||||
|
||||
/** Allocates a PoolWithFailover to connect to MySQL. */
|
||||
PoolWithFailover get(const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_name,
|
||||
unsigned default_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
|
||||
unsigned max_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS,
|
||||
size_t max_tries = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES);
|
||||
|
||||
void reset();
|
||||
|
||||
|
||||
~PoolFactory() = default;
|
||||
PoolFactory& operator=(const PoolFactory &) = delete;
|
||||
|
||||
private:
|
||||
PoolFactory();
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user