Merge branch 'master' of https://git.billsun.dev/bill/AQuery
This commit is contained in:
@@ -187,8 +187,7 @@ decayed_t<VT, types::GetLongType<T>> sumw(uint32_t w, const VT<T>& arr) {
|
||||
}
|
||||
|
||||
template<class T, template<typename ...> class VT>
|
||||
void avgw(uint32_t w, const VT<T>& arr,
|
||||
decayed_t<VT, types::GetFPType<types::GetLongType<T>>>& ret) {
|
||||
void avgw(uint32_t w, const VT<T>& arr, decayed_t<vector_type, types::GetFPType<types::GetLongType<T>>>& ret) {
|
||||
typedef types::GetFPType<types::GetLongType<T>> FPType;
|
||||
const uint32_t& len = arr.size;
|
||||
uint32_t i = 0;
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ namespace ankerl::unordered_dense{
|
||||
struct hash<std::tuple<Types...>> : public hasher<Types...>{ };
|
||||
}
|
||||
|
||||
struct aq_hashtable_value_t{
|
||||
struct aq_hashtable_value_t {
|
||||
uint32_t id;
|
||||
uint32_t cnt;
|
||||
};
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
template <class ...Types>
|
||||
std::string generate_printf_string(const char* sep = " ", const char* end = "\n") {
|
||||
std::string str;
|
||||
@@ -25,6 +26,11 @@ inline decltype(auto) print_hook<bool>(const bool& v) {
|
||||
return v? "true" : "false";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline decltype(auto) print_hook<std::string_view>(const std::string_view& v) {
|
||||
return v.data();
|
||||
}
|
||||
|
||||
extern char* gbuf;
|
||||
|
||||
void setgbuf(char* buf = 0);
|
||||
|
||||
@@ -55,6 +55,7 @@ void print<bool>(const bool&v, const char* delimiter){
|
||||
std::cout<< (v?"true":"false") << delimiter;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T getInt(const char*& buf){
|
||||
T ret = 0;
|
||||
@@ -537,4 +538,11 @@ aq_to_chars<types::timestamp_t>(void* value, char* buffer) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template<>
|
||||
char*
|
||||
aq_to_chars<std::string_view>(void* value, char* buffer){
|
||||
const auto& src = *static_cast<std::string_view*>(value);
|
||||
memcpy(buffer, src.data(), src.size());
|
||||
return buffer + src.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ 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>
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#include "pch_msc.hpp"
|
||||
|
||||
//#define TESTMAIN
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
@@ -668,7 +668,7 @@ int launcher(int argc, char** argv){
|
||||
str = std::string("cd ") + pwd + std::string("&& python3 ./prompt.py ") + str;
|
||||
return system(str.c_str());
|
||||
}
|
||||
#if true || !( defined(_MSC_VER) && defined(_DEBUG) )
|
||||
#if !defined(TESTMAIN) && !( defined(_MSC_VER) && defined(_DEBUG) )
|
||||
extern "C" int __DLLEXPORT__ main(int argc, char** argv) {
|
||||
#ifdef __AQ_BUILD_LAUNCHER__
|
||||
return launcher(argc, argv);
|
||||
|
||||
+16
-14
@@ -10,6 +10,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
#include "io.h"
|
||||
#include "hasher.h"
|
||||
|
||||
@@ -147,18 +148,18 @@ public:
|
||||
return *this;
|
||||
|
||||
}
|
||||
// ColView<_Ty> operator [](vector_type<uint32_t>& idxs) const {
|
||||
// return ColView<_Ty>(*this, std::move(idxs));
|
||||
// }
|
||||
// ColView<_Ty> operator [](const vector_type<uint32_t>& idxs) const {
|
||||
// return ColView<_Ty>(*this, idxs);
|
||||
// }
|
||||
vector_type<_Ty> operator[](vector_type<uint32_t>& idxs) const {
|
||||
vector_type<_Ty> ret(idxs.size);
|
||||
for (uint32_t i = 0; i < idxs.size; ++i)
|
||||
ret.container[i] = this->container[idxs[i]];
|
||||
return ret;
|
||||
}
|
||||
ColView<_Ty> operator [](vector_type<uint32_t>& idxs) const {
|
||||
return ColView<_Ty>(*this, std::move(idxs));
|
||||
}
|
||||
ColView<_Ty> operator [](const vector_type<uint32_t>& idxs) const {
|
||||
return ColView<_Ty>(*this, idxs);
|
||||
}
|
||||
//vector_type<_Ty> operator[](vector_type<uint32_t>& idxs) const {
|
||||
// vector_type<_Ty> ret(idxs.size);
|
||||
// for (uint32_t i = 0; i < idxs.size; ++i)
|
||||
// ret.container[i] = this->container[idxs[i]];
|
||||
// return ret;
|
||||
//}
|
||||
vector_type<_Ty> operator [](const std::vector<bool>& idxs) const {
|
||||
vector_type<_Ty> ret (this->size);
|
||||
uint32_t i = 0;
|
||||
@@ -474,7 +475,7 @@ struct TableInfo {
|
||||
|
||||
std::string printf_string =
|
||||
generate_printf_string<typename std::tuple_element<cols, tuple_type>::type ...>(sep, end);
|
||||
// puts(printf_string.c_str());
|
||||
puts(printf_string.c_str());
|
||||
std::string header_string = std::string();
|
||||
constexpr static int a_cols[] = { cols... };
|
||||
if (fp == nullptr){
|
||||
@@ -488,6 +489,7 @@ struct TableInfo {
|
||||
if (header_string.size() - l_sep >= 0)
|
||||
header_string.resize(header_string.size() - l_sep);
|
||||
}
|
||||
|
||||
const auto& prt_loop = [&fp, &view, &printf_string, *this, &limit](const auto& f) {
|
||||
#ifdef __AQ__HAS__INT128__
|
||||
constexpr auto num_hge = count_type<__int128_t, __uint128_t>((tuple_type*)(0));
|
||||
@@ -920,6 +922,7 @@ template <class ...Types>
|
||||
void print(const TableView<Types...>& v, const char* delimiter = " ", const char* endline = "\n") {
|
||||
v.print(delimiter, endline);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void print(const T& v, const char* delimiter = " ") {
|
||||
std::cout << v << delimiter;
|
||||
@@ -934,7 +937,6 @@ void print<__uint128_t>(const __uint128_t& v, const char* delimiter);
|
||||
#endif
|
||||
template <>
|
||||
void print<bool>(const bool& v, const char* delimiter);
|
||||
|
||||
template <class T>
|
||||
void inline print_impl(const T& v, const char* delimiter, const char* endline) {
|
||||
for (const auto& vi : v) {
|
||||
|
||||
@@ -13,7 +13,7 @@ long long testing_throughput(uint32_t n_jobs, bool prompt = true){
|
||||
auto tp = ThreadPool(thread::hardware_concurrency());
|
||||
getchar();
|
||||
auto i = 0u;
|
||||
fp = fopen("tmp.tmp", "w");
|
||||
fp = fopen("tmp.tmp", "wb");
|
||||
auto time = chrono::high_resolution_clock::now();
|
||||
while(i++ < n_jobs) tp.enqueue_task({ [](void* f) {fprintf(fp, "%d ", *(int*)f); free(f); }, new int(i) });
|
||||
puts("done dispatching.");
|
||||
@@ -53,7 +53,7 @@ long long testing_transaction(uint32_t n_burst, uint32_t n_batch,
|
||||
}
|
||||
|
||||
long long testing_destruction(bool prompt = true){
|
||||
fp = fopen("tmp.tmp", "w");
|
||||
fp = fopen("tmp.tmp", "wb");
|
||||
if (prompt) {
|
||||
puts("Press any key to start.");
|
||||
getchar();
|
||||
|
||||
+38
-22
@@ -3,6 +3,9 @@
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
using std::size_t;
|
||||
|
||||
#if defined(__SIZEOF_INT128__) and not defined(_WIN32)
|
||||
@@ -13,6 +16,9 @@ using std::size_t;
|
||||
#define __restrict__ __restrict
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
struct vector_base {};
|
||||
|
||||
template <class T>
|
||||
constexpr static inline bool is_vector(const T&) {
|
||||
return false;
|
||||
@@ -32,23 +38,23 @@ struct aqis_same_impl {
|
||||
|
||||
std::conditional_t<
|
||||
std::is_same_v<T1, bool> || std::is_same_v<T2, bool>,
|
||||
std::bool_constant<std::is_same_v<T1, bool> && std::is_same_v<T2, bool>>,
|
||||
Cond(
|
||||
(std::is_same_v<T1, bool> && std::is_same_v<T2, bool>),
|
||||
std::true_type,
|
||||
std::false_type
|
||||
),
|
||||
Cond(
|
||||
std::is_signed_v<T1> == std::is_signed_v<T2>,
|
||||
Cond(
|
||||
std::is_floating_point_v<T1> == std::is_floating_point_v<T2>,
|
||||
Cond(
|
||||
aq_szof<T1> == aq_szof<T2>, // deal with sizeof(void)
|
||||
std::true_type,
|
||||
std::false_type
|
||||
),
|
||||
std::false_type
|
||||
),
|
||||
std::false_type
|
||||
!(std::is_class_v<T1> || std::is_class_v<T2>),
|
||||
Cond(
|
||||
std::is_signed_v<T1> == std::is_signed_v<T2>,
|
||||
Cond(
|
||||
std::is_floating_point_v<T1> == std::is_floating_point_v<T2>,
|
||||
std::bool_constant<aq_szof<T1> == aq_szof<T2>>, // deal with sizeof(void)
|
||||
std::false_type
|
||||
),
|
||||
std::false_type
|
||||
),
|
||||
Cond(
|
||||
(std::is_class_v<T1> && std::is_class_v<T2>),
|
||||
std::bool_constant<(std::is_base_of_v<T1, T2> || std::is_base_of_v<T2, T1>)>,
|
||||
std::false_type
|
||||
)
|
||||
)
|
||||
>::value;
|
||||
};
|
||||
@@ -63,12 +69,12 @@ constexpr bool aqis_same<T1, T2> = aqis_same_impl<T1, T2>::value;
|
||||
namespace types {
|
||||
enum Type_t {
|
||||
AINT32, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, AINT64, AINT128, AINT16, ADATE, ATIME, AINT8,
|
||||
AUINT32, AUINT64, AUINT128, AUINT16, AUINT8, ABOOL, VECTOR, ATIMESTAMP, ACHAR, NONE, ERROR
|
||||
AUINT32, AUINT64, AUINT128, AUINT16, AUINT8, ABOOL, VECTOR, ATIMESTAMP, ACHAR, ASV, NONE, ERROR
|
||||
};
|
||||
static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%Lf", "%ld", "%d", "%hi", "%s", "%s", "%hhd",
|
||||
"%u", "%lu", "%s", "%hu", "%hhu", "%s", "%s", "Vector<%s>", "%s", "%c", "NULL", "ERROR" };
|
||||
static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%Lf", "%ld", "%s", "%hi", "%s", "%s", "%hhd",
|
||||
"%u", "%lu", "%s", "%hu", "%hhu", "%s", "Vector<%s>", "%s", "%c", "%s", "NULL", "ERROR" };
|
||||
static constexpr const char* SQL_Type[] = { "INT", "REAL", "TEXT", "DOUBLE", "DOUBLE", "BIGINT", "HUGEINT", "SMALLINT", "DATE", "TIME", "TINYINT",
|
||||
"INT", "BIGINT", "HUGEINT", "SMALLINT", "TINYINT", "BOOL", "HUGEINT", "TIMESTAMP", "CHAR", "NULL", "ERROR"};
|
||||
"INT", "BIGINT", "HUGEINT", "SMALLINT", "TINYINT", "BOOL", "HUGEINT", "TIMESTAMP", "CHAR", "TEXT", "NULL", "ERROR"};
|
||||
|
||||
|
||||
// TODO: deal with data/time <=> str/uint conversion
|
||||
@@ -169,6 +175,8 @@ namespace types {
|
||||
f(unsigned short, AUINT16) \
|
||||
f(bool, ABOOL) \
|
||||
f(timestamp_t, ATIMESTAMP) \
|
||||
f(std::string_view, ASV) \
|
||||
f(std::string, ASV) \
|
||||
F_INT128(f)
|
||||
|
||||
inline constexpr static Type_t getType() {
|
||||
@@ -399,7 +407,6 @@ struct transValues_s<lT<vT, T...>, vT, rT> {
|
||||
using type = rT<T...>;
|
||||
};
|
||||
|
||||
#include <utility>
|
||||
template <class vT, int i, template <vT ...> class rT>
|
||||
using transValues = typename transValues_s<std::make_integer_sequence<vT, i>, vT, rT>::type;
|
||||
template <int i, template <int ...> class rT>
|
||||
@@ -427,8 +434,17 @@ template <class ...T>
|
||||
using get_first = typename get_first_impl<T...>::first;
|
||||
template <class T>
|
||||
struct value_type_rec_impl { typedef T type; };
|
||||
|
||||
template <template <class...> class VT, class ...V>
|
||||
struct value_type_rec_impl<VT<V...>> { typedef typename value_type_rec_impl<get_first<V...>>::type type; };
|
||||
struct value_type_rec_impl<VT<V...>> {
|
||||
typedef typename
|
||||
std::conditional_t<
|
||||
std::is_base_of_v<vector_base<get_first<V...>>, VT<V...>>,
|
||||
typename value_type_rec_impl<get_first<V...>>::type,
|
||||
VT<V...>
|
||||
> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using value_type_r = typename value_type_rec_impl<T>::type;
|
||||
|
||||
|
||||
+68
-12
@@ -1059,17 +1059,13 @@ public:
|
||||
return do_insert_or_assign(std::move(key), std::forward<M>(mapped)).first;
|
||||
}
|
||||
|
||||
template <class K, class M>
|
||||
auto hashtable_push(K&& key, M& mapped) {
|
||||
++ mapped.id;
|
||||
++ mapped.cnt;
|
||||
auto it_isinserted = try_emplace(std::forward<K>(key), std::forward<M>(mapped));
|
||||
if (!it_isinserted.second) {
|
||||
--mapped.cnt;
|
||||
return it_isinserted.first->second.id;
|
||||
}
|
||||
return mapped.id;
|
||||
}
|
||||
// template <class K>
|
||||
// bool hashtable_push(K&& key) {
|
||||
// auto it_isinserted = try_emplace(std::forward<K>(key), 1);
|
||||
// if (!it_isinserted.second)
|
||||
// ++ it_isinserted.first->second;
|
||||
// return it_isinserted.second;
|
||||
// }
|
||||
|
||||
template <typename K,
|
||||
typename M,
|
||||
@@ -1114,6 +1110,66 @@ public:
|
||||
return {begin() + static_cast<difference_type>(value_idx), true};
|
||||
}
|
||||
|
||||
template <class K,
|
||||
typename Q = T,
|
||||
typename H = Hash,
|
||||
typename KE = KeyEqual,
|
||||
std::enable_if_t<!is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>
|
||||
auto hashtable_push(K&& key) -> unsigned {
|
||||
if (is_full()) {
|
||||
increase_size();
|
||||
}
|
||||
|
||||
auto hash = mixed_hash(key);
|
||||
auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);
|
||||
auto bucket_idx = bucket_idx_from_hash(hash);
|
||||
|
||||
while (dist_and_fingerprint <= at(m_buckets, bucket_idx).m_dist_and_fingerprint) {
|
||||
if (dist_and_fingerprint == at(m_buckets, bucket_idx).m_dist_and_fingerprint &&
|
||||
m_equal(key, m_values[at(m_buckets, bucket_idx).m_value_idx])) {
|
||||
// found it, return without ever actually creating anything
|
||||
return static_cast<uint32_t>(at(m_buckets, bucket_idx).m_value_idx);
|
||||
}
|
||||
dist_and_fingerprint = dist_inc(dist_and_fingerprint);
|
||||
bucket_idx = next(bucket_idx);
|
||||
}
|
||||
|
||||
// value is new, insert element first, so when exception happens we are in a valid state
|
||||
m_values.emplace_back(std::forward<K>(key));
|
||||
// now place the bucket and shift up until we find an empty spot
|
||||
auto value_idx = static_cast<value_idx_type>(m_values.size() - 1);
|
||||
place_and_shift_up({dist_and_fingerprint, value_idx}, bucket_idx);
|
||||
return static_cast<uint32_t>(value_idx);
|
||||
}
|
||||
template <class... Args>
|
||||
auto hashtable_push(Args&&... args) -> unsigned {
|
||||
if (is_full()) {
|
||||
increase_size();
|
||||
}
|
||||
|
||||
// we have to instantiate the value_type to be able to access the key.
|
||||
// 1. emplace_back the object so it is constructed. 2. If the key is already there, pop it later in the loop.
|
||||
auto& key = get_key(m_values.emplace_back(std::forward<Args>(args)...));
|
||||
auto hash = mixed_hash(key);
|
||||
auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);
|
||||
auto bucket_idx = bucket_idx_from_hash(hash);
|
||||
|
||||
while (dist_and_fingerprint <= at(m_buckets, bucket_idx).m_dist_and_fingerprint) {
|
||||
if (dist_and_fingerprint == at(m_buckets, bucket_idx).m_dist_and_fingerprint &&
|
||||
m_equal(key, get_key(m_values[at(m_buckets, bucket_idx).m_value_idx]))) {
|
||||
m_values.pop_back(); // value was already there, so get rid of it
|
||||
return static_cast<uint32_t>(at(m_buckets, bucket_idx).m_value_idx);
|
||||
}
|
||||
dist_and_fingerprint = dist_inc(dist_and_fingerprint);
|
||||
bucket_idx = next(bucket_idx);
|
||||
}
|
||||
|
||||
// value is new, place the bucket and shift up until we find an empty spot
|
||||
auto value_idx = static_cast<value_idx_type>(m_values.size() - 1);
|
||||
place_and_shift_up({dist_and_fingerprint, value_idx}, bucket_idx);
|
||||
|
||||
return static_cast<uint32_t>(value_idx);
|
||||
}
|
||||
template <class... Args>
|
||||
auto emplace(Args&&... args) -> std::pair<iterator, bool> {
|
||||
if (is_full()) {
|
||||
@@ -1421,7 +1477,7 @@ public:
|
||||
}
|
||||
|
||||
// nonstandard API: expose the underlying values container
|
||||
[[nodiscard]] auto values() const noexcept -> value_container_type const& {
|
||||
[[nodiscard]] auto values() noexcept -> value_container_type & {
|
||||
return m_values;
|
||||
}
|
||||
|
||||
|
||||
+42
-4
@@ -17,8 +17,6 @@
|
||||
#include "types.h"
|
||||
#include "gc.h"
|
||||
#pragma pack(push, 1)
|
||||
template<class T>
|
||||
struct vector_base {};
|
||||
|
||||
struct vectortype_cstorage{
|
||||
void* container;
|
||||
@@ -32,7 +30,6 @@ public:
|
||||
void inline _copy(const vector_type<_Ty>& vt) {
|
||||
// quick init while using malloc
|
||||
//if (capacity > 0) free(container);
|
||||
|
||||
this->size = vt.size;
|
||||
this->capacity = vt.capacity;
|
||||
if (capacity) {
|
||||
@@ -72,6 +69,8 @@ public:
|
||||
}
|
||||
constexpr vector_type() noexcept : size(0), capacity(0), container(0) {};
|
||||
constexpr vector_type(_Ty* container, uint32_t len) noexcept : size(len), capacity(0), container(container) {};
|
||||
constexpr vector_type(const char** container, uint32_t len,
|
||||
typename std::enable_if_t<!std::is_same_v<_Ty, const char*>>* = nullptr) noexcept = delete;
|
||||
constexpr explicit vector_type(const vector_type<_Ty>& vt) noexcept : capacity(0) {
|
||||
_copy(vt);
|
||||
}
|
||||
@@ -88,6 +87,12 @@ public:
|
||||
constexpr vector_type(const uint32_t size, void* data) :
|
||||
size(size), capacity(0), container(static_cast<_Ty*>(data)) {}
|
||||
|
||||
void init_from(const uint32_t size, void* data) {
|
||||
this->container = static_cast<_Ty*>(data);
|
||||
this->size = size;
|
||||
this->capacity = 0;
|
||||
}
|
||||
|
||||
vector_type<_Ty>& operator =(const _Ty& vt) {
|
||||
if (!container) {
|
||||
container = (_Ty*)malloc(sizeof(_Ty));
|
||||
@@ -134,7 +139,7 @@ public:
|
||||
container[i++] = v;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
vector_type<_Ty> distinct_copy(){
|
||||
auto d_vals = distinct_common();
|
||||
vector_type<_Ty> ret(d_vals.size());
|
||||
@@ -389,6 +394,39 @@ public:
|
||||
_Make_Ops(Opseq)
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr vector_type<std::string_view>::vector_type(const char** container, uint32_t len,
|
||||
typename std::enable_if_t<true>*) noexcept
|
||||
{
|
||||
size = capacity = len;
|
||||
this->container = static_cast<std::string_view*>(
|
||||
malloc(sizeof(std::string_view) * len));
|
||||
for(uint32_t i = 0; i < len; ++i){
|
||||
this->container[i] = container[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr vector_type<std::string_view>::vector_type(const uint32_t size, void* data) :
|
||||
size(size), capacity(0) {
|
||||
this->container = static_cast<std::string_view*>(
|
||||
malloc(sizeof(std::string_view) * size));
|
||||
for(uint32_t i = 0; i < size; ++i){
|
||||
this->container[i] = ((const char**)data)[i];
|
||||
}
|
||||
//std::cout<<size << container[1];
|
||||
}
|
||||
|
||||
// template<>
|
||||
// void vector_type<std::string_view>::init_from(const uint32_t size, void* data) {
|
||||
// this->size = this->capacity = size;
|
||||
// this->container = static_cast<std::string_view*>(
|
||||
// malloc(sizeof(std::string_view) * size));
|
||||
// for(uint32_t i = 0; i < size; ++i){
|
||||
// this->container[i] = container[i];
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
template <>
|
||||
class vector_type<void> {
|
||||
|
||||
Reference in New Issue
Block a user