From 98d6abeb1f88a68930fa4738a5edf0b6af4c5309 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sun, 12 Nov 2023 09:48:46 -0600 Subject: [PATCH] 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 is as efficient as using find() method of an unordered_set. To do: Remove all uses of unordered_set across HomeSpan wherever possible --- src/HomeSpan.cpp | 13 +++++-------- src/HomeSpan.h | 4 ++-- src/Span.h | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 8576666..2de8c34 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -39,6 +39,7 @@ #include "HomeSpan.h" #include "HAP.h" +#include 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... isBridge=false; // ...this is not a bridge device - - unordered_set 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) @@ -932,13 +931,11 @@ void Span::processSerialCommand(const char *c){ if((*chr)->format!=STRING && ((*chr)->uvGet((*chr)->value) < (*chr)->uvGet((*chr)->minValue) || (*chr)->uvGet((*chr)->value) > (*chr)->uvGet((*chr)->maxValue))) LOG0(" *** WARNING #%d! Value of %g is out of range [%g,%g] ***\n",++nWarnings,(*chr)->uvGet((*chr)->value),(*chr)->uvGet((*chr)->minValue),(*chr)->uvGet((*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); } diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 2fb0f97..a61b5ca 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -426,8 +426,8 @@ class SpanService{ protected: virtual ~SpanService(); // destructor - unordered_set req; // unordered set of pointers to all required HAP Characteristic Types for this Service - unordered_set opt; // unordered set of pointers to all optional HAP Characteristic Types for this Service + vector req; // vector of pointers to all required HAP Characteristic Types for this Service + vector opt; // vector of pointers to all optional HAP Characteristic Types for this Service public: diff --git a/src/Span.h b/src/Span.h index ff43382..015a408 100644 --- a/src/Span.h +++ b/src/Span.h @@ -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 {