Skip to content

Commit

Permalink
Merge pull request #953 from frogonwheels/metric-array-reg
Browse files Browse the repository at this point in the history
Metrics - handle registering of array elements properly
  • Loading branch information
dexterbg committed Jan 7, 2024
2 parents 0e15bdc + 400afbc commit aa14327
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
34 changes: 25 additions & 9 deletions vehicle/OVMS.V3/main/ovms_metrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ using namespace std;
RTC_NOINIT_ATTR persistent_metrics pmetrics; // persistent storage container
#define NUM_PERSISTENT_VALUES sizeof_array(pmetrics.values)
static const char* pmetrics_reason; // reason pmetrics was zeroed
std::map<std::size_t, const char*> pmetrics_keymap // hash key → metric name map (registry)
std::map<std::size_t, std::string> pmetrics_keymap // hash key → metric name map (registry)
__attribute__ ((init_priority (1800)));

OvmsMetrics MyMetrics
Expand Down Expand Up @@ -740,19 +740,29 @@ bool pmetrics_check()
return ret;
}

persistent_values *pmetrics_find(const char *name)
static persistent_values *pmetrics_find_hash(size_t namehash)
{
int i;
persistent_values *vp;
std::size_t namehash = std::hash<std::string>{}(name);
for (i = 0, vp = pmetrics.values; i < pmetrics.used; ++i, ++vp)
{
for (i = 0, vp = pmetrics.values; i < pmetrics.used; ++i, ++vp) {
if (vp->namehash == namehash)
return vp;
}
return NULL;
}

persistent_values *pmetrics_find(const char *name)
{
std::size_t namehash = std::hash<std::string>{}(name);
return pmetrics_find_hash(namehash);
}

persistent_values *pmetrics_find(const std::string &name)
{
std::size_t namehash = std::hash<std::string>{}(name);
return pmetrics_find_hash(namehash);
}

void pmetrics_init(bool refresh = false)
{
memset(&pmetrics, 0, sizeof(pmetrics));
Expand All @@ -767,17 +777,23 @@ void pmetrics_init(bool refresh = false)
}

persistent_values *pmetrics_register(const char *name)
{
std::string str_name(name);
return pmetrics_register(str_name);
}

persistent_values *pmetrics_register(const std::string &name)
{
int i;
persistent_values *vp;
std::size_t namehash = std::hash<std::string>{}(name);

// check for hash collision:
auto it = pmetrics_keymap.find(namehash);
if (it != pmetrics_keymap.end() && strcmp(it->second, name) != 0)
if (it != pmetrics_keymap.end() && (it->second != name) )
{
ESP_LOGE(TAG, "pmetrics_register: cannot persist '%s' due to hash collision with '%s'",
name, it->second);
name.c_str(), it->second.c_str());
return NULL;
}

Expand All @@ -793,7 +809,7 @@ persistent_values *pmetrics_register(const char *name)
{
if (i >= NUM_PERSISTENT_VALUES)
{
ESP_LOGE(TAG, "pmetrics_register: no free slots, cannot persist '%s'", name);
ESP_LOGE(TAG, "pmetrics_register: no free slots, cannot persist '%s'", name.c_str());
return NULL;
}
vp->namehash = namehash;
Expand All @@ -802,7 +818,7 @@ persistent_values *pmetrics_register(const char *name)
}

ESP_LOGD(TAG, "pmetrics_register: '%s' => slot=%d, used %d/%d",
name, i, pmetrics.used, NUM_PERSISTENT_VALUES);
name.c_str(), i, pmetrics.used, NUM_PERSISTENT_VALUES);
pmetrics_keymap[namehash] = name;
return vp;
}
Expand Down
26 changes: 22 additions & 4 deletions vehicle/OVMS.V3/main/ovms_metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ struct persistent_metrics
};

extern persistent_values *pmetrics_find(const char *name);
extern persistent_values *pmetrics_find(const std::string &name);
extern persistent_values *pmetrics_register(const char *name);
extern persistent_values *pmetrics_register(const std::string &name);

class OvmsMetric
{
Expand Down Expand Up @@ -725,28 +727,44 @@ class OvmsMetricVector : public OvmsMetric
return true;
if (*m_valuep_size != m_value.size())
{
ESP_LOGE(TAG, "CheckPersist: bad value for %s", m_name);
ESP_LOGE(TAG, "CheckPersist: bad value for %s[] size", m_name);
return false;
}
persistent_values *vp = pmetrics_find(m_name);
if (vp == NULL)
{
ESP_LOGE(TAG, "CheckPersist: can't find %s", m_name);
ESP_LOGE(TAG, "CheckPersist: can't find %s[] size", m_name);
return false;
}
if (m_valuep_size != reinterpret_cast<std::size_t*>(&vp->value))
{
ESP_LOGE(TAG, "CheckPersist: bad address for %s", m_name);
ESP_LOGE(TAG, "CheckPersist: bad address for %s[] size", m_name);
return false;
}
for (int i = 0; i < m_value.size(); i++)
for (std::size_t i = 0; i < m_value.size(); i++)
{
if (*m_valuep_elem[i] != m_value[i])
{
ESP_LOGE(TAG, "CheckPersist: bad value for %s[%d]", m_name, i);
return false;
}
}
char elem_name[100];
for (std::size_t i = 0; i < m_value.size(); ++i)
{
snprintf(elem_name, sizeof(elem_name), "%s_%u", m_name, i);
vp = pmetrics_find(elem_name);
if (!vp)
{
ESP_LOGE(TAG, "CheckPersist: can't find %s[%d]", m_name, i);
return false;
}
if (m_valuep_elem[i] != reinterpret_cast<ElemType*>(&vp->value))
{
ESP_LOGE(TAG, "CheckPersist: bad address for %s[%d]", m_name, i);
return false;
}
}
return true;
}

Expand Down

0 comments on commit aa14327

Please sign in to comment.