aboutsummaryrefslogtreecommitdiffstats
path: root/signal-composer-binding
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2018-07-22 01:13:17 +0200
committerRomain Forlot <romain.forlot@iot.bzh>2018-07-25 10:08:07 +0200
commit7f15ef65f420179b606f136ed805fae9d320b321 (patch)
treec4ef2dde841415ce4dedcaaa5f0edf7e258bc356 /signal-composer-binding
parent3b08cec1ad06f313374bc1fd9cc64e1b28ce798d (diff)
Improved performance
Before value was translated to a C type variable two times, at the reception then at the emission. Now it just receives and sends the signal value without translation nor interpretation except if you ask for an average, minimum or maximum value. Then in those cases it interprets the json to return you a value or an error if there is no numeric values to compute. Remove unneeded log message at event reception. Improved signal search engine, will search in source's signals map by the signal ID not the event name which lead to a more direct map match. Bugs-AGL: SPEC-1612 Depends-On: I43e79ed73a507ac2ca7ed4cdc3f16ec009392194 Change-Id: Ie253c3fe1e8cde42dabe8832da74e9f9bf442c14 Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'signal-composer-binding')
-rw-r--r--signal-composer-binding/signal-composer-binding.cpp4
-rw-r--r--signal-composer-binding/signal-composer.cpp62
-rw-r--r--signal-composer-binding/signal.cpp139
-rw-r--r--signal-composer-binding/signal.hpp45
-rw-r--r--signal-composer-binding/source.cpp2
5 files changed, 102 insertions, 150 deletions
diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp
index 0d9c8e3..f7c8c73 100644
--- a/signal-composer-binding/signal-composer-binding.cpp
+++ b/signal-composer-binding/signal-composer-binding.cpp
@@ -32,10 +32,8 @@
/// @param[in] object - eventual data that comes with the event
void onEvent(const char *event, json_object *object)
{
- Composer& composer = Composer::instance();
- AFB_NOTICE("event: %s", json_object_to_json_string(object));
+ std::vector<std::shared_ptr<Signal>> signals { Composer::instance().searchSignals(event) };
- std::vector<std::shared_ptr<Signal>> signals = composer.searchSignals(event);
if(!signals.empty())
{
// If there is more than 1 element then maybe we can find a more
diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp
index 99129b4..f7c1971 100644
--- a/signal-composer-binding/signal-composer.cpp
+++ b/signal-composer-binding/signal-composer.cpp
@@ -21,7 +21,7 @@
#include "clientApp.hpp"
-extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value)
+extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, json_object* value)
{
std::vector<std::shared_ptr<Signal>> signals = Composer::instance().searchSignals(aName);
if(!signals.empty())
@@ -31,7 +31,7 @@ extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestam
}
}
-extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, struct signalValue value)
+extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, json_object* value)
{
Signal* sig = static_cast<Signal*>(aSignal);
sig->set(timestamp, value);
@@ -380,47 +380,25 @@ void Composer::processOptions(const std::map<std::string, int>& opts, std::share
{
avg = true;
double value = sig->average(o.second);
- json_object_object_add(response, "value",
- json_object_new_double(value));
+ json_object_object_add(response, "value", json_object_new_double(value));
}
else if (o.first.compare("minimum") && !min)
{
min = true;
double value = sig->minimum();
- json_object_object_add(response, "value",
- json_object_new_double(value));
+ json_object_object_add(response, "value", json_object_new_double(value));
}
else if (o.first.compare("maximum") && !max)
{
max = true;
double value = sig->maximum();
- json_object_object_add(response, "value",
- json_object_new_double(value));
+ json_object_object_add(response, "value", json_object_new_double(value));
}
else if (o.first.compare("last") && !last)
{
last = true;
- struct signalValue value = sig->last_value();
- if(value.hasBool)
- {
- json_object_object_add(response, "value",
- json_object_new_boolean(value.boolVal));
- }
- else if(value.hasNum)
- {
- json_object_object_add(response, "value",
- json_object_new_double(value.numVal));
- }
- else if(value.hasStr)
- {
- json_object_object_add(response, "value",
- json_object_new_string(value.strVal.c_str()));
- }
- else
- {
- json_object_object_add(response, "value",
- json_object_new_string("No recorded value so far."));
- }
+ json_object* value = sig->last_value();
+ json_object_object_add(response, "value", value);
}
else
{
@@ -568,8 +546,9 @@ std::vector<std::shared_ptr<Signal>> Composer::searchSignals(const std::string&
if(sep != std::string::npos)
{
api = aName.substr(0, sep);
+ std::string signal_id = aName.substr(sep + 1, std::string::npos);
std::shared_ptr<SourceAPI> source = getSourceAPI(api);
- return source->searchSignals(aName);
+ return source->searchSignals(signal_id);
}
else
{
@@ -603,27 +582,8 @@ json_object* Composer::getsignalValue(const std::string& sig, json_object* optio
"signal", sig->id().c_str());
if (opts.empty())
{
- struct signalValue value = sig->last_value();
- if(value.hasBool)
- {
- json_object_object_add(response, "value",
- json_object_new_boolean(value.boolVal));
- }
- else if(value.hasNum)
- {
- json_object_object_add(response, "value",
- json_object_new_double(value.numVal));
- }
- else if(value.hasStr)
- {
- json_object_object_add(response, "value",
- json_object_new_string(value.strVal.c_str()));
- }
- else
- {
- json_object_object_add(response, "value",
- json_object_new_string("No recorded value so far."));
- }
+ json_object* value = sig->last_value();
+ json_object_object_add(response, "value", value);
}
else
{processOptions(opts, sig, response);}
diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp
index 2f1aa57..14e85ba 100644
--- a/signal-composer-binding/signal.cpp
+++ b/signal-composer-binding/signal.cpp
@@ -148,9 +148,8 @@ json_object* Signal::toJSON() const
if(timestamp_)
json_object_object_add(sigJ, "timestamp", json_object_new_int64(timestamp_));
- if (value_.hasBool) {json_object_object_add(sigJ, "value", json_object_new_boolean(value_.boolVal));}
- else if (value_.hasNum) {json_object_object_add(sigJ, "value", json_object_new_double(value_.numVal));}
- else if (value_.hasStr) {json_object_object_add(sigJ, "value", json_object_new_string(value_.strVal.c_str()));}
+ if(value_)
+ json_object_object_add(sigJ, "value", value_);
return sigJ;
}
@@ -198,19 +197,21 @@ json_object *Signal::getSignalsArgs()
///
/// @param[in] timestamp - timestamp of occured signal
/// @param[in] value - value of change
-void Signal::set(uint64_t timestamp, struct signalValue& value)
+void Signal::set(uint64_t timestamp, json_object*& value)
{
uint64_t diff = retention_+1;
value_ = value;
timestamp_ = timestamp;
- history_[timestamp_] = value_;
+ history_[timestamp_] = json_object_get(value_);
while(diff > retention_)
{
uint64_t first = history_.begin()->first;
diff = (timestamp_ - first)/NANO;
- if(diff > retention_)
- {history_.erase(history_.cbegin());}
+ if(diff > retention_) {
+ json_object_put(history_.cbegin()->second);
+ history_.erase(history_.cbegin());
+ }
}
notify();
@@ -253,37 +254,22 @@ void Signal::update(Signal* sig)
/// @param[in] eventJ - json_object containing event data to process
///
/// @return 0 if ok, -1 or others if not
-void Signal::defaultReceivedCB(json_object *eventJ)
+void Signal::defaultReceivedCB(Signal *signal, json_object *eventJ)
{
uint64_t ts = 0;
- struct signalValue sv;
+ json_object* sv = nullptr;
json_object_iterator iter = json_object_iter_begin(eventJ);
json_object_iterator iterEnd = json_object_iter_end(eventJ);
+
while(!json_object_iter_equal(&iter, &iterEnd))
{
std::string key = json_object_iter_peek_name(&iter);
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
json_object *value = json_object_iter_peek_value(&iter);
if (key.find("value") != std::string::npos ||
- key.find(id_) != std::string::npos)
+ key.find(signal->id()) != std::string::npos)
{
- switch (json_object_get_type(value)) {
- case json_type_double:
- sv = json_object_get_double(value);
- break;
- case json_type_int:
- sv = json_object_get_int(value);
- break;
- case json_type_boolean:
- sv = json_object_get_int(value);
- break;
- case json_type_string:
- sv = json_object_get_string(value);
- break;
- default:
- sv = signalValue();
- break;
- }
+ sv = json_object_get(value);
}
else if (key.find("timestamp") != std::string::npos)
{
@@ -292,9 +278,9 @@ void Signal::defaultReceivedCB(json_object *eventJ)
json_object_iter_next(&iter);
}
- if(!sv.hasBool && !sv.hasNum && !sv.hasStr)
+ if(!sv)
{
- AFB_ERROR("No data found to set signal %s in %s", id_.c_str(), json_object_to_json_string(eventJ));
+ AFB_ERROR("No data found to set signal %s in %s", signal->id().c_str(), json_object_to_json_string(eventJ));
return;
}
else if(ts == 0)
@@ -305,7 +291,7 @@ void Signal::defaultReceivedCB(json_object *eventJ)
ts = (uint64_t)(t.tv_sec) * (uint64_t)NANO + (uint64_t)(t.tv_nsec);
}
- set(ts, sv);
+ signal->set(ts, sv);
}
/// @brief Notify observers that there is a change and execute callback defined
@@ -343,7 +329,7 @@ void Signal::onReceivedCB(json_object *eventJ)
if (onReceived_)
ActionExecOne(&source, onReceived_, json_object_get(eventJ));
else
- defaultReceivedCB(eventJ);
+ defaultReceivedCB(this, eventJ);
}
/// @brief Make a Signal observer observes Signals observables
@@ -382,22 +368,31 @@ double Signal::average(int seconds) const
double total = 0.0;
int nbElt = 0;
- for (const auto& val: history_)
+ for(const auto& val: history_)
{
- if(val.first >= end)
- {break;}
- if(val.second.hasNum)
+ if(val.first >= end) {
+ break;
+ }
+ if(val.second)
{
- total += val.second.numVal;
+ switch(json_object_get_type(val.second)) {
+ case json_type_int:
+ total += static_cast<double>(json_object_get_int64(val.second));
+ break;
+ case json_type_double:
+ total += json_object_get_double(val.second);
+ break;
+ default:
+ AFB_ERROR("The stored value '%s' for the signal '%s' isn't numeric, it is not possible to compute an average value.", json_object_get_string(val.second), id_.c_str());
+ break;
+ }
nbElt++;
}
else
{
- AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value : bool %d, num %lf, str: %s",
+ AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value: %s",
id_.c_str(),
- val.second.boolVal,
- val.second.numVal,
- val.second.strVal.c_str());
+ json_object_get_string(val.second));
break;
}
}
@@ -416,21 +411,34 @@ double Signal::minimum(int seconds) const
uint64_t end = seconds ?
begin+(seconds*NANO) :
history_.rbegin()->first;
+ double current = 0.0;
double min = DBL_MAX;
- for (auto& v : history_)
+ for(const auto& val : history_)
{
- if(v.first >= end)
- {break;}
- else if(v.second.hasNum && v.second.numVal < min)
- {min = v.second.numVal;}
+ if(val.first >= end) {
+ break;
+ }
+ else if(val.second) {
+ switch(json_object_get_type(val.second)) {
+ case json_type_int:
+ current = static_cast<double>(json_object_get_int64(val.second));
+ min = current < min ? current : min;
+ break;
+ case json_type_double:
+ current = json_object_get_double(val.second);
+ min = current < min ? current : min;
+ break;
+ default:
+ AFB_ERROR("The stored value '%s' for signal '%s' isn't numeric, it is not possible to find a minimum value.", json_object_get_string(val.second), id_.c_str());
+ break;
+ }
+ }
else
{
- AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value : bool %d, num %lf, str: %s",
+ AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value: %s",
id_.c_str(),
- v.second.boolVal,
- v.second.numVal,
- v.second.strVal.c_str());
+ json_object_get_string(val.second));
break;
}
}
@@ -448,21 +456,34 @@ double Signal::maximum(int seconds) const
uint64_t end = seconds ?
begin+(seconds*NANO) :
history_.rbegin()->first;
+ double current = 0.0;
double max = 0.0;
- for (auto& v : history_)
+ for(const auto& val : history_)
{
- if(v.first >= end)
- {break;}
- else if(v.second.hasNum && v.second.hasNum > max)
- {max = v.second.numVal;}
+ if(val.first >= end) {
+ break;
+ }
+ else if(val.second) {
+ switch(json_object_get_type(val.second)) {
+ case json_type_int:
+ current = static_cast<double>(json_object_get_int64(val.second));
+ max = current > max ? current : max;
+ break;
+ case json_type_double:
+ current = json_object_get_double(val.second);
+ max = current > max ? current : max;
+ break;
+ default:
+ AFB_ERROR("The stored value '%s' for signal '%s' isn't numeric, it is not possible to find a maximum value.", json_object_get_string(val.second), id_.c_str());
+ break;
+ }
+ }
else
{
- AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value : bool %d, num %lf, str: %s",
+ AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value: %s",
id_.c_str(),
- v.second.boolVal,
- v.second.numVal,
- v.second.strVal.c_str());
+ json_object_get_string(val.second));
break;
}
}
@@ -472,7 +493,7 @@ double Signal::maximum(int seconds) const
/// @brief Return last value recorded
///
/// @return Last value
-struct signalValue Signal::last_value() const
+json_object* Signal::last_value() const
{
return value_;
}
diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp
index 0a12b16..6c7f43f 100644
--- a/signal-composer-binding/signal.hpp
+++ b/signal-composer-binding/signal.hpp
@@ -28,40 +28,14 @@
class Composer;
-/// @brief Structure holding a possible value of a Signal
-/// as it could be different type of value, we declare all
-/// possibility.
-/// Not very efficient or optimized, maybe use of Variant in
-/// C++17 but this is a bit too new to uses it for now
-struct signalValue {
- bool undefined;
- bool hasBool;
- bool boolVal;
- bool hasNum;
- double numVal;
- bool hasStr;
- std::string strVal;
-
- signalValue():
- undefined(true), hasBool(false), boolVal(false), hasNum(false), numVal(0), hasStr(false), strVal("") {};
- signalValue(bool b):
- undefined(false), hasBool(true), boolVal(b), hasNum(false), numVal(0), hasStr(false), strVal("") {};
- signalValue(int i):
- undefined(false), hasBool(false), boolVal(false), hasNum(true), numVal(i), hasStr(false), strVal("") {};
- signalValue(double d):
- undefined(false), hasBool(false), boolVal(false), hasNum(true), numVal(d), hasStr(false), strVal("") {};
- signalValue(const std::string& s):
- undefined(false), hasBool(false), boolVal(false), hasNum(false), numVal(0), hasStr(true), strVal(s) {};
-};
-
-extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value);
-extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, struct signalValue value);
+extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, json_object* value);
+extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, json_object* value);
/// @brief Holds composer callbacks and obj to manipulate
struct signalCBT
{
- void (*searchNsetSignalValue)(const char* aName, uint64_t timestamp, struct signalValue value);
- void (*setSignalValue)(void* aSignal, uint64_t timestamp, struct signalValue value);
+ void (*searchNsetSignalValue)(const char* aName, uint64_t timestamp, json_object* value);
+ void (*setSignalValue)(void* aSignal, uint64_t timestamp, json_object* value);
void* aSignal;
void* pluginCtx;
};
@@ -80,8 +54,8 @@ private:
std::string event_;
std::vector<std::string> dependsSigV_;
uint64_t timestamp_;
- struct signalValue value_;
- std::map<uint64_t, struct signalValue> history_; ///< history_ - Hold signal value history in map with <timestamp, value>
+ json_object* value_;
+ std::map<uint64_t, json_object*> history_; ///< history_ - Hold signal value history in map with <timestamp, value>
int retention_;
double frequency_;
std::string unit_;
@@ -107,17 +81,16 @@ public:
struct signalCBT* get_context();
json_object *getSignalsArgs();
- void set(uint64_t timestamp, struct signalValue& value);
+ void set(uint64_t timestamp, json_object*& value);
void update(Signal* sig);
- static int defaultOnReceivedCB(CtlSourceT* source, json_object* argsJ, json_object *queryJ);
- void defaultReceivedCB(json_object *eventJ);
+ static void defaultReceivedCB(Signal *signal, json_object *eventJ);
void onReceivedCB(json_object *eventJ);
void attachToSourceSignals(Composer& composer);
double average(int seconds = 0) const;
double minimum(int seconds = 0) const;
double maximum(int seconds = 0) const;
- struct signalValue last_value() const;
+ json_object* last_value() const;
uint64_t last_timestamp() const;
int initialRecursionCheck();
diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp
index a46e766..bd988c9 100644
--- a/signal-composer-binding/source.cpp
+++ b/signal-composer-binding/source.cpp
@@ -122,7 +122,7 @@ std::vector<std::shared_ptr<Signal>> SourceAPI::searchSignals(const std::string&
if(signalsM_.count(name))
{signals.emplace_back(signalsM_[name]);}
- if(newSignalsM_.count(name))
+ else if(newSignalsM_.count(name))
{signals.emplace_back(signalsM_[name]);}
else
{