mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 00:52:02 +00:00
Removed all trailing whitespaces [#CLICKHOUSE-2]. find . -name '*.h' -or -name '*.cpp' -or -name '*.cmake' -or -name 'CMakeLists.txt' -or -name '*.html' -or -name '*.xml' | grep -v contrib | xargs sed -i -r -e 's/\s+$//'
This commit is contained in:
parent
f5a7498559
commit
4f44445ff0
@ -16,33 +16,33 @@
|
||||
#
|
||||
# Usage:
|
||||
# set(ENV{Poco_DIR} path/to/poco/sdk)
|
||||
# find_package(Poco REQUIRED OSP Data Crypto)
|
||||
# find_package(Poco REQUIRED OSP Data Crypto)
|
||||
#
|
||||
# On completion, the script defines the following variables:
|
||||
#
|
||||
#
|
||||
# - Compound variables:
|
||||
# Poco_FOUND
|
||||
# Poco_FOUND
|
||||
# - true if all requested components were found.
|
||||
# Poco_LIBRARIES
|
||||
# Poco_LIBRARIES
|
||||
# - contains release (and debug if available) libraries for all requested components.
|
||||
# It has the form "optimized LIB1 debug LIBd1 optimized LIB2 ...", ready for use with the target_link_libraries command.
|
||||
# Poco_INCLUDE_DIRS
|
||||
# - Contains include directories for all requested components.
|
||||
#
|
||||
# - Component variables:
|
||||
# Poco_Xxx_FOUND
|
||||
# - Where Xxx is the properly cased component name (eg. 'Util', 'OSP').
|
||||
# Poco_Xxx_FOUND
|
||||
# - Where Xxx is the properly cased component name (eg. 'Util', 'OSP').
|
||||
# True if a component's library or debug library was found successfully.
|
||||
# Poco_Xxx_LIBRARY
|
||||
# Poco_Xxx_LIBRARY
|
||||
# - Library for component Xxx.
|
||||
# Poco_Xxx_LIBRARY_DEBUG
|
||||
# Poco_Xxx_LIBRARY_DEBUG
|
||||
# - debug library for component Xxx
|
||||
# Poco_Xxx_INCLUDE_DIR
|
||||
# - include directory for component Xxx
|
||||
#
|
||||
# - OSP BundleCreator variables: (i.e. bundle.exe on windows, bundle on unix-likes)
|
||||
# (is only discovered if OSP is a requested component)
|
||||
# Poco_OSP_Bundle_EXECUTABLE_FOUND
|
||||
# Poco_OSP_Bundle_EXECUTABLE_FOUND
|
||||
# - true if the bundle-creator executable was found.
|
||||
# Poco_OSP_Bundle_EXECUTABLE
|
||||
# - the path to the bundle-creator executable.
|
||||
@ -52,24 +52,24 @@
|
||||
set(Poco_HINTS
|
||||
/usr/local
|
||||
C:/AppliedInformatics
|
||||
${Poco_DIR}
|
||||
${Poco_DIR}
|
||||
$ENV{Poco_DIR}
|
||||
)
|
||||
|
||||
if(NOT Poco_ROOT_DIR)
|
||||
# look for the root directory, first for the source-tree variant
|
||||
find_path(Poco_ROOT_DIR
|
||||
find_path(Poco_ROOT_DIR
|
||||
NAMES Foundation/include/Poco/Poco.h
|
||||
HINTS ${Poco_HINTS}
|
||||
)
|
||||
if(NOT Poco_ROOT_DIR)
|
||||
# this means poco may have a different directory structure, maybe it was installed, let's check for that
|
||||
message(STATUS "Looking for Poco install directory structure.")
|
||||
find_path(Poco_ROOT_DIR
|
||||
find_path(Poco_ROOT_DIR
|
||||
NAMES include/Poco/Poco.h
|
||||
HINTS ${Poco_HINTS}
|
||||
)
|
||||
if(NOT Poco_ROOT_DIR)
|
||||
if(NOT Poco_ROOT_DIR)
|
||||
# poco was still not found -> Fail
|
||||
if(Poco_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Poco: Could not find Poco install directory")
|
||||
@ -91,7 +91,7 @@ if(WIN32)
|
||||
find_path(Poco_RUNTIME_LIBRARY_DIRS
|
||||
NAMES PocoFoundation.dll
|
||||
HINTS ${Poco_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
lib
|
||||
)
|
||||
@ -103,17 +103,17 @@ if(Poco_INSTALLED)
|
||||
endif()
|
||||
|
||||
# append the default minimum components to the list to find
|
||||
list(APPEND components
|
||||
${Poco_FIND_COMPONENTS}
|
||||
list(APPEND components
|
||||
${Poco_FIND_COMPONENTS}
|
||||
# default components:
|
||||
"Util"
|
||||
"Util"
|
||||
"Foundation"
|
||||
)
|
||||
list(REMOVE_DUPLICATES components) # remove duplicate defaults
|
||||
|
||||
foreach( component ${components} )
|
||||
#if(NOT Poco_${component}_FOUND)
|
||||
|
||||
|
||||
# include directory for the component
|
||||
if(NOT Poco_${component}_INCLUDE_DIR)
|
||||
if (${component} STREQUAL "DataODBC")
|
||||
@ -127,7 +127,7 @@ foreach( component ${components} )
|
||||
set (component_alt ${component})
|
||||
endif ()
|
||||
find_path(Poco_${component}_INCLUDE_DIR
|
||||
NAMES
|
||||
NAMES
|
||||
Poco/${component}.h # e.g. Foundation.h
|
||||
Poco/${component}/${component}.h # e.g. OSP/OSP.h Util/Util.h
|
||||
Poco/${component_alt}/${component}.h # e.g. Net/NetSSL.h
|
||||
@ -148,8 +148,8 @@ foreach( component ${components} )
|
||||
# release library
|
||||
if(NOT Poco_${component}_LIBRARY)
|
||||
find_library(
|
||||
Poco_${component}_LIBRARY
|
||||
NAMES Poco${component}
|
||||
Poco_${component}_LIBRARY
|
||||
NAMES Poco${component}
|
||||
HINTS ${Poco_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
@ -198,9 +198,9 @@ endif()
|
||||
if(${Poco_OSP_FOUND})
|
||||
# find the osp bundle program
|
||||
find_program(
|
||||
Poco_OSP_Bundle_EXECUTABLE
|
||||
Poco_OSP_Bundle_EXECUTABLE
|
||||
NAMES bundle
|
||||
HINTS
|
||||
HINTS
|
||||
${Poco_RUNTIME_LIBRARY_DIRS}
|
||||
${Poco_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
|
@ -47,12 +47,12 @@ public:
|
||||
{
|
||||
setEmpty();
|
||||
}
|
||||
|
||||
|
||||
AutoArray(size_t size_)
|
||||
{
|
||||
init(size_, false);
|
||||
}
|
||||
|
||||
|
||||
/** Не будут вызваны конструкторы по-умолчанию для элементов.
|
||||
* В этом случае, вы должны вставить все элементы с помощью функции place и placement new,
|
||||
* так как для них потом будут вызваны деструкторы.
|
||||
@ -61,13 +61,13 @@ public:
|
||||
{
|
||||
init(size_, true);
|
||||
}
|
||||
|
||||
|
||||
/** Инициализирует все элементы копирующим конструктором с параметром value.
|
||||
*/
|
||||
AutoArray(size_t size_, const T & value)
|
||||
{
|
||||
init(size_, true);
|
||||
|
||||
|
||||
for (size_t i = 0; i < size_; ++i)
|
||||
{
|
||||
new (place(i)) T(value);
|
||||
@ -134,7 +134,7 @@ public:
|
||||
{
|
||||
return elem(i);
|
||||
}
|
||||
|
||||
|
||||
const T & operator[](size_t i) const
|
||||
{
|
||||
return elem(i);
|
||||
@ -234,7 +234,7 @@ private:
|
||||
setEmpty();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
data = new char[size_ * sizeof(T) + sizeof(size_t)];
|
||||
data += sizeof(size_t);
|
||||
m_size() = size_;
|
||||
|
@ -28,7 +28,7 @@ namespace DB
|
||||
* - один или несколько пакетов Data.
|
||||
* Конец данных определается по отправленному пустому блоку.
|
||||
* Затем сервер отправляет клиенту пакет EndOfStream.
|
||||
*
|
||||
*
|
||||
* Если запрос типа SELECT или другой, то сервер передаёт набор пакетов одного из следующих видов:
|
||||
* - Data - данные результата выполнения запроса (один блок);
|
||||
* - Progress - прогресс выполнения запроса;
|
||||
@ -39,12 +39,12 @@ namespace DB
|
||||
* Также, клиент может передать на сервер пакет Cancel - отмена выполнения запроса.
|
||||
* В этом случае, сервер может прервать выполнение запроса и вернуть неполные данные;
|
||||
* но клиент всё равно должен читать все пакеты до EndOfStream.
|
||||
*
|
||||
*
|
||||
* Перед пакетом EndOfStream, если есть профайлинговая информация и ревизия клиента достаточно новая,
|
||||
* может быть отправлен пакет Totals и/или ProfileInfo.
|
||||
* Totals - блок с тотальными значениями.
|
||||
* ProfileInfo - данные профайлинга - сериализованная структура BlockStreamProfileInfo.
|
||||
*
|
||||
*
|
||||
* При запросах, которые возвращают данные, сервер, перед обработкой запроса,
|
||||
* отправляет заголовочный блок, содержащий описание столбцов из запроса, но с нулем строк.
|
||||
* Используя этот заголовочный блок, клиент может заранее проинициализировать формат вывода
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
ASTDropQuery() = default;
|
||||
ASTDropQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
String getID() const override { return (detach ? "DetachQuery_" : "DropQuery_") + database + "_" + table; };
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
ASTRenameQuery() = default;
|
||||
ASTRenameQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
String getID() const override { return "Rename"; };
|
||||
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
if (sigemptyset(&sig_set)
|
||||
|| sigaddset(&sig_set, SIGINT))
|
||||
throwFromErrno("Cannot manipulate with signal set.", ErrorCodes::CANNOT_MANIPULATE_SIGSET);
|
||||
|
||||
|
||||
block();
|
||||
}
|
||||
|
||||
@ -69,9 +69,9 @@ public:
|
||||
{
|
||||
if (!active)
|
||||
return false;
|
||||
|
||||
|
||||
timespec timeout = { 0, 0 };
|
||||
|
||||
|
||||
if (-1 == sigtimedwait(&sig_set, nullptr, &timeout))
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
|
@ -107,7 +107,7 @@ template < typename keytype, typename hashtype >
|
||||
bool AvalancheTest ( pfHash hash, const int reps )
|
||||
{
|
||||
Rand r(48273);
|
||||
|
||||
|
||||
const int keybytes = sizeof(keytype);
|
||||
const int hashbytes = sizeof(hashtype);
|
||||
|
||||
@ -121,7 +121,7 @@ bool AvalancheTest ( pfHash hash, const int reps )
|
||||
std::vector<int> bins(keybits*hashbits,0);
|
||||
|
||||
calcBias<keytype,hashtype>(hash,bins,reps,r);
|
||||
|
||||
|
||||
//----------
|
||||
|
||||
bool result = true;
|
||||
|
@ -51,7 +51,7 @@ struct Rand
|
||||
{
|
||||
uint32_t t = x ^ (x << 11);
|
||||
x = y; y = z; z = w;
|
||||
w = w ^ (w >> 19) ^ t ^ (t >> 8);
|
||||
w = w ^ (w >> 19) ^ t ^ (t >> 8);
|
||||
}
|
||||
|
||||
uint32_t rand_u32 ( void )
|
||||
@ -61,7 +61,7 @@ struct Rand
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t rand_u64 ( void )
|
||||
uint64_t rand_u64 ( void )
|
||||
{
|
||||
mix();
|
||||
|
||||
|
@ -39,7 +39,7 @@ int main(int argc, char ** argv)
|
||||
}
|
||||
|
||||
std::cerr << std::endl;
|
||||
|
||||
|
||||
{
|
||||
size_t n = 10;
|
||||
using T = std::string;
|
||||
@ -58,7 +58,7 @@ int main(int argc, char ** argv)
|
||||
Arr arr2 = std::move(arr);
|
||||
|
||||
std::cerr << arr.size() << ", " << arr2.size() << std::endl;
|
||||
|
||||
|
||||
for (size_t i = 0; i < arr2.size(); ++i)
|
||||
std::cerr << arr2[i] << std::endl;
|
||||
}
|
||||
@ -78,7 +78,7 @@ int main(int argc, char ** argv)
|
||||
Arr key(n);
|
||||
for (size_t j = 0; j < n; ++j)
|
||||
key[j] = DB::toString(rand());
|
||||
|
||||
|
||||
map[std::move(key)] = "Hello, world! " + DB::toString(i);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ int main(int argc, char ** argv)
|
||||
for (size_t j = 0; j < n; ++j)
|
||||
std::cerr << (j == 0 ? "" : ", ") << it->first[j];
|
||||
std::cerr << "]";
|
||||
|
||||
|
||||
std::cerr << ":\t" << it->second << std::endl;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ int main(int argc, char ** argv)
|
||||
<< " (" << rows / watch.elapsedSeconds() << " rows/sec., " << bytes / 1000000.0 / watch.elapsedSeconds() << " MB/sec.)"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
/* {
|
||||
Stopwatch watch;
|
||||
|
||||
|
@ -120,7 +120,7 @@ int test_vectors()
|
||||
|
||||
hash.update(in, part);
|
||||
hash.update(in + part, i - part);
|
||||
|
||||
|
||||
hash.get128(out);
|
||||
|
||||
uint64_t test_vector;
|
||||
|
@ -19,7 +19,7 @@ int main(int argc, char ** argv)
|
||||
{
|
||||
std::cerr << std::fixed << std::setprecision(3);
|
||||
std::ofstream devnull("/dev/null");
|
||||
|
||||
|
||||
DB::ReadBufferFromFileDescriptor in(STDIN_FILENO);
|
||||
size_t n = atoi(argv[1]);
|
||||
size_t elems_show = 1;
|
||||
@ -116,7 +116,7 @@ int main(int argc, char ** argv)
|
||||
DB::Arena pool;
|
||||
RefsSet set;
|
||||
Stopwatch watch;
|
||||
|
||||
|
||||
for (Vec::iterator it = vec.begin(); it != vec.end(); ++it)
|
||||
set[StringRef(pool.insert(it->data(), it->size()), it->size())] = 0;
|
||||
|
||||
|
@ -53,7 +53,7 @@ int main(int argc, char ** argv)
|
||||
printType(DB::NumberTraits::ResultOfFloatingPointDivision<DB::UInt32, DB::Int16>::Type()); std::cout << std::endl;
|
||||
printType(DB::NumberTraits::ResultOfIntegerDivision<DB::UInt8, DB::Int16>::Type()); std::cout << std::endl;
|
||||
printType(DB::NumberTraits::ResultOfModulo<DB::UInt32, DB::Int8>::Type()); std::cout << std::endl;
|
||||
|
||||
|
||||
ifLeftType<DB::UInt8>();
|
||||
ifLeftType<DB::UInt16>();
|
||||
ifLeftType<DB::UInt32>();
|
||||
@ -64,6 +64,6 @@ int main(int argc, char ** argv)
|
||||
ifLeftType<DB::Int64>();
|
||||
ifLeftType<DB::Float32>();
|
||||
ifLeftType<DB::Float64>();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
using namespace DB;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
UncompressedCache cache(1024);
|
||||
|
@ -23,7 +23,7 @@ namespace test
|
||||
++buf.position();
|
||||
negative = true;
|
||||
}
|
||||
|
||||
|
||||
if (*buf.position() == '0')
|
||||
{
|
||||
++buf.position();
|
||||
|
@ -22,13 +22,13 @@ int main(int argc, char ** argv)
|
||||
|
||||
DB::readIntText(a, in);
|
||||
in.ignore();
|
||||
|
||||
|
||||
DB::readFloatText(b, in);
|
||||
in.ignore();
|
||||
|
||||
|
||||
DB::readEscapedString(c, in);
|
||||
in.ignore();
|
||||
|
||||
|
||||
DB::readQuotedString(d, in);
|
||||
|
||||
std::cout << a << ' ' << b << ' ' << c << '\t' << '\'' << d << '\'' << std::endl;
|
||||
|
@ -24,13 +24,13 @@ int main(int argc, char ** argv)
|
||||
{
|
||||
DB::readIntText(a, in);
|
||||
in.ignore();
|
||||
|
||||
|
||||
DB::readFloatText(b, in);
|
||||
in.ignore();
|
||||
|
||||
|
||||
DB::readEscapedString(c, in);
|
||||
in.ignore();
|
||||
|
||||
|
||||
DB::readQuotedString(d, in);
|
||||
in.ignore();
|
||||
|
||||
|
@ -19,7 +19,7 @@ int main(int argc, char ** argv)
|
||||
std::string s;
|
||||
|
||||
std::cerr << static_cast<Int64>(x1) << std::endl;
|
||||
|
||||
|
||||
{
|
||||
DB::WriteBufferFromString wb(s);
|
||||
DB::writeIntText(x1, wb);
|
||||
|
@ -13,12 +13,12 @@ int main(int argc, char ** argv)
|
||||
int repeats = 1;
|
||||
if (argc >= 2)
|
||||
repeats = atoi(argv[1]);
|
||||
|
||||
|
||||
std::string text((std::istreambuf_iterator<char>(std::cin)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
|
||||
std::cout << "Text length: " << text.size() << std::endl;
|
||||
|
||||
|
||||
Stopwatch timer;
|
||||
std::string str1;
|
||||
{
|
||||
@ -31,9 +31,9 @@ int main(int argc, char ** argv)
|
||||
double t = timer.elapsedSeconds();
|
||||
std::cout << "Wrote to string in " << t << "s at " << text.size() / 1e6 * repeats / t << "MB/s." << std::endl;
|
||||
std::cout << "String length: " << str1.size() << "(" << (str1.size() == text.size() * repeats ? "as " : "un") << "expected)" << std::endl;
|
||||
|
||||
|
||||
timer.restart();
|
||||
|
||||
|
||||
std::string str2;
|
||||
{
|
||||
DB::WriteBufferFromString simple_buf(str2);
|
||||
|
@ -24,10 +24,10 @@ int main(int argc, char ** argv)
|
||||
|
||||
DB::writeIntText(a, out);
|
||||
DB::writeChar(' ', out);
|
||||
|
||||
|
||||
DB::writeFloatText(b, out);
|
||||
DB::writeChar(' ', out);
|
||||
|
||||
|
||||
DB::writeEscapedString(c, out);
|
||||
DB::writeChar('\t', out);
|
||||
|
||||
|
@ -24,10 +24,10 @@ int main(int argc, char ** argv)
|
||||
{
|
||||
DB::writeIntText(a, out);
|
||||
DB::writeChar(' ', out);
|
||||
|
||||
|
||||
DB::writeFloatText(b, out);
|
||||
DB::writeChar(' ', out);
|
||||
|
||||
|
||||
DB::writeEscapedString(c, out);
|
||||
DB::writeChar('\t', out);
|
||||
|
||||
|
@ -143,7 +143,7 @@ int main(int argc, char ** argv)
|
||||
std::unordered_map<Key, Value, DefaultHash<Key> > map;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
++map[data[i]];
|
||||
|
||||
|
||||
watch.stop();
|
||||
std::cerr << std::fixed << std::setprecision(2)
|
||||
<< "std::unordered_map. Size: " << map.size()
|
||||
@ -160,7 +160,7 @@ int main(int argc, char ** argv)
|
||||
map.set_empty_key(-1ULL);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
++map[data[i]];
|
||||
|
||||
|
||||
watch.stop();
|
||||
std::cerr << std::fixed << std::setprecision(2)
|
||||
<< "google::dense_hash_map. Size: " << map.size()
|
||||
|
@ -437,7 +437,7 @@ int main(int argc, char ** argv)
|
||||
std::unordered_map<Key, Value, DefaultHash<Key> > map;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
++map[data[i]];
|
||||
|
||||
|
||||
watch.stop();
|
||||
std::cerr << std::fixed << std::setprecision(2)
|
||||
<< "std::unordered_map. Size: " << map.size()
|
||||
@ -454,7 +454,7 @@ int main(int argc, char ** argv)
|
||||
map.set_empty_key(Key("\0", 1));
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
++map[data[i]];
|
||||
|
||||
|
||||
watch.stop();
|
||||
std::cerr << std::fixed << std::setprecision(2)
|
||||
<< "google::dense_hash_map. Size: " << map.size()
|
||||
|
@ -595,7 +595,7 @@ int Server::main(const std::vector<std::string> & args)
|
||||
}
|
||||
|
||||
LOG_DEBUG(
|
||||
log, "Closed connections." << (current_connections ? " But " + std::to_string(current_connections) + " remains."
|
||||
log, "Closed connections." << (current_connections ? " But " + std::to_string(current_connections) + " remains."
|
||||
+ " Tip: To increase wait time add to config: <shutdown_wait_unfinished>60</shutdown_wait_unfinished> ." : ""));
|
||||
|
||||
main_config_reloader.reset();
|
||||
|
@ -105,7 +105,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataWriter::writeTempPart(BlockWithDa
|
||||
|
||||
size_t part_size = (block.rows() + data.index_granularity - 1) / data.index_granularity;
|
||||
|
||||
|
||||
|
||||
String part_name = ActiveDataPartSet::getPartName(
|
||||
DayNum_t(min_date), DayNum_t(max_date),
|
||||
temp_index, temp_index, 0);
|
||||
|
@ -339,7 +339,7 @@ bool StorageMergeTree::merge(
|
||||
|
||||
/// Logging
|
||||
Stopwatch stopwatch;
|
||||
|
||||
|
||||
auto new_part = merger.mergePartsToTemporaryPart(
|
||||
merging_tagger->parts, merged_name, *merge_entry_ptr, aio_threshold, time(0), merging_tagger->reserved_space.get());
|
||||
|
||||
|
@ -1157,7 +1157,7 @@ bool StorageReplicatedMergeTree::executeLogEntry(const LogEntry & entry)
|
||||
|
||||
/// Logging
|
||||
Stopwatch stopwatch;
|
||||
|
||||
|
||||
auto part = merger.mergePartsToTemporaryPart(
|
||||
parts, entry.new_part_name, *merge_entry, aio_threshold, entry.create_time, reserved_space.get());
|
||||
|
||||
@ -2077,11 +2077,11 @@ bool StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin
|
||||
ReplicatedMergeTreeAddress address(getZooKeeper()->get(replica_path + "/host"));
|
||||
|
||||
Stopwatch stopwatch;
|
||||
|
||||
|
||||
MergeTreeData::MutableDataPartPtr part = fetcher.fetchPart(
|
||||
part_name, replica_path, address.host, address.replication_port, to_detached);
|
||||
|
||||
|
||||
|
||||
if (!to_detached)
|
||||
{
|
||||
zkutil::Ops ops;
|
||||
@ -2386,7 +2386,7 @@ bool StorageReplicatedMergeTree::optimize(const String & partition, bool final,
|
||||
|
||||
/// Logging
|
||||
Stopwatch stopwatch;
|
||||
|
||||
|
||||
auto new_part = unreplicated_merger->mergePartsToTemporaryPart(
|
||||
parts, merged_name, *merge_entry, settings.min_bytes_to_use_direct_io, time(0));
|
||||
|
||||
|
@ -11,11 +11,11 @@
|
||||
<header class="caption">
|
||||
<h1>Параллельный и распределённый GROUP BY</h1>
|
||||
</header>
|
||||
|
||||
|
||||
<section class="slide" id="cover">
|
||||
<h1 style="margin-top: 200px">Параллельный и распределённый GROUP BY</h1>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Обо мне</h2>
|
||||
<p>Алексей, разработчик ClickHouse.</p>
|
||||
@ -28,12 +28,12 @@
|
||||
<p>Один запрос — много данных на входе, мало на выходе.</p>
|
||||
<p>Данные нужно агрегировать налету.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Метрика 2.0</h2>
|
||||
<img src="pictures/metrika2.png" style="height:70%"/>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Пример запроса</h2>
|
||||
<p style="font-family: Monospace">SELECT MobilePhoneModel, COUNT(DISTINCT UserID) AS u<br />
|
||||
@ -42,7 +42,7 @@
|
||||
<b>GROUP BY</b> MobilePhoneModel<br />
|
||||
ORDER BY u DESC</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2> </h2>
|
||||
<p>Чтобы быстро обрабатывать запросы, данные необходимо:</p>
|
||||
@ -54,7 +54,7 @@
|
||||
<p>Конвейер выполнения запроса:</p>
|
||||
<p>— фильтрация, JOIN, <b>агрегация</b>, сортировка...</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2 style="font-size: 45px;">Как тестировать производительность?</h2>
|
||||
<p>Бенчмарки должны быть:</p>
|
||||
@ -65,7 +65,7 @@
|
||||
<li>автоматизированные.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Пример бенчмарка (не лучшего)</h2>
|
||||
<pre style="white-space: pre; font-family: Monospace; font-size: 14px; line-height: 1.25em;">/** Выполнять так:
|
||||
@ -82,7 +82,7 @@ for file in <b>MobilePhoneModel PageCharset Params URLDomain UTMSource Referer U
|
||||
if [[ $TOTAL_ELEMS -gt 25000000 ]]; then break; fi
|
||||
./hash_map_string_3 $size $method < ${file}.bin 2>&1 |
|
||||
grep HashMap | grep -oE '[0-9\.]+ elem';
|
||||
done | awk -W interactive '{ if ($1 > x) { x = $1 }; printf(".") } END { print x }' |
|
||||
done | awk -W interactive '{ if ($1 > x) { x = $1 }; printf(".") } END { print x }' |
|
||||
tee /tmp/hash_map_string_3_res;
|
||||
CUR_RESULT=$(cat /tmp/hash_map_string_3_res | tr -d '.')
|
||||
if [[ $CUR_RESULT -gt $BEST_RESULT ]]; then
|
||||
@ -95,15 +95,15 @@ for file in <b>MobilePhoneModel PageCharset Params URLDomain UTMSource Referer U
|
||||
done
|
||||
*/</pre>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Агрегация</h2>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Одна машина, одно ядро</h2>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Плохой способ</h2>
|
||||
<p>Читаем данные в массив; сортируем по ключу;
|
||||
@ -117,7 +117,7 @@ done
|
||||
Отвратительно работает при N > M — в типичном случае.
|
||||
Тратится O(N) оперативки на промежуточные данные вместо O(M).</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Хороший способ</h2>
|
||||
<p>Читаем данные, кладём в ассоциативный массив</p>
|
||||
@ -131,19 +131,19 @@ done
|
||||
<p>Бинарное дерево. Skip-лист. B-дерево. </p>
|
||||
<p>Трай. Трай+хэш-таблица...</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Бинарное дерево</h2>
|
||||
<p>− слишком большой оверхед на элемент;</p>
|
||||
<p>− отвратительная кэш-локальность;</p>
|
||||
<p>− вообще тормозит.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Skip-лист. Трай. B-дерево...</h2>
|
||||
<p>− вообще для другой задачи;</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Lookup-таблица</h2>
|
||||
<p>+ прекрасно для агрегации по числовым ключам не более ~16 бит;</p>
|
||||
@ -155,12 +155,12 @@ done
|
||||
<p>+ моя любимая структура данных;</p>
|
||||
<p>− много деталей.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Трай+хэш-таблица</h2>
|
||||
<p>+ иногда кое что в этом есть, см. далее;</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>Одна машина, много ядер</h2>
|
||||
</section>
|
||||
@ -168,18 +168,18 @@ done
|
||||
<section class="slide">
|
||||
<h2>1. Тривиальный способ</h2>
|
||||
|
||||
<p>Разные потоки читают разные данные по мере возможности.
|
||||
<p>Разные потоки читают разные данные по мере возможности.
|
||||
Агрегируют независимо в свои локальные хэш-таблицы.
|
||||
Когда все данные прочитаны, мержим все хэш-таблицы в одну.
|
||||
Например, идём по всем локальным хэш-таблицам кроме первой
|
||||
Когда все данные прочитаны, мержим все хэш-таблицы в одну.
|
||||
Например, идём по всем локальным хэш-таблицам кроме первой
|
||||
и перекладываем всё в первую.
|
||||
|
||||
Фаза чтения данных и предварительной агрегации распараллеливается.
|
||||
Фаза мержа выполняется последовательно.
|
||||
|
||||
Пусть N — общее число данных, а M — количество ключей.
|
||||
O(M) работы выполняется последовательно
|
||||
и при большом M (кардинальность GROUP BY)
|
||||
O(M) работы выполняется последовательно
|
||||
и при большом M (кардинальность GROUP BY)
|
||||
работа плохо распараллеливается.
|
||||
|
||||
Достоинства: тривиально.
|
||||
@ -193,42 +193,42 @@ O(M) работы выполняется последовательно
|
||||
|
||||
<p>Для каждого блока данных, выполняем агрегацию в две стадии:
|
||||
|
||||
Стадия 1.
|
||||
Разные потоки будут обрабатывать разные куски блока, какие успеют.
|
||||
В каждом потоке, с помощью отдельной хэш-функции,
|
||||
хэшируем ключ в номер потока и запоминаем его.
|
||||
Стадия 1.
|
||||
Разные потоки будут обрабатывать разные куски блока, какие успеют.
|
||||
В каждом потоке, с помощью отдельной хэш-функции,
|
||||
хэшируем ключ в номер потока и запоминаем его.
|
||||
|
||||
hash: key -> bucket_num
|
||||
|
||||
Стадия 2.
|
||||
Каждый поток идёт по всему блоку данных
|
||||
Стадия 2.
|
||||
Каждый поток идёт по всему блоку данных
|
||||
и берёт для агрегации только строки с нуждым номером корзины.
|
||||
|
||||
Модификация: можно всё в одну стадию — тогда каждый поток
|
||||
будет вычислять хэш-функцию от всех строк заново:
|
||||
Модификация: можно всё в одну стадию — тогда каждый поток
|
||||
будет вычислять хэш-функцию от всех строк заново:
|
||||
подходит, если это дёшево.
|
||||
</section>
|
||||
|
||||
<section class="slide">
|
||||
<p>
|
||||
Достоинства:
|
||||
+ хорошо масштабируется при большой кардинальности
|
||||
+ хорошо масштабируется при большой кардинальности
|
||||
и равномерном распределении ключей;
|
||||
+ идейная простота.
|
||||
|
||||
Недостатки:
|
||||
− если объём данных распределён неравномерно по ключам,
|
||||
− если объём данных распределён неравномерно по ключам,
|
||||
то стадия 2 плохо масштабируется.
|
||||
Это типичный случай.
|
||||
Это типичный случай.
|
||||
Почти всегда объём данных по ключам распределён по power law.
|
||||
|
||||
Ещё недостатки:
|
||||
− если размер блока маленький, то получается слишком
|
||||
мелко-гранулированная многопоточность:
|
||||
− если размер блока маленький, то получается слишком
|
||||
мелко-гранулированная многопоточность:
|
||||
большой оверхед на синхронизацию;
|
||||
− если размер блока большой, то плохая кэш-локальность;
|
||||
− на второй стадии, часть memory bandwidth умножается на число потоков;
|
||||
− нужно вычислять ещё одну хэш-функцию,
|
||||
− нужно вычислять ещё одну хэш-функцию,
|
||||
она должна быть независима от той, что в хэш-таблице;</p>
|
||||
</section>
|
||||
|
||||
@ -238,7 +238,7 @@ O(M) работы выполняется последовательно
|
||||
|
||||
<p>Отресайзим полученные в разных потоках хэш-таблицы к одному размеру.
|
||||
Разобъём их неявно на разные подмножества ключей.
|
||||
В разных потоках будем мержить соответствующие
|
||||
В разных потоках будем мержить соответствующие
|
||||
подмножества ключей хэш-таблиц.
|
||||
|
||||
Рисунок на доске.
|
||||
@ -252,18 +252,18 @@ O(M) работы выполняется последовательно
|
||||
<h2>4. Ordered мерж хэш-таблиц</h2>
|
||||
|
||||
<p>Для open addressing linear probing хэш-таблиц, или для chaining хэш-таблиц,
|
||||
данные в хэш-таблице расположены почти упорядоченно
|
||||
данные в хэш-таблице расположены почти упорядоченно
|
||||
по остатку от деления хэш-функции на размер хэш-таблицы
|
||||
— с точностью до цепочек разрешения коллизий.
|
||||
|
||||
Отресайзим полученные в разных потоках хэш-таблицы к одному размеру.
|
||||
Сделаем ordered iterator, который будет
|
||||
Сделаем ordered iterator, который будет
|
||||
перебирать данные в хэш-таблице в фиксированном порядке.
|
||||
|
||||
Объём работы на итерирование:
|
||||
Объём работы на итерирование:
|
||||
количество цепочек разрешения коллизий * средний квадрат длин цепочек.
|
||||
|
||||
Сделаем merging iterator, который с помощью heap (priority queue)
|
||||
Сделаем merging iterator, который с помощью heap (priority queue)
|
||||
будет перебирать все хэш-таблицы разом.
|
||||
</section>
|
||||
|
||||
@ -279,9 +279,9 @@ O(M) работы выполняется последовательно
|
||||
|
||||
− отвратительно сложный код;
|
||||
|
||||
− для open addressing linear probing хэш-таблиц,
|
||||
− для open addressing linear probing хэш-таблиц,
|
||||
средний квадрат длин цепочек разрешения коллизий слишком большой;
|
||||
|
||||
|
||||
− priority queue тормозит;
|
||||
|
||||
− стадия мержа не распараллеливается*
|
||||
@ -294,9 +294,9 @@ O(M) работы выполняется последовательно
|
||||
<section class="slide">
|
||||
<h2 style="font-size: 40px;">5. Robin Hood ordered мерж хэш-таблиц</h2>
|
||||
|
||||
<p>Если использовать Robin Hood хэш-таблицу, то данные
|
||||
(за исключением O(1) граничных цепочек разрешения коллизий)
|
||||
будут полностью упорядочены
|
||||
<p>Если использовать Robin Hood хэш-таблицу, то данные
|
||||
(за исключением O(1) граничных цепочек разрешения коллизий)
|
||||
будут полностью упорядочены
|
||||
по остатку от деления хэш-функции на размер хэш-таблицы.
|
||||
|
||||
Достоинства:
|
||||
@ -326,12 +326,12 @@ O(M) работы выполняется последовательно
|
||||
|
||||
Недостатки:
|
||||
|
||||
− в типичном случае данные распределены сильно неравномерно,
|
||||
− в типичном случае данные распределены сильно неравномерно,
|
||||
и потоки будут конкурировать на одной горячей корзине.
|
||||
|
||||
− в случае маленькой хэш-таблицы, слишком тормозит.
|
||||
|
||||
Достоинства: если данные почему-то распределены равномерно,
|
||||
Достоинства: если данные почему-то распределены равномерно,
|
||||
то кое-как масштабируется.</p>
|
||||
</section>
|
||||
|
||||
@ -341,11 +341,11 @@ O(M) работы выполняется последовательно
|
||||
|
||||
<p>Недостатки:
|
||||
|
||||
− spin-lock — это очень опасно;
|
||||
очень сложно тестировать производительность;
|
||||
− spin-lock — это очень опасно;
|
||||
очень сложно тестировать производительность;
|
||||
вы обязательно сделаете отстой.
|
||||
|
||||
− в типичном случае данные распределены сильно неравномерно,
|
||||
− в типичном случае данные распределены сильно неравномерно,
|
||||
и потоки будут конкурировать на одной горячей ячейке.</p>
|
||||
</section>
|
||||
|
||||
@ -357,7 +357,7 @@ O(M) работы выполняется последовательно
|
||||
|
||||
− lock free хэш-таблицы либо нельзя ресайзить, либо они очень сложные;
|
||||
|
||||
− в типичном случае данные распределены сильно неравномерно,
|
||||
− в типичном случае данные распределены сильно неравномерно,
|
||||
и потоки будут конкурировать на одной горячей ячейке:
|
||||
false sharing, тормоза.
|
||||
|
||||
@ -370,14 +370,14 @@ O(M) работы выполняется последовательно
|
||||
<section class="slide">
|
||||
<h2 style="font-size: 35px;">10. Shared хэш-таблица + thread local хэш-таблицы</h2>
|
||||
|
||||
<p>Пытаемся положить в shared хэш-таблицу путём блокирования ячейки;
|
||||
если ячейка уже заблокирована — кладём к локальную хэш-таблицу.
|
||||
<p>Пытаемся положить в shared хэш-таблицу путём блокирования ячейки;
|
||||
если ячейка уже заблокирована — кладём к локальную хэш-таблицу.
|
||||
|
||||
Тогда горячие ключи попадут в локальные хэш-таблицы.
|
||||
Локальные хэш-таблицы будут маленькими.
|
||||
Тогда горячие ключи попадут в локальные хэш-таблицы.
|
||||
Локальные хэш-таблицы будут маленькими.
|
||||
В конце мержим все локальные хэш-таблицы в глобальную.
|
||||
|
||||
Дополнения: можно сначала смотреть
|
||||
Дополнения: можно сначала смотреть
|
||||
на наличие ключа в локальной хэш-таблице.
|
||||
|
||||
Достоинства:
|
||||
@ -387,7 +387,7 @@ O(M) работы выполняется последовательно
|
||||
Недостатки:
|
||||
− много лукапов, много инструкций — в целом довольно медленно.
|
||||
|
||||
Даже не смотря на то, что thread local хэш-таблица
|
||||
Даже не смотря на то, что thread local хэш-таблица
|
||||
зачастую ещё и cache local.</p>
|
||||
</section>
|
||||
|
||||
@ -395,18 +395,18 @@ O(M) работы выполняется последовательно
|
||||
<section class="slide">
|
||||
<h2>11. Two-level хэш-таблица</h2>
|
||||
|
||||
<p>На первой стадии, в каждом потоке независимо
|
||||
кладём данные в свои num_buckets = 256 хэш-таблиц,
|
||||
<p>На первой стадии, в каждом потоке независимо
|
||||
кладём данные в свои num_buckets = 256 хэш-таблиц,
|
||||
хранящих разные ключи.
|
||||
|
||||
В какую из них класть (номер корзины)
|
||||
определяется другой хэш-функцией,
|
||||
В какую из них класть (номер корзины)
|
||||
определяется другой хэш-функцией,
|
||||
либо отдельным байтом хэш-функции.
|
||||
|
||||
Имеем num_threads * num_buckets хэш-таблиц.
|
||||
|
||||
На второй стадии мержим состояния
|
||||
num_threads * num_buckets хэш-таблиц
|
||||
На второй стадии мержим состояния
|
||||
num_threads * num_buckets хэш-таблиц
|
||||
в одни num_buckets хэш-таблиц,
|
||||
распараллеливая мерж по bucket-ам.
|
||||
</section>
|
||||
@ -427,13 +427,13 @@ num_threads * num_buckets хэш-таблиц
|
||||
|
||||
Недостатки:
|
||||
|
||||
− при большой кардинальности, во время мержа
|
||||
− при большой кардинальности, во время мержа
|
||||
делается до такого же объёма работ как на первой стадии;
|
||||
|
||||
− при маленькой кардинальности,
|
||||
− при маленькой кардинальности,
|
||||
слишком много отдельных хэш-таблиц;
|
||||
|
||||
− при маленькой кардинальности,
|
||||
− при маленькой кардинальности,
|
||||
работает несколько медленнее тривиального способа;</p>
|
||||
</section>
|
||||
|
||||
@ -453,7 +453,7 @@ num_threads * num_buckets хэш-таблиц
|
||||
<section class="slide">
|
||||
<h2>Много машин, много ядер</h2>
|
||||
|
||||
<p>На разных машинах расположены части данных,
|
||||
<p>На разных машинах расположены части данных,
|
||||
которые надо обработать.
|
||||
|
||||
Отличия от shared memory:
|
||||
@ -466,7 +466,7 @@ num_threads * num_buckets хэш-таблиц
|
||||
<section class="slide">
|
||||
<h2>1. Тривиальный способ</h2>
|
||||
|
||||
<p>Передаём промежуточные результаты на сервер-инициатор запроса.
|
||||
<p>Передаём промежуточные результаты на сервер-инициатор запроса.
|
||||
Последовательно кладём всё в одну хэш-таблицу.
|
||||
|
||||
Достоинства:
|
||||
@ -484,7 +484,7 @@ num_threads * num_buckets хэш-таблиц
|
||||
<section class="slide">
|
||||
<h2>2. Ordered merge</h2>
|
||||
|
||||
<p>Передаём промежуточные результаты на сервер-инициатор запроса
|
||||
<p>Передаём промежуточные результаты на сервер-инициатор запроса
|
||||
в заданном порядке. Мержим.
|
||||
|
||||
Достоинства:
|
||||
@ -501,15 +501,15 @@ num_threads * num_buckets хэш-таблиц
|
||||
<section class="slide">
|
||||
<h2>3. Partitioned merge</h2>
|
||||
|
||||
<p>Передаём промежуточные результаты на сервер-инициатор запроса,
|
||||
разбитыми на отдельные согласованные корзины-партиции,
|
||||
в заданном порядке корзин.
|
||||
<p>Передаём промежуточные результаты на сервер-инициатор запроса,
|
||||
разбитыми на отдельные согласованные корзины-партиции,
|
||||
в заданном порядке корзин.
|
||||
|
||||
Мержим по одной или по несколько корзин одновременно.
|
||||
|
||||
Достоинства:
|
||||
+ тратится до в num_buckets раз меньше оперативки, чем размер результата;
|
||||
+ можно легко распараллелить, мержа сразу несколько корзин
|
||||
+ можно легко распараллелить, мержа сразу несколько корзин
|
||||
— отлично масштабируется по ядрам.
|
||||
|
||||
Недостатки:
|
||||
@ -528,8 +528,8 @@ num_threads * num_buckets хэш-таблиц
|
||||
<p>На удалённых серверах получаем промежуточные результаты,
|
||||
разбитые на согласованные партиции.
|
||||
|
||||
Затем передаём партиции между серверами так,
|
||||
чтобы на разных серверах были разные партиции,
|
||||
Затем передаём партиции между серверами так,
|
||||
чтобы на разных серверах были разные партиции,
|
||||
а данные одной партиции оказались на одном сервере.
|
||||
|
||||
Мержим на всех серверах параллельно, да ещё и используя многие ядра.
|
||||
@ -537,7 +537,7 @@ num_threads * num_buckets хэш-таблиц
|
||||
Достоинства:
|
||||
+ прекрасно масштабируется;
|
||||
+ при INSERT SELECT, результат можно
|
||||
вовсе не передавать на сервер-инициатор,
|
||||
вовсе не передавать на сервер-инициатор,
|
||||
а сразу сохранить в распределённую таблицу на кластере.
|
||||
|
||||
Недостатки:
|
||||
@ -551,8 +551,8 @@ num_threads * num_buckets хэш-таблиц
|
||||
<p style="font-size: 50px;">Можно задавать вопросы.</p>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="progress"></div>
|
||||
<script src="shower/shower.min.js"></script>
|
||||
</body>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<section class="slide" id="cover">
|
||||
<h1 style="margin-top: 200px">ClickHouse meetup<br/>в Санкт-Петербурге</h1>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>ClickHouse: настоящее и будущее</h2>
|
||||
</section>
|
||||
@ -33,7 +33,7 @@
|
||||
</section>
|
||||
|
||||
<section class="slide">
|
||||
|
||||
|
||||
<h2>В предыдущих сериях</h2>
|
||||
|
||||
<p>— HTTP и executable источники;</p>
|
||||
@ -136,7 +136,7 @@
|
||||
<p>https://www.percona.com/blog/2017/02/13/clickhouse-new-opensource-columnar-database/</p>
|
||||
<img src="pictures/spark.png" style="height:60%"/>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="slide">
|
||||
<h2>ClickHouse vs. Greenplum</h2>
|
||||
<p><img src="pictures/greenplum.png" style="width:50%"/></p>
|
||||
|
@ -813,7 +813,7 @@ curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=300000
|
||||
- построение графиков, диаграмм и отображение геокоординат для результатов запросов;
|
||||
- интерактивный конструктор сводных таблиц (pivot) для результатов запросов;
|
||||
- графические средства для анализа состояния ClickHouse;
|
||||
- два цветовых оформления: светлое и темное.
|
||||
- два цветовых оформления: светлое и темное.
|
||||
|
||||
<a href="https://tabix.io/doc/">Документация Tabix</a>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
* Не парсит JSON до конца (парсит только часть, необходимую для выполнения вызванного метода).
|
||||
* Парсинг необходимой части запускается каждый раз при вызове методов.
|
||||
* Может работать с обрезанным JSON-ом.
|
||||
* При этом, (в отличие от SAX-подобных парсеров), предоставляет удобные методы для работы.
|
||||
* При этом, (в отличие от SAX-подобных парсеров), предоставляет удобные методы для работы.
|
||||
*
|
||||
* Эта структура данных более оптимальна, если нужно доставать несколько элементов из большого количества маленьких JSON-ов.
|
||||
* То есть, подходит для обработки "параметров визитов" и "параметров интернет магазинов" в Яндекс.Метрике.
|
||||
@ -81,7 +81,7 @@ public:
|
||||
};
|
||||
|
||||
ElementType getType() const;
|
||||
|
||||
|
||||
bool isObject() const { return getType() == TYPE_OBJECT; };
|
||||
bool isArray() const { return getType() == TYPE_ARRAY; };
|
||||
bool isNumber() const { return getType() == TYPE_NUMBER; };
|
||||
@ -138,7 +138,7 @@ public:
|
||||
/// Класс JSON одновременно является итератором по самому себе.
|
||||
using iterator = JSON;
|
||||
using const_iterator = JSON;
|
||||
|
||||
|
||||
iterator operator* () const { return *this; }
|
||||
const JSON * operator-> () const { return this; }
|
||||
bool operator== (const JSON & rhs) const { return ptr_begin == rhs.ptr_begin; }
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
/** Пример:
|
||||
*
|
||||
*
|
||||
* class Derived : public Singleton<Derived>
|
||||
* {
|
||||
* friend class Singleton<Derived>;
|
||||
|
@ -183,7 +183,7 @@ JSON::ElementType JSON::getType() const
|
||||
return TYPE_OBJECT;
|
||||
case '[':
|
||||
return TYPE_ARRAY;
|
||||
case 't':
|
||||
case 't':
|
||||
case 'f':
|
||||
return TYPE_BOOL;
|
||||
case 'n':
|
||||
@ -225,7 +225,7 @@ void JSON::checkPos(Pos pos) const
|
||||
JSON::Pos JSON::skipString() const
|
||||
{
|
||||
//std::cerr << "skipString()\t" << data() << std::endl;
|
||||
|
||||
|
||||
Pos pos = ptr_begin;
|
||||
checkPos(pos);
|
||||
if (*pos != '"')
|
||||
@ -257,7 +257,7 @@ JSON::Pos JSON::skipString() const
|
||||
if (*pos != '"')
|
||||
throw JSONException(std::string("JSON: expected \", got ") + *pos);
|
||||
++pos;
|
||||
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ JSON::Pos JSON::skipString() const
|
||||
JSON::Pos JSON::skipNumber() const
|
||||
{
|
||||
//std::cerr << "skipNumber()\t" << data() << std::endl;
|
||||
|
||||
|
||||
Pos pos = ptr_begin;
|
||||
|
||||
checkPos(pos);
|
||||
@ -292,10 +292,10 @@ JSON::Pos JSON::skipNumber() const
|
||||
JSON::Pos JSON::skipBool() const
|
||||
{
|
||||
//std::cerr << "skipBool()\t" << data() << std::endl;
|
||||
|
||||
|
||||
Pos pos = ptr_begin;
|
||||
checkPos(pos);
|
||||
|
||||
|
||||
if (*ptr_begin == 't')
|
||||
pos += 4;
|
||||
else if (*ptr_begin == 'f')
|
||||
@ -310,7 +310,7 @@ JSON::Pos JSON::skipBool() const
|
||||
JSON::Pos JSON::skipNull() const
|
||||
{
|
||||
//std::cerr << "skipNull()\t" << data() << std::endl;
|
||||
|
||||
|
||||
return ptr_begin + 4;
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ JSON::Pos JSON::skipNull() const
|
||||
JSON::Pos JSON::skipNameValuePair() const
|
||||
{
|
||||
//std::cerr << "skipNameValuePair()\t" << data() << std::endl;
|
||||
|
||||
|
||||
Pos pos = skipString();
|
||||
checkPos(pos);
|
||||
|
||||
@ -327,14 +327,14 @@ JSON::Pos JSON::skipNameValuePair() const
|
||||
++pos;
|
||||
|
||||
return JSON(pos, ptr_end, level + 1).skipElement();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
JSON::Pos JSON::skipArray() const
|
||||
{
|
||||
//std::cerr << "skipArray()\t" << data() << std::endl;
|
||||
|
||||
|
||||
if (!isArray())
|
||||
throw JSONException("JSON: expected [");
|
||||
Pos pos = ptr_begin;
|
||||
@ -366,7 +366,7 @@ JSON::Pos JSON::skipArray() const
|
||||
JSON::Pos JSON::skipObject() const
|
||||
{
|
||||
//std::cerr << "skipObject()\t" << data() << std::endl;
|
||||
|
||||
|
||||
if (!isObject())
|
||||
throw JSONException("JSON: expected {");
|
||||
Pos pos = ptr_begin;
|
||||
@ -374,7 +374,7 @@ JSON::Pos JSON::skipObject() const
|
||||
checkPos(pos);
|
||||
if (*pos == '}')
|
||||
return ++pos;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
pos = JSON(pos, ptr_end, level + 1).skipNameValuePair();
|
||||
@ -398,7 +398,7 @@ JSON::Pos JSON::skipObject() const
|
||||
JSON::Pos JSON::skipElement() const
|
||||
{
|
||||
//std::cerr << "skipElement()\t" << data() << std::endl;
|
||||
|
||||
|
||||
ElementType type = getType();
|
||||
|
||||
switch(type)
|
||||
@ -618,7 +618,7 @@ std::string JSON::getString() const
|
||||
case 'u':
|
||||
{
|
||||
Poco::UTF8Encoding utf8;
|
||||
|
||||
|
||||
++s;
|
||||
checkPos(s + 4);
|
||||
std::string hex(s, 4);
|
||||
|
@ -36,7 +36,7 @@ static time_t orderedIdentifierToDate(unsigned value)
|
||||
void loop(time_t begin, time_t end, int step)
|
||||
{
|
||||
const auto & date_lut = DateLUT::instance();
|
||||
|
||||
|
||||
for (time_t t = begin; t < end; t += step)
|
||||
{
|
||||
time_t t2 = date_lut.makeDateTime(date_lut.toYear(t), date_lut.toMonth(t), date_lut.toDayOfMonth(t),
|
||||
@ -44,9 +44,9 @@ void loop(time_t begin, time_t end, int step)
|
||||
|
||||
std::string s1 = toString(t);
|
||||
std::string s2 = toString(t2);
|
||||
|
||||
|
||||
std::cerr << s1 << ", " << s2 << std::endl;
|
||||
|
||||
|
||||
if (s1 != s2)
|
||||
throw Poco::Exception("Test failed.");
|
||||
}
|
||||
|
@ -642,7 +642,7 @@ TEST(JSON_Suite, SimpleTest)
|
||||
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);
|
||||
}
|
||||
|
@ -20,18 +20,18 @@ public:
|
||||
template <typename T> using KeyValuePair = std::pair<std::string, T>;
|
||||
template <typename T> using KeyValueVector = std::vector<KeyValuePair<T>>;
|
||||
|
||||
template <typename T> void write(const std::string & key, const T & value,
|
||||
template <typename T> void write(const std::string & key, const T & value,
|
||||
time_t timestamp = 0, const std::string & custom_root_path = "")
|
||||
{
|
||||
writeImpl(KeyValuePair<T>{ key, value }, timestamp, custom_root_path);
|
||||
}
|
||||
|
||||
template <typename T> void write(const KeyValueVector<T> & key_val_vec,
|
||||
template <typename T> void write(const KeyValueVector<T> & key_val_vec,
|
||||
time_t timestamp = 0, const std::string & custom_root_path = "")
|
||||
{
|
||||
writeImpl(key_val_vec, timestamp, custom_root_path);
|
||||
}
|
||||
|
||||
|
||||
/// возвращает путь root_path.server_name
|
||||
static std::string getPerServerPath(const std::string & server_name, const std::string & root_path = "one_min");
|
||||
private:
|
||||
@ -60,7 +60,7 @@ private:
|
||||
template <typename T>
|
||||
void out(std::ostream & os, const KeyValuePair<T> & key_val, time_t timestamp, const std::string & custom_root_path)
|
||||
{
|
||||
os << (custom_root_path.empty() ? root_path : custom_root_path) <<
|
||||
os << (custom_root_path.empty() ? root_path : custom_root_path) <<
|
||||
'.' << key_val.first << ' ' << key_val.second << ' ' << timestamp << '\n';
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ class Query;
|
||||
|
||||
|
||||
/** Базовый класс для UseQueryResult и StoreQueryResult.
|
||||
* Содержит общую часть реализации,
|
||||
* Содержит общую часть реализации,
|
||||
* Ссылается на Connection. Если уничтожить Connection, то пользоваться ResultBase и любым результатом нельзя.
|
||||
* Использовать объект можно только для результата одного запроса!
|
||||
* (При попытке присвоить объекту результат следующего запроса - UB.)
|
||||
|
@ -12,15 +12,15 @@ StoreQueryResult::StoreQueryResult(MYSQL_RES * res_, Connection * conn_, const Q
|
||||
UInt32 fields = getNumFields();
|
||||
reserve(rows);
|
||||
lengths.resize(rows * fields);
|
||||
|
||||
|
||||
for (UInt64 i = 0; MYSQL_ROW row = mysql_fetch_row(res); ++i)
|
||||
{
|
||||
MYSQL_LENGTHS lengths_for_row = mysql_fetch_lengths(res);
|
||||
memcpy(&lengths[i * fields], lengths_for_row, sizeof(lengths[0]) * fields);
|
||||
|
||||
|
||||
push_back(Row(row, this, &lengths[i * fields]));
|
||||
}
|
||||
checkError(conn->getDriver());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ class Foundation_API LevelFilterChannel: public Channel
|
||||
public:
|
||||
void log(const Message& msg);
|
||||
/// Sends the given Message to all
|
||||
/// attaches channels.
|
||||
/// attaches channels.
|
||||
|
||||
void setProperty(const std::string& name, const std::string& value);
|
||||
/// Sets or changes a configuration property.
|
||||
@ -24,7 +24,7 @@ public:
|
||||
/// Only the "level" property is supported, which allows setting desired level
|
||||
|
||||
void setChannel(Channel* pChannel);
|
||||
/// Sets the destination channel to which the formatted
|
||||
/// Sets the destination channel to which the formatted
|
||||
/// messages are passed on.
|
||||
|
||||
Channel* getChannel() const;
|
||||
@ -33,10 +33,10 @@ public:
|
||||
|
||||
void open();
|
||||
/// Opens the attached channel.
|
||||
|
||||
|
||||
void close();
|
||||
/// Closes the attached channel.
|
||||
|
||||
|
||||
void setLevel(Message::Priority);
|
||||
/// Sets the Logger's log level.
|
||||
void setLevel(const std::string& value);
|
||||
|
@ -1,29 +1,29 @@
|
||||
//
|
||||
//
|
||||
// LevelFilterChannel.cpp
|
||||
//
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Library: Ext
|
||||
// Package: Logging
|
||||
// Module: LevelFilterChannel
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
@ -70,7 +70,7 @@ void LevelFilterChannel::open()
|
||||
_channel->open();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LevelFilterChannel::close()
|
||||
{
|
||||
if (_channel)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
namespace zkutil
|
||||
{
|
||||
|
||||
|
||||
class Increment
|
||||
{
|
||||
public:
|
||||
@ -13,15 +13,15 @@ public:
|
||||
{
|
||||
zookeeper_holder->getZooKeeper()->createAncestors(path);
|
||||
}
|
||||
|
||||
|
||||
size_t get()
|
||||
{
|
||||
LOG_TRACE(log, "Get increment");
|
||||
|
||||
|
||||
size_t result = 0;
|
||||
std::string result_str;
|
||||
zkutil::Stat stat;
|
||||
|
||||
|
||||
bool success = false;
|
||||
auto zookeeper = zookeeper_holder->getZooKeeper();
|
||||
do
|
||||
@ -37,7 +37,7 @@ public:
|
||||
}
|
||||
}
|
||||
while (!success);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
|
@ -8,7 +8,7 @@ int main()
|
||||
{
|
||||
auto zookeeper_holder = std::make_shared<zkutil::ZooKeeperHolder>();
|
||||
zookeeper_holder->init("localhost:2181");
|
||||
|
||||
|
||||
zkutil::Lock l(zookeeper_holder, "/test", "test_lock");
|
||||
std::cout << "check " << l.tryCheck() << std::endl;
|
||||
std::cout << "lock tryLock() " << l.tryLock() << std::endl;
|
||||
|
Loading…
Reference in New Issue
Block a user