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 10060 : LabelBlockManager::LabelBlockManager() { 15 10060 : refcount_ = 0; 16 10060 : } 17 : 18 10060 : LabelBlockManager::~LabelBlockManager() { 19 10060 : assert(blocks_.size() == 0); 20 10060 : } 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 862 : LabelBlock *block = *it; 28 862 : if (block->first_ == first && block->last_ == last) { 29 679 : return LabelBlockPtr(block); 30 : } 31 : } 32 : 33 1113 : LabelBlock *block = new LabelBlock(this, first, last); 34 1113 : blocks_.push_back(block); 35 1113 : return LabelBlockPtr(block); 36 1792 : } 37 : 38 1113 : void LabelBlockManager::RemoveBlock(LabelBlock *block) { 39 1113 : for (LabelBlockList::iterator it = blocks_.begin(); 40 1203 : it != blocks_.end(); ++it) { 41 1203 : if (*it == block) { 42 1113 : blocks_.erase(it); 43 1113 : return; 44 : } 45 : } 46 0 : assert(false); 47 : } 48 : 49 1066 : size_t LabelBlockManager::size() { 50 1066 : std::scoped_lock lock(mutex_); 51 2134 : return blocks_.size(); 52 1067 : } 53 : 54 6346 : LabelBlock::LabelBlock(uint32_t first, uint32_t last) 55 6346 : : block_manager_(NULL), 56 6346 : first_(first), 57 6346 : last_(last), 58 6346 : prev_pos_(BitSet::npos) { 59 6346 : refcount_ = 0; 60 6346 : } 61 : 62 1113 : LabelBlock::LabelBlock( 63 1113 : LabelBlockManager *block_manager, uint32_t first, uint32_t last) 64 1113 : : block_manager_(block_manager), 65 1113 : first_(first), 66 1113 : last_(last), 67 1113 : prev_pos_(BitSet::npos) { 68 1113 : refcount_ = 0; 69 1113 : } 70 : 71 7459 : LabelBlock::~LabelBlock() { 72 7459 : assert(used_bitset_.empty()); 73 7459 : if (block_manager_) 74 1113 : block_manager_->RemoveBlock(this); 75 7459 : } 76 : 77 5623 : uint32_t LabelBlock::AllocateLabel() { 78 5623 : std::scoped_lock lock(mutex_); 79 : 80 : size_t pos; 81 6179 : for (int idx = 0; idx < 2; prev_pos_ = BitSet::npos, idx++) { 82 6166 : if (prev_pos_ == BitSet::npos) { 83 2174 : pos = used_bitset_.find_first_clear(); 84 : } else { 85 3992 : pos = used_bitset_.find_next_clear(prev_pos_); 86 : } 87 : 88 6166 : if (first_ + pos <= last_) { 89 5610 : used_bitset_.set(pos); 90 5610 : prev_pos_ = pos; 91 5610 : return static_cast<uint32_t>(first_ + pos); 92 : } 93 : } 94 : 95 13 : return 0; 96 5623 : } 97 : 98 5610 : void LabelBlock::ReleaseLabel(uint32_t value) { 99 5610 : std::scoped_lock lock(mutex_); 100 : 101 5610 : assert(value >= first_ && value <= last_); 102 5610 : size_t pos = value - first_; 103 5610 : used_bitset_.reset(pos); 104 5610 : } 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 : }