From 75527e1dea411fe4287369739663ab77d4d5984c Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Mon, 13 Feb 2023 20:54:51 +0000 Subject: Remove optimisation now void since libc now optimizes for newer cpus. Time has caught up. --- document/src/vespa/document/base/idstring.cpp | 85 ++++++--------------------- document/src/vespa/document/base/idstring.h | 38 ++++++------ 2 files changed, 36 insertions(+), 87 deletions(-) (limited to 'document') diff --git a/document/src/vespa/document/base/idstring.cpp b/document/src/vespa/document/base/idstring.cpp index f3e41981c8e..be3a62b36a3 100644 --- a/document/src/vespa/document/base/idstring.cpp +++ b/document/src/vespa/document/base/idstring.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -54,83 +53,31 @@ union FourByte { uint32_t as32; }; -const FourByte _G_null = {{'n', 'u', 'l', 'l'}}; -const TwoByte _G_id = {{'i', 'd'}}; +constexpr FourByte G_null = {{'n', 'u', 'l', 'l'}}; +constexpr TwoByte G_id = {{'i', 'd'}}; -#ifdef __x86_64__ -typedef char v16qi __attribute__ ((__vector_size__(16))); - -v16qi _G_zero = { ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':' }; -#endif - -inline const char * -fmemchr(const char * s, const char * e) -{ -#ifdef __x86_64__ - while (s+15 < e) { -#ifdef __clang__ - v16qi tmpCurrent = __builtin_ia32_lddqu(s); - v16qi tmp0 = tmpCurrent == _G_zero; -#else - v16qi tmpCurrent = __builtin_ia32_loaddqu(s); - v16qi tmp0 = __builtin_ia32_pcmpeqb128(tmpCurrent, _G_zero); -#endif - uint32_t charMap = __builtin_ia32_pmovmskb128(tmp0); // 1 in charMap equals to '\0' in input buffer - if (__builtin_expect(charMap, 1)) { - return s + vespalib::Optimized::lsbIdx(charMap); - } - s+=16; - } - - const char c(':'); - while (s+3 < e) { - if (s[0] == c) { - return s; - } - if (s[1] == c) { - return s+1; - } - if (s[2] == c) { - return s+2; - } - if (s[3] == c) { - return s+3; - } - s+=4; - } - while (s < e) { - if (s[0] == c) { - return s; - } - s++; - } - return nullptr; -#else +const char * +fmemchr(const char * s, const char * e) noexcept { return static_cast(memchr(s, ':', e - s)); -#endif } -namespace { - // Avoid issues with primitive alignment when reading from buffer. // Requires caller to ensure buffer is big enough to read from. template -inline T read_unaligned(const char* buf) noexcept +constexpr T read_unaligned(const char* buf) noexcept { T tmp; memcpy(&tmp, buf, sizeof(T)); return tmp; } -} - void verifyIdString(const char * id, size_t sz_) { - if (sz_ > 4) { - if ((_G_id.as16 == read_unaligned(id)) && (id[2] == ':')) { + if (sz_ > 4) [[likely]] { + if ((G_id.as16 == read_unaligned(id)) && (id[2] == ':')) [[likely]] { return; - } else if ((sz_ == 6) && (_G_null.as32 == read_unaligned(id)) && (id[4] == ':') && (id[5] == ':')) { + } else if ((sz_ == 6) && (G_null.as32 == read_unaligned(id)) && (id[4] == ':') && (id[5] == ':')) { reportNoId(id); } else if (sz_ > 8) { reportNoSchemeSeparator(id); @@ -159,29 +106,31 @@ validate(uint16_t numComponents) constexpr uint32_t NAMESPACE_OFFSET = 3; -const vespalib::stringref DEFAULT_ID("id::::"); +constexpr vespalib::stringref DEFAULT_ID("id::::", 6); union LocationUnion { uint8_t _key[16]; IdString::LocationType _location[2]; }; -uint64_t parseNumber(stringref number) { +uint64_t +parseNumber(stringref number) { char* errPos = nullptr; errno = 0; uint64_t n = strtoul(number.data(), &errPos, 10); - if (*errPos) { + if (*errPos) [[unlikely]]{ throw IdParseException("'n'-value must be a 64-bit number. It was " + number, VESPA_STRLOC); } - if (errno == ERANGE) { + if (errno == ERANGE) [[unlikely]] { throw IdParseException("'n'-value out of range (" + number + ")", VESPA_STRLOC); } return n; } -void setLocation(IdString::LocationType &loc, IdString::LocationType val, +void +setLocation(IdString::LocationType &loc, IdString::LocationType val, bool &has_set_location, stringref key_values) { - if (has_set_location) { + if (has_set_location) [[unlikely]] { throw IdParseException("Illegal key combination in " + key_values); } loc = val; @@ -193,7 +142,7 @@ void setLocation(IdString::LocationType &loc, IdString::LocationType val, const IdString::Offsets IdString::Offsets::DefaultID(DEFAULT_ID); -IdString::Offsets::Offsets(stringref id) +IdString::Offsets::Offsets(stringref id) noexcept : _offsets() { compute(id); diff --git a/document/src/vespa/document/base/idstring.h b/document/src/vespa/document/base/idstring.h index bb752bd456e..176d810fccc 100644 --- a/document/src/vespa/document/base/idstring.h +++ b/document/src/vespa/document/base/idstring.h @@ -25,40 +25,40 @@ public: explicit IdString(vespalib::stringref ns); IdString(); - vespalib::stringref getNamespace() const { return getComponent(0); } - bool hasDocType() const { return size(1) != 0; } - vespalib::stringref getDocType() const { return getComponent(1); } - LocationType getLocation() const { return _location; } - bool hasNumber() const { return _has_number; } - uint64_t getNumber() const { return _location; } - bool hasGroup() const { return _groupOffset != 0; } - vespalib::stringref getGroup() const { - return vespalib::stringref(getRawId().c_str() + _groupOffset, offset(3) - _groupOffset - 1); + [[nodiscard]] vespalib::stringref getNamespace() const { return getComponent(0); } + [[nodiscard]] bool hasDocType() const { return size(1) != 0; } + [[nodiscard]] vespalib::stringref getDocType() const { return getComponent(1); } + [[nodiscard]] LocationType getLocation() const { return _location; } + [[nodiscard]] bool hasNumber() const { return _has_number; } + [[nodiscard]] uint64_t getNumber() const { return _location; } + [[nodiscard]] bool hasGroup() const { return _groupOffset != 0; } + [[nodiscard]] vespalib::stringref getGroup() const { + return {getRawId().c_str() + _groupOffset, size_t(offset(3) - _groupOffset - 1)}; } - vespalib::stringref getNamespaceSpecific() const { - return vespalib::stringref(_rawId.c_str() + offset(3), _rawId.size() - offset(3)); + [[nodiscard]] vespalib::stringref getNamespaceSpecific() const { + return {_rawId.c_str() + offset(3), _rawId.size() - offset(3)}; } bool operator==(const IdString& other) const { return toString() == other.toString(); } - const vespalib::string & toString() const { return _rawId; } + [[nodiscard]] const vespalib::string & toString() const { return _rawId; } private: - uint16_t offset(uint32_t index) const { return _offsets[index]; } - uint16_t size(uint32_t index) const { return std::max(0, int(offset(index+1)) - int(offset(index)) - 1); } - vespalib::stringref getComponent(size_t index) const { return vespalib::stringref(_rawId.c_str() + offset(index), size(index)); } - const vespalib::string & getRawId() const { return _rawId; } + [[nodiscard]] uint16_t offset(uint32_t index) const { return _offsets[index]; } + [[nodiscard]] uint16_t size(uint32_t index) const { return std::max(0, int(offset(index+1)) - int(offset(index)) - 1); } + [[nodiscard]] vespalib::stringref getComponent(size_t index) const { return {_rawId.c_str() + offset(index), size(index)}; } + [[nodiscard]] const vespalib::string & getRawId() const { return _rawId; } class Offsets { public: - Offsets() = default; - uint16_t compute(vespalib::stringref id); + Offsets() noexcept = default; + VESPA_DLL_LOCAL uint16_t compute(vespalib::stringref id); uint16_t operator [] (size_t i) const { return _offsets[i]; } static const Offsets DefaultID; private: static constexpr uint32_t MAX_COMPONENTS = 4; - Offsets(vespalib::stringref id); + VESPA_DLL_LOCAL explicit Offsets(vespalib::stringref id) noexcept; uint16_t _offsets[MAX_COMPONENTS]; }; -- cgit v1.2.3