Merge branch 'master' of github.com:yandex/ClickHouse into group_by_in_order_optimization

This commit is contained in:
Dmitry 2020-03-30 20:05:07 +03:00
commit 3146d99d90
3725 changed files with 198241 additions and 57741 deletions

View File

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

205
.clang-tidy Normal file
View File

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

1
.github/CODEOWNERS vendored
View File

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

View File

@ -0,0 +1,27 @@
---
name: Backward compatibility issue
about: Create a report to help us improve ClickHouse
title: ''
labels: backward compatibility
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the issue**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server versions are incompatible
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/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.

View File

@ -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**

View File

@ -0,0 +1,30 @@
---
name: Unexpected behaviour
about: Create a report to help us improve ClickHouse
title: ''
labels: unexpected behaviour
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the unexpected behaviour**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server version to use
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/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.

View File

@ -0,0 +1,30 @@
---
name: Usability issue
about: Create a report to help us improve ClickHouse
title: ''
labels: usability
assignees: ''
---
(you don't have to strictly follow this form)
**Describe the issue**
A clear and concise description of what works not as it is supposed to.
**How to reproduce**
* Which ClickHouse server version to use
* Which interface to use, if matters
* Non-default settings, if any
* `CREATE TABLE` statements for all tables involved
* Sample data for all these tables, use [clickhouse-obfuscator](https://github.com/ClickHouse/ClickHouse/blob/master/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.

4
.gitignore vendored
View File

@ -15,7 +15,11 @@
/docs/build
/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

9
.gitmodules vendored
View File

@ -104,6 +104,10 @@
[submodule "contrib/sparsehash-c11"]
path = contrib/sparsehash-c11
url = https://github.com/sparsehash/sparsehash-c11.git
[submodule "contrib/grpc"]
path = contrib/grpc
url = https://github.com/ClickHouse-Extras/grpc.git
branch = v1.25.0
[submodule "contrib/aws"]
path = contrib/aws
url = https://github.com/aws/aws-sdk-cpp.git
@ -136,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
@ -144,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

File diff suppressed because it is too large Load Diff

View File

@ -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,9 +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 (WERROR)
add_warning(error)
endif ()
# Make this extra-checks for correct library dependencies.
@ -276,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 ()
@ -326,7 +316,6 @@ include (cmake/find/poco.cmake)
include (cmake/find/lz4.cmake)
include (cmake/find/xxhash.cmake)
include (cmake/find/sparsehash.cmake)
include (cmake/find/rt.cmake)
include (cmake/find/execinfo.cmake)
include (cmake/find/re2.cmake)
include (cmake/find/libgsasl.cmake)
@ -341,10 +330,10 @@ endif()
include (cmake/find/libxml2.cmake)
include (cmake/find/brotli.cmake)
include (cmake/find/protobuf.cmake)
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)
@ -364,9 +353,8 @@ if (ENABLE_TESTS)
endif ()
# Need to process before "contrib" dir:
include (libs/libcommon/cmake/find_jemalloc.cmake)
include (libs/libcommon/cmake/find_cctz.cmake)
include (libs/libmysqlxx/cmake/find_mysqlclient.cmake)
include (cmake/find/jemalloc.cmake)
include (cmake/find/mysqlclient.cmake)
# When testing for memory leaks with Valgrind, don't link tcmalloc or jemalloc.
@ -398,7 +386,7 @@ macro (add_executable target)
endif()
endmacro()
add_subdirectory (libs)
add_subdirectory (base)
add_subdirectory (utils)
add_subdirectory (dbms)

1
CODE_OF_CONDUCT.md Normal file
View File

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

View File

@ -1,17 +1,21 @@
[![ClickHouse — open source distributed column-oriented DBMS](https://github.com/ClickHouse/ClickHouse/raw/master/website/images/logo-400x240.png)](https://clickhouse.yandex)
[![ClickHouse — open source distributed column-oriented DBMS](https://github.com/ClickHouse/ClickHouse/raw/master/website/images/logo-400x240.png)](https://clickhouse.tech)
ClickHouse is an open-source column-oriented database management system that allows generating analytical data reports in real time.
## Useful Links
* [Official website](https://clickhouse.yandex/) has quick high-level overview of ClickHouse on main page.
* [Tutorial](https://clickhouse.yandex/tutorial.html) shows how to set up and query small ClickHouse cluster.
* [Documentation](https://clickhouse.yandex/docs/en/) provides more in-depth information.
* [Official website](https://clickhouse.tech/) has quick high-level overview of ClickHouse on main page.
* [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.yandex/#contacts) can help to get your questions answered if there are any.
* [Contacts](https://clickhouse.tech/#contacts) can help to get your questions answered if there are any.
* You can also [fill this form](https://forms.yandex.com/surveys/meet-yandex-clickhouse-team/) to meet Yandex ClickHouse team in person.
## 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.

View File

@ -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

11
base/CMakeLists.txt Normal file
View File

@ -0,0 +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_MYSQL)
add_subdirectory (mysqlxx)
endif ()

View File

@ -0,0 +1,90 @@
configure_file (config_common.h.in config_common.h)
set (SRCS
argsToConfig.cpp
coverage.cpp
DateLUT.cpp
DateLUTImpl.cpp
demangle.cpp
getFQDNOrHostName.cpp
getMemoryAmount.cpp
getThreadId.cpp
JSON.cpp
LineReader.cpp
mremap.cpp
phdr_cache.cpp
preciseExp10.c
setTerminalEcho.cpp
shift10.cpp
sleep.cpp
terminalColors.cpp
)
if (ENABLE_REPLXX)
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})
if (WITH_COVERAGE)
target_compile_definitions(common PUBLIC WITH_COVERAGE=1)
else ()
target_compile_definitions(common PUBLIC WITH_COVERAGE=0)
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})
endif ()
if(NOT USE_INTERNAL_POCO_LIBRARY)
target_include_directories (common SYSTEM BEFORE PUBLIC ${Poco_Foundation_INCLUDE_DIR})
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 ()
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)
add_subdirectory (tests)
endif ()

View File

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

View File

@ -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.

View File

@ -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));

View File

@ -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>
@ -391,9 +392,9 @@ public:
/*
The bits in week_mode has the following meaning:
WeekModeFlag::MONDAY_FIRST (0) If not set Sunday is first day of week
If set Monday is first day of week
WeekModeFlag::YEAR (1) If not set Week is in range 0-53
WeekModeFlag::MONDAY_FIRST (0) If not set Sunday is first day of week
If set Monday is first day of week
WeekModeFlag::YEAR (1) If not set Week is in range 0-53
Week 0 is returned for the the last week of the previous year (for
a date at start of january) In this case one can get 53 for the
@ -401,19 +402,19 @@ public:
relevant for the given year. Note that this flag is only
releveant if WeekModeFlag::JANUARY is not set.
If set Week is in range 1-53.
If set Week is in range 1-53.
In this case one may get week 53 for a date in January (when
the week is that last week of previous year) and week 1 for a
date in December.
WeekModeFlag::FIRST_WEEKDAY (2) If not set Weeks are numbered according
WeekModeFlag::FIRST_WEEKDAY (2) If not set Weeks are numbered according
to ISO 8601:1988
If set The week that contains the first
If set The week that contains the first
'first-day-of-week' is week 1.
WeekModeFlag::NEWYEAR_DAY (3) If not set no meaning
If set The week that contains the January 1 is week 1.
WeekModeFlag::NEWYEAR_DAY (3) If not set no meaning
If set The week that contains the January 1 is week 1.
Week is in range 1-53.
And ignore WeekModeFlag::YEAR, WeekModeFlag::FIRST_WEEKDAY

View File

@ -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.

View File

@ -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();
@ -399,7 +399,7 @@ JSON::Pos JSON::skipElement() const
ElementType type = getType();
switch(type)
switch (type)
{
case TYPE_NULL:
return skipNull();
@ -587,7 +587,7 @@ std::string JSON::getString() const
++s;
checkPos(s);
switch(*s)
switch (*s)
{
case '"':
buf += '"';
@ -665,7 +665,7 @@ StringRef JSON::getRawString() const
if (*s != '"')
throw JSONException(std::string("JSON: expected \", got ") + *s);
while (++s != ptr_end && *s != '"');
if (s != ptr_end )
if (s != ptr_end)
return StringRef(ptr_begin + 1, s - ptr_begin - 1);
throw JSONException("JSON: incorrect syntax (expected end of string, found end of JSON).");
}
@ -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;

View File

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

View File

@ -3,8 +3,8 @@
#include <iostream>
#include <string_view>
#include <port/unistd.h>
#include <string.h>
#include <unistd.h>
#ifdef OS_LINUX
/// We can detect if code is linked with one or another readline variants or open the library dynamically.
@ -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;
});

View File

@ -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
{

View 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
};

View 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;
};

View File

@ -1,8 +1,9 @@
#include <common/ReplxxLineReader.h>
#include <errno.h>
#include <port/unistd.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();
};

View File

@ -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;

View File

@ -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>;

View File

@ -1,4 +1,4 @@
#include <common/argsToConfig.h>
#include "argsToConfig.h"
#include <Poco/Util/Application.h>
#include <Poco/Util/LayeredConfiguration.h>

View File

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

View File

@ -4,4 +4,3 @@
#cmakedefine01 USE_JEMALLOC
#cmakedefine01 UNBUNDLED
#cmakedefine01 WITH_COVERAGE

View File

@ -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
View File

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

View File

@ -1,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;
}
}

View File

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

View File

@ -33,7 +33,7 @@ uint64_t getMemoryAmountOrZero()
/* New 64-bit MEMORYSTATUSEX isn't available. Use old 32.bit */
MEMORYSTATUS status;
status.dwLength = sizeof(status);
GlobalMemoryStatus( &status );
GlobalMemoryStatus(&status);
return status.dwTotalPhys;
#elif defined(WIN32) || defined(_WIN32)
@ -41,7 +41,7 @@ uint64_t getMemoryAmountOrZero()
/* Use new 64-bit MEMORYSTATUSEX, not old 32-bit MEMORYSTATUS */
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx( &status );
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys;
#else
@ -58,24 +58,24 @@ 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? */
#elif defined(_SC_AIX_REALMEM)
/* AIX. ----------------------------------------------------- */
return sysconf( _SC_AIX_REALMEM ) * 1024;
return sysconf(_SC_AIX_REALMEM) * 1024;
#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. -------- */
@ -87,10 +87,10 @@ uint64_t getMemoryAmountOrZero()
mib[1] = HW_PHYSMEM; /* Others. ------------------ */
#endif
unsigned int size = 0; /* 32-bit */
size_t len = sizeof( size );
if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 ) {
size_t len = sizeof(size);
if (sysctl(mib, 2, &size, &len, nullptr, 0) == 0)
return size;
}
return 0; /* Failed? */
#endif /* sysctl and sysconf variants */

View File

@ -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, &current_tid))
throw std::logic_error("pthread_threadid_np returned error");

View File

@ -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)

View File

@ -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)
{

65
base/common/memory.h Normal file
View File

@ -0,0 +1,65 @@
#pragma once
#include <new>
#include "defines.h"
#if __has_include(<common/config_common.h>)
#include <common/config_common.h>
#endif
#if USE_JEMALLOC
#include <jemalloc/jemalloc.h>
#if JEMALLOC_VERSION_MAJOR < 4
#undef USE_JEMALLOC
#define USE_JEMALLOC 0
#include <cstdlib>
#endif
#else
#include <cstdlib>
#endif
namespace Memory
{
inline ALWAYS_INLINE void * newImpl(std::size_t size)
{
auto * ptr = malloc(size);
if (likely(ptr != nullptr))
return ptr;
/// @note no std::get_new_handler logic implemented
throw std::bad_alloc{};
}
inline ALWAYS_INLINE void * newNoExept(std::size_t size) noexcept
{
return malloc(size);
}
inline ALWAYS_INLINE void deleteImpl(void * ptr) noexcept
{
free(ptr);
}
#if USE_JEMALLOC
inline ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size) noexcept
{
if (unlikely(ptr == nullptr))
return;
sdallocx(ptr, size, 0);
}
#else
inline ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size [[maybe_unused]]) noexcept
{
free(ptr);
}
#endif
}

View File

@ -1,14 +1,15 @@
#include <common/shift10.h>
#include <common/likely.h>
#include "defines.h"
#include <limits>
#include <port/ssize_t.h>
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[] =
{
@ -46,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;
}

View File

@ -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:

View 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";
}

View 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();

View File

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

View File

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

View File

@ -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);

View File

@ -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;
}

View File

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

View File

@ -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"}));
}
}

View File

@ -0,0 +1,656 @@
#include <vector>
#include <string>
#include <exception>
#include <common/JSON.h>
#include <boost/range/irange.hpp>
using namespace std::literals::string_literals;
#include <gtest/gtest.h>
enum class ResultType
{
Return,
Throw
};
struct GetStringTestRecord
{
std::string input;
ResultType result_type;
std::string result;
};
TEST(JSONSuite, SimpleTest)
{
std::vector<GetStringTestRecord> test_data =
{
{ 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 },
{ 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 },
{ "\"/Творчество/Рисование/Инструменты и кра\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Строительство и ремонт/Силовая техника/Зарядные устройства для автомобильных аккумуляторов/Пуско-зарядные устр\xD0\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Строительство и ремонт/Силовая техника/Зарядные устройств\xD0\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Строительство и ремонт/Силовая техника/Зарядные устройства для автомобиль\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\0t"s, ResultType::Throw, "JSON: expected \", got \0"s },
{ "\"/Хозтовары/Хранение вещей и организа\xD1\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Хозтовары/Товары для стир\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"li\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/734859/samolet-radioupravlyaemyy-istrebitel-rabotaet-o\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/kosmetika-i-parfyum/parfyumeriya/mu\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/ko\0\x04"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ ""s, ResultType::Throw, "JSON: begin >= end."s },
{ "\"/stroitelstvo-i-remont/stroit\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/stroitelstvo-i-remont/stroitelnyy-instrument/av\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/s\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Строительство и ремонт/Строительный инструмент/Изм\0e"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/avto/soputstvuy\0l"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/str\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Отвертка 2 в 1 \\\"TUNDRA basic\\\" 5х75 мм (+,-) \0\xFF"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/stroitelstvo-i-remont/stroitelnyy-instrument/avtoinstrumen\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Мелкая бытовая техника/Мелки\xD0\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Пряжа \\\"Бамбук стрейч\\0\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Карандаш чёрнографитны\xD0\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Творчество/Рукоделие, аппликации/Пряжа и шерсть для \xD0\0l"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/1071547/karandash-chernografitnyy-volshebstvo-nv-kruglyy-d-7-2mm-dl-176mm-plast-tuba/\0e"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"ca\0e"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"ca\0e"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/1165424/chipbord-vyrubnoy-dlya-skrapbukinga-malyshi-mikki-maus-disney-bebi\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/posuda/kuhonnye-prinadlezhnosti-i-i\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Канцтовары/Ежедневники и блокн\xD0\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/kanctovary/ezhednevniki-i-blok\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Стакан \xD0\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Набор бумаги для скрапбукинга \\\"Мои первый годик\\\": Микки Маус, Дисней бэби, 12 листов 29.5 х 29.5 см, 160\0\x80"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"c\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Органайзер для хранения аксессуаров, \0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"quantity\00"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Сменный блок для тетрадей на кольцах А5, 160 листов клетка, офсет \xE2\x84\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Сувениры/Ф\xD0\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"\0\""s, ResultType::Return, "\0"s },
{ "\"\0\x04"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"va\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"ca\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"В \0\x04"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/letnie-tovary/z\0\x04"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Посудомоечная машина Ha\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Крупная бытов\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Полочная акустическая система Magnat Needl\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"brand\00"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"pos\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"c\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"var\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Телевизоры и видеотехника/Всё для домашних кинотеатр\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Флеш-диск Transcend JetFlash 620 8GB (TS8GJF62\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Табурет Мег\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"variant\0\x04"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Катал\xD0\0\""s, ResultType::Return, "Катал\xD0\0"s },
{ "\"К\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Полочная акустическая система Magnat Needl\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"brand\00"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"pos\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"c\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"17\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/igrushki/razvivayusc\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Ключница \\\"\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Игр\xD1\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Игрушки/Игрушки для девочек/Игровые модули дл\xD1\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Крупная бытовая техника/Стиральные машины/С фронт\xD0\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\0 "s, ResultType::Throw, "JSON: expected \", got \0"s },
{ "\"Светодиодная лента SMD3528, 5 м. IP33, 60LED, зеленый, 4,8W/мет\xD1\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Сантехника/Мебель для ванных комнат/Стол\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\0o"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 },
{ "\"/posuda/kuhonnye-prinadlezhnosti-i-instrumenty/kuhonnye-pr\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-\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Творчество/Рисование/Инструменты и кра\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Строительство и ремонт/Силовая техника/Зарядные устройства для автомобильных аккумуляторов/Пуско-зарядные устр\xD0\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Строительство и ремонт/Силовая техника/Зарядные устройств\xD0\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Строительство и ремонт/Силовая техника/Зарядные устройства для автомобиль\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\0 "s, ResultType::Throw, "JSON: expected \", got \0"s },
{ "\"/Хозтовары/Хранение вещей и организа\xD1\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Хозтовары/Товары для стир\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"li\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/igrushki/igrus\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/734859/samolet-radioupravlyaemyy-istrebitel-rabotaet-o\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/kosmetika-i-parfyum/parfyumeriya/mu\00"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/ko\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/avto/avtomobilnyy\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/stroitelstvo-i-remont/stroit\00"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/stroitelstvo-i-remont/stroitelnyy-instrument/av\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/s\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Строительство и ремонт/Строительный инструмент/Изм\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/avto/soputstvuy\0\""s, ResultType::Return, "/avto/soputstvuy\0"s },
{ "\"/str\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Отвертка 2 в 1 \\\"TUNDRA basic\\\" 5х75 мм (+,-) \0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/stroitelstvo-i-remont/stroitelnyy-instrument/avtoinstrumen\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Чайник электрический Vitesse\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Мелкая бытовая техника/Мелки\xD0\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Пряжа \\\"Бамбук стрейч\\0о"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Карандаш чёрнографитны\xD0\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Творчество/Рукоделие, аппликации/Пряжа и шерсть для \xD0\0\""s, ResultType::Return, "/Творчество/Рукоделие, аппликации/Пряжа и шерсть для \xD0\0"s },
{ "\"/1071547/karandash-chernografitnyy-volshebstvo-nv-kruglyy-d-7-2mm-dl-176mm-plast-tuba/\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"ca\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Подаро\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Средство для прочис\xD1\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"i\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/p\0\""s, ResultType::Return, "/p\0"s },
{ "\"/Сувениры/Магниты, н\xD0\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Дерев\xD0\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/prazdniki/svadba/svadebnaya-c\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Канцт\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Праздники/То\xD0\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"v\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Косметика \xD0\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Спорт и отдых/Настольные игры/Покер, руле\xD1\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"categ\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/retailr\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/retailrocket\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Ежедневник недат А5 140л кл,ляссе,обл пв\0="s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/432809/ezhednevnik-organayzer-sredniy-s-remeshkom-na-knopke-v-oblozhke-kalkulyator-kalendar-do-\0\xD0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/1165424/chipbord-vyrubnoy-dlya-skrapbukinga-malyshi-mikki-maus-disney-bebi\0d"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/posuda/kuhonnye-prinadlezhnosti-i-i\0 "s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/Канцтовары/Ежедневники и блокн\xD0\0o"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"/kanctovary/ezhednevniki-i-blok\00"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Стакан \xD0\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"Набор бумаги для скрапбукинга \\\"Мои первый годик\\\": Микки Маус, Дисней бэби, 12 листов 29.5 х 29.5 см, 160\0\0"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s },
{ "\"c\0\""s, ResultType::Return, "c\0"s },
};
for (auto i : boost::irange(0, 1/*00000*/))
{
static_cast<void>(i);
for (auto & r : test_data)
{
try
{
JSON j(r.input.c_str(), r.input.c_str() + r.input.size());
ASSERT_EQ(j.getString(), r.result);
ASSERT_TRUE(r.result_type == ResultType::Return);
}
catch (JSONException & e)
{
ASSERT_TRUE(r.result_type == ResultType::Throw);
ASSERT_EQ(e.message(), r.result);
}
}
}
}

View File

@ -54,7 +54,7 @@ TEST(StrongTypedefSuite, NoDefaultCtor)
{
struct NoDefaultCtor
{
NoDefaultCtor(int i) {}
NoDefaultCtor(int) {} // NOLINT
};
STRONG_TYPEDEF(NoDefaultCtor, MyStruct);

7
base/common/time.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <time.h>
#if defined (OS_DARWIN)
# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
#endif

View File

@ -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
View File

@ -0,0 +1,12 @@
LIBRARY()
PEERDIR(
contrib/libs/poco/Util
)
SRCS(
argsToConfig.cpp
coverage.cpp
)
END()

View File

@ -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_)

View File

@ -1,7 +1,7 @@
#pragma once
#include <sys/types.h>
#include <port/unistd.h>
#include <unistd.h>
#include <iostream>
#include <memory>
#include <functional>
@ -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();
};

View File

@ -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})

View File

@ -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 += ".";

View File

@ -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>>

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