Skip to content

Commit

Permalink
settings: query for specific entry
Browse files Browse the repository at this point in the history
separate search and value retrieval
  • Loading branch information
mcspr committed Apr 14, 2024
1 parent 20583c7 commit c3ab86b
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 61 deletions.
2 changes: 1 addition & 1 deletion code/espurna/button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ bool checkSamePrefix(StringView key) {
}

String findValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
button::internal::buttons.size(), IndexedSettings, key);
}

Expand Down
2 changes: 1 addition & 1 deletion code/espurna/homeassistant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ bool checkSamePrefix(espurna::StringView key) {
}

String findValueFrom(espurna::StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}

void setup() {
Expand Down
2 changes: 1 addition & 1 deletion code/espurna/led.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ bool checkSamePrefix(StringView key) {
}

String findValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
::espurna::led::internal::leds.size(), IndexedSettings, key);
}

Expand Down
2 changes: 1 addition & 1 deletion code/espurna/mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ bool checkSamePrefix(espurna::StringView key) {
}

String findValueFrom(espurna::StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}

void setup() {
Expand Down
4 changes: 2 additions & 2 deletions code/espurna/relay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3322,7 +3322,7 @@ bool checkSamePrefix(StringView key) {
}

String findIndexedValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(_relays.size(), IndexedSettings, key);
return espurna::settings::query::findValueFrom(_relays.size(), IndexedSettings, key);
}

bool checkExact(StringView key) {
Expand All @@ -3336,7 +3336,7 @@ bool checkExact(StringView key) {
}

String findValueFrom(StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}

void setup() {
Expand Down
2 changes: 1 addition & 1 deletion code/espurna/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ bool checkSamePrefix(StringView key) {
}

String findIndexedValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(count(), IndexedSettings, key);
return espurna::settings::query::findValueFrom(count(), IndexedSettings, key);
}

void setup() {
Expand Down
2 changes: 1 addition & 1 deletion code/espurna/sensors/DigitalSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ bool checkSamePrefix(StringView key) {
}

String findValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
build::SensorsMax, IndexedSettings, key);
}

Expand Down
52 changes: 36 additions & 16 deletions code/espurna/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,53 +41,73 @@ static kvs_type kv_store(

namespace query {

const Setting* Setting::findFrom(const Setting* begin, const Setting* end, StringView key) {
String Result::value() const {
if (_ptr == nullptr) {
return String();
}

return (_index == IndexMax)
? (*reinterpret_cast<const Setting*>(_ptr)).value()
: (*reinterpret_cast<const IndexedSetting*>(_ptr)).value(_index);
}

Result findFrom(const Setting* begin, const Setting* end, StringView key) {
for (auto it = begin; it != end; ++it) {
if ((*it) == key) {
return it;
return Result(it);
}
}

return end;
return Result(nullptr);
}

String Setting::findValueFrom(const Setting* begin, const Setting* end, StringView key) {
String findValueFrom(const Setting* begin, const Setting* end, StringView key) {
String out;

const auto value = findFrom(begin, end, key);
if (value != end) {
out = (*value).value();
const auto result = findFrom(begin, end, key);
if (result.ok()) {
out = result.value();
}

return out;
}

bool IndexedSetting::findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
const IndexedSetting* findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
const IndexedSetting* out { nullptr };

for (auto it = begin; it != end; ++it) {
if (key.startsWith((*it).prefix())) {
return true;
out = it;
break;
}
}

return false;
return out;
}

String IndexedSetting::findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
String out;

Result findFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
while (iota) {
for (auto it = begin; it != end; ++it) {
const auto expected = Key(
(*it).prefix().toString(), *iota);
if (key == expected.value()) {
out = (*it).value(*iota);
goto output;
return Result(it, *iota);
}
}
++iota;
}

output:
return Result(nullptr);
}

String findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
String out;

const auto result = findFrom(iota, begin, end, key);
if (result.pointer() != end) {
out = result.value();
}

return out;
}

Expand Down
118 changes: 90 additions & 28 deletions code/espurna/settings_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,8 @@ struct StringViewIterator {
// both require a linear iterators as input e.g. most commonly - a static array
// (either a plain [], or an std::array. template should treat both equally)

struct Result;

// single key variant, exact match of the provided string
struct alignas(8) Setting {
using ValueFunc = String(*)();
Expand All @@ -373,20 +375,6 @@ struct alignas(8) Setting {
return _key == key;
}

static const Setting* findFrom(const Setting* begin, const Setting* end, StringView key);

template <typename T>
static const Setting* findFrom(const T& settings, StringView key) {
return findFrom(std::begin(settings), std::end(settings), key);
}

static String findValueFrom(const Setting* begin, const Setting* end, StringView key);

template <typename T>
static String findValueFrom(const T& settings, StringView key) {
return findValueFrom(std::begin(settings), std::end(settings), key);
}

private:
StringView _key;
ValueFunc _func;
Expand Down Expand Up @@ -415,30 +403,104 @@ struct alignas(8) IndexedSetting {
return _prefix;
}

static bool findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key);
private:
StringView _prefix;
ValueFunc _func;
};

template <typename T>
static bool findSamePrefix(const T& settings, StringView key) {
return findSamePrefix(std::begin(settings), std::end(settings), key);
}
// generic way to retrieve specific settings entry or report its absence
struct Result {
static constexpr size_t IndexMax = std::numeric_limits<size_t>::max();

static String findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key);
Result(const Result&) = default;
Result& operator=(const Result&) = default;

template <typename T>
static String findValueFrom(Iota iota, const T& settings, StringView key) {
return findValueFrom(iota, std::begin(settings), std::end(settings), key);
Result(Result&&) = default;
Result& operator=(Result&&) = default;

Result() = default;

explicit Result(const Setting* setting) :
_ptr(setting)
{}

Result(const IndexedSetting* setting, size_t index) :
_ptr(setting),
_index(index)
{}

bool ok() const {
return _ptr != nullptr;
}

template <typename T>
static String findValueFrom(size_t size, const T& settings, StringView key) {
return findValueFrom(Iota{size}, settings, key);
explicit operator bool() const {
return ok();
}

String value() const;

const void* pointer() const {
return _ptr;
}

private:
StringView _prefix;
ValueFunc _func;
const void* _ptr { nullptr };
size_t _index { IndexMax };
};

Result findFrom(const Setting* begin, const Setting* end, StringView key);

template <typename T>
inline Result findFrom(const T& settings, StringView key) {
return findFrom(std::begin(settings), std::end(settings), key);
}

String findValueFrom(const Setting* begin, const Setting* end, StringView key);

template <typename T>
inline String findValueFrom(const T& settings, StringView key) {
return findValueFrom(std::begin(settings), std::end(settings), key);
}

Result findFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key);

template <typename T>
inline Result findFrom(Iota iota, const T& settings, StringView key) {
return findFrom(iota, std::begin(settings), std::end(settings), key);
}

template <typename T>
inline Result findFrom(size_t size, const T& settings, StringView key) {
return findFrom(Iota{size}, settings, key);
}

String findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key);

template <typename T>
inline String findValueFrom(Iota iota, const T& settings, StringView key) {
return findValueFrom(iota, std::begin(settings), std::end(settings), key);
}

template <typename T>
inline String findValueFrom(size_t size, const T& settings, StringView key) {
return findValueFrom(Iota{size}, settings, key);
}

const IndexedSetting* findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key);

template <typename T>
inline const IndexedSetting* findSamePrefix(const T& settings, StringView key) {
return findSamePrefix(std::begin(settings), std::end(settings), key);
}

inline bool hasSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
return nullptr != findSamePrefix(begin, end, key);
}

template <typename T>
inline bool hasSamePrefix(const T& settings, StringView key) {
return hasSamePrefix(std::begin(settings), std::end(settings), key);
}

} // namespace query
} // namespace settings
Expand Down
4 changes: 2 additions & 2 deletions code/espurna/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,11 +599,11 @@ static constexpr std::array<espurna::settings::query::Setting, 5> Settings PROGM
}};

bool checkExact(StringView key) {
return espurna::settings::query::Setting::findFrom(Settings, key) != Settings.end();
return espurna::settings::query::findFrom(Settings, key).ok();
}

String findValueFrom(StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}

void setup() {
Expand Down
2 changes: 1 addition & 1 deletion code/espurna/telnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ bool checkExactPrefix(StringView key) {
}

String findValueFrom(StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}

void setup() {
Expand Down
2 changes: 1 addition & 1 deletion code/espurna/uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ bool checkSamePrefix(StringView key) {
}

String findIndexedValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
ports(), IndexedSettings, key);

}
Expand Down
8 changes: 3 additions & 5 deletions code/espurna/wifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2264,7 +2264,7 @@ static constexpr std::array<espurna::settings::query::Setting, 11> Settings PROG

// indexed settings for 'sta' connections
bool checkIndexedPrefix(StringView key) {
return espurna::settings::query::IndexedSetting::findSamePrefix(
return espurna::settings::query::hasSamePrefix(
sta::settings::query::Settings, key);
}

Expand All @@ -2274,15 +2274,13 @@ bool checkExactPrefix(StringView key) {
}

String findIndexedValueFrom(StringView key) {
using espurna::settings::query::IndexedSetting;
return IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
sta::countNetworks(),
sta::settings::query::Settings, key);
}

String findValueFrom(StringView key) {
using espurna::settings::query::Setting;
return Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}

void setup() {
Expand Down

0 comments on commit c3ab86b

Please sign in to comment.