mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Allow random stores and accesses to MapBuffer values
Summary: Removes the need to store keys in incremental order by sorting them after before inserting into MapBuffer. Updates MapBuffer to support random access on C++ side, actually retrieving values by keys and not bucket index. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D33611758 fbshipit-source-id: c81e970613c8ecc688bfacb29ba038bf081a0c0f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1ec399781d
commit
d287598d23
@@ -12,6 +12,14 @@ using namespace facebook::react;
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static inline int32_t bucketOffset(int32_t index) {
|
||||
return HEADER_SIZE + BUCKET_SIZE * index;
|
||||
}
|
||||
|
||||
static inline int32_t valueOffset(int32_t bucketIndex) {
|
||||
return bucketOffset(bucketIndex) + offsetof(Bucket, data);
|
||||
}
|
||||
|
||||
// TODO T83483191: Extend MapBuffer C++ implementation to support basic random
|
||||
// access
|
||||
MapBuffer::MapBuffer(std::vector<uint8_t> data) : bytes_(std::move(data)) {
|
||||
@@ -25,13 +33,33 @@ MapBuffer::MapBuffer(std::vector<uint8_t> data) : bytes_(std::move(data)) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t MapBuffer::getKeyBucket(Key key) const {
|
||||
uint32_t lo = 0;
|
||||
uint32_t hi = count_ - 1;
|
||||
while (lo <= hi) {
|
||||
uint32_t mid = (lo + hi) >> 1;
|
||||
|
||||
Key midVal =
|
||||
*reinterpret_cast<Key const *>(bytes_.data() + bucketOffset(mid));
|
||||
|
||||
if (midVal < key) {
|
||||
lo = mid + 1;
|
||||
} else if (midVal > key) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t MapBuffer::getInt(Key key) const {
|
||||
int32_t value = 0;
|
||||
memcpy(
|
||||
reinterpret_cast<uint8_t *>(&value),
|
||||
bytes_.data() + getValueOffset(key),
|
||||
INT_SIZE);
|
||||
return value;
|
||||
auto bucketIndex = getKeyBucket(key);
|
||||
react_native_assert(bucketIndex != -1 && "Key not found in MapBuffer");
|
||||
|
||||
return *reinterpret_cast<int32_t const *>(
|
||||
bytes_.data() + valueOffset(bucketIndex));
|
||||
}
|
||||
|
||||
bool MapBuffer::getBool(Key key) const {
|
||||
@@ -39,41 +67,31 @@ bool MapBuffer::getBool(Key key) const {
|
||||
}
|
||||
|
||||
double MapBuffer::getDouble(Key key) const {
|
||||
// TODO T83483191: extract this code into a "template method" and reuse it for
|
||||
// other types
|
||||
double value = 0;
|
||||
memcpy(
|
||||
reinterpret_cast<uint8_t *>(&value),
|
||||
bytes_.data() + getValueOffset(key),
|
||||
DOUBLE_SIZE);
|
||||
return value;
|
||||
auto bucketIndex = getKeyBucket(key);
|
||||
react_native_assert(bucketIndex != -1 && "Key not found in MapBuffer");
|
||||
|
||||
return *reinterpret_cast<double const *>(
|
||||
bytes_.data() + valueOffset(bucketIndex));
|
||||
;
|
||||
}
|
||||
|
||||
int32_t MapBuffer::getDynamicDataOffset() const {
|
||||
// The begininig of dynamic data can be calculated as the offset of the next
|
||||
// The start of dynamic data can be calculated as the offset of the next
|
||||
// key in the map
|
||||
return getKeyOffset(count_);
|
||||
return bucketOffset(count_);
|
||||
}
|
||||
|
||||
std::string MapBuffer::getString(Key key) const {
|
||||
// TODO T83483191:Add checks to verify that offsets are under the boundaries
|
||||
// of the map buffer
|
||||
int32_t dynamicDataOffset = getDynamicDataOffset();
|
||||
int32_t stringLength = 0;
|
||||
int32_t offset = getInt(key);
|
||||
memcpy(
|
||||
reinterpret_cast<uint8_t *>(&stringLength),
|
||||
bytes_.data() + dynamicDataOffset + offset,
|
||||
INT_SIZE);
|
||||
int32_t stringLength = *reinterpret_cast<int32_t const *>(
|
||||
bytes_.data() + dynamicDataOffset + offset);
|
||||
uint8_t const *stringPtr =
|
||||
bytes_.data() + dynamicDataOffset + offset + INT_SIZE;
|
||||
|
||||
char *value = new char[stringLength];
|
||||
|
||||
memcpy(
|
||||
reinterpret_cast<char *>(value),
|
||||
bytes_.data() + dynamicDataOffset + offset + INT_SIZE,
|
||||
stringLength);
|
||||
|
||||
return std::string(value, 0, stringLength);
|
||||
return std::string(stringPtr, stringPtr + stringLength);
|
||||
}
|
||||
|
||||
MapBuffer MapBuffer::getMapBuffer(Key key) const {
|
||||
@@ -81,12 +99,9 @@ MapBuffer MapBuffer::getMapBuffer(Key key) const {
|
||||
// of the map buffer
|
||||
int32_t dynamicDataOffset = getDynamicDataOffset();
|
||||
|
||||
int32_t mapBufferLength = 0;
|
||||
int32_t offset = getInt(key);
|
||||
memcpy(
|
||||
reinterpret_cast<uint8_t *>(&mapBufferLength),
|
||||
bytes_.data() + dynamicDataOffset + offset,
|
||||
INT_SIZE);
|
||||
int32_t mapBufferLength = *reinterpret_cast<int32_t const *>(
|
||||
bytes_.data() + dynamicDataOffset + offset);
|
||||
|
||||
std::vector<uint8_t> value(mapBufferLength);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user