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_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
@@ -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_
|
||||||
|
|||||||
Reference in New Issue
Block a user