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