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 "HomeSpan.h"
#include "HAP.h" #include "HAP.h"
#include <algorithm>
const __attribute__((section(".rodata_custom_desc"))) SpanPartition spanPartition = {HOMESPAN_MAGIC_COOKIE,0}; const __attribute__((section(".rodata_custom_desc"))) SpanPartition spanPartition = {HOMESPAN_MAGIC_COOKIE,0};
@ -889,9 +890,7 @@ 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... 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 isBridge=false; // ...this is not a bridge device
unordered_set<HapChar *> hapChar;
for(auto chr=(*svc)->Characteristics.begin(); chr!=(*svc)->Characteristics.end(); chr++){ for(auto chr=(*svc)->Characteristics.begin(); chr!=(*svc)->Characteristics.end(); chr++){
LOG0(" \u21e8 Characteristic %s(%s): IID=%d, %sUUID=\"%s\", %sPerms=", 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-":""); (*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(" (nvs)");
LOG0("\n"); 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); LOG0(" *** WARNING #%d! Service does not support this Characteristic ***\n",++nWarnings);
else else
if(invalidUUID((*chr)->type,(*chr)->isCustom)) if(invalidUUID((*chr)->type,(*chr)->isCustom))
LOG0(" *** ERROR #%d! Format of UUID is invalid ***\n",++nErrors); LOG0(" *** ERROR #%d! Format of UUID is invalid ***\n",++nErrors);
else 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); LOG0(" *** ERROR #%d! Characteristic already defined for this Service ***\n",++nErrors);
if((*chr)->setRangeError) if((*chr)->setRangeError)
@ -932,13 +931,11 @@ 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))) 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)); 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 } // Characteristics
for(auto req=(*svc)->req.begin(); req!=(*svc)->req.end(); req++){ 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); LOG0(" *** WARNING #%d! Required '%s' Characteristic for this Service not found ***\n",++nWarnings,(*req)->hapName);
} }

View File

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

View File

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