You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AQuery/server/libaquery.h

328 lines
7.3 KiB

#ifndef _AQUERY_H
#define _AQUERY_H
#ifdef __INTELLISENSE__
#define __AQUERY_ITC_USE_SEMPH__
#define THREADING
#endif
#ifdef THREADING
#include "threading.h"
#endif
#include <unordered_map>
#include <chrono>
#include <filesystem>
#include <cstring>
class aq_timer {
private:
std::chrono::high_resolution_clock::time_point now;
public:
aq_timer(){
now = std::chrono::high_resolution_clock::now();
}
void reset(){
now = std::chrono::high_resolution_clock::now();
}
long long elapsed(){
long long ret = (std::chrono::high_resolution_clock::now() - now).count();
reset();
return ret;
}
long long lap() const{
long long ret = (std::chrono::high_resolution_clock::now() - now).count();
return ret;
}
};
#include "table.h"
template<class T = int>
T getInt(const char*& buf){
T ret = 0;
while(*buf >= '0' and *buf <= '9'){
ret = ret*10 + *buf - '0';
buf++;
}
return ret;
}
template<class T>
char* intToString(T val, char* buf){
while (val > 0){
*--buf = val%10 + '0';
val /= 10;
}
return buf;
}
enum Log_level : int {
LOG_INFO,
LOG_ERROR,
LOG_SILENT
};
#ifndef __AQBACKEND_TYPE__
#define __AQBACKEND_TYPE__ 1
enum Backend_Type : int {
BACKEND_AQuery,
BACKEND_MonetDB,
BACKEND_MariaDB,
BACKEND_DuckDB,
BACKEND_SQLite,
BACKEND_TOTAL
};
#endif
struct QueryStats{
long long monet_time;
long long postproc_time;
};
struct Config{
int running, new_query, server_mode,
backend_type, has_dll,
n_buffers;
QueryStats stats;
int buffer_sizes[];
};
#ifndef __AQQueryResult__
#define __AQQueryResult__ 1
struct AQQueryResult {
void* res;
unsigned ref;
};
#endif
struct Session{
struct Statistic{
size_t total_active;
size_t cnt_object;
size_t total_alloc;
} stats;
void* memory_map;
};
struct StoredProcedure {
uint32_t cnt, postproc_modules;
char **queries;
const char* name;
void **__rt_loaded_modules;
};
struct Trigger;
struct IntervalBasedTriggerHost;
struct CallbackBasedTriggerHost;
struct Context {
typedef int (*printf_type) (const char *format, ...);
void* module_function_maps = nullptr;
Config* cfg;
int n_buffers, *sz_bufs;
void **buffers;
void* curr_server;
void* alt_server[BACKEND_TOTAL] = {nullptr};
Log_level log_level = LOG_INFO;
Session current;
const char* aquery_root_path;
#ifdef THREADING
void* thread_pool;
#endif
#ifndef __AQ_USE_THREADEDGC__
void* gc;
#endif
printf_type print = &printf;
Context();
virtual ~Context();
template <class ...Types>
void log(Types... args) {
if (log_level == LOG_INFO)
print(args...);
}
template <class ...Types>
void err(Types... args) {
if (log_level <= LOG_ERROR)
print(args...);
}
void init_session();
void end_session();
void* get_module_function(const char*);
std::unordered_map<std::string, void*> tables;
std::unordered_map<std::string, uColRef *> cols;
std::unordered_map<std::string, StoredProcedure> stored_proc;
std::unordered_map<std::string, Trigger> triggers;
IntervalBasedTriggerHost *it_host;
CallbackBasedTriggerHost *ct_host;
};
struct StoredProcedurePayload {
StoredProcedure *p;
Context* cxt;
};
struct StoredProcedurePayloadCond {
StoredProcedure *condition;
StoredProcedure *action;
Context* cxt;
};
int execTriggerPayload(void*);
int execTriggerPayloadCond(void*);
#ifdef _WIN32
#define __DLLEXPORT__ __declspec(dllexport) __stdcall
#else
#define __DLLEXPORT__
#endif
#define __AQEXPORT__(_Ty) extern "C" _Ty __DLLEXPORT__
typedef void (*deallocator_t) (void*);
#include <type_traits>
#include "jeaiii_to_text.h"
template<class T>
inline std::enable_if_t<std::is_integral_v<T>, char *>
aq_to_chars(void* value, char* buffer) {
return to_text(buffer, *static_cast<T*>(value));
}
template<class T>
inline std::enable_if_t<!std::is_integral_v<T>, char *>
aq_to_chars(void* value, char* buffer) {
return buffer;
}
#ifdef __SIZEOF_INT128__
template<>
inline char*
aq_to_chars<__int128_t>(void* value, char* buffer) {
return jeaiii_i128<__int128_t>(buffer, *static_cast<__int128_t*>(value));
}
template<>
inline char*
aq_to_chars<__uint128_t>(void* value, char* buffer) {
return jeaiii_i128<__uint128_t>(buffer, *static_cast<__uint128_t*>(value));
}
#endif
template<> char* aq_to_chars<float>(void* , char*);
template<> char* aq_to_chars<double>(void* , char*);
template<> char* aq_to_chars<char*>(void* , char*);
template<> char* aq_to_chars<types::date_t>(void* , char*);
template<> char* aq_to_chars<types::time_t>(void* , char*);
template<> char* aq_to_chars<types::timestamp_t>(void* , char*);
template<> char* aq_to_chars<std::string_view>(void* , char*);
typedef int (*code_snippet)(void*);
template <class _This_Struct>
inline void AQ_ZeroMemory(_This_Struct& __val) {
memset(&__val, 0, sizeof(_This_Struct));
}
template <typename _This_Type>
inline _This_Type* AQ_DupObject(_This_Type* __val) {
auto ret = (_This_Type*)(malloc(sizeof(_This_Type)));
memcpy(ret, __val, sizeof(_This_Type));
return ret;
}
inline char* AQ_DupString(const char* __val) {
auto __len = strlen(__val) + 1;
auto ret = (char*)malloc(__len);
memcpy(ret, __val, __len);
return ret;
}
#ifdef __USE_STD_SEMAPHORE__
#include <semaphore>
class A_Semaphore {
private:
std::binary_semaphore native_handle;
public:
A_Semaphore(bool v = false) {
native_handle = std::binary_semaphore(v);
}
void acquire() {
native_handle.acquire();
}
void release() {
native_handle.release();
}
~A_Semaphore() { }
};
#else
#ifndef _WIN32
#ifdef __APPLE__
#include <dispatch/dispatch.h>
class A_Semaphore {
private:
dispatch_semaphore_t native_handle;
public:
explicit A_Semaphore(bool v = false) {
native_handle = dispatch_semaphore_create(v);
}
void acquire() {
// puts("acquire");
dispatch_semaphore_wait(native_handle, DISPATCH_TIME_FOREVER);
}
void release() {
// puts("release");
dispatch_semaphore_signal(native_handle);
}
~A_Semaphore() {
}
};
#else
#include <semaphore.h>
class A_Semaphore {
private:
sem_t native_handle;
public:
A_Semaphore(bool v = false) {
sem_init(&native_handle, v, 1);
}
void acquire() {
sem_wait(&native_handle);
}
void release() {
sem_post(&native_handle);
}
~A_Semaphore() {
sem_destroy(&native_handle);
}
};
#endif // __APPLE__
#endif // _WIN32
#endif //__USE_STD_SEMAPHORE__
void print_monetdb_results(void* _srv, const char* sep, const char* end, uint32_t limit);
StoredProcedure get_procedure(Context* cxt, const char* name);
#define AQTIMER(x) auto __timer##x = std::chrono::high_resolution_clock::now();
#define __AQTIMERLAP__IMPL(x, y) \
printf(#y": %llu\n", (unsigned long long)( \
std::chrono::high_resolution_clock::now() - __timer##x \
).count()); \
__timer##x = std::chrono::high_resolution_clock::now();
#define __AQTIMERLAP_STRIP(X, Y, IMPL, ...) IMPL
#define AQTIMERLAP(...) \
__AQTIMERLAP_STRIP(__VA_ARGS__, \
__AQTIMERLAP__IMPL(__VA_ARGS__), \
__AQTIMERLAP__IMPL(, __VA_ARGS__), \
__AQTIMERLAP__IMPL(,) \
)
#endif