Files
react-native/ReactCommon/react/renderer/core/RawPropsKeyMap.cpp
T
Samuel Susla 51af7cdcde Use nested namespace name
Summary:
changelog: [internal]

Enable two new clang tidy checks:
- modernize-concat-nested-namespaces
- google-build-using-namespace

jest_e2e[run_all_tests]

Reviewed By: rshest

Differential Revision: D40020646

fbshipit-source-id: f3be80b5f829dd0ba376bdd70ed13332e114d48a
2022-10-13 05:07:59 -07:00

107 lines
3.0 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "RawPropsKeyMap.h"
#include <react/debug/react_native_assert.h>
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <cstring>
namespace facebook::react {
bool RawPropsKeyMap::hasSameName(Item const &lhs, Item const &rhs) noexcept {
return lhs.length == rhs.length &&
(std::memcmp(lhs.name, rhs.name, lhs.length) == 0);
}
bool RawPropsKeyMap::shouldFirstOneBeBeforeSecondOne(
Item const &lhs,
Item const &rhs) noexcept {
if (lhs.length != rhs.length) {
return lhs.length < rhs.length;
}
return std::memcmp(lhs.name, rhs.name, rhs.length) < 0;
}
void RawPropsKeyMap::insert(
RawPropsKey const &key,
RawPropsValueIndex value) noexcept {
auto item = Item{};
item.value = value;
key.render(item.name, &item.length);
items_.push_back(item);
}
void RawPropsKeyMap::reindex() noexcept {
// Sorting `items_` by property names length and then lexicographically.
// Note, sort algorithm must be stable.
std::stable_sort(
items_.begin(),
items_.end(),
&RawPropsKeyMap::shouldFirstOneBeBeforeSecondOne);
// Filtering out duplicating keys.
// If some `*Props` object requests a prop more than once, only the first
// request will be fulfilled. E.g. `TextInputProps` class has a sub-property
// `backgroundColor` twice, the first time as part of `ViewProps` base-class
// and the second as part of `BaseTextProps` base-class. In this
// configuration, the only one which comes first (from `ViewProps`, which
// appear first) will be assigned.
items_.erase(
std::unique(items_.begin(), items_.end(), &RawPropsKeyMap::hasSameName),
items_.end());
buckets_.resize(kPropNameLengthHardCap);
auto length = RawPropsPropNameLength{0};
for (size_t i = 0; i < items_.size(); i++) {
auto &item = items_[i];
if (item.length != length) {
for (auto j = length; j < item.length; j++) {
buckets_[j] = static_cast<RawPropsPropNameLength>(i);
}
length = item.length;
}
}
for (auto j = length; j < buckets_.size(); j++) {
buckets_[j] = static_cast<RawPropsPropNameLength>(items_.size());
}
}
RawPropsValueIndex RawPropsKeyMap::at(
char const *name,
RawPropsPropNameLength length) noexcept {
react_native_assert(length > 0);
react_native_assert(length < kPropNameLengthHardCap);
// 1. Find the bucket.
auto lower = int{buckets_[length - 1]};
auto upper = int{buckets_[length]} - 1;
react_native_assert(lower - 1 <= upper);
// 2. Binary search in the bucket.
while (lower <= upper) {
auto median = (lower + upper) / 2;
auto condition = std::memcmp(items_[median].name, name, length);
if (condition < 0) {
lower = median + 1;
} else if (condition == 0) {
return items_[median].value;
} else /* if (condition > 0) */ {
upper = median - 1;
}
}
return kRawPropsValueIndexEmpty;
}
} // namespace facebook::react