Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "base/task.h" 6 : #include "db/db.h" 7 : #include "db/db_partition.h" 8 : #include "db/db_table.h" 9 : #include "db/db_table_walker.h" 10 : #include "db/db_table_walk_mgr.h" 11 : #include "tbb/task_scheduler_init.h" 12 : 13 : using namespace std; 14 : 15 : int DB::partition_count_; 16 : 17 : // factory map is declared as a local static variable in order to avoid 18 : // static initialization order dependencies. 19 290157 : DB::FactoryMap *DB::factories() { 20 290157 : static FactoryMap factory_map; 21 290157 : return &factory_map; 22 : } 23 : 24 1494 : void DB::RegisterFactory(const std::string &prefix, CreateFunction create_fn) { 25 1494 : DB::factories()->insert(make_pair(prefix, create_fn)); 26 1494 : } 27 : 28 13 : void DB::ClearFactoryRegistry() { 29 13 : DB::factories()->clear(); 30 13 : } 31 : 32 40920184 : int DB::PartitionCount() { 33 : 34 : // Initialize static partition_count_. 35 40920184 : if (!partition_count_) { 36 181 : partition_count_ = TaskScheduler::GetInstance()->HardwareThreadCount(); 37 : } 38 40926885 : return partition_count_; 39 : } 40 : 41 : // For unit testing only. 42 4 : void DB::SetPartitionCount(int partition_count) { 43 4 : partition_count_ = partition_count; 44 4 : } 45 : 46 27398 : DB::DB(int task_id) : task_id_(task_id) { 47 27398 : if (task_id == -1) 48 19186 : task_id_ = TaskScheduler::GetInstance()->GetTaskId("db::DBTable"); 49 27398 : walker_.reset(new DBTableWalker(task_id_)); 50 27398 : walk_mgr_.reset(new DBTableWalkMgr()); 51 135940 : for (int i = 0; i < PartitionCount(); i++) { 52 108542 : partitions_.push_back(new DBPartition(this, i)); 53 : } 54 27398 : } 55 : 56 27398 : DB::~DB() { 57 27398 : Clear(); 58 27398 : } 59 : 60 2340068 : DBPartition *DB::GetPartition(int index) { 61 2340068 : return partitions_[index]; 62 : } 63 : 64 6254906 : const DBPartition *DB::GetPartition(int index) const { 65 6254906 : return partitions_[index]; 66 : } 67 : 68 1522023 : DBTableBase *DB::FindTable(const string &name) { 69 1522023 : TableMap::iterator loc = tables_.find(name); 70 1521670 : if (loc != tables_.end()) { 71 1465364 : DBTableBase *tbl_base = loc->second; 72 1465363 : return tbl_base; 73 : } 74 56346 : return NULL; 75 : } 76 : 77 0 : DB::iterator DB::FindTableIter(const string &name) { 78 0 : return tables_.find(name); 79 : } 80 : 81 1232820 : void DB::AddTable(DBTableBase *tbl_base) { 82 : pair<TableMap::iterator, bool> result = 83 1232820 : tables_.insert(make_pair(tbl_base->name(), tbl_base)); 84 1232820 : assert(result.second); 85 1232820 : } 86 : 87 288603 : void DB::RemoveTable(DBTableBase *tbl_base) { 88 288603 : tables_.erase(tbl_base->name()); 89 288603 : } 90 : 91 1664784 : bool DB::IsDBQueueEmpty() const { 92 7799186 : for (int i = 0; i < PartitionCount(); i++) { 93 6254906 : if (!GetPartition(i)->IsDBQueueEmpty()) return false; 94 : } 95 : 96 1544280 : return true; 97 : } 98 : 99 288651 : DBTableBase *DB::CreateTable(const string &name) { 100 288651 : FactoryMap *factory_map = factories(); 101 288649 : string prefix = name; 102 527911 : while (prefix.size()) { 103 527899 : FactoryMap::iterator loc = factory_map->find(prefix); 104 527656 : if (loc != factory_map->end()) { 105 288604 : DBTableBase *tbl_base = (loc->second)(this, name); 106 288628 : std::scoped_lock lock(mutex_); 107 288673 : tables_.insert(make_pair(name, tbl_base)); 108 288673 : return tbl_base; 109 288673 : } 110 239156 : size_t index = prefix.find('.'); 111 239222 : if (index == string::npos) { 112 0 : break; 113 : } 114 239222 : if (index == (prefix.length()-1)) { 115 0 : break; 116 : } 117 239235 : prefix = prefix.substr(index+1); 118 : } 119 0 : return NULL; 120 288673 : } 121 : 122 30 : DBGraph *DB::GetGraph(const std::string &name) { 123 30 : GraphMap::iterator loc = graph_map_.find(name); 124 30 : if (loc != graph_map_.end()) { 125 30 : return loc->second; 126 : } 127 0 : return NULL; 128 : } 129 : 130 6 : void DB::SetGraph(const std::string &name, DBGraph *graph) { 131 : pair<GraphMap::iterator, bool> result = 132 6 : graph_map_.insert(make_pair(name, graph)); 133 6 : assert(result.second); 134 6 : } 135 : 136 10 : void DB::SetQueueDisable(bool disable) { 137 44 : for (int i = 0; i < PartitionCount(); i++) { 138 34 : partitions_[i]->SetQueueDisable(disable); 139 : } 140 10 : } 141 : 142 35457 : void DB::Clear() { 143 35457 : STLDeleteElements(&tables_); 144 35457 : STLDeleteValues(&partitions_); 145 35457 : }