Commit 54df6c08 authored by Michael Ott's avatar Michael Ott
Browse files

Implement wildcard matches for the SensorCache

parent ef142c5e
......@@ -73,15 +73,12 @@ typedef boost::network::http::server<httpHandler_t> httpServer_t;
struct httpHandler_t {
void operator()(httpServer_t::request const &request, httpServer_t::connection_ptr connection) {
httpServer_t::string_type ip = source(request);
DCDB::SensorId sid;
sid.mqttTopicConvert(request.destination);
std::ostringstream data;
static httpServer_t::response_header headers[] = { { "Connection", "close" }, { "Content-Type", "text/plain" } };
//try getting the latest value
try {
uint64_t val = mySensorCache.getSensor(sid);
uint64_t val = mySensorCache.getSensor(request.destination);
data << val << "\n";
//data << "Sid : " << sid.toString() << ", Value: " << val << "." << std::endl;
......
......@@ -41,32 +41,87 @@ void SensorCache::storeSensor(SensorId sid, uint64_t ts, uint64_t val) {
sensorCache[sid] = e;
}
bool SensorCache::checkValid(cacheEntry_t &entry) {
if (entry.deltaT.size()) {
uint64_t ts = Messaging::calculateTimestamp();
uint64_t avg = 0;
for (std::list<uint32_t>::iterator dt = entry.deltaT.begin(); dt != entry.deltaT.end(); dt++) {
avg+= *dt;
}
avg/= entry.deltaT.size();
/*
* A SID is outdated if it's older than 5x the average sampling period.
* The 1000000 accounts for the conversion ns->ms in deltaT.
*/
if ((ts - entry.timestamp) > 5 * 1000000 * avg) {
return false;
}
}
return true;
}
uint64_t SensorCache::getSensor(SensorId sid) {
/* Remove the reserved bytes to leverage the standard find function */
sid.setRsvd(0);
sensorCache_t::iterator it = sensorCache.find(sid);
/* Remove the reserved bytes to leverage the standard find function */
sid.setRsvd(0);
sensorCache_t::iterator it = sensorCache.find(sid);
if (it == sensorCache.end()) {
throw std::invalid_argument("Sid not found");
}
if (it == sensorCache.end()) {
throw std::invalid_argument("Sid not found");
}
if (it->second.deltaT.size()) {
uint64_t ts = Messaging::calculateTimestamp();
uint64_t avg = 0;
for (std::list<uint32_t>::iterator dt = it->second.deltaT.begin(); dt != it->second.deltaT.end(); dt++) {
avg+= *dt;
}
avg/= it->second.deltaT.size();
/*
* A SID is outdated if it's older than 5x the average sampling period.
* The 1000000 accounts for the conversion ns->ms in deltaT.
*/
if ((ts - it->second.timestamp) > 5 * 1000000 * avg) {
throw std::out_of_range("Sid outdated");
}
}
if (!checkValid(it->second))
{
throw std::out_of_range("Sid outdated");
}
return it->second.val;
}
return it->second.val;
uint64_t SensorCache::getSensor(std::string topic) {
topic.erase(std::remove(topic.begin(), topic.end(), '/'), topic.end());
size_t wp = topic.find("*");
if (wp == std::string::npos) {
return getSensor(DCDB::SensorId(topic));
}
int wl = 33 - topic.length();
/* Create SensorIds with the lowest and highest values matching the wildcard */
DCDB::SensorId sidLow(std::string(topic).replace(wp, 1, std::string(wl, '0')));
DCDB::SensorId sidHi(std::string(topic).replace(wp, 1, std::string(wl, 'f')));
sidLow.setRsvd(0);
sidHi.setRsvd(0);
/* See whether there's a SensorId in the cache >= sidLow */
sensorCache_t::iterator it = sensorCache.lower_bound(sidLow);
sensorCache_t::iterator mostRecentSidIt;
bool foundOne = false;
/* Iterate over the cache until the current entry is >= sidHi */
while (it != sensorCache.end() && it->first <= sidHi) {
foundOne = true;
/* We only return one value, even if multiple SensorIds would match.
* At least make sure it's the most recent value
*/
if (checkValid(it->second) && ((mostRecentSidIt == sensorCache.end()) || mostRecentSidIt->second.timestamp < it->second.timestamp)) {
mostRecentSidIt = it;
}
it++;
}
if (mostRecentSidIt == sensorCache.end()) {
/* Check whether we actually found at least an outdated entry */
if (foundOne) {
throw std::out_of_range("Sid outdated");
} else {
throw std::invalid_argument("Sid not found");
}
}
return mostRecentSidIt->second.val;
}
void SensorCache::dump() {
......
......@@ -28,9 +28,11 @@ public:
virtual ~SensorCache();
void storeSensor(SensorId sid, uint64_t ts, uint64_t val);
uint64_t getSensor(SensorId sid);
uint64_t getSensor(std::string sid);
void dump();
private:
bool checkValid(cacheEntry_t &entry);
sensorCache_t sensorCache;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment