From ea2f95ed70daf7b5eb3bf193a96f9cf080f9a560 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 31 Jul 2020 14:05:54 -0700 Subject: [PATCH] Optimizations, make Locator deserialize the same regardless of serialized field order. --- core/Locator.cpp | 23 ++++++++++++++--------- core/Locator.hpp | 2 ++ core/SharedPtr.hpp | 21 ++++++++++++++++++++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/core/Locator.cpp b/core/Locator.cpp index 994b107a4..279219d4f 100644 --- a/core/Locator.cpp +++ b/core/Locator.cpp @@ -46,20 +46,12 @@ bool Locator::add(const Endpoint &ep, const SharedPtr< const EndpointAttributes return false; } -struct p_SortByEndpoint -{ - // There can't be more than one of the same endpoint, so only need to sort - // by endpoint. - ZT_INLINE bool operator()(const std::pair< Endpoint, SharedPtr< const Locator::EndpointAttributes > > &a,const std::pair< Endpoint, SharedPtr< const Locator::EndpointAttributes > > &b) const noexcept - { return a.first < b.first; } -}; - bool Locator::sign(const int64_t ts, const Identity &id) noexcept { m_ts = ts; m_signer = id.fingerprint(); - std::sort(m_endpoints.begin(), m_endpoints.end(), p_SortByEndpoint()); + m_sortEndpoints(); uint8_t signdata[ZT_LOCATOR_MARSHAL_SIZE_MAX]; const unsigned int signlen = marshal(signdata, true); @@ -195,9 +187,22 @@ int Locator::unmarshal(const uint8_t *data, const int len) noexcept if (unlikely(p > len)) return -1; + m_sortEndpoints(); + return p; } +struct p_SortByEndpoint +{ + // There can't be more than one of the same endpoint, so only need to sort + // by endpoint. + ZT_INLINE bool operator()(const std::pair< Endpoint, SharedPtr< const Locator::EndpointAttributes > > &a,const std::pair< Endpoint, SharedPtr< const Locator::EndpointAttributes > > &b) const noexcept + { return a.first < b.first; } +}; + +void Locator::m_sortEndpoints() noexcept +{ std::sort(m_endpoints.begin(), m_endpoints.end(), p_SortByEndpoint()); } + } // namespace ZeroTier extern "C" { diff --git a/core/Locator.hpp b/core/Locator.hpp index f1c88517f..2cf4ff974 100644 --- a/core/Locator.hpp +++ b/core/Locator.hpp @@ -227,6 +227,8 @@ public: { return !(*this == l); } private: + void m_sortEndpoints() noexcept; + int64_t m_ts; Fingerprint m_signer; Vector< std::pair< Endpoint, SharedPtr< const EndpointAttributes > > > m_endpoints; diff --git a/core/SharedPtr.hpp b/core/SharedPtr.hpp index 7e8e61b21..5a95e117b 100644 --- a/core/SharedPtr.hpp +++ b/core/SharedPtr.hpp @@ -213,10 +213,29 @@ private: } // namespace ZeroTier +// Augment std::swap to speed up some operations with SharedPtr. namespace std { + template< typename T > ZT_INLINE void swap(ZeroTier::SharedPtr< T > &a, ZeroTier::SharedPtr< T > &b) noexcept { a.swap(b); } -} + +template< typename T > +constexpr bool is_swappable(ZeroTier::SharedPtr< T > &a) noexcept +{ return true; } + +template< typename T > +constexpr bool is_swappable_with(ZeroTier::SharedPtr< T > &a, ZeroTier::SharedPtr< T > &b) noexcept +{ return true; } + +template< typename T > +constexpr bool is_nothrow_swappable(ZeroTier::SharedPtr< T > &a) noexcept +{ return true; } + +template< typename T > +constexpr bool is_nothrow_swappable_with(ZeroTier::SharedPtr< T > &a, ZeroTier::SharedPtr< T > &b) noexcept +{ return true; } + +} // namespace std #endif