common/countertable.h (125 lines of code) (raw):

#pragma once #include <assert.h> #include <string> #include <vector> #include "table.h" #include "luatable.h" namespace swss { struct Counter; class CounterTable: public TableBase { public: CounterTable(const DBConnector *db, const std::string &tableName=COUNTERS_TABLE); public: bool get(const Counter &counter, const std::string &key, std::vector<FieldValueTuple> &values); bool hget(const Counter &counter, const std::string &key, const std::string &field, std::string &value); const std::unique_ptr<DBConnector>& getCountersDB() const { return m_countersDB; } const std::unique_ptr<DBConnector>& getGbcountersDB() const { return m_gbcountersDB; } private: std::unique_ptr<DBConnector> m_countersDB; std::unique_ptr<DBConnector> m_gbcountersDB; }; template <typename T> class KeyCache { private: std::function<void (const CounterTable& t)> m_cachingFunc; std::unordered_map<std::string, T> m_keyMap; bool m_enabled; KeyCache (const KeyCache&) = delete; public: KeyCache(const std::function<void (const CounterTable& t)> &f) :m_cachingFunc(f), m_enabled(false) { } bool enabled() const { return m_enabled; } void enable(const CounterTable& t) { refresh(t); m_enabled = true; } void disable() { m_keyMap.clear(); m_enabled = false; } bool empty() const { return m_keyMap.empty(); } void clear() { m_keyMap.clear(); } const T& at(const std::string &name) const { return m_keyMap.at(name); } #if defined(SWIG) && defined(SWIGPYTHON) %pythoncode %{ def __getitem__(self, name): return self.at(name) def get(self, name, default=None): try: return self.at(name) except IndexError: return default %} #endif template <class InputIterator> void insert(InputIterator first, InputIterator last) { m_keyMap.insert(first, last); } void insert(const std::string &name, const T &key) { m_keyMap.insert({name, key}); } void refresh(const CounterTable& t) { m_keyMap.clear(); m_cachingFunc(t); } }; class Counter { public: typedef std::pair<int, std::string> KeyPair; virtual const std::string& getLuaScript() const { return defaultLuaScript; } virtual std::vector<std::string> getLuaArgv() const { return {}; } virtual bool usingLuaTable(const CounterTable&, const std::string &name) const { return false; } virtual std::vector<std::string> getLuaKeys(const CounterTable&, const std::string &name) const { return {}; } virtual KeyPair getKey(const CounterTable&, const std::string &name) const = 0; virtual ~Counter() = default; private: static const std::string defaultLuaScript; }; class PortCounter: public Counter { public: enum class Mode {UNION, ASIC, SYSTEMSIDE, LINESIDE}; PortCounter(Mode mode=Mode::UNION); ~PortCounter() = default; const std::string& getLuaScript() const override; bool usingLuaTable(const CounterTable&, const std::string &name) const override; std::vector<std::string> getLuaKeys(const CounterTable&, const std::string &name) const override; KeyPair getKey(const CounterTable&, const std::string &name) const override; static KeyCache<std::string>& keyCacheInstance(void); private: Mode m_mode; std::string m_luaScript; static std::unique_ptr<KeyCache<std::string>> keyCachePtr; static void cachingKey(const CounterTable& t); }; class MacsecCounter: public Counter { public: MacsecCounter() = default; ~MacsecCounter() = default; KeyPair getKey(const CounterTable&, const std::string &name) const override; static KeyCache<KeyPair>& keyCacheInstance(void); private: static std::unique_ptr<KeyCache<KeyPair>> keyCachePtr; static void cachingKey(const CounterTable& t); }; }