rollback modbus hash map - fix #2752

This commit is contained in:
proddy
2025-12-02 19:41:17 +01:00
parent 41122dddb2
commit 9ca9f25fd3
2 changed files with 9 additions and 31 deletions

View File

@@ -632,9 +632,6 @@ void EMSdevice::add_device_value(int8_t tag, // to b
devicevalues_.emplace_back(
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
// add to index for fast lookup by (tag, short_name)
devicevalue_index_[{static_cast<uint8_t>(tag), short_name}] = devicevalues_.size() - 1;
// add a new command if it has a function attached
if (has_cmd) {
uint8_t flags = CommandFlag::ADMIN_ONLY; // executing commands require admin privileges
@@ -2212,13 +2209,14 @@ std::string EMSdevice::name() {
// copy a raw value (i.e. without applying the numeric_operator) to the output buffer.
// returns true on success.
int EMSdevice::get_modbus_value(uint8_t tag, const std::string & shortname, std::vector<uint16_t> & result) {
// find device value by shortname using hash map index
auto index_it = devicevalue_index_.find({tag, shortname});
if (index_it == devicevalue_index_.end()) {
// find device value by shortname
// TODO replace linear search which is inefficient
const auto & it = std::find_if(devicevalues_.begin(), devicevalues_.end(), [&](const DeviceValue & x) { return x.tag == tag && x.short_name == shortname; });
if (it == devicevalues_.end() && (it->short_name != shortname || it->tag != tag)) {
return -1;
}
auto & dv = devicevalues_[index_it->second];
auto & dv = *it;
// check if it exists, there is a value for the entity. Set the flag to ACTIVE
// not that this will override any previously removed states
@@ -2299,13 +2297,13 @@ int EMSdevice::get_modbus_value(uint8_t tag, const std::string & shortname, std:
int EMSdevice::modbus_value_to_json(uint8_t tag, const std::string & shortname, const std::vector<uint8_t> & modbus_data, JsonObject jsonValue) {
// LOG_DEBUG("modbus_value_to_json(%d,%s,[%d bytes])\n", tag, shortname.c_str(), modbus_data.size());
// find device value by shortname using hash map index
auto index_it = devicevalue_index_.find({tag, shortname});
if (index_it == devicevalue_index_.end()) {
// find device value by shortname
const auto & it = std::find_if(devicevalues_.begin(), devicevalues_.end(), [&](const DeviceValue & x) { return x.tag == tag && x.short_name == shortname; });
if (it == devicevalues_.end() && (it->short_name != shortname || it->tag != tag)) {
return -1;
}
auto & dv = devicevalues_[index_it->second];
auto & dv = *it;
// handle Booleans
if (dv.type == DeviceValueType::BOOL) {

View File

@@ -556,26 +556,6 @@ class EMSdevice {
#endif
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
std::vector<DeviceValue> devicevalues_; // all the device values
// added for modbus
// Hash map for O(1) lookup of device values by (tag, short_name) key
struct DeviceValueKey {
uint8_t tag;
std::string short_name;
bool operator==(const DeviceValueKey & other) const {
return tag == other.tag && short_name == other.short_name;
}
};
struct DeviceValueKeyHash {
std::size_t operator()(const DeviceValueKey & key) const {
// Combine hash of tag and short_name
return std::hash<uint8_t>()(key.tag) ^ (std::hash<std::string>()(key.short_name) << 1);
}
};
std::unordered_map<DeviceValueKey, size_t, DeviceValueKeyHash> devicevalue_index_; // index: key -> devicevalues_ position
};
} // namespace emsesp