added polling by priority
This commit is contained in:
Regular → Executable
+39
-3
@@ -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<string, Message*>::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;
|
||||
}
|
||||
|
||||
+57
-4
@@ -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 <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.
|
||||
*/
|
||||
@@ -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<string, Message*> m_messagesByName;
|
||||
|
||||
/** the known passive @a Message instances by key. */
|
||||
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_
|
||||
|
||||
Reference in New Issue
Block a user