slot 0.0.1
A real time UI render framework
载入中...
搜索中...
未找到
SmallValueBuffer.h
浏览该文件的文档.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#pragma once
9
10#include <array>
11#include <bitset>
12#include <cassert>
13#include <cstdint>
14#include <memory>
15#include <vector>
16
17namespace facebook::yoga {
18
19// Container which allows storing 32 or 64 bit integer values, whose index may
20// never change. Values are first stored in a fixed buffer of `BufferSize`
21// 32-bit chunks, before falling back to heap allocation.
22template <size_t BufferSize>
24 public:
25 SmallValueBuffer() = default;
27 *this = other;
28 }
29 SmallValueBuffer(SmallValueBuffer&& other) noexcept = default;
30
31 // Add a new element to the buffer, returning the index of the element
32 uint16_t push(uint32_t value) {
33 const auto index = count_++;
34 assert(index < 4096 && "SmallValueBuffer can only hold up to 4096 chunks");
35 if (index < buffer_.size()) {
36 buffer_[index] = value;
37 return index;
38 }
39
40 if (overflow_ == nullptr) {
41 overflow_ = std::make_unique<SmallValueBuffer::Overflow>();
42 }
43
44 overflow_->buffer_.push_back(value);
45 overflow_->wideElements_.push_back(false);
46 return index;
47 }
48
49 uint16_t push(uint64_t value) {
50 const auto lsb = static_cast<uint32_t>(value & 0xFFFFFFFF);
51 const auto msb = static_cast<uint32_t>(value >> 32);
52
53 const auto lsbIndex = push(lsb);
54 [[maybe_unused]] const auto msbIndex = push(msb);
55 assert(
56 msbIndex < 4096 && "SmallValueBuffer can only hold up to 4096 chunks");
57
58 if (lsbIndex < buffer_.size()) {
59 wideElements_[lsbIndex] = true;
60 } else {
61 overflow_->wideElements_[lsbIndex - buffer_.size()] = true;
62 }
63 return lsbIndex;
64 }
65
66 // Replace an existing element in the buffer with a new value. A new index
67 // may be returned, e.g. if a new value is wider than the previous.
68 [[nodiscard]] uint16_t replace(uint16_t index, uint32_t value) {
69 if (index < buffer_.size()) {
70 buffer_[index] = value;
71 } else {
72 overflow_->buffer_.at(index - buffer_.size()) = value;
73 }
74
75 return index;
76 }
77
78 [[nodiscard]] uint16_t replace(uint16_t index, uint64_t value) {
79 const bool isWide = index < wideElements_.size()
80 ? wideElements_[index]
81 : overflow_->wideElements_.at(index - buffer_.size());
82
83 if (isWide) {
84 const auto lsb = static_cast<uint32_t>(value & 0xFFFFFFFF);
85 const auto msb = static_cast<uint32_t>(value >> 32);
86
87 [[maybe_unused]] auto lsbIndex = replace(index, lsb);
88 [[maybe_unused]] auto msbIndex = replace(index + 1, msb);
89 return index;
90 } else {
91 return push(value);
92 }
93 }
94
95 // Get a value of a given width
96 uint32_t get32(uint16_t index) const {
97 if (index < buffer_.size()) {
98 return buffer_[index];
99 } else {
100 return overflow_->buffer_.at(index - buffer_.size());
101 }
102 }
103
104 uint64_t get64(uint16_t index) const {
105 const auto lsb = get32(index);
106 const auto msb = get32(index + 1);
107 return (static_cast<uint64_t>(msb) << 32) | lsb;
108 }
109
111 count_ = other.count_;
112 buffer_ = other.buffer_;
114 overflow_ = other.overflow_ ? std::make_unique<Overflow>(*other.overflow_)
115 : nullptr;
116 return *this;
117 }
118
119 SmallValueBuffer& operator=(SmallValueBuffer&& other) noexcept = default;
120
121 private:
122 struct Overflow {
123 std::vector<uint32_t> buffer_;
124 std::vector<bool> wideElements_;
125 };
126
127 uint16_t count_{0};
128 std::array<uint32_t, BufferSize> buffer_{};
129 std::bitset<BufferSize> wideElements_;
130 std::unique_ptr<Overflow> overflow_;
131};
132
133} // namespace facebook::yoga
Definition SmallValueBuffer.h:23
std::unique_ptr< Overflow > overflow_
Definition SmallValueBuffer.h:130
uint16_t push(uint32_t value)
Definition SmallValueBuffer.h:32
uint16_t push(uint64_t value)
Definition SmallValueBuffer.h:49
SmallValueBuffer & operator=(const SmallValueBuffer &other)
Definition SmallValueBuffer.h:110
uint64_t get64(uint16_t index) const
Definition SmallValueBuffer.h:104
uint16_t replace(uint16_t index, uint64_t value)
Definition SmallValueBuffer.h:78
std::bitset< BufferSize > wideElements_
Definition SmallValueBuffer.h:129
SmallValueBuffer(SmallValueBuffer &&other) noexcept=default
uint16_t count_
Definition SmallValueBuffer.h:127
uint16_t replace(uint16_t index, uint32_t value)
Definition SmallValueBuffer.h:68
SmallValueBuffer(const SmallValueBuffer &other)
Definition SmallValueBuffer.h:26
uint32_t get32(uint16_t index) const
Definition SmallValueBuffer.h:96
std::array< uint32_t, BufferSize > buffer_
Definition SmallValueBuffer.h:128
SmallValueBuffer & operator=(SmallValueBuffer &&other) noexcept=default
Definition Benchmark.cpp:19
Definition SmallValueBuffer.h:122
std::vector< bool > wideElements_
Definition SmallValueBuffer.h:124
std::vector< uint32_t > buffer_
Definition SmallValueBuffer.h:123