updated code generation for compound-columns, initial support for scratchspace

master
Bill 2 years ago
parent aaef489029
commit 540672cdc4

@ -305,7 +305,7 @@ opor = OperatorBase('or', 2, logical, cname = '||', sqlname = ' OR ', call = bin
opxor = OperatorBase('xor', 2, logical, cname = '^', sqlname = ' XOR ', call = binary_op_behavior)
opgt = OperatorBase('gt', 2, logical, cname = '>', sqlname = '>', call = binary_op_behavior)
oplt = OperatorBase('lt', 2, logical, cname = '<', sqlname = '<', call = binary_op_behavior)
opge = OperatorBase('gte', 2, logical, cname = '>=', sqlname = '>=', call = binary_op_behavior)
opgte = OperatorBase('gte', 2, logical, cname = '>=', sqlname = '>=', call = binary_op_behavior)
oplte = OperatorBase('lte', 2, logical, cname = '<=', sqlname = '<=', call = binary_op_behavior)
opneq = OperatorBase('neq', 2, logical, cname = '!=', sqlname = '!=', call = binary_op_behavior)
opeq = OperatorBase('eq', 2, logical, cname = '==', sqlname = '=', call = binary_op_behavior)
@ -355,19 +355,27 @@ fnpow = OperatorBase('pow', 2, lambda *_ : DoubleT, cname = 'pow', sqlname = 'PO
# type collections
def _op_make_dict(*items : OperatorBase):
return { i.name: i for i in items}
#binary op
builtin_binary_arith = _op_make_dict(opadd, opdiv, opmul, opsub, opmod)
builtin_binary_logical = _op_make_dict(opand, opor, opxor, opgt, oplt,
opge, oplte, opneq, opeq)
opgte, oplte, opneq, opeq)
builtin_binary_ops = {**builtin_binary_arith, **builtin_binary_logical}
#unary op
builtin_unary_logical = _op_make_dict(opnot)
builtin_unary_arith = _op_make_dict(opneg)
builtin_unary_special = _op_make_dict(spnull, opdistinct)
# functions
builtin_cstdlib = _op_make_dict(fnsqrt, fnlog, fnsin, fncos, fntan, fnpow)
builtin_func = _op_make_dict(fnmax, fnmin, fnsum, fnavg, fnmaxs,
fnmins, fndeltas, fnratios, fnlast,
fnfirst, fnsums, fnavgs, fncnt,
fnpack, fntrunc, fnprev, fnnext,
fnvar, fnvars, fnstd, fnstds)
builtin_aggfunc = _op_make_dict(fnmax, fnmin, fnsum, fnavg,
fnlast, fnfirst, fncnt, fnvar, fnstd)
builtin_vecfunc = _op_make_dict(fnmaxs,
fnmins, fndeltas, fnratios, fnsums, fnavgs,
fnpack, fntrunc, fnprev, fnnext, fnvars, fnstds)
builtin_vecfunc = {**builtin_vecfunc, **builtin_cstdlib}
builtin_func = {**builtin_vecfunc, **builtin_aggfunc}
user_module_func = {}
builtin_operators : Dict[str, OperatorBase] = {**builtin_binary_arith, **builtin_binary_logical,
**builtin_unary_arith, **builtin_unary_logical, **builtin_unary_special, **builtin_func, **builtin_cstdlib,
**user_module_func}

@ -604,9 +604,10 @@ class groupby_c(ast_node):
self.arr_len = 'arrlen_' + base62uuid(3)
self.arr_values = 'arrvals_' + base62uuid(3)
self.context.emitc(f'auto {self.arr_len} = {self.group}.size();')
self.context.emitc(f'auto {self.arr_values} = {self.group}.values();')
if len(tovec_columns):
self.context.emitc(f'auto {self.arr_len} = {self.group}.size();')
self.context.emitc(f'auto {self.arr_values} = {self.group}.values();')
preproc_scanner = scan(self, self.arr_len)
preproc_scanner_it = preproc_scanner.it_var
for c in tovec_columns:
@ -674,11 +675,8 @@ class groupby_c(ast_node):
gscanner.add(f'{ex.eval(c_code = True, y=get_var_names, materialize_builtin = materialize_builtin)};\n')
continue
if col_tovec[i]:
if ex.opname == 'avgs':
patch_expr = get_var_names_ex(ex)
patch_expr = patch_expr[:patch_expr.rindex(')')]
patch_expr += ', ' + f'{ce[0]}[{gscanner.it_var}]' + ')'
gscanner.add(f'{patch_expr};\n')
if ex.remake_binary(f'{ce[0]}[{gscanner.it_var}]'):
gscanner.add(f'{get_var_names_ex(ex)};\n')
else:
gscanner.add(f'{ce[0]}[{gscanner.it_var}] = {get_var_names_ex(ex)};\n')
else:

@ -367,6 +367,19 @@ class expr(ast_node):
self.curr_code += c.codegen(delegate)
return self.curr_code
def remake_binary(self, ret_expr):
if self.root:
self.oldsql = self.sql
if (self.opname in builtin_binary_ops):
patched_opname = 'aqop_' + self.opname
self.sql = (f'{patched_opname}({self.children[0].sql}, '
f'{self.children[1].sql}, {ret_expr})')
return True
elif self.opname in builtin_vecfunc:
self.sql = self.sql[:self.sql.rindex(')')]
self.sql += ', ' + ret_expr + ')'
return True
return False
def __str__(self):
return self.sql
def __repr__(self):

@ -1,5 +1,6 @@
#pragma once
#include "types.h"
#include "gc.h"
#include <utility>
#include <limits>
#include <deque>
@ -29,14 +30,19 @@ double avg(const VT<T>& v) {
return (sum<T>(v) / static_cast<double>(v.size));
}
template<class T, template<typename ...> class VT, class Ret>
void sqrt(const VT<T>& v, Ret& ret) {
for (uint32_t i = 0; i < v.size; ++i)
ret[i] = sqrt(v[i]);
}
template<class T, template<typename ...> class VT>
VT<double> sqrt(const VT<T>& v) {
VT<double> ret(v.size);
for (uint32_t i = 0; i < v.size; ++i) {
ret[i] = sqrt(v[i]);
}
sqrt(v, ret);
return ret;
}
template <class T>
T truncate(const T& v, const uint32_t precision) {
auto multiplier = pow(10, precision);
@ -73,109 +79,153 @@ T min(const VT<T>& v) {
min_v = min_v < _v ? min_v : _v;
return min_v;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, T> mins(const VT<T>& arr) {
// simplify this using a template std::binary_function<T, T, bool> = std::less;
template<class T, template<typename ...> class VT, class Ret>
void mins(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
std::deque<std::pair<T, uint32_t>> cache;
decayed_t<VT, T> ret(len);
T min = std::numeric_limits<T>::max();
for (int i = 0; i < len; ++i) {
if (arr[i] < min)
min = arr[i];
ret[i] = min;
}
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, T> maxs(const VT<T>& arr) {
decayed_t<VT, T> mins(const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
mins(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void maxs(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, T> ret(len);
T max = std::numeric_limits<T>::min();
for (int i = 0; i < len; ++i) {
if (arr[i] > max)
max = arr[i];
ret[i] = max;
}
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, T> minw(uint32_t w, const VT<T>& arr) {
decayed_t<VT, T> maxs(const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
maxs(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void minw(uint32_t w, const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, T> ret(len);
std::deque<std::pair<T, uint32_t>> cache;
for (int i = 0; i < len; ++i) {
if (!cache.empty() && cache.front().second == i - w) cache.pop_front();
while (!cache.empty() && cache.back().first > arr[i]) cache.pop_back();
cache.push_back({ arr[i], i });
ret[i] = cache.front().first;
}
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, T> maxw(uint32_t w, const VT<T>& arr) {
decayed_t<VT, T> minw(uint32_t w, const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
minw(w, arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void maxw(uint32_t w, const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, T> ret(len);
std::deque<std::pair<T, uint32_t>> cache;
for (int i = 0; i < len; ++i) {
if (!cache.empty() && cache.front().second == i - w) cache.pop_front();
while (!cache.empty() && cache.back().first > arr[i]) cache.pop_back();
while (!cache.empty() && cache.back().first < arr[i]) cache.pop_back();
cache.push_back({ arr[i], i });
arr[i] = cache.front().first;
ret[i] = cache.front().first;
}
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<T>> ratiow(uint32_t w, const VT<T>& arr) {
inline decayed_t<VT, T> maxw(uint32_t w, const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
maxw(w, arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void ratiow(uint32_t w, const VT<T>& arr, Ret& ret) {
typedef std::decay_t<types::GetFPType<T>> FPType;
uint32_t len = arr.size;
if (arr.size <= w)
len = 1;
w = w > len ? len : w;
decayed_t<VT, FPType> ret(arr.size);
ret[0] = 0;
for (uint32_t i = 0; i < w; ++i)
ret[i] = arr[i] / (FPType)arr[0];
for (uint32_t i = w; i < arr.size; ++i)
ret[i] = arr[i] / (FPType) arr[i - w];
}
template<class T, template<typename ...> class VT>
inline decayed_t<VT, types::GetFPType<T>> ratiow(uint32_t w, const VT<T>& arr) {
typedef std::decay_t<types::GetFPType<T>> FPType;
decayed_t<VT, FPType> ret(arr.size);
ratiow(w, arr, ret);
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<T>> ratios(const VT<T>& arr) {
inline decayed_t<VT, types::GetFPType<T>> ratios(const VT<T>& arr) {
return ratiow(1, arr);
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetLongType<T>> sums(const VT<T>& arr) {
template<class T, template<typename ...> class VT, class Ret>
inline void ratios(const VT<T>& arr, Ret& ret) {
return ratiow(1, arr, ret);
}
template<class T, template<typename ...> class VT, class Ret>
void sums(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, types::GetLongType<T>> ret(len);
uint32_t i = 0;
if (len) ret[i++] = arr[0];
for (; i < len; ++i)
ret[i] = ret[i - 1] + arr[i];
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> avgs(const VT<T>& arr) {
inline decayed_t<VT, types::GetLongType<T>> sums(const VT<T>& arr) {
decayed_t<VT, types::GetLongType<T>> ret(arr.size);
sums(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void avgs(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
typedef types::GetFPType<types::GetLongType<T>> FPType;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s;
if (len) s = ret[i++] = arr[0];
for (; i < len; ++i)
ret[i] = (s += arr[i]) / (FPType)(i + 1);
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetLongType<T>> sumw(uint32_t w, const VT<T>& arr) {
inline decayed_t<VT, types::GetFPType<types::GetLongType<T>>> avgs(const VT<T>& arr) {
typedef types::GetFPType<types::GetLongType<T>> FPType;
decayed_t<VT, FPType> ret(arr.size);
avgs(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void sumw(uint32_t w, const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, types::GetLongType<T>> ret(len);
uint32_t i = 0;
w = w > len ? len : w;
if (len) ret[i++] = arr[0];
@ -183,11 +233,17 @@ decayed_t<VT, types::GetLongType<T>> sumw(uint32_t w, const VT<T>& arr) {
ret[i] = ret[i - 1] + arr[i];
for (; i < len; ++i)
ret[i] = ret[i - 1] + arr[i] - arr[i - w];
return ret;
}
template<class T, template<typename ...> class VT>
void avgw(uint32_t w, const VT<T>& arr, decayed_t<vector_type, types::GetFPType<types::GetLongType<T>>>& ret) {
decayed_t<VT, types::GetLongType<T>> sumw(uint32_t w, const VT<T>& arr) {
decayed_t<VT, types::GetLongType<T>> ret(arr.size);
sumw(w, arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void avgw(uint32_t w, const VT<T>& arr, Ret& ret) {
typedef types::GetFPType<types::GetLongType<T>> FPType;
const uint32_t& len = arr.size;
uint32_t i = 0;
@ -201,26 +257,19 @@ void avgw(uint32_t w, const VT<T>& arr, decayed_t<vector_type, types::GetFPType<
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> avgw(uint32_t w, const VT<T>& arr) {
inline decayed_t<VT, types::GetFPType<types::GetLongType<T>>> avgw(uint32_t w, const VT<T>& arr) {
typedef types::GetFPType<types::GetLongType<T>> FPType;
const uint32_t& len = arr.size;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s{};
w = w > len ? len : w;
if (len) s = ret[i++] = arr[0];
for (; i < w; ++i)
ret[i] = (s += arr[i]) / (FPType)(i + 1);
for (; i < len; ++i)
ret[i] = ret[i - 1] + (arr[i] - arr[i - w]) / (FPType)w;
avgw(w, arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, bool sd = false>
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> varw(uint32_t w, const VT<T>& arr) {
template<class T, template<typename ...> class VT, class Ret, bool sd = false>
void varw(uint32_t w, const VT<T>& arr,
Ret& ret) {
using FPType = types::GetFPType<types::GetLongType<T>>;
const uint32_t& len = arr.size;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s{};
w = w > len ? len : w;
@ -252,7 +301,14 @@ decayed_t<VT, types::GetFPType<types::GetLongType<T>>> varw(uint32_t w, const VT
if constexpr(sd)
if(i)
ret[i-1] = sqrt(ret[i-1]);
}
template<class T, template<typename ...> class VT, bool sd = false>
inline decayed_t<VT, types::GetFPType<types::GetLongType<T>>> varw(uint32_t w, const VT<T>& arr) {
using FPType = types::GetFPType<types::GetLongType<T>>;
decayed_t<VT, FPType> ret(arr.size);
varw<T, VT, decayed_t<VT, types::GetFPType<types::GetLongType<T>>>, sd>(w, arr, ret);
return ret;
}
@ -274,11 +330,10 @@ types::GetFPType<types::GetLongType<decays<T>>> var(const VT<T>& arr) {
return (ssq - s * s / (FPType)(len + 1)) / (FPType)(len + 1);
}
template<class T, template<typename ...> class VT, bool sd = false>
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> vars(const VT<T>& arr) {
template<class T, template<typename ...> class VT, class Ret, bool sd = false>
void vars(const VT<T>& arr, Ret& ret) {
typedef types::GetFPType<types::GetLongType<T>> FPType;
const uint32_t& len = arr.size;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s{};
FPType MnX{};
@ -298,51 +353,88 @@ decayed_t<VT, types::GetFPType<types::GetLongType<T>>> vars(const VT<T>& arr) {
ret[i] = MnX / (FPType)(i + 1);
if constexpr(sd) ret[i] = sqrt(ret[i]);
}
}
template<class T, template<typename ...> class VT, bool sd = false>
inline decayed_t<VT, types::GetFPType<types::GetLongType<T>>> vars(const VT<T>& arr) {
typedef types::GetFPType<types::GetLongType<T>> FPType;
decayed_t<VT, FPType> ret(arr.size);
vars<T, VT, decayed_t<VT, types::GetFPType<types::GetLongType<T>>>, sd>(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT>
types::GetFPType<types::GetLongType<decays<T>>> stddev(const VT<T>& arr) {
inline types::GetFPType<types::GetLongType<decays<T>>> stddev(const VT<T>& arr) {
return sqrt(var(arr));
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> stddevs(const VT<T>& arr) {
inline decayed_t<VT, types::GetFPType<types::GetLongType<T>>> stddevs(const VT<T>& arr) {
return vars<T, VT, true>(arr);
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> stddevw(uint32_t w, const VT<T>& arr) {
inline decayed_t<VT, types::GetFPType<types::GetLongType<T>>> stddevw(uint32_t w, const VT<T>& arr) {
return varw<T, VT, true>(w, arr);
}
template<class T, template<typename ...> class VT, class Ret>
inline auto stddevs(const VT<T>& arr, Ret& ret) {
return vars<T, VT, Ret, true>(arr, ret);
}
template<class T, template<typename ...> class VT, class Ret>
inline auto stddevw(uint32_t w, const VT<T>& arr, Ret& ret) {
return varw<T, VT, Ret, true>(w, arr, ret);
}
// use getSignedType
template<class T, template<typename ...> class VT>
decayed_t<VT, T> deltas(const VT<T>& arr) {
template<class T, template<typename ...> class VT, class Ret>
void deltas(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, T> ret(len);
uint32_t i = 0;
if (len) ret[i++] = 0;
for (; i < len; ++i)
ret[i] = arr[i] - arr[i - 1];
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, T> prev(const VT<T>& arr) {
inline decayed_t<VT, T> deltas(const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
deltas(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void prev(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, T> ret(len);
uint32_t i = 0;
if (len) ret[i++] = arr[0];
for (; i < len; ++i)
ret[i] = arr[i - 1];
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, T> aggnext(const VT<T>& arr) {
inline decayed_t<VT, T> prev(const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
prev(arr, ret);
return ret;
}
template<class T, template<typename ...> class VT, class Ret>
void aggnext(const VT<T>& arr, Ret& ret) {
const uint32_t& len = arr.size;
decayed_t<VT, T> ret(len);
uint32_t i = 1;
for (; i < len; ++i)
ret[i - 1] = arr[i];
if (len > 0) ret[len - 1] = arr[len - 1];
}
template<class T, template<typename ...> class VT>
inline decayed_t<VT, T> aggnext(const VT<T>& arr) {
decayed_t<VT, T> ret(arr.size);
aggnext(arr, ret);
return ret;
}
@ -360,8 +452,6 @@ T first(const VT<T>& arr) {
return arr[0];
}
#define __DEFAULT_AGGREGATE_FUNCTION__(NAME, RET) \
template <class T> constexpr T NAME(const T& v) { return RET; }

@ -1,4 +1,39 @@
#pragma once
class ScratchSpace {
public:
void* ret;
char* scratchspace;
size_t ptr;
size_t cnt;
size_t capacity;
size_t initial_capacity;
void* temp_memory_fractions;
//uint8_t status;
// record maximum size
constexpr static uint8_t Grow = 0x1;
// no worry about overflow
constexpr static uint8_t Use = 0x0;
void init(size_t initial_capacity);
// apply for memory
void* alloc(uint32_t sz);
void register_ret(void* ret);
// reorganize memory space
void release();
// reset status of the scratch space
void reset();
// reset scratch space to initial capacity.
void cleanup();
};
#ifndef __AQ_USE_THREADEDGC__
#include <atomic>
class GC {
@ -18,7 +53,7 @@ private:;
std::atomic<uint64_t> current_size;
volatile bool lock;
using gc_deallocator_t = void (*)(void*);
ScratchSpace scratch;
// maybe use volatile std::thread::id instead
protected:
void acquire_lock();
@ -29,28 +64,36 @@ protected:
void terminate_daemon();
public:
void reg(void* v, uint32_t sz = 1,
void reg(void* v, uint32_t sz = 0xffffffff,
void(*f)(void*) = free
);
uint32_t get_threshold() const {
return threshould;
}
GC(
uint64_t max_size = 0xfffffff, uint32_t max_slots = 4096,
uint32_t interval = 10000, uint32_t forced_clean = 1000000,
uint32_t threshould = 64 //one seconds
uint32_t threshould = 64, //one seconds
uint32_t scratch_sz = 0x1000000 // 16 MB
) : max_size(max_size), max_slots(max_slots),
interval(interval), forced_clean(forced_clean),
threshould(threshould) {
start_deamon();
GC::gc_handle = this;
this->scratch.init(scratch_sz);
} // 256 MB
~GC(){
terminate_daemon();
scratch.cleanup();
}
static GC* gc_handle;
template <class T>
constexpr static inline gc_deallocator_t _delete(T*){
static inline gc_deallocator_t _delete(T*) {
return [](void* v){
delete (T*)v;
};

@ -452,6 +452,9 @@ void GC::reg(void* v, uint32_t sz, void(*f)(void*)) { //~ 40ns expected v. free
f(v);
return;
}
else if (sz == 0xffffffff)
sz = this->threshould;
auto _q = static_cast<memoryqueue_t>(q);
while(lock);
++alive_cnt;
@ -466,6 +469,71 @@ void GC::reg(void* v, uint32_t sz, void(*f)(void*)) { //~ 40ns expected v. free
inline GC* GC::gc_handle = nullptr;
void ScratchSpace::init(size_t initial_capacity) {
ret = nullptr;
scratchspace = static_cast<char*>(malloc(initial_capacity));
ptr = cnt = 0;
capacity = initial_capacity;
this->initial_capacity = initial_capacity;
temp_memory_fractions = new vector_type<void*>();
}
inline void* ScratchSpace::alloc(uint32_t sz){
this->cnt += sz; // major cost
ptr = this->cnt;
if (this->cnt > capacity) {
[[unlikely]]
capacity = this->cnt + (capacity >> 1);
auto vec_tmpmem_fractions = static_cast<vector_type<char *>*>(temp_memory_fractions);
vec_tmpmem_fractions->emplace_back(scratchspace);
scratchspace = static_cast<char*>(malloc(capacity));
ptr = 0;
}
return scratchspace + ptr;
}
inline void ScratchSpace::register_ret(void* ret){
this->ret = ret;
}
inline void ScratchSpace::release(){
ptr = cnt = 0;
ret = nullptr;
auto vec_tmpmem_fractions =
static_cast<vector_type<void*>*>(temp_memory_fractions);
if (vec_tmpmem_fractions->size) {
//[[unlikely]]
for(auto& mem : *vec_tmpmem_fractions){
free(mem);
//GC::gc_handle->reg(mem);
}
vec_tmpmem_fractions->clear();
}
}
inline void ScratchSpace::reset() {
this->release();
if (capacity != initial_capacity){
capacity = initial_capacity;
scratchspace = static_cast<char*>(realloc(scratchspace, capacity));
}
}
void ScratchSpace::cleanup(){
auto vec_tmpmem_fractions =
static_cast<vector_type<void*>*>(temp_memory_fractions);
if (vec_tmpmem_fractions->size) {
for(auto& mem : *vec_tmpmem_fractions){
free(mem);
//GC::gc_handle->reg(mem);
}
vec_tmpmem_fractions->clear();
}
delete vec_tmpmem_fractions;
free(this->scratchspace);
}
#include "dragonbox/dragonbox_to_chars.hpp"

@ -36,7 +36,8 @@ struct ColRef_cstorage {
int ty; // what if enum is not int?
};
template <template <class...> class VT, class T>
template <template <class...> class VT, class T,
std::enable_if_t<std::is_base_of_v<vector_base<T>, VT<T>>>* = nullptr>
std::ostream& operator<<(std::ostream& os, const VT<T>& v)
{
v.out();
@ -143,7 +144,7 @@ public:
vector_type<_Ty>::operator=(vt);
return *this;
}
ColRef<_Ty>& operator =(ColRef<_Ty>&& vt) {
ColRef<_Ty>& operator =(ColRef<_Ty>&& vt) noexcept {
vector_type<_Ty>::operator=(std::move(vt));
return *this;
@ -475,7 +476,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){
@ -659,11 +660,11 @@ struct TableView {
};
template <class T>
constexpr static inline bool is_vector(const ColRef<T>&) {
constexpr static bool is_vector(const ColRef<T>&) {
return true;
}
template <class T>
constexpr static inline bool is_vector(const vector_type<T>&) {
constexpr static bool is_vector(const vector_type<T>&) {
return true;
}
@ -913,6 +914,42 @@ VT<bool> operator >(const T2& lhs, const VT<T1>& rhs) {
return ret;
}
#define _AQ_OP_(x) __AQ_OP__##x
#define __AQ_OP__add +
#define __AQ_OP__minus -
#define __AQ_OP__div *
#define __AQ_OP__mul /
#define __AQ_OP__and &
#define __AQ_OP__or |
#define __AQ_OP__xor ^
#define __AQ_OP__gt >
#define __AQ_OP__lt <
#define __AQ_OP__gte >=
#define __AQ_OP__lte <=
#define __AQ_OP__eq ==
#define __AQ_OP__neq !=
#define __D_AQOP(x) \
template <class T1, class T2, template<typename> class VT, class Ret>\
void aqop_##x (const VT<T1>& lhs, const VT<T2>& rhs, Ret& ret){\
for (uint32_t i = 0; i < ret.size; ++i)\
ret[i] = lhs[i] _AQ_OP_(x) rhs[i];\
}
__D_AQOP(add)
__D_AQOP(minus)
__D_AQOP(div)
__D_AQOP(mul)
__D_AQOP(and)
__D_AQOP(or)
__D_AQOP(xor)
__D_AQOP(gt)
__D_AQOP(lt)
__D_AQOP(gte)
__D_AQOP(lte)
__D_AQOP(eq)
__D_AQOP(neq)
template <class ...Types>
void print(const TableInfo<Types...>& v, const char* delimiter = " ", const char* endline = "\n") {

@ -187,15 +187,15 @@ public:
grow<false>(sz);
}
void emplace_back(const _Ty& _val) {
inline void emplace_back(const _Ty& _val) {
grow();
container[size++] = _val;
}
void emplace_back(_Ty& _val) {
inline void emplace_back(_Ty& _val) {
grow();
container[size++] = std::move(_val);
}
void emplace_back(_Ty&& _val) {
inline void emplace_back(_Ty&& _val) {
grow();
container[size++] = std::move(_val);
}
@ -212,10 +212,10 @@ public:
return _it;
}
iterator_t begin() const {
inline iterator_t begin() const {
return container;
}
iterator_t end() const {
inline iterator_t end() const {
return container + size;
}
@ -229,7 +229,7 @@ public:
return container[_i];
}
void shrink_to_fit() {
inline void shrink_to_fit() {
if (size && capacity != size) {
capacity = size;
_Ty* _container = (_Ty*)malloc(sizeof(_Ty) * size);
@ -239,13 +239,17 @@ public:
}
}
_Ty& back() {
inline void clear() {
this->size = 0;
}
inline _Ty& back() {
return container[size - 1];
}
void qpop() {
inline void qpop() {
size = size ? size - 1 : size;
}
void pop_resize() {
inline void pop_resize() {
if (size) {
--size;
if (capacity > (size << 1))
@ -258,7 +262,7 @@ public:
}
}
}
_Ty pop() {
inline _Ty pop() {
return container[--size];
}
void merge(vector_type<_Ty>& _other) {
@ -368,7 +372,7 @@ public:
#define Ops(o, x) \
template<typename T>\
vector_type<typename types::Coercion<_Ty, T>::type> operator o (const vector_type<T>& r) const {\
/*[[likely]] if (r.size == size) {*/\
/*if (r.size == size) { [[likely]] */\
return x(r);\
/*}*/\
}
@ -376,7 +380,7 @@ public:
#define Opseq(o, x) \
template<typename T>\
vector_type<typename types::Coercion<_Ty, T>::type> operator o##= (const vector_type<T>& r) {\
/*[[likely]] if (r.size == size) {*/\
/*if (r.size == size) { [[likely]] */\
return x##eq(r);\
/*}*/\
}

Loading…
Cancel
Save