From 406593a311370b38d3839d2b8462703b2025028d Mon Sep 17 00:00:00 2001 From: Bill Date: Sun, 25 Sep 2022 23:30:36 +0800 Subject: [PATCH] Fixed g++ std::hash<__uint128_t> undefined problem --- Dockerfile | 2 +- README.md | 2 +- build.py | 3 ++- server/hasher.h | 46 +++++++++++++++++++++++++++++++++++++++++++--- server/types.h | 32 ++++++++++++++++++++++---------- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index d463363..92bd75d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ RUN git clone https://github.com/sunyinqi0508/AQuery2 RUN python3 -m pip install -r AQuery2/requirements.txt -ENV IS_DOCKER_IMAGE=1 CXX=clang-14 +ENV IS_DOCKER_IMAGE=1 CXX=clang++-14 CMD cd AQuery2 && python3 prompt.py diff --git a/README.md b/README.md index 27f86b6..6bb0f6c 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ There're multiple options to run AQuery on Windows. You can use the native toolc - Install monetdb, see [Monetdb Easy Setup](https://www.monetdb.org/easy-setup/) for instructions. - Install python3, C++ compiler and git. (For Ubuntu, run `apt update && apt install -y python3 python3-pip clang-14 libmonetdbe-dev git `) - Install required python packages by `python3 -m pip install -r requirements.txt` -- If you have multiple C++ compilers on the system. Specify C++ compiler by setting the **CXX** environment variable. e.g. `export CXX=clang-14` +- If you have multiple C++ compilers on the system. Specify C++ compiler by setting the **CXX** environment variable. e.g. `export CXX=clang++-14` ### Docker: - Alternatively, you can also use docker to run AQuery. - Type `make docker` to build the docker image from scratch. diff --git a/build.py b/build.py index aa10a7a..f6f2561 100644 --- a/build.py +++ b/build.py @@ -104,7 +104,8 @@ class build_manager: def __init__(self, mgr : 'build_manager') -> None: super().__init__(mgr) os.environ['PCH'] = f'{mgr.PCH}' - os.environ['CXX'] = mgr.cxx if mgr.cxx else 'c++' + if 'CXX' not in os.environ: + os.environ['CXX'] = mgr.cxx if mgr.cxx else 'c++' def libaquery_a(self): self.build_cmd = [['rm', 'libaquery.a'],['make', 'libaquery.a']] diff --git a/server/hasher.h b/server/hasher.h index 526c168..70a97e8 100644 --- a/server/hasher.h +++ b/server/hasher.h @@ -2,6 +2,7 @@ #include #include +#include #include "types.h" // only works for 64 bit systems constexpr size_t _FNV_offset_basis = 14695981039346656037ULL; @@ -21,7 +22,31 @@ inline size_t append_bytes(const astring_view& view) noexcept { return append_bytes(view.str); } - +#ifdef __SIZEOF_INT128__ +union int128_struct +{ + struct { + uint64_t low, high; + }__struct; + __int128_t value = 0; + __uint128_t uvalue; + constexpr int128_struct() : value(0) {} + constexpr int128_struct(const __int128_t &value) noexcept : value(value) {} + constexpr int128_struct(const __uint128_t &value) noexcept : uvalue(value) {} + operator __int128_t () const { + return value; + } + operator __uint128_t () const { + return uvalue; + } + operator __int128_t& () { + return value; + } + operator __uint128_t& () { + return uvalue; + } +}; +#endif template struct hasher { template typename std::enable_if< i == sizeof...(Types), @@ -32,8 +57,15 @@ struct hasher { template typename std::enable_if < i < sizeof ...(Types), size_t>::type hashi(const std::tuple& record) const { using current_type = typename std::decay>::type>::type; - - return std::hash()(std::get(record)) ^ hashi(record); +#ifdef __SIZEOF_INT128__ + using _current_type = typename std::conditional_t< + std::is_same_v || + std::is_same_v, + int128_struct, current_type>; +#else + #define _current_type current_type +#endif + return std::hash<_current_type>()(std::get(record)) ^ hashi(record); } size_t operator()(const std::tuple& record) const { return hashi(record); @@ -75,7 +107,15 @@ namespace std{ std::hash()(_Keyval.time); } }; +#ifdef __SIZEOF_INT128__ + template<> + struct hash{ + size_t operator() (const int128_struct& _Keyval) const noexcept { + return std::hash()(_Keyval.__struct.low) ^ std::hash()(_Keyval.__struct.high); + } + }; +#endif template struct hash> : public hasher{ }; diff --git a/server/types.h b/server/types.h index f988d4d..80f9eac 100644 --- a/server/types.h +++ b/server/types.h @@ -3,6 +3,7 @@ #include #include #include +using std::size_t; #if defined(__SIZEOF_INT128__) and not defined(_WIN32) #define __AQ__HAS__INT128__ @@ -194,19 +195,19 @@ namespace types { } -struct astring_view { +union astring_view { const unsigned char* str = 0; + const signed char* sstr; + const char* rstr; + size_t ptr; + -#if defined(__clang__) || !defined(__GNUC__) constexpr -#endif astring_view(const char* str) noexcept : - str((const unsigned char*)(str)) {} -#if defined(__clang__) || !defined(__GNUC__) + rstr(str) {} constexpr -#endif astring_view(const signed char* str) noexcept : - str((const unsigned char*)(str)) {} + sstr(str) {} constexpr astring_view(const unsigned char* str) noexcept : @@ -225,16 +226,27 @@ struct astring_view { return !(*this_str || *other_str); } bool operator >(const astring_view&r) const{ + auto this_str = str; + auto other_str = r.str; + bool ret = true; + while (*this_str && *other_str) { + if (*this_str <= *other_str) + ret = false; + this_str++; + other_str++; + } + return (*this_str && !*other_str) || + (ret && !*this_str && *other_str); } operator const char* () const { - return reinterpret_cast(str); + return rstr; } operator const unsigned char* () const { - return reinterpret_cast(str); + return str; } operator const signed char* () const { - return reinterpret_cast(str); + return sstr; } };