From a8c1343218aed35d2d74e6522e7803f58c8f1fb6 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 7 Dec 2014 14:45:33 +0100 Subject: [PATCH] added polling by priority --- src/lib/ebus/message.cpp | 42 +++++++++++++++++++++++++-- src/lib/ebus/message.h | 61 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 96 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/lib/ebus/message.cpp diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp old mode 100644 new mode 100755 index 4e245ae0..ed8aa0a4 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -36,7 +36,7 @@ Message::Message(const string clazz, const string name, const bool isSet, m_isPassive(isPassive), m_comment(comment), m_srcAddress(srcAddress), m_dstAddress(dstAddress), m_id(id), m_data(data), m_pollPriority(pollPriority), - m_lastUpdateTime(0) + m_lastUpdateTime(0), m_pollCount(0), m_lastPollTime(0) { int exp = 7; unsigned long long key = (unsigned long long)(id.size()-2) << (8 * exp + 5); @@ -269,7 +269,7 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma result = m_data->write(input, pt_masterData, master, m_id.size() - 2, separator); if (result != RESULT_OK) return result; - masterData = SymbolString(master); + masterData = SymbolString(master, true); return result; } @@ -298,6 +298,18 @@ result_t Message::decode(const PartType partType, SymbolString& data, return RESULT_OK; } +bool Message::isLessPollWeight(Message* other) { + if (m_pollPriority * m_pollCount < other->m_pollPriority * other->m_pollCount) + return true; + if (m_pollPriority < other->m_pollPriority) + return true; + if (m_lastPollTime < other->m_lastPollTime) + return true; + + return false; +} + + result_t MessageMap::add(Message* message) { unsigned long long pkey = message->getKey(); @@ -318,6 +330,7 @@ result_t MessageMap::add(Message* message) } m_messagesByName[key] = message; + m_messageCount++; key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // also store without class m_messagesByName[key] = message; // last key without class overrides previous @@ -331,7 +344,8 @@ result_t MessageMap::add(Message* message) m_passiveMessagesByKey[pkey] = message; } - //m_pollMessages.push() + if (message->getPollPriority() > 0) + m_pollMessages.push(message); return RESULT_OK; } @@ -418,12 +432,34 @@ Message* MessageMap::find(SymbolString& master) void MessageMap::clear() { + // clear poll messages + while (m_pollMessages.empty() == false) { + m_pollMessages.top(); + m_pollMessages.pop(); + } + // free message instances for (map::iterator it=m_messagesByName.begin(); it!=m_messagesByName.end(); it++) { if (it->first[0] != '-') // avoid double free delete it->second; it->second = NULL; } + // clear messages by name + m_messageCount = 0; m_messagesByName.clear(); + // clear messages by key m_passiveMessagesByKey.clear(); + m_minIdLength = 4; m_maxIdLength = 0; } + +Message* MessageMap::getNextPoll() +{ + if (m_pollMessages.empty() == true) + return NULL; + Message* ret = m_pollMessages.top(); + m_pollMessages.pop(); + ret->m_pollCount++; + time(&(ret->m_lastPollTime)); + m_pollMessages.push(ret); // re-insert at new position + return ret; +} diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index a5bef802..b26d240b 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -29,11 +29,14 @@ using namespace std; +class MessageMap; + /** * @brief Defines parameters of a message sent or received on the bus. */ class Message { + friend class MessageMap; public: /** @@ -151,11 +154,24 @@ public: string getLastValue() { return m_lastValue; } /** - * @brief Get the system time when @a m_lastValue was updated. - * @return the system time when @a m_lastValue was updated, or 0 if this message was not decoded yet. + * @brief Get the time when @a m_lastValue was updated. + * @return the time when @a m_lastValue was updated, or 0 if this message was not decoded yet. */ time_t getLastUpdateTime() { return m_lastUpdateTime; } + /** + * @brief Get the time when this message was last polled for. + * @return the time when this message was last polled for, or 0 for never. + */ + time_t getLastPollTime() { return m_lastPollTime; } + + /** + * @brief Return whether this @a Message needs to be polled before the other one. + * @param other the other @a Message to compare with. + * @return true if this @a Message needs to be polled before the other one. + */ + bool isLessPollWeight(Message* other); + private: /** the optional device class. */ @@ -183,10 +199,24 @@ private: const unsigned char m_pollPriority; /** the last decoded value. */ string m_lastValue; - /** the system time when @a m_lastValue was updated. */ + /** the system time when @a m_lastValue was updated, 0 for never. */ time_t m_lastUpdateTime; + /** the number of times this messages was already polled for. */ + unsigned int m_pollCount; + /** the system time when this message was last polled for, 0 for never. */ + time_t m_lastPollTime; + }; + +/** + * @brief A function that compares the poll priority of two @a Message instances. + */ +struct compareMessagePriority : binary_function { + bool operator() (Message* x, Message* y) const { return x->isLessPollWeight(y) == false; }; +}; + + /** * @brief Holds a map of all known @a Message instances. */ @@ -197,7 +227,7 @@ public: /** * @brief Construct a new instance. */ - MessageMap() : FileReader(true), m_minIdLength(4), m_maxIdLength(0) {} + MessageMap() : FileReader(true), m_minIdLength(4), m_maxIdLength(0), m_messageCount(0) {} /** * @brief Destructor. */ @@ -232,6 +262,23 @@ public: * @brief Removes all @a Message instances. */ void clear(); + /** + * @brief Get the number of stored @a Message instances. + * @param passiveOnly true to count only passive messages, false to count all messages. + * @return the the number of stored @a Message instances. + */ + int size(const bool passiveOnly=false) { return passiveOnly ? m_passiveMessagesByKey.size() : m_messageCount; } + /** + * @brief Get the number of stored @a Message instances with a poll priority. + * @return the the number of stored @a Message instances with a poll priority. + */ + int sizePoll() { return m_pollMessages.size(); } + /** + * @brief Get the next @a Message to poll. + * @return the next @a Message to poll, or NULL. + * Note: the caller may not free the returned instance. + */ + Message* getNextPoll(); private: @@ -241,12 +288,18 @@ private: /** the maximum ID length used by any of the known @a Message instances. */ unsigned char m_maxIdLength; + /** the number of distinct @a Message instances stored in @a m_messagesByName. */ + int m_messageCount; + /** the known @a Message instances by class and name. */ map m_messagesByName; /** the known passive @a Message instances by key. */ map m_passiveMessagesByKey; + /** the known @a Message instances to poll, by priority. */ + priority_queue, compareMessagePriority> m_pollMessages; + }; #endif // LIBEBUS_MESSAGE_H_