From 7bf3696a3bc50b0b36f28e8ce24ee9b763d57ee8 Mon Sep 17 00:00:00 2001 From: mumpf Date: Fri, 21 Oct 2022 10:03:11 +0200 Subject: [PATCH] Feature175 binarysearch (#218) * #175 added a binary search for address and assoc table can be enabled by defining USE_BINSEARCH * Corrected BIN_SEARCH * AddressTableObject::contains minimal improve * Review: changed ntohs to htons * corrected byte order during access to sorted array Co-authored-by: SirSydom Co-authored-by: Waldemar Porscha --- src/knx/address_table_object.cpp | 26 ++++++++++++++++++++------ src/knx/association_table_object.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/knx/address_table_object.cpp b/src/knx/address_table_object.cpp index c2e9154..7b18af4 100644 --- a/src/knx/address_table_object.cpp +++ b/src/knx/address_table_object.cpp @@ -37,9 +37,28 @@ uint16_t AddressTableObject::getGroupAddress(uint16_t tsap) uint16_t AddressTableObject::getTsap(uint16_t addr) { uint16_t size = entryCount(); + #ifdef USE_BINSEARCH + + uint16_t low,high,i; + low = 1; + high = size; + + while(low <= high) + { + i = (low+high)/2; + uint16_t ga = ntohs(_groupAddresses[i]); + if (ga == addr) + return i; + if(addr < ga) + high = i - 1; + else + low = i + 1 ; + } + #else for (uint16_t i = 1; i <= size; i++) if (ntohs(_groupAddresses[i]) == addr) return i; + #endif return 0; } @@ -58,12 +77,7 @@ const uint8_t* AddressTableObject::restore(const uint8_t* buffer) bool AddressTableObject::contains(uint16_t addr) { - uint16_t size = entryCount(); - for (uint16_t i = 1; i <= size; i++) - if (ntohs(_groupAddresses[i]) == addr) - return true; - - return false; + return (getTsap(addr) > 0); } void AddressTableObject::beforeStateChange(LoadState& newState) diff --git a/src/knx/association_table_object.cpp b/src/knx/association_table_object.cpp index 92cc839..2afbc7b 100644 --- a/src/knx/association_table_object.cpp +++ b/src/knx/association_table_object.cpp @@ -50,11 +50,35 @@ const uint8_t* AssociationTableObject::restore(const uint8_t* buffer) int32_t AssociationTableObject::translateAsap(uint16_t asap) { uint16_t entries = entryCount(); + #ifdef USE_BINSEARCH + uint16_t low,high,i; + low = 0; + high = entries-1; + + while(low <= high) + { + i = (low+high)/2; + uint16_t asap_i = getASAP(i); + if (asap_i == asap) + { + // as the binary search does not hit the first element in a list with identical items, + // search downwards to return the first occurence in the table + while(getASAP(--i) == asap) + ; + return getTSAP(i+1); + } + if(asap_i > asap) + high = i - 1; + else + low = i + 1 ; + } + #else for (uint16_t i = 0; i < entries; i++) { if (getASAP(i) == asap) return getTSAP(i); } + #endif return -1; }