Changed storage of required and optional Characteristics from unordered_set to vector

Significantly reduces memory usage - unordered_sets take up much more memory and using std::find from <algorithm> is as efficient as using find() method of an unordered_set.

To do: Remove all uses of unordered_set across HomeSpan wherever possible
This commit is contained in:
Gregg 2023-11-12 09:48:46 -06:00
parent ae60a84855
commit 98d6abeb1f
3 changed files with 9 additions and 12 deletions

View File

@ -39,6 +39,7 @@
#include "HomeSpan.h"
#include "HAP.h"
#include <algorithm>
const __attribute__((section(".rodata_custom_desc"))) SpanPartition spanPartition = {HOMESPAN_MAGIC_COOKIE,0};
@ -890,8 +891,6 @@ void Span::processSerialCommand(const char *c){
else if((*acc)->aid==1) // this is an Accessory with aid=1, but it has more than just AccessoryInfo. So...
isBridge=false; // ...this is not a bridge device
unordered_set<HapChar *> hapChar;
for(auto chr=(*svc)->Characteristics.begin(); chr!=(*svc)->Characteristics.end(); chr++){
LOG0(" \u21e8 Characteristic %s(%s): IID=%d, %sUUID=\"%s\", %sPerms=",
(*chr)->hapName,(*chr)->uvPrint((*chr)->value).c_str(),(*chr)->iid,(*chr)->isCustom?"Custom-":"",(*chr)->type,(*chr)->perms!=(*chr)->hapChar->perms?"Custom-":"");
@ -915,13 +914,13 @@ void Span::processSerialCommand(const char *c){
LOG0(" (nvs)");
LOG0("\n");
if(!(*chr)->isCustom && !(*svc)->isCustom && (*svc)->req.find((*chr)->hapChar)==(*svc)->req.end() && (*svc)->opt.find((*chr)->hapChar)==(*svc)->opt.end())
if(!(*chr)->isCustom && !(*svc)->isCustom && std::find((*svc)->req.begin(),(*svc)->req.end(),(*chr)->hapChar)==(*svc)->req.end() && std::find((*svc)->opt.begin(),(*svc)->opt.end(),(*chr)->hapChar)==(*svc)->opt.end())
LOG0(" *** WARNING #%d! Service does not support this Characteristic ***\n",++nWarnings);
else
if(invalidUUID((*chr)->type,(*chr)->isCustom))
LOG0(" *** ERROR #%d! Format of UUID is invalid ***\n",++nErrors);
else
if(hapChar.find((*chr)->hapChar)!=hapChar.end())
if(std::find_if((*svc)->Characteristics.begin(),chr,[chr](SpanCharacteristic *c)->boolean{return(c->hapChar==(*chr)->hapChar);})!=chr)
LOG0(" *** ERROR #%d! Characteristic already defined for this Service ***\n",++nErrors);
if((*chr)->setRangeError)
@ -933,12 +932,10 @@ void Span::processSerialCommand(const char *c){
if((*chr)->format!=STRING && ((*chr)->uvGet<double>((*chr)->value) < (*chr)->uvGet<double>((*chr)->minValue) || (*chr)->uvGet<double>((*chr)->value) > (*chr)->uvGet<double>((*chr)->maxValue)))
LOG0(" *** WARNING #%d! Value of %g is out of range [%g,%g] ***\n",++nWarnings,(*chr)->uvGet<double>((*chr)->value),(*chr)->uvGet<double>((*chr)->minValue),(*chr)->uvGet<double>((*chr)->maxValue));
hapChar.insert((*chr)->hapChar);
} // Characteristics
for(auto req=(*svc)->req.begin(); req!=(*svc)->req.end(); req++){
if(hapChar.find(*req)==hapChar.end())
if(std::find_if((*svc)->Characteristics.begin(),(*svc)->Characteristics.end(),[req](SpanCharacteristic *c)->boolean{return(c->hapChar==*req);})==(*svc)->Characteristics.end())
LOG0(" *** WARNING #%d! Required '%s' Characteristic for this Service not found ***\n",++nWarnings,(*req)->hapName);
}

View File

@ -426,8 +426,8 @@ class SpanService{
protected:
virtual ~SpanService(); // destructor
unordered_set<HapChar *> req; // unordered set of pointers to all required HAP Characteristic Types for this Service
unordered_set<HapChar *> opt; // unordered set of pointers to all optional HAP Characteristic Types for this Service
vector<HapChar *> req; // vector of pointers to all required HAP Characteristic Types for this Service
vector<HapChar *> opt; // vector of pointers to all optional HAP Characteristic Types for this Service
public:

View File

@ -35,8 +35,8 @@
#define CREATE_SERV(NAME,UUID) struct NAME : SpanService { NAME() : SpanService{#UUID,#NAME}{
#define END_SERV }};
#define REQ(HAPCHAR) req.insert(&hapChars.HAPCHAR)
#define OPT(HAPCHAR) opt.insert(&hapChars.HAPCHAR)
#define REQ(HAPCHAR) req.push_back(&hapChars.HAPCHAR)
#define OPT(HAPCHAR) opt.push_back(&hapChars.HAPCHAR)
namespace Service {