This is an automated email from the ASF dual-hosted git repository. amc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new e91317c libswoc - Update to 1.3.7 (#8709) e91317c is described below commit e91317cb0be17a1314e2d7d92325b7e2d257c2b2 Author: Alan M. Carroll <a...@apache.org> AuthorDate: Fri Mar 4 15:30:48 2022 -0600 libswoc - Update to 1.3.7 (#8709) --- lib/swoc/include/swoc/Lexicon.h | 2 +- lib/swoc/include/swoc/MemSpan.h | 43 +++--- lib/swoc/include/swoc/TextView.h | 35 +++++ lib/swoc/include/swoc/ext/HashFNV.h | 256 +++++++++++++++++++++++++++++++++++ lib/swoc/include/swoc/swoc_ip.h | 3 +- lib/swoc/include/swoc/swoc_version.h | 4 +- lib/swoc/src/swoc_file.cc | 18 +-- 7 files changed, 327 insertions(+), 34 deletions(-) diff --git a/lib/swoc/include/swoc/Lexicon.h b/lib/swoc/include/swoc/Lexicon.h index cd8a196..90ea861 100644 --- a/lib/swoc/include/swoc/Lexicon.h +++ b/lib/swoc/include/swoc/Lexicon.h @@ -18,7 +18,7 @@ #include "swoc/IntrusiveHashMap.h" #include "swoc/MemArena.h" #include "swoc/bwf_base.h" -#include "swoc/HashFNV.h" +#include "swoc/ext/HashFNV.h" namespace swoc { inline namespace SWOC_VERSION_NS { namespace detail { diff --git a/lib/swoc/include/swoc/MemSpan.h b/lib/swoc/include/swoc/MemSpan.h index 17e9880..f5aad67 100644 --- a/lib/swoc/include/swoc/MemSpan.h +++ b/lib/swoc/include/swoc/MemSpan.h @@ -277,8 +277,8 @@ public: /// Copy constructor. constexpr MemSpan(self_type const &that) = default; - /// Copy assignment operator. - constexpr self_type& operator=(self_type const &that) = default; + /// Copy assignment + constexpr self_type & operator = (self_type const& that) = default; /** Cross type copy constructor. * @@ -364,21 +364,21 @@ public: */ template <typename U> MemSpan<U> rebind() const; - /// Set the span. - /// This is faster but equivalent to constructing a new span with the same - /// arguments and assigning it. - /// @return @c this. - self_type &assign(value_type *ptr, ///< Buffer start. - size_t n ///< # of bytes - ); + /** Update the span. + * + * @param ptr Start of span memory. + * @param n Number of elements in the span. + * @return @a this + */ + self_type &assign(value_type *ptr, size_t n); - /// Set the span. - /// This is faster but equivalent to constructing a new span with the same - /// arguments and assigning it. - /// @return @c this. - self_type &assign(value_type *first, ///< First valid element. - value_type const *last ///< First invalid element. - ); + /** Update the span. + * + * @param first First element in the span. + * @param last One past the last element in the span. + * @return @a this + */ + self_type &assign(value_type *first, value_type const *last); /// Clear the span (become an empty span). self_type &clear(); @@ -416,12 +416,13 @@ public: /** Return a sub span of @a this span. * - * @param offset Offset (index) of first element in subspan. - * @param count Number of elements in the subspan. - * @return A subspan starting at @a offset for @a count elements. + * @param offset Offset (index) of first element. + * @param count Number of elements. + * @return The span starting at @a offset for @a count elements in @a this. * - * The result is clipped by @a this - if @a offset is out of range an empty span is returned. - * Otherwise @c count is clipped by the number of elements available in @a this. + * The result is clipped by @a this - if @a offset is out of range an empty span is returned. Otherwise @c count is clipped by the + * number of elements available in @a this. In effect the intersection of the span described by ( @a offset , @a count ) and @a + * this span is returned, which may be the empty span. */ constexpr self_type subspan(size_t offset, size_t count) const; diff --git a/lib/swoc/include/swoc/TextView.h b/lib/swoc/include/swoc/TextView.h index 5e27ddf..e32d861 100644 --- a/lib/swoc/include/swoc/TextView.h +++ b/lib/swoc/include/swoc/TextView.h @@ -79,6 +79,22 @@ public: */ constexpr TextView(char const *first, char const *last) noexcept; + /** Construct from any character container following STL standards. + * + * @tparam C Container type. + * @param c container + * + * The container type must have the methods @c data and @c size which must return values convertible + * to @c char @c const @c * and @c size_t respectively. + */ + template < typename C + , typename = std::enable_if_t< + std::is_convertible_v<decltype(std::declval<C>().data()), char const*> && + std::is_convertible_v<decltype(std::declval<C>().size()), size_t> + , void + > + > constexpr TextView(C const& c); + /** Construct from literal string or array. All elements of the array are included in the view unless the last element is nul, in which case it is elided. @@ -164,6 +180,24 @@ public: /// Explicitly set the view from a @c std::string self_type &assign(std::string const &s); + /** Assign from any character container following STL standards. + * + * @tparam C Container type. + * @param c container + * + * The container type must have the methods @c data and @c size which must return values convertible + * to @c char @c const @c * and @c size_t respectively. + */ + template < typename C + , typename = std::enable_if_t< + std::is_convertible_v<decltype(std::declval<C>().data()), char const*> && + std::is_convertible_v<decltype(std::declval<C>().size()), size_t> + , void + > + > constexpr self_type & assign(C const& c) { + return this->assign(c.data(), c.size()); + } + /** Dereference operator. @note This allows the view to be used as if it were a character iterator to a null terminated @@ -923,6 +957,7 @@ inline constexpr TextView::TextView(std::nullptr_t) noexcept : super_type(nullpt inline TextView::TextView(std::string const &str) noexcept : super_type(str) {} inline constexpr TextView::TextView(super_type const &that) noexcept : super_type(that) {} template <size_t N> constexpr TextView::TextView(const char (&s)[N]) noexcept : super_type(s, s[N - 1] ? N : N - 1) {} +template <typename C, typename> constexpr TextView::TextView(C const &c) : super_type(c.data(), c.size()) {} inline void TextView::init_delimiter_set(std::string_view const &delimiters, std::bitset<256> &set) { diff --git a/lib/swoc/include/swoc/ext/HashFNV.h b/lib/swoc/include/swoc/ext/HashFNV.h new file mode 100644 index 0000000..b22d43f --- /dev/null +++ b/lib/swoc/include/swoc/ext/HashFNV.h @@ -0,0 +1,256 @@ +/** @file + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. + See the NOTICE file distributed with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance with the License. You may obtain a + copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the License for the specific language governing permissions and limitations under + the License. + */ + +/* + http://www.isthe.com/chongo/tech/comp/fnv/ + + Currently implemented FNV-1a 32bit and FNV-1a 64bit + */ + +#pragma once + +#include <cstdint> + +#include "swoc/TextView.h" + +namespace swoc { inline namespace SWOC_VERSION_NS { + +struct Hash32FNV1a { +protected: + using self_type = Hash32FNV1a; + static constexpr uint32_t INIT = 0x811c9dc5u; + +public: + using value_type = uint32_t; + + Hash32FNV1a() = default; + + /** Update the hash value. + * + * @param data Input data to hash. + * @return @a this + */ + self_type &update(std::string_view const &data); + + /** Finalize the hash value. + * + * @return @a this + * + * No more updates are valid after finalization. + */ + self_type & final(); + + /// Return the hash value. + value_type get() const; + + /// Re-initialize to default state. + self_type &clear(); + + /** Update with transformed data. + * + * @tparam X Transform functor. + * @tparam V Input data + * @param view transformed view + * @return @a this + * + * The hash is updated using the transformed data provided by @a view. + */ + template <typename X, typename V> self_type &update(TransformView<X, V> view); + + /** Update and finalize. + * + * @param data Input data to hash. + * @return The final hash value. + * + * Convenience method to compute a hash in one step. + */ + value_type hash_immediate(std::string_view const &data); + + /** Update and finalized with transformed data. + * + * @tparam X Transform functor. + * @tparam V Input data + * @param view transformed view + * @return @a this + * + * The hash is updated using the transformed data provided by @a view, then finalized. + */ + template <typename X, typename V> value_type hash_immediate(TransformView<X, V> const &view); + +private: + value_type hval{INIT}; +}; + +struct Hash64FNV1a { +protected: + using self_type = Hash64FNV1a; + static constexpr uint64_t INIT = 0xcbf29ce484222325ull; + +public: + using value_type = uint64_t; + + Hash64FNV1a() = default; + + /** Update the hash value. + * + * @param data Input data to hash. + * @return @a this + */ + self_type &update(std::string_view const &data); + + /** Finalize the hash value. + * + * @return @a this + * + * No more updates are valid after finalization. + */ + self_type & final(); + + /// Return the hash value. + value_type get() const; + + /// Re-initialize to default state. + self_type &clear(); + + /** Update with transformed data. + * + * @tparam X Transform functor. + * @tparam V Input data + * @param view transformed view + * @return @a this + * + * The hash is updated using the transformed data provided by @a view. + */ + template <typename X, typename V> self_type &update(TransformView<X, V> view); + + /** Update and finalize. + * + * @param data Input data to hash. + * @return The final hash value. + * + * Convenience method to compute a hash in one step. + */ + value_type hash_immediate(std::string_view const &data); + + /** Update and finalized with transformed data. + * + * @tparam X Transform functor. + * @tparam V Input data type. + * @param view transformed view + * @return @a this + * + * The hash is updated using the transformed data provided by @a view, then finalized. + */ + template <typename X, typename V> value_type hash_immediate(TransformView<X, V> const &view); + +private: + value_type hval{INIT}; +}; + +// ---------- +// Implementation + +// -- 32 -- + +inline auto +Hash32FNV1a::clear() -> self_type & { + hval = INIT; + return *this; +} + +template <typename X, typename V> +auto +Hash32FNV1a::update(TransformView<X, V> view) -> self_type & { + for (; view; ++view) { + hval ^= static_cast<value_type>(*view); + hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); + } + return *this; +} + +inline auto +Hash32FNV1a::update(std::string_view const &data) -> self_type & { + return this->update(transform_view_of(data)); +} + +inline auto +Hash32FNV1a::final() -> self_type & { + return *this; +} + +inline auto +Hash32FNV1a::get() const -> value_type { + return hval; +} + +template <typename X, typename V> +auto +Hash32FNV1a::hash_immediate(swoc::TransformView<X, V> const &view) -> value_type { + return this->update(view).get(); +} + +inline auto +Hash32FNV1a::hash_immediate(std::string_view const &data) -> value_type { + return this->update(data).final().get(); +} + +// -- 64 -- + +inline auto +Hash64FNV1a::clear() -> self_type & { + hval = INIT; + return *this; +} + +template <typename X, typename V> +auto +Hash64FNV1a::update(TransformView<X, V> view) -> self_type & { + for (; view; ++view) { + hval ^= static_cast<value_type>(*view); + hval += (hval << 1) + (hval << 4) + (hval << 5) + (hval << 7) + (hval << 8) + (hval << 40); + } + return *this; +} + +inline auto +Hash64FNV1a::update(std::string_view const &data) -> self_type & { + return this->update(transform_view_of(data)); +} + +inline auto +Hash64FNV1a::final() -> self_type & { + return *this; +} + +inline auto +Hash64FNV1a::get() const -> value_type { + return hval; +} + +template <typename X, typename V> +auto +Hash64FNV1a::hash_immediate(swoc::TransformView<X, V> const &view) -> value_type { + return this->update(view).final().get(); +} + +inline auto +Hash64FNV1a::hash_immediate(std::string_view const &data) -> value_type { + return this->update(data).final().get(); +} + +}} // namespace swoc::SWOC_VERSION_NS diff --git a/lib/swoc/include/swoc/swoc_ip.h b/lib/swoc/include/swoc/swoc_ip.h index e5351cb..430c0e2 100644 --- a/lib/swoc/include/swoc/swoc_ip.h +++ b/lib/swoc/include/swoc/swoc_ip.h @@ -6,11 +6,12 @@ */ #pragma once +#include <array> #include <climits> #include <netinet/in.h> +#include <sys/socket.h> #include <string_view> #include <variant> -#include <array> #include "swoc/swoc_version.h" #include "swoc/TextView.h" diff --git a/lib/swoc/include/swoc/swoc_version.h b/lib/swoc/include/swoc/swoc_version.h index 8dce2b4..a35e2d7 100644 --- a/lib/swoc/include/swoc/swoc_version.h +++ b/lib/swoc/include/swoc/swoc_version.h @@ -23,11 +23,11 @@ #pragma once #if !defined(SWOC_VERSION_NS) -#define SWOC_VERSION_NS _1_3_6 +#define SWOC_VERSION_NS _1_3_7 #endif namespace swoc { inline namespace SWOC_VERSION_NS { static constexpr unsigned MAJOR_VERSION = 1; static constexpr unsigned MINOR_VERSION = 3; -static constexpr unsigned POINT_VERSION = 6; +static constexpr unsigned POINT_VERSION = 7; }} // namespace swoc::SWOC_VERSION_NS diff --git a/lib/swoc/src/swoc_file.cc b/lib/swoc/src/swoc_file.cc index ef0788e..50bf36a 100644 --- a/lib/swoc/src/swoc_file.cc +++ b/lib/swoc/src/swoc_file.cc @@ -114,37 +114,37 @@ chrono_cast(timespec const &ts) { // Under -O2 these are completely elided. template <typename S> auto -a_time(S const &s) -> decltype(S::st_atim) { +a_time(S const &s, meta::CaseTag<0>) -> decltype(S::st_atim) { return s.st_atim; } template <typename S> auto -a_time(S const &s) -> decltype(S::st_atimespec) { +a_time(S const &s, meta::CaseTag<1>) -> decltype(S::st_atimespec) { return s.st_atimespec; } template <typename S> auto -m_time(S const &s) -> decltype(S::st_mtim) { +m_time(S const &s, meta::CaseTag<0>) -> decltype(S::st_mtim) { return s.st_mtim; } template <typename S> auto -m_time(S const &s) -> decltype(S::st_mtimespec) { +m_time(S const &s, meta::CaseTag<1>) -> decltype(S::st_mtimespec) { return s.st_mtimespec; } template <typename S> auto -c_time(S const &s) -> decltype(S::st_ctim) { +c_time(S const &s, meta::CaseTag<0>) -> decltype(S::st_ctim) { return s.st_ctim; } template <typename S> auto -c_time(S const &s) -> decltype(S::st_ctimespec) { +c_time(S const &s, meta::CaseTag<1>) -> decltype(S::st_ctimespec) { return s.st_ctimespec; } @@ -152,17 +152,17 @@ c_time(S const &s) -> decltype(S::st_ctimespec) { std::chrono::system_clock::time_point modify_time(file_status const &fs) { - return chrono_cast(m_time(fs._stat)); + return chrono_cast(m_time(fs._stat, meta::CaseArg)); } std::chrono::system_clock::time_point access_time(file_status const &fs) { - return chrono_cast(a_time(fs._stat)); + return chrono_cast(a_time(fs._stat, meta::CaseArg)); } std::chrono::system_clock::time_point status_time(file_status const &fs) { - return chrono_cast(c_time(fs._stat)); + return chrono_cast(c_time(fs._stat, meta::CaseArg)); } bool