Closed mpawlowski-eyeo closed 3 months ago
Another way this problem manifests is:
key: "key1"
data: {I want this}
std::string key = "key100"
std::string_view truncated_key = key;
truncated_key.remove_suffix(2); // truncated_key = "key1"
auto* result = mapping()->LookupByKey(truncated_key.data());
result
is empty - I don't find what I'm looking even though
"key1"
-> {I want this}
mappingtruncated_key
== "key1"
LookupByKey
quietly searches for "key100"
instead.
Seems you can fix this while still using std::bsearch
- PR submitted.
Using flatc version 23.5.26.
With a schema like this:
If you add to this table:
And then perform a lookup like so:
result
will contain {some data}.My intention was to search for "key1" but instead I got results for "key100".
This is because
truncated_key
's value is not null-terminated, and the algorithm effectively goes out-of-bounds with respect to the string_view'ssize()
.LookupByKey
is implemented withstd::bsearch
and its pointer-based API makes it impossible to fix the problem I think.std::bsearch
can only compare akey
pointer with adata
pointer, without knowing the size ofkey
- only the size ofdata
can be specified upfront. Even a custom comparator cannot solve the problem because it's a function pointer that receives two void* arguments and cannot be bound with extra information (like the size ofkey
).Maybe
LookupByKey
can be implemented viastd::binary_search
instead - it allows arbitrary key values and comparators and should be just as efficient.