LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/base - label_block.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 68 69 98.6 %
Date: 2026-11-09 02:10:49 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "base/label_block.h"
       7             : 
       8             : #include <stdio.h>
       9             : 
      10             : #include <cassert>
      11             : #include <string>
      12             : 
      13             : using std::string;
      14             : 
      15       10052 : LabelBlockManager::LabelBlockManager() {
      16       10052 :     refcount_ = 0;
      17       10052 : }
      18             : 
      19       10052 : LabelBlockManager::~LabelBlockManager() {
      20       10052 :     assert(blocks_.size() == 0);
      21       10052 : }
      22             : 
      23        1791 : LabelBlockPtr LabelBlockManager::LocateBlock(uint32_t first, uint32_t last) {
      24        1791 :     std::scoped_lock lock(mutex_);
      25             : 
      26        1792 :     for (LabelBlockList::iterator it = blocks_.begin();
      27        1975 :          it != blocks_.end(); ++it) {
      28         476 :         LabelBlock *block = *it;
      29         476 :         if (block->first_ == first && block->last_ == last) {
      30         293 :             return LabelBlockPtr(block);
      31             :         }
      32             :     }
      33             : 
      34        1499 :     LabelBlock *block = new LabelBlock(this, first, last);
      35        1499 :     blocks_.push_back(block);
      36        1498 :     return LabelBlockPtr(block);
      37        1792 : }
      38             : 
      39        1499 : void LabelBlockManager::RemoveBlock(LabelBlock *block) {
      40        1499 :     for (LabelBlockList::iterator it = blocks_.begin();
      41        1590 :          it != blocks_.end(); ++it) {
      42        1590 :         if (*it == block) {
      43        1499 :             blocks_.erase(it);
      44        1499 :             return;
      45             :         }
      46             :     }
      47           0 :     assert(false);
      48             : }
      49             : 
      50        1067 : size_t LabelBlockManager::size() {
      51        1067 :     std::scoped_lock lock(mutex_);
      52        2134 :     return blocks_.size();
      53        1067 : }
      54             : 
      55        6426 : LabelBlock::LabelBlock(uint32_t first, uint32_t last)
      56        6426 :     : block_manager_(NULL),
      57        6426 :       first_(first),
      58        6426 :       last_(last),
      59        6426 :       prev_pos_(BitSet::npos) {
      60        6426 :       refcount_ = 0;
      61        6427 : }
      62             : 
      63        1499 : LabelBlock::LabelBlock(
      64        1499 :         LabelBlockManager *block_manager, uint32_t first, uint32_t last)
      65        1499 :     : block_manager_(block_manager),
      66        1499 :       first_(first),
      67        1499 :       last_(last),
      68        1499 :       prev_pos_(BitSet::npos) {
      69        1499 :       refcount_ = 0;
      70        1499 : }
      71             : 
      72        7926 : LabelBlock::~LabelBlock() {
      73        7926 :     assert(used_bitset_.empty());
      74        7926 :     if (block_manager_)
      75        1499 :         block_manager_->RemoveBlock(this);
      76        7926 : }
      77             : 
      78        5515 : uint32_t LabelBlock::AllocateLabel() {
      79        5515 :     std::scoped_lock lock(mutex_);
      80             : 
      81             :     size_t pos;
      82        6043 :     for (int idx = 0; idx < 2; prev_pos_ = BitSet::npos, idx++) {
      83        6033 :         if (prev_pos_ == BitSet::npos) {
      84        2126 :             pos = used_bitset_.find_first_clear();
      85             :         } else {
      86        3907 :             pos = used_bitset_.find_next_clear(prev_pos_);
      87             :         }
      88             : 
      89        6033 :         if (first_ + pos <= last_) {
      90        5505 :             used_bitset_.set(pos);
      91        5505 :             prev_pos_ = pos;
      92        5505 :             return static_cast<uint32_t>(first_ + pos);
      93             :         }
      94             :     }
      95             : 
      96          10 :     return 0;
      97        5515 : }
      98             : 
      99        5505 : void LabelBlock::ReleaseLabel(uint32_t value) {
     100        5505 :     std::scoped_lock lock(mutex_);
     101             : 
     102        5505 :     assert(value >= first_ && value <= last_);
     103        5505 :     size_t pos = value - first_;
     104        5505 :     used_bitset_.reset(pos);
     105        5505 : }
     106             : 
     107           8 : string LabelBlock::ToString() const {
     108             :     char repr[32];
     109           8 :     snprintf(repr, sizeof(repr), "%u-%u", first_, last_);
     110           8 :     return repr;
     111             : }

Generated by: LCOV version 1.14