diff --git a/userspace/engine/indexed_vector.h b/userspace/engine/indexed_vector.h new file mode 100644 index 00000000..cafb17e9 --- /dev/null +++ b/userspace/engine/indexed_vector.h @@ -0,0 +1,133 @@ +/* +Copyright (C) 2022 The Falco Authors. + +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. +*/ + +#pragma once + +#include +#include +#include + +/*! + \brief Simple wrapper of std::vector that allows random access + through both numeric and string indexes with O(1) complexity. +*/ +template +class indexed_vector +{ +public: + /*! + \brief Returns the number of elements + */ + virtual inline uint32_t size() + { + return m_entries.size(); + } + + /*! + \brief Returns true if the vector is empty + */ + virtual inline bool empty() + { + return m_entries.empty(); + } + + /*! + \brief Removes all the elements + */ + virtual inline void clear() + { + m_entries.clear(); + m_index.clear(); + } + + /*! + \brief Inserts a new element in the vector with a given string index + and returns its numeric index. String indexes are unique in + the vector. If no element is already present with the given string + index, then the provided element is added to the vector and its + numeric index is assigned as the next free slot in the vector. + Otherwise, the existing element gets overwritten with the contents + of the provided one and the numeric index of the existing element + is returned. + \param entry Element to add in the vector + \param index String index of the element to be added in the vector + \return The numeric index of the element + */ + virtual inline uint32_t insert(T& entry, const std::string& index) + { + uint32_t id; + auto prev = m_index.find(index); + if (prev != m_index.end()) { + id = prev->second; + m_entries[id - 1] = entry; + return id; + } + id = m_entries.size() + 1; + m_entries.push_back(entry); + m_index[index] = id; + return id; + } + + /*! + \brief Returns a pointer to the element at the given numeric index, + or nullptr if no element exists at the given index. + */ + virtual inline T* at(uint32_t id) + { + if (id <= m_entries.size()) + { + return &*(m_entries.begin() + id - 1);; + } + return nullptr; + } + + /*! + \brief Returns a pointer to the element at the given string index, + or nullptr if no element exists at the given index. + */ + virtual inline T* at(const std::string& index) + { + auto it = m_index.find(index); + if (it != m_index.end()) { + return at(it->second); + } + return nullptr; + } + + virtual inline typename std::vector::iterator begin() + { + return m_entries.begin(); + } + + virtual inline typename std::vector::iterator end() + { + return m_entries.end(); + } + + virtual inline typename std::vector::const_iterator begin() const + { + return m_entries.begin(); + } + + virtual inline typename std::vector::const_iterator end() const + { + return m_entries.end(); + } + +private: + std::vector m_entries; + std::map m_index; +};