mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-15 10:52:30 +00:00
299 lines
8.0 KiB
C++
299 lines
8.0 KiB
C++
/// c++ sample dictionary library
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
namespace ClickHouseLibrary
|
|
{
|
|
using CString = const char *;
|
|
using ColumnName = CString;
|
|
using ColumnNames = ColumnName[];
|
|
|
|
struct CStrings
|
|
{
|
|
CString * data = nullptr;
|
|
uint64_t size = 0;
|
|
};
|
|
|
|
struct VectorUInt64
|
|
{
|
|
const uint64_t * data = nullptr;
|
|
uint64_t size = 0;
|
|
};
|
|
|
|
struct ColumnsUInt64
|
|
{
|
|
VectorUInt64 * data = nullptr;
|
|
uint64_t size = 0;
|
|
};
|
|
|
|
struct Field
|
|
{
|
|
const void * data = nullptr;
|
|
uint64_t size = 0;
|
|
};
|
|
|
|
struct Row
|
|
{
|
|
const Field * data = nullptr;
|
|
uint64_t size = 0;
|
|
};
|
|
|
|
struct Table
|
|
{
|
|
const Row * data = nullptr;
|
|
uint64_t size = 0;
|
|
uint64_t error_code = 0; // 0 = ok; !0 = error, with message in error_string
|
|
const char * error_string = nullptr;
|
|
};
|
|
|
|
enum LogLevel
|
|
{
|
|
FATAL = 1,
|
|
CRITICAL,
|
|
ERROR,
|
|
WARNING,
|
|
NOTICE,
|
|
INFORMATION,
|
|
DEBUG,
|
|
TRACE,
|
|
};
|
|
|
|
void log(LogLevel level, CString msg);
|
|
}
|
|
|
|
|
|
#define LOG(logger, message) \
|
|
do \
|
|
{ \
|
|
std::stringstream builder; \
|
|
builder << message; \
|
|
(logger)(ClickHouseLibrary::INFORMATION, builder.str().c_str()); \
|
|
} while (false)
|
|
|
|
|
|
struct LibHolder
|
|
{
|
|
std::function<void(ClickHouseLibrary::LogLevel, ClickHouseLibrary::CString)> log;
|
|
};
|
|
|
|
|
|
struct DataHolder
|
|
{
|
|
std::vector<std::vector<uint64_t>> dataHolder; // Actual data storage
|
|
std::vector<std::vector<ClickHouseLibrary::Field>> fieldHolder; // Pointers and sizes of data
|
|
std::unique_ptr<ClickHouseLibrary::Row[]> rowHolder;
|
|
ClickHouseLibrary::Table ctable; // Result data prepared for transfer via c-style interface
|
|
LibHolder * lib = nullptr;
|
|
|
|
size_t num_rows;
|
|
size_t num_cols;
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
void MakeColumnsFromVector(T * ptr)
|
|
{
|
|
if (ptr->dataHolder.empty())
|
|
{
|
|
LOG(ptr->lib->log, "generating null values, cols: " << ptr->num_cols);
|
|
std::vector<ClickHouseLibrary::Field> fields;
|
|
for (size_t i = 0; i < ptr->num_cols; ++i)
|
|
fields.push_back({nullptr, 0});
|
|
ptr->fieldHolder.push_back(fields);
|
|
}
|
|
else
|
|
{
|
|
for (const auto & row : ptr->dataHolder)
|
|
{
|
|
std::vector<ClickHouseLibrary::Field> fields;
|
|
for (const auto & field : row)
|
|
fields.push_back({&field, sizeof(field)});
|
|
ptr->fieldHolder.push_back(fields);
|
|
}
|
|
}
|
|
|
|
const auto rows_num = ptr->fieldHolder.size();
|
|
ptr->rowHolder = std::make_unique<ClickHouseLibrary::Row[]>(rows_num);
|
|
size_t i = 0;
|
|
for (auto & row : ptr->fieldHolder)
|
|
{
|
|
ptr->rowHolder[i].size = row.size();
|
|
ptr->rowHolder[i].data = row.data();
|
|
++i;
|
|
}
|
|
ptr->ctable.size = rows_num;
|
|
ptr->ctable.data = ptr->rowHolder.get();
|
|
}
|
|
|
|
|
|
extern "C"
|
|
{
|
|
|
|
void * ClickHouseDictionary_v3_loadIds(void * data_ptr,
|
|
ClickHouseLibrary::CStrings * settings,
|
|
ClickHouseLibrary::CStrings * columns,
|
|
const struct ClickHouseLibrary::VectorUInt64 * ids)
|
|
{
|
|
auto ptr = static_cast<DataHolder *>(data_ptr);
|
|
|
|
if (ids)
|
|
LOG(ptr->lib->log, "loadIds lib call ptr=" << data_ptr << " => " << ptr << " size=" << ids->size);
|
|
|
|
if (!ptr)
|
|
return nullptr;
|
|
|
|
if (settings)
|
|
{
|
|
LOG(ptr->lib->log, "settings passed: " << settings->size);
|
|
for (size_t i = 0; i < settings->size; ++i)
|
|
{
|
|
LOG(ptr->lib->log, "setting " << i << " :" << settings->data[i]);
|
|
}
|
|
}
|
|
|
|
if (columns)
|
|
{
|
|
LOG(ptr->lib->log, "columns passed:" << columns->size);
|
|
for (size_t i = 0; i < columns->size; ++i)
|
|
{
|
|
LOG(ptr->lib->log, "column " << i << " :" << columns->data[i]);
|
|
}
|
|
}
|
|
|
|
if (ids)
|
|
{
|
|
LOG(ptr->lib->log, "ids passed: " << ids->size);
|
|
for (size_t i = 0; i < ids->size; ++i)
|
|
{
|
|
LOG(ptr->lib->log, "id " << i << " :" << ids->data[i] << " generating.");
|
|
ptr->dataHolder.emplace_back(std::vector<uint64_t>{ids->data[i], ids->data[i] + 100, ids->data[i] + 200, ids->data[i] + 300});
|
|
}
|
|
}
|
|
|
|
MakeColumnsFromVector(ptr);
|
|
return static_cast<void *>(&ptr->ctable);
|
|
}
|
|
|
|
|
|
void * ClickHouseDictionary_v3_loadAll(void * data_ptr, ClickHouseLibrary::CStrings * settings, ClickHouseLibrary::CStrings * /*columns*/)
|
|
{
|
|
auto ptr = static_cast<DataHolder *>(data_ptr);
|
|
|
|
LOG(ptr->lib->log, "loadAll lib call ptr=" << data_ptr << " => " << ptr);
|
|
|
|
if (!ptr)
|
|
return nullptr;
|
|
|
|
size_t num_rows = 0, num_cols = 4;
|
|
std::string test_type;
|
|
std::vector<std::string> settings_values;
|
|
if (settings)
|
|
{
|
|
LOG(ptr->lib->log, "settings size: " << settings->size);
|
|
|
|
for (size_t i = 0; i < settings->size; ++i)
|
|
{
|
|
std::string setting_name = settings->data[i];
|
|
std::string setting_value = settings->data[++i];
|
|
LOG(ptr->lib->log, "setting " + std::to_string(i) + " name " + setting_name + " value " + setting_value);
|
|
|
|
if (setting_name == "num_rows")
|
|
num_rows = std::atoi(setting_value.data());
|
|
else if (setting_name == "num_cols")
|
|
num_cols = std::atoi(setting_value.data());
|
|
else if (setting_name == "test_type")
|
|
test_type = setting_value;
|
|
else
|
|
{
|
|
LOG(ptr->lib->log, "Adding setting " + setting_name);
|
|
settings_values.push_back(setting_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (test_type == "test_simple")
|
|
{
|
|
for (size_t i = 0; i < 10; ++i)
|
|
{
|
|
LOG(ptr->lib->log, "id " << i << " :" << " generating.");
|
|
ptr->dataHolder.emplace_back(std::vector<uint64_t>{i, i + 10, i + 20, i + 30});
|
|
}
|
|
}
|
|
else if (test_type == "test_many_rows" && num_rows)
|
|
{
|
|
for (size_t i = 0; i < num_rows; ++i)
|
|
{
|
|
ptr->dataHolder.emplace_back(std::vector<uint64_t>{i, i, i, i});
|
|
}
|
|
}
|
|
|
|
ptr->num_cols = num_cols;
|
|
ptr->num_rows = num_rows;
|
|
|
|
MakeColumnsFromVector(ptr);
|
|
return static_cast<void *>(&ptr->ctable);
|
|
}
|
|
|
|
|
|
void * ClickHouseDictionary_v3_loadKeys(void * data_ptr, ClickHouseLibrary::CStrings * settings, ClickHouseLibrary::Table * requested_keys)
|
|
{
|
|
auto ptr = static_cast<DataHolder *>(data_ptr);
|
|
LOG(ptr->lib->log, "loadKeys lib call ptr=" << data_ptr << " => " << ptr);
|
|
if (settings)
|
|
{
|
|
LOG(ptr->lib->log, "settings passed: " << settings->size);
|
|
for (size_t i = 0; i < settings->size; ++i)
|
|
{
|
|
LOG(ptr->lib->log, "setting " << i << " :" << settings->data[i]);
|
|
}
|
|
}
|
|
if (requested_keys)
|
|
{
|
|
LOG(ptr->lib->log, "requested_keys columns passed: " << requested_keys->size);
|
|
for (size_t i = 0; i < requested_keys->size; ++i)
|
|
{
|
|
LOG(ptr->lib->log, "requested_keys at column " << i << " passed: " << requested_keys->data[i].size);
|
|
ptr->dataHolder.emplace_back(std::vector<uint64_t>{i, i + 100, i + 200, i + 300});
|
|
}
|
|
}
|
|
|
|
MakeColumnsFromVector(ptr);
|
|
return static_cast<void *>(&ptr->ctable);
|
|
}
|
|
|
|
void * ClickHouseDictionary_v3_libNew(
|
|
ClickHouseLibrary::CStrings * /*settings*/, void (*logFunc)(ClickHouseLibrary::LogLevel, ClickHouseLibrary::CString))
|
|
{
|
|
auto lib_ptr = new LibHolder;
|
|
lib_ptr->log = logFunc;
|
|
return lib_ptr;
|
|
}
|
|
|
|
void ClickHouseDictionary_v3_libDelete(void * lib_ptr)
|
|
{
|
|
auto ptr = static_cast<LibHolder *>(lib_ptr);
|
|
delete ptr;
|
|
return;
|
|
}
|
|
|
|
void * ClickHouseDictionary_v3_dataNew(void * lib_ptr)
|
|
{
|
|
auto data_ptr = new DataHolder;
|
|
data_ptr->lib = static_cast<decltype(data_ptr->lib)>(lib_ptr);
|
|
return data_ptr;
|
|
}
|
|
|
|
void ClickHouseDictionary_v3_dataDelete(void * /*lib_ptr*/, void * data_ptr)
|
|
{
|
|
auto ptr = static_cast<DataHolder *>(data_ptr);
|
|
delete ptr;
|
|
return;
|
|
}
|
|
|
|
}
|