added polling by priority

This commit is contained in:
john30
2014-12-07 14:45:33 +01:00
parent dc6f5a0980
commit a8c1343218
2 changed files with 96 additions and 7 deletions
Regular → Executable
+39 -3
View File
@@ -36,7 +36,7 @@ Message::Message(const string clazz, const string name, const bool isSet,
m_isPassive(isPassive), m_comment(comment), m_isPassive(isPassive), m_comment(comment),
m_srcAddress(srcAddress), m_dstAddress(dstAddress), m_srcAddress(srcAddress), m_dstAddress(dstAddress),
m_id(id), m_data(data), m_pollPriority(pollPriority), m_id(id), m_data(data), m_pollPriority(pollPriority),
m_lastUpdateTime(0) m_lastUpdateTime(0), m_pollCount(0), m_lastPollTime(0)
{ {
int exp = 7; int exp = 7;
unsigned long long key = (unsigned long long)(id.size()-2) << (8 * exp + 5); 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); result = m_data->write(input, pt_masterData, master, m_id.size() - 2, separator);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
masterData = SymbolString(master); masterData = SymbolString(master, true);
return result; return result;
} }
@@ -298,6 +298,18 @@ result_t Message::decode(const PartType partType, SymbolString& data,
return RESULT_OK; 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) result_t MessageMap::add(Message* message)
{ {
unsigned long long pkey = message->getKey(); unsigned long long pkey = message->getKey();
@@ -318,6 +330,7 @@ result_t MessageMap::add(Message* message)
} }
m_messagesByName[key] = message; m_messagesByName[key] = message;
m_messageCount++;
key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // also store without class key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // also store without class
m_messagesByName[key] = message; // last key without class overrides previous 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_passiveMessagesByKey[pkey] = message;
} }
//m_pollMessages.push() if (message->getPollPriority() > 0)
m_pollMessages.push(message);
return RESULT_OK; return RESULT_OK;
} }
@@ -418,12 +432,34 @@ Message* MessageMap::find(SymbolString& master)
void MessageMap::clear() void MessageMap::clear()
{ {
// clear poll messages
while (m_pollMessages.empty() == false) {
m_pollMessages.top();
m_pollMessages.pop();
}
// free message instances
for (map<string, Message*>::iterator it=m_messagesByName.begin(); it!=m_messagesByName.end(); it++) { for (map<string, Message*>::iterator it=m_messagesByName.begin(); it!=m_messagesByName.end(); it++) {
if (it->first[0] != '-') // avoid double free if (it->first[0] != '-') // avoid double free
delete it->second; delete it->second;
it->second = NULL; it->second = NULL;
} }
// clear messages by name
m_messageCount = 0;
m_messagesByName.clear(); m_messagesByName.clear();
// clear messages by key
m_passiveMessagesByKey.clear(); m_passiveMessagesByKey.clear();
m_minIdLength = 4;
m_maxIdLength = 0; 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;
}
+57 -4
View File
@@ -29,11 +29,14 @@
using namespace std; using namespace std;
class MessageMap;
/** /**
* @brief Defines parameters of a message sent or received on the bus. * @brief Defines parameters of a message sent or received on the bus.
*/ */
class Message class Message
{ {
friend class MessageMap;
public: public:
/** /**
@@ -151,11 +154,24 @@ public:
string getLastValue() { return m_lastValue; } string getLastValue() { return m_lastValue; }
/** /**
* @brief Get the system time when @a m_lastValue was updated. * @brief Get the 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. * @return the time when @a m_lastValue was updated, or 0 if this message was not decoded yet.
*/ */
time_t getLastUpdateTime() { return m_lastUpdateTime; } 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: private:
/** the optional device class. */ /** the optional device class. */
@@ -183,10 +199,24 @@ private:
const unsigned char m_pollPriority; const unsigned char m_pollPriority;
/** the last decoded value. */ /** the last decoded value. */
string m_lastValue; 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; 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 <Message*,Message*,bool> {
bool operator() (Message* x, Message* y) const { return x->isLessPollWeight(y) == false; };
};
/** /**
* @brief Holds a map of all known @a Message instances. * @brief Holds a map of all known @a Message instances.
*/ */
@@ -197,7 +227,7 @@ public:
/** /**
* @brief Construct a new instance. * @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. * @brief Destructor.
*/ */
@@ -232,6 +262,23 @@ public:
* @brief Removes all @a Message instances. * @brief Removes all @a Message instances.
*/ */
void clear(); 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: private:
@@ -241,12 +288,18 @@ private:
/** the maximum ID length used by any of the known @a Message instances. */ /** the maximum ID length used by any of the known @a Message instances. */
unsigned char m_maxIdLength; 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. */ /** the known @a Message instances by class and name. */
map<string, Message*> m_messagesByName; map<string, Message*> m_messagesByName;
/** the known passive @a Message instances by key. */ /** the known passive @a Message instances by key. */
map<unsigned long long, Message*> m_passiveMessagesByKey; map<unsigned long long, Message*> m_passiveMessagesByKey;
/** the known @a Message instances to poll, by priority. */
priority_queue<Message*, vector<Message*>, compareMessagePriority> m_pollMessages;
}; };
#endif // LIBEBUS_MESSAGE_H_ #endif // LIBEBUS_MESSAGE_H_