Skip to content

Commit ab55e1c

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 <[email protected]>
1 parent a13da8b commit ab55e1c

File tree

1 file changed

+93
-51
lines changed

1 file changed

+93
-51
lines changed

src/platform/Zephyr/KeyValueStoreManagerImpl.cpp

Lines changed: 93 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,33 +108,118 @@ 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+
printk("Riadh loading key %s bytesRead %u\n", fullkey, bytesRead);
132+
// If the return code is -ENOENT the key is not found
133+
if ((bytesRead == -ENOENT) || (!bytesRead))
134+
{
135+
*result = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
136+
*readSize = 0;
137+
return;
138+
}
139+
if ((bytesRead == kEmptyValueSize) && !memcmp(dest_buf, kEmptyValue, kEmptyValueSize))
140+
{
141+
*result = CHIP_NO_ERROR;
142+
*readSize = 0;
143+
return;
144+
}
145+
if ((size_t)bytesRead > dest_size)
146+
{
147+
*result = CHIP_ERROR_BUFFER_TOO_SMALL;
148+
}
149+
else if (bytesRead >= 0)
150+
{
151+
*result = CHIP_NO_ERROR;
152+
}
153+
else
154+
{
155+
*result = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
156+
}
157+
158+
*readSize = (bytesRead > 0) ? bytesRead : 0;
159+
160+
return;
161+
}
162+
155163
CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
156164
size_t offset_bytes) const
157165
{
166+
CHIP_ERROR result;
167+
size_t readSize = 0;
168+
uint8_t emptyValue[kEmptyValueSize];
158169
// Offset and partial reads are not supported, for now just return NOT_IMPLEMENTED.
159170
// Support can be added in the future if this is needed.
160171
VerifyOrReturnError(offset_bytes == 0, CHIP_ERROR_NOT_IMPLEMENTED);
161172

162173
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
163174
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
164175

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

168207
// Assign readSize only in case read_bytes_size is not nullptr, as it is optional argument
169208
if (read_bytes_size)
170209
{
171-
*read_bytes_size = entry.readSize;
210+
*read_bytes_size = readSize;
172211
}
212+
printk("Riadh result : %" CHIP_ERROR_FORMAT "\n", result.Format());
173213

174-
return entry.result;
214+
return result;
175215
}
176216

177217
CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size)
178218
{
179219
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
180220
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
181221

222+
printk("Riadh Put %s size %u\n", fullKey, value_size);
182223
if (value_size == 0)
183224
{
184225
value = kEmptyValue;
@@ -193,10 +234,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value,
193234
CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key)
194235
{
195236
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
237+
size_t val_len;
238+
196239
ReturnErrorOnFailure(MakeFullKey(fullKey, key));
197240

198-
ReturnErrorCodeIf(Get(key, nullptr, 0) == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND,
199-
CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
241+
ReturnErrorCodeIf(!KeyValueExist(fullKey, &val_len), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
200242
ReturnErrorCodeIf(settings_delete(fullKey) != 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED);
201243

202244
return CHIP_NO_ERROR;

0 commit comments

Comments
 (0)