1+ /* *
2+ * \file
3+ * \author Damir Zainullin <[email protected] > 4+ * \brief CacheRowSpan implementation.
5+ */
6+ /*
7+ * Copyright (C) 2023 CESNET
8+ *
9+ * LICENSE TERMS
10+ *
11+ * Redistribution and use in source and binary forms, with or without
12+ * modification, are permitted provided that the following conditions
13+ * are met:
14+ * 1. Redistributions of source code must retain the above copyright
15+ * notice, this list of conditions and the following disclaimer.
16+ * 2. Redistributions in binary form must reproduce the above copyright
17+ * notice, this list of conditions and the following disclaimer in
18+ * the documentation and/or other materials provided with the
19+ * distribution.
20+ * 3. Neither the name of the Company nor the names of its contributors
21+ * may be used to endorse or promote products derived from this
22+ * software without specific prior written permission.
23+ */
24+
25+ #include " cacheRowSpan.hpp"
26+
27+ #include < algorithm>
28+
29+ #include " fragmentationCache/timevalUtils.hpp"
30+
31+ namespace ipxp {
32+
33+ CacheRowSpan::CacheRowSpan (FlowRecord** begin, size_t count) noexcept
34+ : m_begin(begin), m_count(count)
35+ {
36+ }
37+
38+ std::optional<size_t > CacheRowSpan::find_by_hash (uint64_t hash) const noexcept
39+ {
40+ auto it = std::find_if (m_begin, m_begin + m_count, [&](const FlowRecord* flow) {
41+ return flow->belongs (hash);
42+ });
43+ if (it == m_begin + m_count) {
44+ return std::nullopt ;
45+ }
46+ return it - m_begin;
47+ }
48+
49+ void CacheRowSpan::advance_flow_to (size_t from, size_t to) noexcept
50+ {
51+ if (from < to) {
52+ std::rotate (m_begin + from, m_begin + from + 1 , m_begin + to + 1 );
53+ return ;
54+ }
55+ std::rotate (m_begin + to, m_begin + from, m_begin + from + 1 );
56+ }
57+
58+ void CacheRowSpan::advance_flow (size_t flow_index) noexcept
59+ {
60+ advance_flow_to (flow_index, 0 );
61+ }
62+
63+ std::optional<size_t > CacheRowSpan::find_empty () const noexcept
64+ {
65+ auto it = std::find_if (m_begin, m_begin + m_count, [](const FlowRecord* flow) {
66+ return flow->is_empty ();
67+ });
68+ if (it == m_begin + m_count) {
69+ return std::nullopt ;
70+ }
71+ return it - m_begin;
72+ }
73+
74+ #ifdef WITH_CTT
75+ size_t CacheRowSpan::find_victim (const timeval& now) const noexcept
76+ {
77+ FlowRecord* const * victim = m_begin + m_count - 1 ;
78+ auto it = std::find_if (m_begin, m_begin + m_count, [&](FlowRecord* const & flow) {
79+ if (!flow->is_in_ctt ) {
80+ victim = &flow;
81+ }
82+ return flow->is_waiting_for_export && now > flow->export_time ;
83+ });
84+ if (it == m_begin + m_count) {
85+ return victim - m_begin;
86+ }
87+ return it - m_begin;
88+ }
89+ #endif /* WITH_CTT */
90+
91+ } // ipxp
0 commit comments