parent
4dd571b3d2
commit
c46ce578d4
@ -1,4 +1,13 @@
|
|||||||
|
OS_SUPPORT =
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
OS_SUPPORT += server/winhelper.cpp
|
||||||
|
endif
|
||||||
|
$(info $(OS_SUPPORT))
|
||||||
|
|
||||||
|
server.bin:
|
||||||
|
g++ server/server.cpp $(OS_SUPPORT) --std=c++1z -O3 -march=native -o server.bin
|
||||||
snippet:
|
snippet:
|
||||||
g++ -shared --std=c++1z out.cpp -O3 -march=native -o dll.so
|
g++ -shared -fPIC --std=c++1z out.cpp -O3 -march=native -o dll.so
|
||||||
clean:
|
clean:
|
||||||
rm *.shm -rf
|
rm *.shm -rf
|
@ -1,56 +1,61 @@
|
|||||||
from engine.ast import ast_node
|
from engine.ast import TableInfo, ast_node
|
||||||
|
from engine.scan import scan
|
||||||
from engine.utils import base62uuid
|
from engine.utils import base62uuid
|
||||||
from engine.expr import expr
|
from engine.expr import expr
|
||||||
|
import engine.types
|
||||||
class groupby(ast_node):
|
class groupby(ast_node):
|
||||||
name = '_groupby'
|
name = '_groupby'
|
||||||
def init(self, _):
|
def init(self, _):
|
||||||
|
self.context.headers.add('"./server/hasher.h"')
|
||||||
|
self.context.headers.add('unordered_map')
|
||||||
self.group = 'g' + base62uuid(7)
|
self.group = 'g' + base62uuid(7)
|
||||||
|
self.group_type = 'record_type' + base62uuid(7)
|
||||||
self.datasource = self.parent.datasource
|
self.datasource = self.parent.datasource
|
||||||
|
self.scanner = None
|
||||||
self.datasource.rec = []
|
self.datasource.rec = []
|
||||||
|
self.raw_groups = []
|
||||||
def produce(self, node):
|
def produce(self, node):
|
||||||
|
|
||||||
if type(node) is not list:
|
if type(node) is not list:
|
||||||
node = [node]
|
node = [node]
|
||||||
g_contents = '('
|
g_contents = ''
|
||||||
|
g_contents_list = []
|
||||||
first_col = ''
|
first_col = ''
|
||||||
for i, g in enumerate(node):
|
for i, g in enumerate(node):
|
||||||
v = g['value']
|
v = g['value']
|
||||||
e = expr(self, v).cexpr
|
e = expr(self, v)
|
||||||
|
self.raw_groups.append(e.raw_col)
|
||||||
|
e = e._expr
|
||||||
# if v is compound expr, create tmp cols
|
# if v is compound expr, create tmp cols
|
||||||
if type(v) is not str:
|
if type(v) is not str:
|
||||||
tmpcol = 't' + base62uuid(7)
|
tmpcol = 't' + base62uuid(7)
|
||||||
self.emit(f'{tmpcol}:{e}')
|
self.emit(f'auto {tmpcol} = {e};')
|
||||||
e = tmpcol
|
e = tmpcol
|
||||||
if i == 0:
|
if i == 0:
|
||||||
first_col = e
|
first_col = e
|
||||||
g_contents += e + (';'if i < len(node)-1 else '')
|
g_contents_list.append(e)
|
||||||
|
g_contents_decltype = [f'decltype({c})' for c in g_contents_list]
|
||||||
self.emit(f'{self.group}:'+g_contents+')')
|
g_contents = expr.toCExpr(','.join(g_contents_list))
|
||||||
|
self.emit(f'typedef record<{expr.toCExpr(",".join(g_contents_decltype))(0)}> {self.group_type};')
|
||||||
|
self.emit(f'unordered_map<{self.group_type}, vector_type<uint32_t>, '
|
||||||
|
f'transTypes<{self.group_type}, hasher>> {self.group};')
|
||||||
self.n_grps = len(node)
|
self.n_grps = len(node)
|
||||||
if self.n_grps <= 1:
|
self.scanner = scan(self, None, expr.toCExpr(first_col)()+'.size')
|
||||||
self.emit(f'{self.group}:={self.group}')
|
self.scanner.add(f'{self.group}[forward_as_tuple({g_contents(self.scanner.it_ver)})].emplace_back({self.scanner.it_ver});')
|
||||||
else:
|
|
||||||
self.emit(f'{self.group}:groupby[({self.group},(,!(#({first_col}))))]')
|
|
||||||
|
|
||||||
def consume(self, _):
|
def consume(self, _):
|
||||||
self.referenced = self.datasource.rec
|
self.referenced = self.datasource.rec
|
||||||
self.datasource.rec = None
|
self.datasource.rec = None
|
||||||
return super().consume(_)
|
self.scanner.finalize()
|
||||||
|
|
||||||
|
def finalize(self, cexprs, out:TableInfo):
|
||||||
|
gscanner = scan(self, self.group)
|
||||||
|
key_var = 'key_'+base62uuid(7)
|
||||||
|
val_var = 'val_'+base62uuid(7)
|
||||||
|
|
||||||
|
gscanner.add(f'auto &{key_var} = {gscanner.it_ver}.first;')
|
||||||
|
gscanner.add(f'auto &{val_var} = {gscanner.it_ver}.second;')
|
||||||
|
gscanner.add(';\n'.join([f'{out.columns[i].reference()}.emplace_back({ce(x=val_var, y=key_var)})' for i, ce in enumerate(cexprs)])+';')
|
||||||
|
|
||||||
def finalize(self, ret, out):
|
gscanner.finalize()
|
||||||
self.groupby_function = 'fgrp'+base62uuid(4)
|
|
||||||
grp = self.group
|
|
||||||
if self.n_grps <= 1:
|
|
||||||
cfn = "{[range] start:*range;"+ ret + "}"
|
|
||||||
self.emit(f'{out}:(({cfn}\'{grp})[!{grp}])')
|
|
||||||
self.parent.inv = False
|
|
||||||
else:
|
|
||||||
cfn = "{[ids;grps;ll;dim;x] " + \
|
|
||||||
"start:grps[x][dim];" + \
|
|
||||||
"end:$[x=0;ll;grps[x-1][dim]];" + \
|
|
||||||
"range:(end-start)#((start-ll)#ids);" + \
|
|
||||||
"start:ids[start];" + \
|
|
||||||
ret + '}'
|
|
||||||
self.emit(f'{self.groupby_function}:{cfn}')
|
|
||||||
self.emit(f'{out}:+({self.groupby_function}' + \
|
|
||||||
f'[{grp}[1];{grp}[0];(#{grp}[0])+1;(#({grp}[0][0]))-1]\'!(#({grp}[0])))')
|
|
@ -0,0 +1,168 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{8081fdaa-4d13-4b7a-adb2-8224af7f1c81}</ProjectGuid>
|
||||||
|
<RootNamespace>Project1</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>msc-plugin</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<TargetExt />
|
||||||
|
<TargetName>dll.so</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<TargetExt />
|
||||||
|
<TargetName>dll.so</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<TargetExt />
|
||||||
|
<TargetName>dll.so</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<TargetExt />
|
||||||
|
<TargetName>dll.so</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\out.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\csv.h" />
|
||||||
|
<ClInclude Include="..\server\aggregations.h" />
|
||||||
|
<ClInclude Include="..\server\gc.hpp" />
|
||||||
|
<ClInclude Include="..\server\hasher.h" />
|
||||||
|
<ClInclude Include="..\server\libaquery.h" />
|
||||||
|
<ClInclude Include="..\server\table.h" />
|
||||||
|
<ClInclude Include="..\server\types.h" />
|
||||||
|
<ClInclude Include="..\server\utils.h" />
|
||||||
|
<ClInclude Include="..\server\vector_type.hpp" />
|
||||||
|
<ClInclude Include="..\server\winhelper.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "types.h"
|
||||||
|
#include <utility>
|
||||||
|
#include <limits>
|
||||||
|
#include <deque>
|
||||||
|
template <class T, template<typename ...> class VT>
|
||||||
|
size_t count(const VT<T>& v) {
|
||||||
|
return v.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
constexpr static inline size_t count(const T&) { return 1; }
|
||||||
|
|
||||||
|
// TODO: Specializations for dt/str/none
|
||||||
|
template<class T, template<typename ...> class VT>
|
||||||
|
types::GetLongType<T> sum(const VT<T>& v) {
|
||||||
|
types::GetLongType<T> ret = 0;
|
||||||
|
for (const auto& _v : v)
|
||||||
|
ret += _v;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template<class T, template<typename ...> class VT>
|
||||||
|
types::GetFPType<T> avg(const VT<T>& v) {
|
||||||
|
return static_cast<types::GetFPType<T>>(
|
||||||
|
sum<T>(v) / static_cast<long double>(v.size));
|
||||||
|
}
|
||||||
|
template <class T, template<typename ...> class VT>
|
||||||
|
T max(const VT<T>& v) {
|
||||||
|
T max_v = std::numeric_limits<T>::min();
|
||||||
|
for (const auto& _v : v)
|
||||||
|
max_v = max_v > _v ? max_v : _v;
|
||||||
|
return max_v;
|
||||||
|
}
|
||||||
|
template <class T, template<typename ...> class VT>
|
||||||
|
T min(const VT<T>& v) {
|
||||||
|
T min_v = std::numeric_limits<T>::max();
|
||||||
|
for (const auto& _v : v)
|
||||||
|
min_v = min_v < _v ? min_v : _v;
|
||||||
|
return min_v;
|
||||||
|
}
|
||||||
|
template<class T, template<typename ...> class VT>
|
||||||
|
VT<T> mins(const VT<T>& arr) {
|
||||||
|
const int& len = arr.size;
|
||||||
|
std::deque<std::pair<T, uint32_t>> cache;
|
||||||
|
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>
|
||||||
|
VT<T> maxs(const VT<T>& arr) {
|
||||||
|
const int& len = arr.size;
|
||||||
|
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>
|
||||||
|
VT<T> minw(const VT<T>& arr, uint32_t w) {
|
||||||
|
const int& len = arr.size;
|
||||||
|
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>
|
||||||
|
VT<T> maxw(const VT<T>& arr, uint32_t w) {
|
||||||
|
const int& len = arr.size;
|
||||||
|
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 });
|
||||||
|
arr[i] = cache.front().first;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> constexpr inline T max(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T min(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T avg(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T sum(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T maxw(const T& v, uint32_t) { return v; }
|
||||||
|
template <class T> constexpr inline T minw(const T& v, uint32_t) { return v; }
|
||||||
|
template <class T> constexpr inline T avgw(const T& v, uint32_t) { return v; }
|
||||||
|
template <class T> constexpr inline T sumw(const T& v, uint32_t) { return v; }
|
||||||
|
template <class T> constexpr inline T maxs(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T mins(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T avgs(const T& v) { return v; }
|
||||||
|
template <class T> constexpr inline T sums(const T& v) { return v; }
|
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <tuple>
|
||||||
|
template <class ...Types>
|
||||||
|
struct hasher {
|
||||||
|
template <size_t i = 0> typename std::enable_if< i == sizeof...(Types),
|
||||||
|
size_t>::type hashi(const std::tuple<Types...>& record) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t i = 0> typename std::enable_if< i < sizeof ...(Types),
|
||||||
|
size_t>::type hashi(const std::tuple<Types...>& record) const {
|
||||||
|
using current_type = typename std::decay<typename std::tuple_element<i, std::tuple<Types...>>::type>::type;
|
||||||
|
return std::hash<current_type>()(std::get<i>(record)) ^ hashi<i+1>(record);
|
||||||
|
}
|
||||||
|
size_t operator()(const std::tuple<Types...>& record) const {
|
||||||
|
return hashi(record);
|
||||||
|
}
|
||||||
|
};
|
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210806.1" targetFramework="native" />
|
|
||||||
</packages>
|
|
@ -0,0 +1,18 @@
|
|||||||
|
#include "utils.h"
|
||||||
|
#include <random>
|
||||||
|
#include <chrono>
|
||||||
|
using std::string;
|
||||||
|
string base62uuid(int l = 8) {
|
||||||
|
using namespace std;
|
||||||
|
constexpr static const char* base62alp = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
static mt19937_64 engine(chrono::system_clock::now().time_since_epoch().count());
|
||||||
|
static uniform_int_distribution<uint64_t> u(0x10000, 0xfffff);
|
||||||
|
uint64_t uuid = (u(engine) << 32ull) + (chrono::system_clock::now().time_since_epoch().count() & 0xffffffff);
|
||||||
|
printf("%llx\n", uuid);
|
||||||
|
string ret;
|
||||||
|
while (uuid && l-- >= 0) {
|
||||||
|
ret = string("") + base62alp[uuid % 62] + ret;
|
||||||
|
uuid /= 62;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <random>
|
|
||||||
using std::string;
|
template<int cnt, int begin = 0, int interval = 1>
|
||||||
string base62uuid(int l = 8) {
|
struct const_range {
|
||||||
constexpr static const char* base62alp = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
int arr[cnt];
|
||||||
static mt19937_64 engine(chrono::system_clock::now().time_since_epoch().count());
|
constexpr const_range() {
|
||||||
static uniform_int_distribution<uint64_t> u(0x100000000, 0xfffffffff);
|
for (int i = begin, n = 0; n < cnt; ++n, i += interval)
|
||||||
uint64_t uuid = (u(engine)<<16ull) + (time(0)&0xffff);
|
arr[n] = i;
|
||||||
printf("%lx\n", uuid);
|
|
||||||
string ret;
|
|
||||||
while (uuid && l-- >= 0){
|
|
||||||
ret = string("") + base62alp[uuid % 62] + ret;
|
|
||||||
uuid /= 62;
|
|
||||||
}
|
}
|
||||||
return ret;
|
const int* begin() const {
|
||||||
|
return arr;
|
||||||
}
|
}
|
||||||
|
const int* end() const {
|
||||||
|
return arr + cnt;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in new issue