This commit is contained in:
2022-12-28 12:59:07 +08:00
24 changed files with 1003 additions and 93 deletions
+1 -2
View File
@@ -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
View File
@@ -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;
};
+6
View File
@@ -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);
+8
View File
@@ -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();
}
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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) {
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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> {