Skip to content

Commit caaf118

Browse files
committed
[nrf toup] simplify Key/Value Get function
Use settings_load_one function to load one key/value settings entry instead of settings_load_subtree_direct. This will avoid loading all the keys for some storage backends. Simplify as well the Delete function by using settings_get_val_len() function. Signed-off-by: Riadh Ghaddab <[email protected]>
1 parent df5368c commit caaf118

File tree

1 file changed

+88
-51
lines changed

1 file changed

+88
-51
lines changed

src/platform/Zephyr/KeyValueStoreManagerImpl.cpp

Lines changed: 88 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,6 @@ namespace DeviceLayer {
3434
namespace PersistedStorage {
3535
namespace {
3636

37-
struct ReadEntry
38-
{
39-
void * destination; // destination address
40-
size_t destinationBufferSize; // size of destination buffer
41-
size_t readSize; // [out] size of read entry value
42-
CHIP_ERROR result; // [out] read result
43-
};
44-
4537
struct DeleteSubtreeEntry
4638
{
4739
int result;
@@ -87,43 +79,6 @@ CHIP_ERROR MakeFullKey(char (&fullKey)[SETTINGS_MAX_NAME_LEN + 1], const char *
8779
return CHIP_NO_ERROR;
8880
}
8981

90-
int LoadEntryCallback(const char * name, size_t entrySize, settings_read_cb readCb, void * cbArg, void * param)
91-
{
92-
ReadEntry & entry = *static_cast<ReadEntry *>(param);
93-
94-
// If requested key X, process just node X and ignore all its descendants: X/*
95-
if (name != nullptr && *name != '\0')
96-
return 0;
97-
98-
// Found requested key.
99-
uint8_t emptyValue[kEmptyValueSize];
100-
101-
if (entrySize == kEmptyValueSize && readCb(cbArg, emptyValue, kEmptyValueSize) == kEmptyValueSize &&
102-
memcmp(emptyValue, kEmptyValue, kEmptyValueSize) == 0)
103-
{
104-
// Special case - an empty value represented by known magic bytes.
105-
entry.result = CHIP_NO_ERROR;
106-
107-
// Return 1 to stop processing further keys
108-
return 1;
109-
}
110-
111-
const ssize_t bytesRead = readCb(cbArg, entry.destination, entry.destinationBufferSize);
112-
entry.readSize = bytesRead > 0 ? bytesRead : 0;
113-
114-
if (entrySize > entry.destinationBufferSize)
115-
{
116-
entry.result = CHIP_ERROR_BUFFER_TOO_SMALL;
117-
}
118-
else
119-
{
120-
entry.result = bytesRead > 0 ? CHIP_NO_ERROR : CHIP_ERROR_PERSISTED_STORAGE_FAILED;
121-
}
122-
123-
// Return 1 to stop processing further keys
124-
return 1;
125-
}
126-
12782
int DeleteSubtreeCallback(const char * name, size_t /* entrySize */, settings_read_cb /* readCb */, void * /* cbArg */,
12883
void * param)
12984
{
@@ -143,6 +98,7 @@ int DeleteSubtreeCallback(const char * name, size_t /* entrySize */, settings_re
14398
return 0;
14499
}
145100

101+
146102
} // namespace
147103

148104
KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance;
@@ -152,26 +108,107 @@ void KeyValueStoreManagerImpl::Init()
152108
VerifyOrDie(settings_subsys_init() == 0);
153109
}
154110

111+
void LoadOneAndVerifyResult(const char * fullkey, void * dest_buf, size_t dest_size, size_t * readSize,
112+
CHIP_ERROR * result)
113+
{
114+
ssize_t bytesRead = settings_load_one(fullkey, dest_buf, dest_size);
115+
116+
// If the return code is -ENOENT the key is not found
117+
if ((bytesRead == -ENOENT) || (!bytesRead))
118+
{
119+
*result = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
120+
*readSize = 0;
121+
return;
122+
}
123+
if ((bytesRead == kEmptyValueSize) && !memcmp(dest_buf, kEmptyValue, kEmptyValueSize))
124+
{
125+
*result = CHIP_NO_ERROR;
126+
*readSize = 0;
127+
return;
128+
}
129+
if ((size_t)bytesRead > dest_size)
130+
{
131+
*result = CHIP_ERROR_BUFFER_TOO_SMALL;
132+
*readSize = dest_size;
133+
return;
134+
}
135+
else if (bytesRead >= 0)
136+
{
137+
*result = CHIP_NO_ERROR;
138+
}
139+
else
140+
{
141+
*result = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
142+
}
143+
144+
*readSize = (bytesRead > 0) ? bytesRead : 0;
145+
146+
return;
147+
}
148+
155149
CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
156150
size_t offset_bytes) const
157151
{
152+
CHIP_ERROR result;
153+
size_t readSize = 0;
154+
ssize_t ret = 0;
155+
uint8_t emptyValue[kEmptyValueSize];
158156
// Offset and partial reads are not supported, for now just return NOT_IMPLEMENTED.
159157
// Support can be added in the future if this is needed.
160158
VerifyOrReturnError(offset_bytes == 0, CHIP_ERROR_NOT_IMPLEMENTED);
161159

162160
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
163161
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
164162

165-
ReadEntry entry{ value, value_size, 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND };
166-
settings_load_subtree_direct(fullKey, LoadEntryCallback, &entry);
163+
if ((!value) || (value_size == 0))
164+
{
165+
// we want only to verify that the key exists
166+
ret = settings_get_val_len(fullKey);
167+
if (ret > 0)
168+
{
169+
result = CHIP_NO_ERROR;
170+
}
171+
else if (!ret || (ret == -ENOENT))
172+
{
173+
result = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
174+
}
175+
else
176+
{
177+
result = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
178+
}
179+
// check that this pointer is not null as it is an optional argument
180+
if (read_bytes_size)
181+
{
182+
*read_bytes_size = 0;
183+
}
184+
185+
return result;
186+
}
187+
188+
if (value_size < kEmptyValueSize)
189+
{
190+
LoadOneAndVerifyResult(fullKey, emptyValue, kEmptyValueSize, &readSize, &result);
191+
if (readSize)
192+
{
193+
memcpy(value, emptyValue, value_size);
194+
}
195+
if (readSize > value_size)
196+
{
197+
result = CHIP_ERROR_BUFFER_TOO_SMALL;
198+
}
199+
}
200+
else
201+
{
202+
LoadOneAndVerifyResult(fullKey, value, value_size, &readSize, &result);
203+
}
167204

168205
// Assign readSize only in case read_bytes_size is not nullptr, as it is optional argument
169206
if (read_bytes_size)
170207
{
171-
*read_bytes_size = entry.readSize;
208+
*read_bytes_size = readSize;
172209
}
173210

174-
return entry.result;
211+
return result;
175212
}
176213

177214
CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size)
@@ -193,10 +230,10 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value,
193230
CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key)
194231
{
195232
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
233+
196234
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
197235

198-
ReturnErrorCodeIf(Get(key, nullptr, 0) == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND,
199-
CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
236+
ReturnErrorCodeIf(!settings_get_val_len(fullKey), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
200237
ReturnErrorCodeIf(settings_delete(fullKey) != 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED);
201238

202239
return CHIP_NO_ERROR;

0 commit comments

Comments
 (0)