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