Skip to content

Commit 7293889

Browse files
committed
[nrf toup] simplify Key/Value Get function and add
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. Add as well internal KeyValueExist function that returns whether a Key exist in the persistent storage or not and returns the size of its value. Simplify as well the Delete function by using KeyValueExist function. Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
1 parent d360f55 commit 7293889

File tree

1 file changed

+90
-51
lines changed

1 file changed

+90
-51
lines changed

src/platform/Zephyr/KeyValueStoreManagerImpl.cpp

+90-51
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,108 @@ void KeyValueStoreManagerImpl::Init()
152108
VerifyOrDie(settings_subsys_init() == 0);
153109
}
154110

111+
bool KeyValueExist(const char * fullkey, size_t * val_len)
112+
{
113+
ssize_t len;
114+
115+
len = settings_get_val_len(fullkey);
116+
117+
if (len > 0)
118+
{
119+
*val_len = len;
120+
return true;;
121+
}
122+
123+
return false;
124+
}
125+
126+
void LoadOneAndVerifyResult(const char * fullkey, void * dest_buf, size_t dest_size, size_t * readSize,
127+
CHIP_ERROR * result)
128+
{
129+
ssize_t bytesRead = settings_load_one(fullkey, dest_buf, dest_size);
130+
131+
// If the return code is -ENOENT the key is not found
132+
if (bytesRead == -ENOENT)
133+
{
134+
*result = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
135+
*readSize = 0;
136+
return;
137+
}
138+
if ((bytesRead == kEmptyValueSize) && !memcmp(dest_buf, kEmptyValue, kEmptyValueSize))
139+
{
140+
*result = CHIP_NO_ERROR;
141+
*readSize = 0;
142+
return;
143+
}
144+
if ((size_t)bytesRead > dest_size)
145+
{
146+
*result = CHIP_ERROR_BUFFER_TOO_SMALL;
147+
}
148+
else if (bytesRead >= 0)
149+
{
150+
*result = CHIP_NO_ERROR;
151+
}
152+
else
153+
{
154+
*result = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
155+
}
156+
157+
*readSize = (bytesRead > 0) ? bytesRead : 0;
158+
159+
return;
160+
}
161+
155162
CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
156163
size_t offset_bytes) const
157164
{
165+
CHIP_ERROR result;
166+
size_t readSize = 0;
167+
uint8_t emptyValue[kEmptyValueSize];
158168
// Offset and partial reads are not supported, for now just return NOT_IMPLEMENTED.
159169
// Support can be added in the future if this is needed.
160170
VerifyOrReturnError(offset_bytes == 0, CHIP_ERROR_NOT_IMPLEMENTED);
161171

162172
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
163173
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
164174

165-
ReadEntry entry{ value, value_size, 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND };
166-
settings_load_subtree_direct(fullKey, LoadEntryCallback, &entry);
175+
if ((!value) || (value_size == 0))
176+
{
177+
// we want only to check data size
178+
if (!KeyValueExist(fullKey, &readSize))
179+
{
180+
result = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
181+
readSize = 0;
182+
}
183+
else
184+
{
185+
result = CHIP_NO_ERROR;
186+
}
187+
}
188+
189+
if (value_size < kEmptyValueSize)
190+
{
191+
LoadOneAndVerifyResult(fullKey, emptyValue, kEmptyValueSize, &readSize, &result);
192+
if (readSize)
193+
{
194+
memcpy(value, emptyValue, value_size);
195+
}
196+
if (readSize > value_size)
197+
{
198+
result = CHIP_ERROR_BUFFER_TOO_SMALL;
199+
}
200+
}
201+
else
202+
{
203+
LoadOneAndVerifyResult(fullKey, value, value_size, &readSize, &result);
204+
}
167205

168206
// Assign readSize only in case read_bytes_size is not nullptr, as it is optional argument
169207
if (read_bytes_size)
170208
{
171-
*read_bytes_size = entry.readSize;
209+
*read_bytes_size = readSize;
172210
}
173211

174-
return entry.result;
212+
return result;
175213
}
176214

177215
CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size)
@@ -193,10 +231,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value,
193231
CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key)
194232
{
195233
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
234+
size_t val_len;
235+
196236
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
197237

198-
ReturnErrorCodeIf(Get(key, nullptr, 0) == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND,
199-
CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
238+
ReturnErrorCodeIf(!KeyValueExist(fullKey, &val_len), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
200239
ReturnErrorCodeIf(settings_delete(fullKey) != 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED);
201240

202241
return CHIP_NO_ERROR;

0 commit comments

Comments
 (0)