From b428863b4b1fc75a9c1bf21f372ba6f17b684b78 Mon Sep 17 00:00:00 2001 From: Nanosonde <2073569+nanosonde@users.noreply.github.com> Date: Thu, 2 Jul 2020 12:01:01 +0200 Subject: [PATCH] Move map to own file --- src/knx/simple_map.h | 131 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/knx/simple_map.h diff --git a/src/knx/simple_map.h b/src/knx/simple_map.h new file mode 100644 index 0000000..895f9f3 --- /dev/null +++ b/src/knx/simple_map.h @@ -0,0 +1,131 @@ +#pragma once + +// Provides a simple unordered map which is based on two arrays of the same data type. +// One array is used for the keys, the other array is used for the values. +// Tracking of free/occupied slots in the arrays is realized by a bitmask of size uint64_t. +// As a result the maximum size of the map is 64 entries. +// If a non-primitive data type is required for the key by using a "class" or "struct", +// then the operator== has to be provided by that class/struct: +// bool operator ==(const K&) const { return true/false; } + +template +class Map +{ +public: + Map() + { + static_assert (SIZE <= 64, "Map is too big! Max. 64 elements."); + } + + void clear() + { + _validEntries = 0; + } + + bool empty() + { + return (_validEntries == 0); + } + + uint8_t size() + { + uint8_t size = 0; + + for (uint8_t i = 0; i < SIZE; i++) + { + size += (((_validEntries >> i) & 0x01) == 0x01) ? 1 : 0; + } + + return size; + } + + bool insert(K key, V value) + { + uint8_t index = getNextFreeIndex(); + if (index != noFreeEntryFoundIndex) + { + keys[index] = key; + values[index] = value; + + _validEntries |= 1 << index; + return true; + } + + // No free space + return false; + } + + bool insertOrAssign(K key, V value) + { + // Try to find the key + for (uint8_t i = 0; i < SIZE; i++) + { + // Check if this array slot is occupied + if ((_validEntries >> i) & 0x01) + { + // Key found? + if (keys[i] == key) + { + values[i] = value; + return true; + } + } + } + + // Key does not exist, add it if enough space + return insert(key, value); + } + + bool erase(K key) + { + for (uint8_t i = 0; i < SIZE; i++) + { + if ((_validEntries >> i) & 0x01) + { + if (keys[i] == key) + { + _validEntries &= ~(1 << i); + return true; + } + } + } + return false; + } + + V* get(K key) + { + // Try to find the key + for (uint8_t i = 0; i < SIZE; i++) + { + // Check if this array slot is occupied + if ((_validEntries >> i) & 0x01) + { + // Key found? + if (keys[i] == key) + { + return &values[i]; + } + } + } + return nullptr; + } + +private: + uint8_t getNextFreeIndex() + { + for (uint8_t i = 0; i < SIZE; i++) + { + if (((_validEntries >> i) & 0x01) == 0) + { + return i; + } + } + + return noFreeEntryFoundIndex; + } + + uint64_t _validEntries{0}; + K keys[SIZE]; + V values[SIZE]; + static constexpr uint8_t noFreeEntryFoundIndex = 255; +};