.. _program_listing_file_completion_table.cpp: Program Listing for File completion_table.cpp ============================================= |exhale_lsh| :ref:`Return to documentation for file ` (``completion_table.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "completion_table.hpp" #include "log.hpp" #include typedef enum { CT_OK, CT_EMPTY, CT_ERR, } ct_return; CompletionTable::CompletionTable() : m_rd(UINT32_MAX), m_last_pushed_addr(0x0), m_last_provided_addr(0x0), m_current_table(&m_table_a), m_wrap_table(&m_table_b) {} // When a chunk has been decoded void CompletionTable::push(uint32_t addr) { if (addr >= m_rd || m_rd == UINT32_MAX) { (*m_current_table)[addr]++; } else { (*m_wrap_table)[addr]++; } m_last_pushed_addr = addr; // swap tables if current is empty if (m_current_table->empty() && !m_wrap_table->empty()) { m_rd = m_wrap_table->begin()->first; std::swap(m_current_table, m_wrap_table); } } // When a completion object is read int CompletionTable::update(uint32_t addr) { if (m_current_table->empty() && m_wrap_table->empty()) { return CT_EMPTY; } m_last_provided_addr = m_rd; if (m_rd <= addr || m_rd == UINT32_MAX) { auto it = m_current_table->find(addr); if (it == m_current_table->end()) { LOG_WARN("Completion object provided block addr 0x%x not in current table", addr); return CT_ERR; } --(it->second); if (it->second == 0) { if (it == m_current_table->begin()) { m_rd = m_current_table->size() > 1 ? std::next(it, 1)->first : it->first; } m_current_table->erase(it); } } else { auto it = m_wrap_table->find(addr); if (it == m_wrap_table->end()) { return CT_ERR; } --(it->second); if (it->second == 0) { m_wrap_table->erase(it); } } return CT_OK; } uint32_t CompletionTable::get_count(uint32_t addr) const { uint32_t count = 0; if (m_rd <= addr || m_rd == UINT32_MAX) { if (m_current_table->count(addr) == 1) { count = m_current_table->at(addr); } } else { if (m_wrap_table->count(addr) == 1) { count = m_wrap_table->at(addr); } } return count; } uint32_t CompletionTable::get_rd() const { return m_rd; } size_t CompletionTable::get_entries() const { return (m_current_table->size() + m_wrap_table->size()); } bool CompletionTable::is_empty() const { return (m_current_table->empty() and m_wrap_table->empty()); } void CompletionTable::inspect() const { LOG_INFO("Completion table contains %lu entries", (m_current_table->size() + m_wrap_table->size())); int printed{0}, max_printout{100}; for (auto &c : *m_current_table) { LOG_INFO("CT Block 0x%08x count %u", c.first, c.second); ++printed; if (printed == max_printout) { break; } } for (auto &w : *m_wrap_table) { LOG_INFO("WT Block 0x%08x count %u", w.first, w.second); ++printed; if (printed == max_printout) { break; } } } uint32_t CompletionTable::get_previous_rd() const { return m_last_provided_addr; }