diff options
Diffstat (limited to 'libtransport/src/utils')
-rw-r--r-- | libtransport/src/utils/CMakeLists.txt | 7 | ||||
-rw-r--r-- | libtransport/src/utils/content_store.cc | 9 | ||||
-rw-r--r-- | libtransport/src/utils/content_store.h | 5 | ||||
-rw-r--r-- | libtransport/src/utils/daemonizator.cc | 2 | ||||
-rw-r--r-- | libtransport/src/utils/deadline_timer.h | 57 | ||||
-rw-r--r-- | libtransport/src/utils/epoll_event_reactor.cc | 190 | ||||
-rw-r--r-- | libtransport/src/utils/epoll_event_reactor.h | 165 | ||||
-rw-r--r-- | libtransport/src/utils/event_reactor.h | 2 | ||||
-rw-r--r-- | libtransport/src/utils/fd_deadline_timer.h | 8 | ||||
-rw-r--r-- | libtransport/src/utils/log.cc | 4 | ||||
-rw-r--r-- | libtransport/src/utils/max_filter.h | 58 | ||||
-rw-r--r-- | libtransport/src/utils/membuf.cc | 23 | ||||
-rw-r--r-- | libtransport/src/utils/memory_pool_allocator.h | 2 | ||||
-rw-r--r-- | libtransport/src/utils/min_filter.h | 2 | ||||
-rw-r--r-- | libtransport/src/utils/stream_buffer.h | 2 | ||||
-rw-r--r-- | libtransport/src/utils/string_tokenizer.cc | 2 | ||||
-rw-r--r-- | libtransport/src/utils/suffix_strategy.h | 166 | ||||
-rw-r--r-- | libtransport/src/utils/test.h | 2 | ||||
-rw-r--r-- | libtransport/src/utils/uri.cc | 2 |
19 files changed, 309 insertions, 399 deletions
diff --git a/libtransport/src/utils/CMakeLists.txt b/libtransport/src/utils/CMakeLists.txt index a85ab16bf..5bb76303a 100644 --- a/libtransport/src/utils/CMakeLists.txt +++ b/libtransport/src/utils/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed 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: @@ -23,6 +23,7 @@ list(APPEND SOURCE_FILES list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/event_reactor.h ${CMAKE_CURRENT_SOURCE_DIR}/min_filter.h + ${CMAKE_CURRENT_SOURCE_DIR}/max_filter.h ${CMAKE_CURRENT_SOURCE_DIR}/stream_buffer.h ${CMAKE_CURRENT_SOURCE_DIR}/suffix_strategy.h ${CMAKE_CURRENT_SOURCE_DIR}/content_store.h @@ -34,10 +35,6 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") ${CMAKE_CURRENT_SOURCE_DIR}/epoll_event_reactor.h ${CMAKE_CURRENT_SOURCE_DIR}/fd_deadline_timer.h ) - - list(APPEND SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/epoll_event_reactor.cc - ) endif() if(NOT WIN32) diff --git a/libtransport/src/utils/content_store.cc b/libtransport/src/utils/content_store.cc index 8ae7fd4d4..d9d4147f7 100644 --- a/libtransport/src/utils/content_store.cc +++ b/libtransport/src/utils/content_store.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -17,6 +17,7 @@ #include <hicn/transport/core/content_object.h> #include <hicn/transport/core/interest.h> #include <hicn/transport/core/name.h> +#include <hicn/transport/utils/chrono_typedefs.h> #include <utils/content_store.h> namespace utils { @@ -56,7 +57,7 @@ void ContentStore::insert( fifo_list_.push_front(std::cref(content_object->getName())); auto pos = fifo_list_.begin(); content_store_hash_table_[content_object->getName()] = ContentStoreEntry( - ObjectTimeEntry(content_object, std::chrono::steady_clock::now()), pos); + ObjectTimeEntry(content_object, utils::SteadyTime::now()), pos); } std::shared_ptr<ContentObject> ContentStore::find(const Name &name) { @@ -67,8 +68,8 @@ std::shared_ptr<ContentObject> ContentStore::find(const Name &name) { if (it != content_store_hash_table_.end()) { auto content_lifetime = it->second.first.first->getLifetime(); auto time_passed_since_creation = - std::chrono::duration_cast<std::chrono::milliseconds>( - std::chrono::steady_clock::now() - it->second.first.second) + utils::SteadyTime::getDurationMs(it->second.first.second, + utils::SteadyTime::now()) .count(); if (time_passed_since_creation > content_lifetime) { diff --git a/libtransport/src/utils/content_store.h b/libtransport/src/utils/content_store.h index abe5e7f6c..ecd62cc2c 100644 --- a/libtransport/src/utils/content_store.h +++ b/libtransport/src/utils/content_store.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -35,8 +35,7 @@ using Name = transport::core::Name; using ContentObject = transport::core::ContentObject; using Interest = transport::core::Interest; -typedef std::pair<std::shared_ptr<ContentObject>, - std::chrono::steady_clock::time_point> +typedef std::pair<std::shared_ptr<ContentObject>, utils::SteadyTime::TimePoint> ObjectTimeEntry; typedef std::pair<ObjectTimeEntry, std::list<std::reference_wrapper<const Name>>::iterator> diff --git a/libtransport/src/utils/daemonizator.cc b/libtransport/src/utils/daemonizator.cc index 6cb7d16ba..4c17aa96b 100644 --- a/libtransport/src/utils/daemonizator.cc +++ b/libtransport/src/utils/daemonizator.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/deadline_timer.h b/libtransport/src/utils/deadline_timer.h index 5187754f0..6c105ed3d 100644 --- a/libtransport/src/utils/deadline_timer.h +++ b/libtransport/src/utils/deadline_timer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -22,61 +22,6 @@ #include <cstring> #include <utility> -namespace std { -namespace chrono { -namespace detail { - -template <typename From, typename To> -struct posix_duration_cast; - -// chrono -> timespec caster -template <typename Rep, typename Period> -struct posix_duration_cast<std::chrono::duration<Rep, Period>, - struct timespec> { - static struct timespec cast(std::chrono::duration<Rep, Period> const &d) { - struct timespec tv; - - std::chrono::seconds const sec = - std::chrono::duration_cast<std::chrono::seconds>(d); - - tv.tv_sec = sec.count(); - tv.tv_nsec = - std::chrono::duration_cast<std::chrono::nanoseconds>(d - sec).count(); - - return tv; - } -}; - -// timespec -> chrono caster -template <typename Rep, typename Period> -struct posix_duration_cast<struct timespec, - std::chrono::duration<Rep, Period>> { - static std::chrono::duration<Rep, Period> cast(struct timespec const &tv) { - return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>( - std::chrono::seconds(tv.tv_sec) + std::chrono::nanoseconds(tv.tv_nsec)); - } -}; - -} // namespace detail - -// chrono -> timespec -template <typename T, typename Rep, typename Period> -auto duration_cast(std::chrono::duration<Rep, Period> const &d) -> - typename std::enable_if<std::is_same<T, struct timespec>::value, - struct timespec>::type { - return detail::posix_duration_cast<std::chrono::duration<Rep, Period>, - timespec>::cast(d); -} - -// timespec -> chrono -template <typename Duration> -Duration duration_cast(struct timespec const &tv) { - return detail::posix_duration_cast<struct timespec, Duration>::cast(tv); -} - -} // namespace chrono -} // namespace std - namespace utils { template <typename Implementation> diff --git a/libtransport/src/utils/epoll_event_reactor.cc b/libtransport/src/utils/epoll_event_reactor.cc deleted file mode 100644 index 457727bbe..000000000 --- a/libtransport/src/utils/epoll_event_reactor.cc +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed 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. - */ - -#include <glog/logging.h> -#include <hicn/transport/utils/branch_prediction.h> -#include <signal.h> -#include <unistd.h> -#include <utils/epoll_event_reactor.h> -#include <utils/fd_deadline_timer.h> - -#include <iostream> - -namespace utils { - -EpollEventReactor::EpollEventReactor() - : epoll_fd_(epoll_create(20000)), run_event_loop_(true) {} - -EpollEventReactor::~EpollEventReactor() { close(epoll_fd_); } - -int EpollEventReactor::addFileDescriptor(int fd, uint32_t events) { - if (TRANSPORT_EXPECT_FALSE(fd < 0)) { - LOG(ERROR) << "invalid fd " << fd; - return -1; - } - - struct epoll_event evt; - std::memset(&evt, 0, sizeof(evt)); - evt.events = events; - evt.data.fd = fd; - - if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &evt) < - 0)) { - LOG(ERROR) << "epoll_ctl: " << strerror(errno) << " fd " << fd; - return -1; - } - - return 0; -} - -int EpollEventReactor::modFileDescriptor(int fd, uint32_t events) { - if (TRANSPORT_EXPECT_FALSE(fd < 0)) { - LOG(ERROR) << "invalid fd " << fd; - return -1; - } - - struct epoll_event evt; - memset(&evt, 0, sizeof(evt)); - evt.events = events; - evt.data.fd = fd; - - if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &evt) < - 0)) { - LOG(ERROR) << "epoll_ctl: " << strerror(errno) << " fd " << fd; - return -1; - } - - return 0; -} - -std::size_t EpollEventReactor::mapSize() { return event_callback_map_.size(); } - -int EpollEventReactor::delFileDescriptor(int fd) { - if (TRANSPORT_EXPECT_FALSE(fd < 0)) { - LOG(ERROR) << "invalid fd " << fd; - return -1; - } - - struct epoll_event evt; - memset(&evt, 0, sizeof(evt)); - - if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &evt) < - 0)) { - LOG(ERROR) << "epoll_ctl: " << strerror(errno) << " fd " << fd; - return -1; - } - - utils::SpinLock::Acquire locked(event_callback_map_lock_); - event_callback_map_.erase(fd); - - return 0; -} - -void EpollEventReactor::runEventLoop(int timeout) { - Event evt[128]; - int en = 0; - EventCallbackMap::iterator it; - EventCallback callback; - - // evt.events = EPOLLIN | EPOLLOUT; - sigset_t sigset; - sigemptyset(&sigset); - - while (run_event_loop_) { - memset(&evt, 0, sizeof(evt)); - en = epoll_pwait(epoll_fd_, evt, 128, timeout, &sigset); - - if (TRANSPORT_EXPECT_FALSE(en < 0)) { - LOG(ERROR) << "epoll_pwait: " << strerror(errno); - if (errno == EINTR) { - continue; - } else { - return; - } - } - - for (int i = 0; i < en; i++) { - if (evt[i].data.fd > 0) { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - it = event_callback_map_.find(evt[i].data.fd); - } - - if (TRANSPORT_EXPECT_FALSE(it == event_callback_map_.end())) { - LOG(ERROR) << "unexpected event. fd " << evt[i].data.fd; - } else { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - callback = event_callback_map_[evt[i].data.fd]; - } - - callback(evt[i]); - - // In the callback the epoll event reactor could have been stopped, - // then we need to check whether the event loop is still running. - if (TRANSPORT_EXPECT_FALSE(!run_event_loop_)) { - return; - } - } - } else { - LOG(ERROR) << "unexpected event. fd " << evt[i].data.fd; - } - } - } -} - -void EpollEventReactor::runOneEvent() { - Event evt; - int en = 0; - EventCallbackMap::iterator it; - EventCallback callback; - - // evt.events = EPOLLIN | EPOLLOUT; - sigset_t sigset; - sigemptyset(&sigset); - - memset(&evt, 0, sizeof(evt)); - - en = epoll_pwait(epoll_fd_, &evt, 1, -1, &sigset); - - if (TRANSPORT_EXPECT_FALSE(en < 0)) { - LOG(ERROR) << "epoll_pwait: " << strerror(errno); - return; - } - - if (TRANSPORT_EXPECT_TRUE(evt.data.fd > 0)) { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - it = event_callback_map_.find(evt.data.fd); - } - - if (TRANSPORT_EXPECT_FALSE(it == event_callback_map_.end())) { - LOG(ERROR) << "unexpected event. fd " << evt.data.fd; - } else { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - callback = event_callback_map_[evt.data.fd]; - } - - callback(evt); - } - } else { - LOG(ERROR) << "unexpected event. fd " << evt.data.fd; - } -} - -void EpollEventReactor::stop() { run_event_loop_ = false; } - -} // namespace utils
\ No newline at end of file diff --git a/libtransport/src/utils/epoll_event_reactor.h b/libtransport/src/utils/epoll_event_reactor.h index 9ebfca937..8e7681c20 100644 --- a/libtransport/src/utils/epoll_event_reactor.h +++ b/libtransport/src/utils/epoll_event_reactor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -15,6 +15,7 @@ #pragma once +#include <glog/logging.h> #include <hicn/transport/utils/spinlock.h> #include <sys/epoll.h> #include <utils/event_reactor.h> @@ -35,9 +36,10 @@ typedef std::unordered_map<int, EventCallback> EventCallbackMap; class EpollEventReactor : public EventReactor { public: - explicit EpollEventReactor(); + explicit EpollEventReactor() + : epoll_fd_(epoll_create(20000)), run_event_loop_(true) {} - ~EpollEventReactor(); + ~EpollEventReactor() { close(epoll_fd_); } template <typename EventHandler> int addFileDescriptor(int fd, uint32_t events, EventHandler &&callback) { @@ -56,20 +58,163 @@ class EpollEventReactor : public EventReactor { return ret; } - int delFileDescriptor(int fd); + int delFileDescriptor(int fd) { + if (TRANSPORT_EXPECT_FALSE(fd < 0)) { + LOG(ERROR) << "invalid fd " << fd; + return -1; + } + + struct epoll_event evt; + memset(&evt, 0, sizeof(evt)); + + if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &evt) < + 0)) { + return -1; + } + + utils::SpinLock::Acquire locked(event_callback_map_lock_); + event_callback_map_.erase(fd); + + return 0; + } + + int modFileDescriptor(int fd, uint32_t events) { + if (TRANSPORT_EXPECT_FALSE(fd < 0)) { + LOG(ERROR) << "invalid fd " << fd; + return -1; + } + + struct epoll_event evt; + memset(&evt, 0, sizeof(evt)); + evt.events = events; + evt.data.fd = fd; + + if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &evt) < + 0)) { + LOG(ERROR) << "epoll_ctl: " << strerror(errno) << " fd " << fd; + return -1; + } + + return 0; + } + + void runEventLoop(int timeout = -1) override { + Event evt[128]; + int en = 0; + EventCallbackMap::iterator it; + EventCallback callback; + + // evt.events = EPOLLIN | EPOLLOUT; + sigset_t sigset; + sigemptyset(&sigset); + + while (run_event_loop_) { + memset(&evt, 0, sizeof(evt)); + en = epoll_pwait(epoll_fd_, evt, 128, timeout, &sigset); + + if (TRANSPORT_EXPECT_FALSE(en < 0)) { + LOG(ERROR) << "epoll_pwait: " << strerror(errno); + if (errno == EINTR) { + continue; + } else { + return; + } + } + + for (int i = 0; i < en; i++) { + if (evt[i].data.fd > 0) { + { + utils::SpinLock::Acquire locked(event_callback_map_lock_); + it = event_callback_map_.find(evt[i].data.fd); + } + + if (TRANSPORT_EXPECT_FALSE(it == event_callback_map_.end())) { + LOG(ERROR) << "unexpected event. fd " << evt[i].data.fd; + } else { + { + utils::SpinLock::Acquire locked(event_callback_map_lock_); + callback = event_callback_map_[evt[i].data.fd]; + } + + callback(evt[i]); + + // In the callback the epoll event reactor could have been stopped, + // then we need to check whether the event loop is still running. + if (TRANSPORT_EXPECT_FALSE(!run_event_loop_)) { + return; + } + } + } else { + LOG(ERROR) << "unexpected event. fd " << evt[i].data.fd; + } + } + } + } + + void runOneEvent() override { + Event evt; + int en = 0; + EventCallbackMap::iterator it; + EventCallback callback; - int modFileDescriptor(int fd, uint32_t events); + // evt.events = EPOLLIN | EPOLLOUT; + sigset_t sigset; + sigemptyset(&sigset); - void runEventLoop(int timeout = -1) override; + memset(&evt, 0, sizeof(evt)); - void runOneEvent() override; + en = epoll_pwait(epoll_fd_, &evt, 1, -1, &sigset); - void stop() override; + if (TRANSPORT_EXPECT_FALSE(en < 0)) { + LOG(ERROR) << "epoll_pwait: " << strerror(errno); + return; + } + + if (TRANSPORT_EXPECT_TRUE(evt.data.fd > 0)) { + { + utils::SpinLock::Acquire locked(event_callback_map_lock_); + it = event_callback_map_.find(evt.data.fd); + } - std::size_t mapSize(); + if (TRANSPORT_EXPECT_FALSE(it == event_callback_map_.end())) { + LOG(ERROR) << "unexpected event. fd " << evt.data.fd; + } else { + { + utils::SpinLock::Acquire locked(event_callback_map_lock_); + callback = event_callback_map_[evt.data.fd]; + } + + callback(evt); + } + } else { + LOG(ERROR) << "unexpected event. fd " << evt.data.fd; + } + } + + void stop() override { run_event_loop_ = false; } + + std::size_t mapSize() { return event_callback_map_.size(); } private: - int addFileDescriptor(int fd, uint32_t events); + int addFileDescriptor(int fd, uint32_t events) { + if (TRANSPORT_EXPECT_FALSE(fd < 0)) { + LOG(ERROR) << "invalid fd " << fd; + return -1; + } + + struct epoll_event evt; + std::memset(&evt, 0, sizeof(evt)); + evt.events = events; + evt.data.fd = fd; + + if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &evt) < + 0)) { + LOG(ERROR) << "epoll_ctl: " << strerror(errno) << " fd " << fd; + return -1; + } + + return 0; + } int epoll_fd_; std::atomic_bool run_event_loop_; diff --git a/libtransport/src/utils/event_reactor.h b/libtransport/src/utils/event_reactor.h index 4f8b58296..09af6f84c 100644 --- a/libtransport/src/utils/event_reactor.h +++ b/libtransport/src/utils/event_reactor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/fd_deadline_timer.h b/libtransport/src/utils/fd_deadline_timer.h index 22c13a763..e15cd4d2a 100644 --- a/libtransport/src/utils/fd_deadline_timer.h +++ b/libtransport/src/utils/fd_deadline_timer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -16,6 +16,7 @@ #pragma once #include <hicn/transport/errors/runtime_exception.h> +#include <hicn/transport/utils/chrono_typedefs.h> #include <sys/timerfd.h> #include <unistd.h> #include <utils/deadline_timer.h> @@ -37,6 +38,11 @@ class FdDeadlineTimer : public DeadlineTimer<FdDeadlineTimer> { } } + FdDeadlineTimer(const FdDeadlineTimer &other) + : reactor_(other.reactor_), + timer_fd_(other.timer_fd_), + flags_(other.flags_) {} + ~FdDeadlineTimer() { close(timer_fd_); } template <typename WaitHandler> diff --git a/libtransport/src/utils/log.cc b/libtransport/src/utils/log.cc index 755d5bafa..44acf4595 100644 --- a/libtransport/src/utils/log.cc +++ b/libtransport/src/utils/log.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -36,7 +36,7 @@ foreach_log_level static constexpr char log_config_section[] = "log"; #define LOG_NAME \ "Libhicntransport-" HICNTRANSPORT_VERSION_MAJOR \ - "." HICNTRANSPORT_VERSION_MINOR "." HICNTRANSPORT_VERSION_REVISION + "." HICNTRANSPORT_VERSION_MINOR "." HICNTRANSPORT_VERSION_PATCH static constexpr char log_name[] = LOG_NAME; #define foreach_log_config \ diff --git a/libtransport/src/utils/max_filter.h b/libtransport/src/utils/max_filter.h new file mode 100644 index 000000000..7a2c6aace --- /dev/null +++ b/libtransport/src/utils/max_filter.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed 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.sudo make instamake install + */ + +#pragma once + +#include <deque> +#include <iostream> +#include <set> +#include <type_traits> +#include <vector> + +namespace utils { + +template <typename T> +class MaxFilter { + public: + MaxFilter(std::size_t size) : size_(size) {} + + std::size_t size() { return by_arrival_.size(); } + + template <typename R> + void pushBack(R&& value) { + if (by_arrival_.size() >= size_) { + by_order_.erase(by_arrival_.back()); + by_arrival_.pop_back(); + } + + by_arrival_.push_front(by_order_.insert(std::forward<R>(value))); + } + + void clear() { + by_arrival_.clear(); + by_order_.clear(); + } + + const T& begin() { return *by_order_.crbegin(); } + + const T& rBegin() { return *by_order_.rbegin(); } + + private: + std::multiset<T> by_order_; + std::deque<typename std::multiset<T>::const_iterator> by_arrival_; + std::size_t size_; +}; + +} // namespace utils diff --git a/libtransport/src/utils/membuf.cc b/libtransport/src/utils/membuf.cc index 73c45cf6d..952116bb7 100644 --- a/libtransport/src/utils/membuf.cc +++ b/libtransport/src/utils/membuf.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Copyright 2013-present Facebook, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include <hicn/transport/portability/win_portability.h> #endif +#include <glog/logging.h> #include <hicn/transport/utils/membuf.h> #include <cassert> @@ -209,7 +210,7 @@ MemBuf::MemBuf(CopyBufferOp /* op */, const void* buf, std::size_t size, : MemBuf(CREATE, headroom + size + min_tailroom) { advance(headroom); if (size > 0) { - assert(buf != nullptr); + DCHECK(buf != nullptr); memcpy(writableData(), buf, size); append(size); } @@ -369,8 +370,8 @@ MemBuf::MemBuf(InternalConstructor, uintptr_t flagsAndSharedInfo, uint8_t* buf, length_(length), capacity_(capacity), flags_and_shared_info_(flagsAndSharedInfo) { - assert(data >= buf); - assert(data + length <= buf + capacity); + DCHECK(data >= buf); + DCHECK(data + length <= buf + capacity); } MemBuf::~MemBuf() { @@ -559,7 +560,7 @@ void MemBuf::unshareOneSlow() { // minimum capacity we also maintain at least the same amount of tailroom. std::size_t headlen = headroom(); if (length_ > 0) { - assert(data_ != nullptr); + DCHECK(data_ != nullptr); memcpy(buf + headlen, data_, length_); } @@ -576,7 +577,7 @@ void MemBuf::unshareOneSlow() { void MemBuf::unshareChained() { // unshareChained() should only be called if we are part of a chain of // multiple MemBufs. The caller should have already verified this. - assert(isChained()); + DCHECK(isChained()); MemBuf* current = this; while (true) { @@ -606,7 +607,7 @@ void MemBuf::markExternallyShared() { } void MemBuf::makeManagedChained() { - assert(isChained()); + DCHECK(isChained()); MemBuf* current = this; while (true) { @@ -677,15 +678,15 @@ void MemBuf::coalesceAndReallocate(size_t new_headroom, size_t new_length, size_t remaining = new_length; do { if (current->length_ > 0) { - assert(current->length_ <= remaining); - assert(current->data_ != nullptr); + DCHECK(current->length_ <= remaining); + DCHECK(current->data_ != nullptr); remaining -= current->length_; memcpy(p, current->data_, current->length_); p += current->length_; } current = current->next_; } while (current != end); - assert(remaining == 0); + DCHECK(remaining == 0); // Point at the new buffer decrementRefcount(); @@ -799,7 +800,7 @@ void MemBuf::reserveSlow(std::size_t min_headroom, std::size_t min_tailroom) { new_allocated_capacity = goodExtBufferSize(new_capacity); new_buffer = static_cast<uint8_t*>(malloc(new_allocated_capacity)); if (length_ > 0) { - assert(data_ != nullptr); + DCHECK(data_ != nullptr); memcpy(new_buffer + min_headroom, data_, length_); } if (sharedInfo()) { diff --git a/libtransport/src/utils/memory_pool_allocator.h b/libtransport/src/utils/memory_pool_allocator.h index a960b91bb..c2b34e7aa 100644 --- a/libtransport/src/utils/memory_pool_allocator.h +++ b/libtransport/src/utils/memory_pool_allocator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/min_filter.h b/libtransport/src/utils/min_filter.h index 092555ce0..4c7ae81f1 100644 --- a/libtransport/src/utils/min_filter.h +++ b/libtransport/src/utils/min_filter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/stream_buffer.h b/libtransport/src/utils/stream_buffer.h index adfb696f2..dde769a55 100644 --- a/libtransport/src/utils/stream_buffer.h +++ b/libtransport/src/utils/stream_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/string_tokenizer.cc b/libtransport/src/utils/string_tokenizer.cc index a280a3c43..cb0a4a3ad 100644 --- a/libtransport/src/utils/string_tokenizer.cc +++ b/libtransport/src/utils/string_tokenizer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/suffix_strategy.h b/libtransport/src/utils/suffix_strategy.h index ee016308e..96eaed662 100644 --- a/libtransport/src/utils/suffix_strategy.h +++ b/libtransport/src/utils/suffix_strategy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: @@ -15,72 +15,88 @@ #pragma once -#include <core/manifest_format.h> +#include <hicn/transport/core/name.h> +#include <hicn/transport/errors/runtime_exception.h> namespace utils { -using transport::core::NextSegmentCalculationStrategy; +/** + * INCREMENTAL: Manifests will be received inline with the data with no specific + * assumption regarding the manifest capacity. Consumers can send interests + * using a +1 heuristic. + * + * MANIFEST_CAPACITY_BASED: manifests with capacity N have a suffix multiple of + * N+1: 0, N+1, 2(N+1) etc. Contents have a suffix incremented by 1 except when + * it conflicts with a manifest: 1, 2, ..., N, N+2, N+3, ..., 2N+1, 2N+3 + */ +enum class NextSuffixStrategy : uint8_t { + INCREMENTAL = 1, +}; class SuffixStrategy { public: - static constexpr uint32_t INVALID_SUFFIX = - std::numeric_limits<uint32_t>::max(); + static constexpr uint32_t MAX_SUFFIX = std::numeric_limits<uint32_t>::max(); + static constexpr uint8_t MAX_MANIFEST_CAPACITY = + std::numeric_limits<uint8_t>::max(); - SuffixStrategy(NextSegmentCalculationStrategy strategy) + SuffixStrategy(NextSuffixStrategy strategy, uint32_t offset = 0, + uint32_t manifest_capacity = MAX_MANIFEST_CAPACITY) : suffix_stragegy_(strategy), + next_suffix_(offset), + manifest_capacity_(manifest_capacity), total_count_(0), - final_suffix_(INVALID_SUFFIX) {} + final_suffix_(MAX_SUFFIX) {} virtual ~SuffixStrategy() = default; - virtual uint32_t checkNextSuffix() = 0; - + virtual uint32_t checkNextSuffix() const = 0; virtual uint32_t getNextSuffix() = 0; - virtual uint32_t getFinalSuffix() { return final_suffix_; } - - virtual void setFinalSuffix(std::uint32_t final_suffix) { - if (final_suffix != INVALID_SUFFIX) { - final_suffix_ = final_suffix; - } - } - - virtual uint32_t checkNextManifestSuffix() = 0; - + virtual uint32_t checkNextManifestSuffix() const = 0; virtual uint32_t getNextManifestSuffix() = 0; - virtual uint32_t checkNextContentSuffix() = 0; - + virtual uint32_t checkNextContentSuffix() const = 0; virtual uint32_t getNextContentSuffix() = 0; - virtual void reset(uint32_t offset = 0) = 0; + virtual void reset(uint32_t offset = 0) { + next_suffix_ = offset; + total_count_ = 0; + } - virtual uint32_t getManifestCapacity() = 0; + virtual uint32_t getManifestCapacity() const { return manifest_capacity_; }; - virtual void setManifestCapacity(uint32_t capacity) = 0; + virtual void setManifestCapacity(uint8_t capacity) { + manifest_capacity_ = capacity; + } - virtual uint32_t getTotalCount() { return total_count_; }; + virtual uint32_t getFinalSuffix() const { return final_suffix_; } - NextSegmentCalculationStrategy getSuffixStrategy() { - return suffix_stragegy_; + virtual void setFinalSuffix(std::uint32_t final_suffix) { + if (final_suffix != MAX_SUFFIX) { + final_suffix_ = final_suffix; + } } - protected: - inline void incrementTotalCount() { total_count_++; }; + NextSuffixStrategy getSuffixStrategy() const { return suffix_stragegy_; } + + virtual uint32_t getTotalCount() const { return total_count_; } protected: - NextSegmentCalculationStrategy suffix_stragegy_; + NextSuffixStrategy suffix_stragegy_; + std::uint32_t next_suffix_; + std::uint8_t manifest_capacity_; std::uint32_t total_count_; std::uint32_t final_suffix_; + + inline void incrementTotalCount() { total_count_++; }; }; class IncrementalSuffixStrategy : public SuffixStrategy { public: IncrementalSuffixStrategy(std::uint32_t start_offset) - : SuffixStrategy(NextSegmentCalculationStrategy::INCREMENTAL), - next_suffix_(start_offset) {} + : SuffixStrategy(NextSuffixStrategy::INCREMENTAL, start_offset) {} - TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextSuffix() override { + TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextSuffix() const override { return next_suffix_; } @@ -89,7 +105,8 @@ class IncrementalSuffixStrategy : public SuffixStrategy { return next_suffix_++; } - TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextContentSuffix() override { + TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextContentSuffix() + const override { return checkNextSuffix(); } @@ -97,7 +114,8 @@ class IncrementalSuffixStrategy : public SuffixStrategy { return getNextSuffix(); } - TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextManifestSuffix() override { + TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextManifestSuffix() + const override { return checkNextSuffix(); } @@ -105,90 +123,20 @@ class IncrementalSuffixStrategy : public SuffixStrategy { return getNextSuffix(); } - uint32_t getManifestCapacity() override { - throw errors::RuntimeException( - "No manifest capacity in IncrementalSuffixStrategy."); - } - - void setManifestCapacity(uint32_t capacity) override { - throw errors::RuntimeException( - "No manifest capacity in IncrementalSuffixStrategy."); - } - void reset(std::uint32_t offset = 0) override { next_suffix_ = offset; } - - protected: - std::uint32_t next_suffix_; -}; - -class CapacityBasedSuffixStrategy : public SuffixStrategy { - public: - CapacityBasedSuffixStrategy(std::uint32_t start_offset, - std::uint32_t manifest_capacity) - : SuffixStrategy(NextSegmentCalculationStrategy::INCREMENTAL), - next_suffix_(start_offset), - segments_in_manifest_(manifest_capacity), - current_manifest_iteration_(0) {} - - TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextSuffix() override { - return next_suffix_; - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextSuffix() override { - incrementTotalCount(); - return next_suffix_++; - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextContentSuffix() override { - return next_suffix_ % segments_in_manifest_ == 0 ? next_suffix_ - : (next_suffix_ + 1); - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextContentSuffix() override { - incrementTotalCount(); - return next_suffix_ % segments_in_manifest_ == 0 ? next_suffix_++ - : ++next_suffix_; - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t checkNextManifestSuffix() override { - return (current_manifest_iteration_ + 1) * (segments_in_manifest_ + 1); - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextManifestSuffix() override { - incrementTotalCount(); - return (current_manifest_iteration_++) * (segments_in_manifest_ + 1); - } - - TRANSPORT_ALWAYS_INLINE uint32_t getManifestCapacity() override { - return segments_in_manifest_; - } - - TRANSPORT_ALWAYS_INLINE void setManifestCapacity(uint32_t capacity) override { - segments_in_manifest_ = capacity; - } - - void reset(std::uint32_t offset = 0) override { next_suffix_ = offset; } - - protected: - std::uint32_t next_suffix_; - std::uint32_t segments_in_manifest_; - std::uint32_t current_manifest_iteration_; }; class SuffixStrategyFactory { public: static std::unique_ptr<SuffixStrategy> getSuffixStrategy( - NextSegmentCalculationStrategy strategy, uint32_t start_offset, - uint32_t manifest_capacity = 0) { + NextSuffixStrategy strategy, uint32_t start_offset = 0, + uint32_t manifest_capacity = SuffixStrategy::MAX_MANIFEST_CAPACITY) { switch (strategy) { - case NextSegmentCalculationStrategy::INCREMENTAL: + case NextSuffixStrategy::INCREMENTAL: return std::make_unique<IncrementalSuffixStrategy>(start_offset); - case NextSegmentCalculationStrategy::MANIFEST_CAPACITY_BASED: - return std::make_unique<CapacityBasedSuffixStrategy>(start_offset, - manifest_capacity); default: throw errors::RuntimeException( - "No valid NextSegmentCalculationStrategy specified."); + "No valid NextSuffixStrategy specified."); } } }; diff --git a/libtransport/src/utils/test.h b/libtransport/src/utils/test.h index e3dd619ac..b91c8cb1f 100644 --- a/libtransport/src/utils/test.h +++ b/libtransport/src/utils/test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: diff --git a/libtransport/src/utils/uri.cc b/libtransport/src/utils/uri.cc index 33eb8b45b..12b11641c 100644 --- a/libtransport/src/utils/uri.cc +++ b/libtransport/src/utils/uri.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed 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: |