Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef ctrlplane_db_table_partition_h 6 : #define ctrlplane_db_table_partition_h 7 : 8 : #include <mutex> 9 : 10 : #include <boost/intrusive/list.hpp> 11 : #include <tbb/spin_rw_mutex.h> 12 : 13 : #include "db/db_entry.h" 14 : 15 : class DBTableBase; 16 : class DBTable; 17 : 18 : // Table shard contained within a DBPartition. 19 : class DBTablePartBase { 20 : public: 21 : static const int kMaxIterations = 256; 22 : typedef boost::intrusive::member_hook<DBEntryBase, 23 : boost::intrusive::list_member_hook<>, 24 : &DBEntryBase::chg_list_> ChangeListMember; 25 : 26 : typedef boost::intrusive::list<DBEntryBase, ChangeListMember> ChangeList; 27 : 28 : 29 2075401 : DBTablePartBase(DBTableBase *tbl_base, int index) 30 2075401 : : parent_(tbl_base), index_(index) { 31 2075216 : } 32 : 33 : // Input processing stage for DBRequests. Called from per-partition thread. 34 : virtual void Process(DBClient *client, DBRequest *req) = 0; 35 : 36 : // Enqueue a change notification. Deferred until the RunNotify stage. 37 : void Notify(DBEntryBase *entry); 38 : 39 : // Run the notification queue. 40 : bool RunNotify(); 41 : 42 17115633 : DBTableBase *parent() { return parent_; } 43 4517776 : int index() const { return index_; } 44 : 45 : virtual void Remove(DBEntryBase *) = 0; 46 : 47 : void Delete(DBEntryBase *); 48 : 49 : // Walk functions 50 : virtual DBEntryBase *lower_bound(const DBEntryBase *key) = 0; 51 : virtual DBEntryBase *GetFirst() = 0; 52 : virtual DBEntryBase *GetNext(const DBEntryBase *) = 0; 53 : 54 19961405 : tbb::spin_rw_mutex &dbstate_mutex() { 55 19961405 : return dbstate_mutex_; 56 : } 57 : 58 2075785 : virtual ~DBTablePartBase() {}; 59 : private: 60 : tbb::spin_rw_mutex dbstate_mutex_; 61 : DBTableBase *parent_; 62 : int index_; 63 : ChangeList change_list_; 64 : DISALLOW_COPY_AND_ASSIGN(DBTablePartBase); 65 : }; 66 : 67 : class DBTablePartition : public DBTablePartBase { 68 : public: 69 : typedef boost::intrusive::member_hook<DBEntry, 70 : boost::intrusive::set_member_hook<>, 71 : &DBEntry::node_> SetMember; 72 : typedef boost::intrusive::set<DBEntry, SetMember> Tree; 73 : 74 : DBTablePartition(DBTable *parent, int index); 75 : 76 : /////////////////////////////////////////////////////////////// 77 : // Virtual functions from DBTableBase implemented by DBTable 78 : /////////////////////////////////////////////////////////////// 79 : void Process(DBClient *client, DBRequest *req); 80 : // Returns the matching route or next in lex order 81 : virtual DBEntry *lower_bound(const DBEntryBase *entry); 82 : 83 : // Returns the next route (Doesn't search). Threaded walk 84 : virtual DBEntry *GetNext(const DBEntryBase *entry); 85 : 86 : virtual DBEntry *GetFirst(); 87 : 88 : /////////////////////////////////////////////////////////// 89 : // Methods used in implementing DBTablePartition 90 : /////////////////////////////////////////////////////////// 91 : 92 : // Add a DB Entry 93 : virtual void Add(DBEntry *entry); 94 : 95 : // Generate Change notification for an entry 96 : virtual void Change(DBEntry *entry); 97 : 98 : // Remove an entry from DB Table. Entry will not be accessible from 99 : // DB anymore 100 : virtual void Remove(DBEntryBase *entry); 101 : 102 : // Find DB Entry. Get key from from argument 103 : DBEntry *Find(const DBEntry *entry); 104 : const DBEntry *Find(const DBEntry *entry) const; 105 : DBEntry *FindNoLock(const DBEntry *entry); 106 : 107 : // Find DB Entry. Get key from from argument 108 : DBEntry *Find(const DBRequestKey *key); 109 : DBEntry *FindNoLock(const DBRequestKey *key); 110 : 111 : // Find the next in lex order 112 : DBEntry *FindNext(const DBRequestKey *key); 113 : 114 : DBTable *table(); 115 5614298 : size_t size() const { return tree_.size(); } 116 : 117 : // Add an entry to DB without allocating 118 : void AddWithoutAlloc(DBEntry *entry); 119 : 120 : // Remove an entry from DB without delete 121 : void RemoveWithoutDelete(DBEntry *entry); 122 : 123 : private: 124 : DBEntry *FindInternal(const DBEntry *entry); 125 : const DBEntry *FindInternal(const DBEntry *entry) const; 126 : 127 : mutable std::mutex mutex_; 128 : Tree tree_; 129 : DISALLOW_COPY_AND_ASSIGN(DBTablePartition); 130 : }; 131 : 132 : #endif