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 : 12 : using namespace std; 13 : 14 : int DB::partition_count_; 15 : 16 : // factory map is declared as a local static variable in order to avoid 17 : // static initialization order dependencies. 18 291327 : DB::FactoryMap *DB::factories() { 19 291327 : static FactoryMap factory_map; 20 291323 : return &factory_map; 21 : } 22 : 23 1590 : void DB::RegisterFactory(const std::string &prefix, CreateFunction create_fn) { 24 1590 : DB::factories()->insert(make_pair(prefix, create_fn)); 25 1590 : } 26 : 27 16 : void DB::ClearFactoryRegistry() { 28 16 : DB::factories()->clear(); 29 16 : } 30 : 31 41742772 : int DB::PartitionCount() { 32 : 33 : // Initialize static partition_count_. 34 41742772 : if (!partition_count_) { 35 184 : partition_count_ = TaskScheduler::GetInstance()->HardwareThreadCount(); 36 : } 37 41746277 : return partition_count_; 38 : } 39 : 40 : // For unit testing only. 41 4 : void DB::SetPartitionCount(int partition_count) { 42 4 : partition_count_ = partition_count; 43 4 : } 44 : 45 27401 : DB::DB(int task_id) : task_id_(task_id) { 46 27401 : if (task_id == -1) 47 19189 : task_id_ = TaskScheduler::GetInstance()->GetTaskId("db::DBTable"); 48 27401 : walker_.reset(new DBTableWalker(task_id_)); 49 27401 : walk_mgr_.reset(new DBTableWalkMgr()); 50 135955 : for (int i = 0; i < PartitionCount(); i++) { 51 108554 : partitions_.push_back(new DBPartition(this, i)); 52 : } 53 27401 : } 54 : 55 27401 : DB::~DB() { 56 27401 : Clear(); 57 27401 : } 58 : 59 2416200 : DBPartition *DB::GetPartition(int index) { 60 2416200 : return partitions_[index]; 61 : } 62 : 63 6252754 : const DBPartition *DB::GetPartition(int index) const { 64 6252754 : return partitions_[index]; 65 : } 66 : 67 1568205 : DBTableBase *DB::FindTable(const string &name) { 68 1568205 : TableMap::iterator loc = tables_.find(name); 69 1566955 : if (loc != tables_.end()) { 70 1510672 : DBTableBase *tbl_base = loc->second; 71 1510589 : return tbl_base; 72 : } 73 56338 : return NULL; 74 : } 75 : 76 0 : DB::iterator DB::FindTableIter(const string &name) { 77 0 : return tables_.find(name); 78 : } 79 : 80 1233267 : void DB::AddTable(DBTableBase *tbl_base) { 81 : pair<TableMap::iterator, bool> result = 82 1233267 : tables_.insert(make_pair(tbl_base->name(), tbl_base)); 83 1233267 : assert(result.second); 84 1233267 : } 85 : 86 289642 : void DB::RemoveTable(DBTableBase *tbl_base) { 87 289642 : tables_.erase(tbl_base->name()); 88 289642 : } 89 : 90 1665200 : bool DB::IsDBQueueEmpty() const { 91 7796175 : for (int i = 0; i < PartitionCount(); i++) { 92 6252754 : if (!GetPartition(i)->IsDBQueueEmpty()) return false; 93 : } 94 : 95 1543421 : return true; 96 : } 97 : 98 289726 : DBTableBase *DB::CreateTable(const string &name) { 99 289726 : FactoryMap *factory_map = factories(); 100 289714 : string prefix = name; 101 529973 : while (prefix.size()) { 102 529957 : FactoryMap::iterator loc = factory_map->find(prefix); 103 529579 : if (loc != factory_map->end()) { 104 289622 : DBTableBase *tbl_base = (loc->second)(this, name); 105 289686 : std::scoped_lock lock(mutex_); 106 289786 : tables_.insert(make_pair(name, tbl_base)); 107 289787 : return tbl_base; 108 289787 : } 109 240102 : size_t index = prefix.find('.'); 110 240215 : if (index == string::npos) { 111 0 : break; 112 : } 113 240215 : if (index == (prefix.length()-1)) { 114 0 : break; 115 : } 116 240220 : prefix = prefix.substr(index+1); 117 : } 118 0 : return NULL; 119 289787 : } 120 : 121 30 : DBGraph *DB::GetGraph(const std::string &name) { 122 30 : GraphMap::iterator loc = graph_map_.find(name); 123 30 : if (loc != graph_map_.end()) { 124 30 : return loc->second; 125 : } 126 0 : return NULL; 127 : } 128 : 129 6 : void DB::SetGraph(const std::string &name, DBGraph *graph) { 130 : pair<GraphMap::iterator, bool> result = 131 6 : graph_map_.insert(make_pair(name, graph)); 132 6 : assert(result.second); 133 6 : } 134 : 135 10 : void DB::SetQueueDisable(bool disable) { 136 44 : for (int i = 0; i < PartitionCount(); i++) { 137 34 : partitions_[i]->SetQueueDisable(disable); 138 : } 139 10 : } 140 : 141 35460 : void DB::Clear() { 142 35460 : STLDeleteElements(&tables_); 143 35460 : STLDeleteValues(&partitions_); 144 35460 : }