From ef24cdc7dee3c56876c7d9bb9ceaa703d33a6a2e Mon Sep 17 00:00:00 2001 From: SirSydom Date: Sat, 19 Feb 2022 23:18:39 +0100 Subject: [PATCH] #175 added a binary search for address and assoc table can be enabled by defining USE_BINSEARCH --- src/knx/address_table_object.cpp | 39 +++++++++++++++++++++++++++- src/knx/association_table_object.cpp | 24 +++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/knx/address_table_object.cpp b/src/knx/address_table_object.cpp index 689580c..5c90b40 100644 --- a/src/knx/address_table_object.cpp +++ b/src/knx/address_table_object.cpp @@ -36,9 +36,28 @@ uint16_t AddressTableObject::getGroupAddress(uint16_t tsap) uint16_t AddressTableObject::getTsap(uint16_t addr) { uint16_t size = entryCount(); + #ifdef USE_BINSEARCH + addr = htons(addr); + + uint16_t low,high,i; + low = 0; + high = size-1; + + while(low <= high) + { + i = (low+high)/2; + if (_groupAddresses[i] == addr) + return i; + if(addr < _groupAddresses[i]) + 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,10 +77,28 @@ const uint8_t* AddressTableObject::restore(const uint8_t* buffer) bool AddressTableObject::contains(uint16_t addr) { uint16_t size = entryCount(); + #ifdef USE_BINSEARCH + addr = htons(addr); + + uint16_t low,high,i; + low = 0; + high = size-1; + + while(low <= high) + { + i = (low+high)/2; + if (_groupAddresses[i] == addr) + return true; + if(addr < _groupAddresses[i]) + high = i - 1; + else + low = i + 1 ; + } + #else for (uint16_t i = 1; i <= size; i++) if (ntohs(_groupAddresses[i]) == addr) return true; - + #endif return false; } diff --git a/src/knx/association_table_object.cpp b/src/knx/association_table_object.cpp index 0880fc7..b1d8c56 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 getASAP(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; }