From a10470180235e27a1f0b4dd36721965d9e83c611 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 29 Jun 2026 02:27:31 -0700 Subject: [PATCH 1/2] Add IntBuffer and DoubleBuffer entry types to MapBuffer Summary: Adds two new MapBuffer entry types, `IntBuffer` and `DoubleBuffer`, for storing homogeneous arrays of ints and doubles compactly in the dynamic data section. Unlike `Map` / map lists, these carry no per-element key/type overhead: a batch of N values costs ~N*elementSize bytes plus a single 4-byte count prefix instead of N 12-byte buckets. The bucket value holds the offset of the array within the dynamic data section. Covers the full surface: the C++ reader (`MapBuffer::getIntBuffer` / `getDoubleBuffer`), the C++ builder (`MapBufferBuilder::putIntBuffer` / `putDoubleBuffer`), and the Kotlin reader API (`MapBuffer.getIntBuffer` / `getDoubleBuffer`, `Entry.intBufferValue` / `doubleBufferValue`). The `DataType` enum gains `IntBuffer = 6` and `DoubleBuffer = 7`, kept in sync across C++ and Kotlin. Changelog: [General][Added] - Add `IntBuffer` and `DoubleBuffer` entry types to MapBuffer for compact homogeneous int/double arrays Differential Revision: D109848476 --- .../ReactAndroid/api/ReactAndroid.api | 8 +++ .../react/common/mapbuffer/MapBuffer.kt | 40 ++++++++++++ .../common/mapbuffer/ReadableMapBuffer.kt | 34 ++++++++++ .../common/mapbuffer/WritableMapBuffer.kt | 10 +++ .../react/renderer/mapbuffer/MapBuffer.cpp | 40 ++++++++++++ .../react/renderer/mapbuffer/MapBuffer.h | 16 ++++- .../renderer/mapbuffer/MapBufferBuilder.cpp | 46 +++++++++++++ .../renderer/mapbuffer/MapBufferBuilder.h | 4 ++ .../mapbuffer/tests/MapBufferTest.cpp | 64 +++++++++++++++++++ .../api-snapshots/ReactAndroidDebugCxx.api | 6 ++ .../api-snapshots/ReactAndroidNewarchCxx.api | 6 ++ .../api-snapshots/ReactAndroidReleaseCxx.api | 6 ++ .../api-snapshots/ReactAppleDebugCxx.api | 6 ++ .../api-snapshots/ReactAppleNewarchCxx.api | 6 ++ .../api-snapshots/ReactAppleReleaseCxx.api | 6 ++ .../api-snapshots/ReactCommonDebugCxx.api | 6 ++ .../api-snapshots/ReactCommonNewarchCxx.api | 6 ++ .../api-snapshots/ReactCommonReleaseCxx.api | 6 ++ 18 files changed, 314 insertions(+), 2 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index aadbe5c2df21..20ba290a81ba 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1665,7 +1665,9 @@ public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer : public abstract fun getBoolean (I)Z public abstract fun getCount ()I public abstract fun getDouble (I)D + public abstract fun getDoubleBuffer (I)[D public abstract fun getInt (I)I + public abstract fun getIntBuffer (I)[I public abstract fun getKeyOffset (I)I public abstract fun getLong (I)J public abstract fun getMapBuffer (I)Lcom/facebook/react/common/mapbuffer/MapBuffer; @@ -1680,7 +1682,9 @@ public final class com/facebook/react/common/mapbuffer/MapBuffer$Companion { public final class com/facebook/react/common/mapbuffer/MapBuffer$DataType : java/lang/Enum { public static final field BOOL Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field DOUBLE Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; + public static final field DOUBLE_BUFFER Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field INT Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; + public static final field INT_BUFFER Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field LONG Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field MAP Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field STRING Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; @@ -1691,7 +1695,9 @@ public final class com/facebook/react/common/mapbuffer/MapBuffer$DataType : java public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer$Entry { public abstract fun getBooleanValue ()Z + public abstract fun getDoubleBufferValue ()[D public abstract fun getDoubleValue ()D + public abstract fun getIntBufferValue ()[I public abstract fun getIntValue ()I public abstract fun getKey ()I public abstract fun getLongValue ()J @@ -1708,7 +1714,9 @@ public final class com/facebook/react/common/mapbuffer/ReadableMapBuffer : com/f public fun getBoolean (I)Z public fun getCount ()I public fun getDouble (I)D + public fun getDoubleBuffer (I)[D public fun getInt (I)I + public fun getIntBuffer (I)[I public fun getKeyOffset (I)I public fun getLong (I)J public synthetic fun getMapBuffer (I)Lcom/facebook/react/common/mapbuffer/MapBuffer; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt index 44af587bd9f1..17db9cd7a1d3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt @@ -46,6 +46,8 @@ public interface MapBuffer : Iterable { STRING, MAP, LONG, + INT_BUFFER, + DOUBLE_BUFFER, } /** @@ -161,6 +163,30 @@ public interface MapBuffer : Iterable { */ public fun getMapBufferList(key: Int): List + /** + * Provides parsed [IntArray] value if the entry for given key exists with [DataType.INT_BUFFER] + * type. This is a compact representation of a homogeneous list of ints with no per-element + * key/type overhead. + * + * @param key key to lookup the [IntArray] value for + * @return value associated with the requested key + * @throws IllegalArgumentException if the key doesn't exist + * @throws IllegalStateException if the data type doesn't match + */ + public fun getIntBuffer(key: Int): IntArray + + /** + * Provides parsed [DoubleArray] value if the entry for given key exists with + * [DataType.DOUBLE_BUFFER] type. This is a compact representation of a homogeneous list of + * doubles with no per-element key/type overhead. + * + * @param key key to lookup the [DoubleArray] value for + * @return value associated with the requested key + * @throws IllegalArgumentException if the key doesn't exist + * @throws IllegalStateException if the data type doesn't match + */ + public fun getDoubleBuffer(key: Int): DoubleArray + /** Iterable entry representing parsed MapBuffer values */ public interface Entry { /** @@ -213,5 +239,19 @@ public interface MapBuffer : Iterable { * @throws IllegalStateException if the data type doesn't match [DataType.MAP] */ public val mapBufferValue: MapBuffer + + /** + * Entry value represented as [IntArray] + * + * @throws IllegalStateException if the data type doesn't match [DataType.INT_BUFFER] + */ + public val intBufferValue: IntArray + + /** + * Entry value represented as [DoubleArray] + * + * @throws IllegalStateException if the data type doesn't match [DataType.DOUBLE_BUFFER] + */ + public val doubleBufferValue: DoubleArray } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt index c73ccb6da1dc..79d701fadd01 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt @@ -152,6 +152,20 @@ private constructor( return readMapBufferList } + private fun readIntBufferValue(bufferPosition: Int): IntArray { + var offset = offsetForDynamicData + buffer.getInt(bufferPosition) + val count = buffer.getInt(offset) + offset += Int.SIZE_BYTES + return IntArray(count) { i -> buffer.getInt(offset + i * Int.SIZE_BYTES) } + } + + private fun readDoubleBufferValue(bufferPosition: Int): DoubleArray { + var offset = offsetForDynamicData + buffer.getInt(bufferPosition) + val count = buffer.getInt(offset) + offset += Int.SIZE_BYTES + return DoubleArray(count) { i -> buffer.getDouble(offset + i * Double.SIZE_BYTES) } + } + private fun getKeyOffsetForBucketIndex(bucketIndex: Int): Int { return offsetToMapBuffer + HEADER_SIZE + BUCKET_SIZE * bucketIndex } @@ -193,6 +207,12 @@ private constructor( override fun getMapBufferList(key: Int): List = readMapBufferListValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP)) + override fun getIntBuffer(key: Int): IntArray = + readIntBufferValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.INT_BUFFER)) + + override fun getDoubleBuffer(key: Int): DoubleArray = + readDoubleBufferValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.DOUBLE_BUFFER)) + override fun hashCode(): Int { buffer.rewind() return buffer.hashCode() @@ -229,6 +249,8 @@ private constructor( append('"') } MapBuffer.DataType.MAP -> append(entry.mapBufferValue.toString()) + MapBuffer.DataType.INT_BUFFER -> append(entry.intBufferValue.contentToString()) + MapBuffer.DataType.DOUBLE_BUFFER -> append(entry.doubleBufferValue.contentToString()) } } } @@ -311,6 +333,18 @@ private constructor( assertType(MapBuffer.DataType.MAP) return readMapBufferValue(bucketOffset + VALUE_OFFSET) } + + override val intBufferValue: IntArray + get() { + assertType(MapBuffer.DataType.INT_BUFFER) + return readIntBufferValue(bucketOffset + VALUE_OFFSET) + } + + override val doubleBufferValue: DoubleArray + get() { + assertType(MapBuffer.DataType.DOUBLE_BUFFER) + return readDoubleBufferValue(bucketOffset + VALUE_OFFSET) + } } public companion object { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt index d75e8a39a8a2..d02283bb54fc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt @@ -126,6 +126,10 @@ internal class WritableMapBuffer : MapBuffer { override fun getMapBufferList(key: Int): List = verifyValue(key, values.get(key)) + override fun getIntBuffer(key: Int): IntArray = verifyValue(key, values.get(key)) + + override fun getDoubleBuffer(key: Int): DoubleArray = verifyValue(key, values.get(key)) + /** Generalizes verification of the value types based on the requested type. */ private inline fun verifyValue(key: Int, value: Any?): T { require(value != null) { "Key not found: $key" } @@ -176,6 +180,12 @@ internal class WritableMapBuffer : MapBuffer { override val mapBufferValue: MapBuffer get() = verifyValue(key, values.valueAt(index)) + + override val intBufferValue: IntArray + get() = verifyValue(key, values.valueAt(index)) + + override val doubleBufferValue: DoubleArray + get() = verifyValue(key, values.valueAt(index)) } /* diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp index 401a6670d03b..e7c0a97ffe5c 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp @@ -163,6 +163,46 @@ std::vector MapBuffer::getMapBufferList(MapBuffer::Key key) const { return mapBufferList; } +std::vector MapBuffer::getIntBuffer(MapBuffer::Key key) const { + auto bucketIndex = getKeyBucket(key); + react_native_assert(bucketIndex != -1 && "Key not found in MapBuffer"); + if (bucketIndex == -1) { + return {}; + } + + int32_t offset = getDynamicDataOffset() + getIntAtBucket(bucketIndex); + int32_t count = *reinterpret_cast(bytes_.data() + offset); + + std::vector result(count); + if (count > 0) { + memcpy( + result.data(), + bytes_.data() + offset + sizeof(int32_t), + static_cast(count) * sizeof(int32_t)); + } + return result; +} + +std::vector MapBuffer::getDoubleBuffer(MapBuffer::Key key) const { + auto bucketIndex = getKeyBucket(key); + react_native_assert(bucketIndex != -1 && "Key not found in MapBuffer"); + if (bucketIndex == -1) { + return {}; + } + + int32_t offset = getDynamicDataOffset() + getIntAtBucket(bucketIndex); + int32_t count = *reinterpret_cast(bytes_.data() + offset); + + std::vector result(count); + if (count > 0) { + memcpy( + result.data(), + bytes_.data() + offset + sizeof(int32_t), + static_cast(count) * sizeof(double)); + } + return result; +} + size_t MapBuffer::size() const { return bytes_.size(); } diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h index 1ae3595368c9..2d920af86e8e 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h @@ -94,8 +94,9 @@ class MapBuffer { /** * Data types available for serialization in MapBuffer - * Keep in sync with `DataType` enum in `JReadableMapBuffer.java`, which - * expects the same values after reading them through JNI. + * Keep in sync with the `DataType` enum in `MapBuffer.kt` + * (packages/react-native/ReactAndroid/.../common/mapbuffer/MapBuffer.kt), + * which is ordinal-indexed on the JVM side, so the order must match exactly. */ enum DataType : uint16_t { Boolean = 0, @@ -104,6 +105,13 @@ class MapBuffer { String = 3, Map = 4, Long = 5, + // Homogeneous, length-prefixed arrays stored contiguously in the dynamic + // data section. Unlike Map, they carry no per-element key/type overhead, so + // a batch of N values costs ~N*elementSize bytes plus a single 4-byte count + // prefix instead of N*12-byte buckets. The bucket value is the offset of the + // array within the dynamic data section. + IntBuffer = 6, + DoubleBuffer = 7, }; explicit MapBuffer(std::vector data); @@ -131,6 +139,10 @@ class MapBuffer { std::vector getMapBufferList(MapBuffer::Key key) const; + std::vector getIntBuffer(MapBuffer::Key key) const; + + std::vector getDoubleBuffer(MapBuffer::Key key) const; + size_t size() const; const uint8_t *data() const; diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp index eb6e859fec24..781204a16d8a 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp @@ -161,6 +161,52 @@ void MapBufferBuilder::putMapBufferList( INT_SIZE); } +void MapBufferBuilder::putIntBuffer( + MapBuffer::Key key, + const std::vector& value) { + // Wire format: [element count (int32)] + [count * int32]. The count is the + // number of elements, not bytes; see MapBuffer::getIntBuffer. + auto count = static_cast(value.size()); + auto payloadSize = static_cast(value.size() * sizeof(int32_t)); + + auto offset = static_cast(dynamicData_.size()); + dynamicData_.resize(offset + INT_SIZE + payloadSize, 0); + memcpy(dynamicData_.data() + offset, &count, INT_SIZE); + if (payloadSize > 0) { + memcpy(dynamicData_.data() + offset + INT_SIZE, value.data(), payloadSize); + } + + storeKeyValue( + key, + MapBuffer::DataType::IntBuffer, + reinterpret_cast(&offset), + INT_SIZE); +} + +void MapBufferBuilder::putDoubleBuffer( + MapBuffer::Key key, + const std::vector& value) { + // Wire format: [element count (int32)] + [count * double]. Doubles are copied + // byte-for-byte; the reader uses memcpy, so the payload needs no special + // alignment for correctness. A consumer that wants a zero-copy typed view on + // the JVM (ByteBuffer::asDoubleBuffer) must ensure 8-byte alignment itself. + auto count = static_cast(value.size()); + auto payloadSize = static_cast(value.size() * sizeof(double)); + + auto offset = static_cast(dynamicData_.size()); + dynamicData_.resize(offset + INT_SIZE + payloadSize, 0); + memcpy(dynamicData_.data() + offset, &count, INT_SIZE); + if (payloadSize > 0) { + memcpy(dynamicData_.data() + offset + INT_SIZE, value.data(), payloadSize); + } + + storeKeyValue( + key, + MapBuffer::DataType::DoubleBuffer, + reinterpret_cast(&offset), + INT_SIZE); +} + static inline bool compareBuckets( const MapBuffer::Bucket& a, const MapBuffer::Bucket& b) { diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h index af054da55789..2963c77a9b36 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h @@ -39,6 +39,10 @@ class MapBufferBuilder { void putMapBufferList(MapBuffer::Key key, const std::vector &mapBufferList); + void putIntBuffer(MapBuffer::Key key, const std::vector &value); + + void putDoubleBuffer(MapBuffer::Key key, const std::vector &value); + MapBuffer build(); private: diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp b/packages/react-native/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp index 3cc169563fca..c4c641bf2c27 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp @@ -205,6 +205,70 @@ TEST(MapBufferTest, testMapListEntries) { EXPECT_EQ(mapBufferList2[1].getDouble(3), 908.1); } +TEST(MapBufferTest, testIntBufferEntries) { + auto builder = MapBufferBuilder(); + + std::vector values{ + 1, + -2, + 3, + std::numeric_limits::min(), + std::numeric_limits::max()}; + builder.putIntBuffer(0, values); + auto map = builder.build(); + + EXPECT_EQ(map.count(), 1); + EXPECT_EQ(map.getIntBuffer(0), values); +} + +TEST(MapBufferTest, testEmptyIntBuffer) { + auto builder = MapBufferBuilder(); + + builder.putIntBuffer(0, {}); + auto map = builder.build(); + + EXPECT_EQ(map.getIntBuffer(0).size(), 0); +} + +TEST(MapBufferTest, testDoubleBufferEntries) { + auto builder = MapBufferBuilder(); + + std::vector values{0.0, -1.5, 3.14159, 1e300, -1e-300}; + builder.putDoubleBuffer(0, values); + auto map = builder.build(); + + EXPECT_EQ(map.count(), 1); + EXPECT_EQ(map.getDoubleBuffer(0), values); +} + +TEST(MapBufferTest, testEmptyDoubleBuffer) { + auto builder = MapBufferBuilder(); + + builder.putDoubleBuffer(0, {}); + auto map = builder.build(); + + EXPECT_EQ(map.getDoubleBuffer(0).size(), 0); +} + +// Mirrors the batched-animated-props use case: a pair of typed streams plus +// some scalar metadata, with keys inserted out of order to exercise both the +// dynamic-data section and the bucket sort path. +TEST(MapBufferTest, testIntAndDoubleBuffersAlongsideScalars) { + std::vector intStream{1, 100, 1, 2, 4, 15, 4}; + std::vector doubleStream{0.5, 12.0, 0.25}; + + auto builder = MapBufferBuilder(); + builder.putDoubleBuffer(2, doubleStream); + builder.putInt(0, 7); + builder.putIntBuffer(1, intStream); + auto map = builder.build(); + + EXPECT_EQ(map.count(), 3); + EXPECT_EQ(map.getInt(0), 7); + EXPECT_EQ(map.getIntBuffer(1), intStream); + EXPECT_EQ(map.getDoubleBuffer(2), doubleStream); +} + TEST(MapBufferTest, testMapRandomAccess) { auto builder = MapBufferBuilder(); builder.putInt(1234, 4321); diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index 8e829c46bde1..7be967c85f14 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -3253,7 +3253,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -3261,7 +3263,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -3286,7 +3290,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index 68888450c512..fe60f7c77d6e 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -3162,7 +3162,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -3170,7 +3172,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -3195,7 +3199,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 14571543b728..48d57a0ef37f 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -3250,7 +3250,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -3258,7 +3260,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -3283,7 +3287,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 1eed958ecd58..bc86a085fdbe 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -5483,7 +5483,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -5491,7 +5493,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -5516,7 +5520,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index d29785710d59..7980fccad7b4 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -5407,7 +5407,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -5415,7 +5417,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -5440,7 +5444,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 4c5d3b6c1d86..493db5dda3bb 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -5480,7 +5480,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -5488,7 +5490,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -5513,7 +5517,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index e040adc8b613..adc358e565f5 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -2168,7 +2168,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -2176,7 +2178,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -2201,7 +2205,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index 42992e00ebac..89589ef3f882 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -2104,7 +2104,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -2112,7 +2114,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -2137,7 +2141,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index c56d1d911a28..1962940950d0 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -2165,7 +2165,9 @@ class facebook::react::MapBuffer { public size_t size() const; public static constexpr uint16_t HEADER_ALIGNMENT; public std::string getString(facebook::react::MapBuffer::Key key) const; + public std::vector getDoubleBuffer(facebook::react::MapBuffer::Key key) const; public std::vector getMapBufferList(facebook::react::MapBuffer::Key key) const; + public std::vector getIntBuffer(facebook::react::MapBuffer::Key key) const; public uint16_t count() const; public using Key = uint16_t; } @@ -2173,7 +2175,9 @@ class facebook::react::MapBuffer { enum facebook::react::MapBuffer::DataType : uint16_t { Boolean, Double, + DoubleBuffer, Int, + IntBuffer, Long, Map, String, @@ -2198,7 +2202,9 @@ class facebook::react::MapBufferBuilder { public static facebook::react::MapBuffer EMPTY(); public void putBool(facebook::react::MapBuffer::Key key, bool value); public void putDouble(facebook::react::MapBuffer::Key key, double value); + public void putDoubleBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putInt(facebook::react::MapBuffer::Key key, int32_t value); + public void putIntBuffer(facebook::react::MapBuffer::Key key, const std::vector& value); public void putLong(facebook::react::MapBuffer::Key key, int64_t value); public void putMapBuffer(facebook::react::MapBuffer::Key key, const facebook::react::MapBuffer& map); public void putMapBufferList(facebook::react::MapBuffer::Key key, const std::vector& mapBufferList); From 17a3186e92161edfae3822855e5aefa3d34910b7 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 29 Jun 2026 04:19:02 -0700 Subject: [PATCH 2/2] Add MapBufferList entry type to MapBuffer (#57360) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57360 Introduces a dedicated `MapBufferList` `DataType` for an ordered array of nested MapBuffers, instead of overloading the `Map` type for lists. This makes a list of MapBuffers self-describing and distinguishable from a single nested `Map` (they were byte-distinct in payload but previously shared the `Map` type tag). Updates the C++ builder (`putMapBufferList`), the Kotlin `MapBuffer` interface, `ReadableMapBuffer`, and `WritableMapBuffer`, and adds cross-language JNI round-trip coverage in the serialization instrumentation test. Changelog: [Android][Added] - Add a dedicated `MapBufferList` type to `MapBuffer` for ordered lists of nested `MapBuffer`s Differential Revision: D109848477 --- .../react-native/ReactAndroid/api/ReactAndroid.api | 2 ++ .../com/facebook/react/common/mapbuffer/MapBuffer.kt | 12 ++++++++++-- .../react/common/mapbuffer/ReadableMapBuffer.kt | 9 ++++++++- .../react/common/mapbuffer/WritableMapBuffer.kt | 3 +++ .../ReactCommon/react/renderer/mapbuffer/MapBuffer.h | 4 ++++ .../react/renderer/mapbuffer/MapBufferBuilder.cpp | 5 +++-- .../cxx-api/api-snapshots/ReactAndroidDebugCxx.api | 1 + .../cxx-api/api-snapshots/ReactAndroidNewarchCxx.api | 1 + .../cxx-api/api-snapshots/ReactAndroidReleaseCxx.api | 1 + scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api | 1 + .../cxx-api/api-snapshots/ReactAppleNewarchCxx.api | 1 + .../cxx-api/api-snapshots/ReactAppleReleaseCxx.api | 1 + .../cxx-api/api-snapshots/ReactCommonDebugCxx.api | 1 + .../cxx-api/api-snapshots/ReactCommonNewarchCxx.api | 1 + .../cxx-api/api-snapshots/ReactCommonReleaseCxx.api | 1 + 15 files changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 20ba290a81ba..c7482b75e90d 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1687,6 +1687,7 @@ public final class com/facebook/react/common/mapbuffer/MapBuffer$DataType : java public static final field INT_BUFFER Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field LONG Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field MAP Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; + public static final field MAP_BUFFER_LIST Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static final field STRING Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; @@ -1701,6 +1702,7 @@ public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer$En public abstract fun getIntValue ()I public abstract fun getKey ()I public abstract fun getLongValue ()J + public abstract fun getMapBufferListValue ()Ljava/util/List; public abstract fun getMapBufferValue ()Lcom/facebook/react/common/mapbuffer/MapBuffer; public abstract fun getStringValue ()Ljava/lang/String; public abstract fun getType ()Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt index 17db9cd7a1d3..feba0dc97d6a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt @@ -48,6 +48,7 @@ public interface MapBuffer : Iterable { LONG, INT_BUFFER, DOUBLE_BUFFER, + MAP_BUFFER_LIST, } /** @@ -153,8 +154,8 @@ public interface MapBuffer : Iterable { public fun getMapBuffer(key: Int): MapBuffer /** - * Provides parsed [List] value if the entry for given key exists with [DataType.MAP] - * type + * Provides parsed [List] value if the entry for given key exists with + * [DataType.MAP_BUFFER_LIST] type * * @param key key to lookup [List] value for * @return value associated with the requested key @@ -253,5 +254,12 @@ public interface MapBuffer : Iterable { * @throws IllegalStateException if the data type doesn't match [DataType.DOUBLE_BUFFER] */ public val doubleBufferValue: DoubleArray + + /** + * Entry value represented as [List] + * + * @throws IllegalStateException if the data type doesn't match [DataType.MAP_BUFFER_LIST] + */ + public val mapBufferListValue: List } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt index 79d701fadd01..14b0a29f1ea6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt @@ -205,7 +205,7 @@ private constructor( readMapBufferValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP)) override fun getMapBufferList(key: Int): List = - readMapBufferListValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP)) + readMapBufferListValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP_BUFFER_LIST)) override fun getIntBuffer(key: Int): IntArray = readIntBufferValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.INT_BUFFER)) @@ -251,6 +251,7 @@ private constructor( MapBuffer.DataType.MAP -> append(entry.mapBufferValue.toString()) MapBuffer.DataType.INT_BUFFER -> append(entry.intBufferValue.contentToString()) MapBuffer.DataType.DOUBLE_BUFFER -> append(entry.doubleBufferValue.contentToString()) + MapBuffer.DataType.MAP_BUFFER_LIST -> append(entry.mapBufferListValue.toString()) } } } @@ -345,6 +346,12 @@ private constructor( assertType(MapBuffer.DataType.DOUBLE_BUFFER) return readDoubleBufferValue(bucketOffset + VALUE_OFFSET) } + + override val mapBufferListValue: List + get() { + assertType(MapBuffer.DataType.MAP_BUFFER_LIST) + return readMapBufferListValue(bucketOffset + VALUE_OFFSET) + } } public companion object { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt index d02283bb54fc..6e3d1359df02 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt @@ -186,6 +186,9 @@ internal class WritableMapBuffer : MapBuffer { override val doubleBufferValue: DoubleArray get() = verifyValue(key, values.valueAt(index)) + + override val mapBufferListValue: List + get() = verifyValue(key, values.valueAt(index)) } /* diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h index 2d920af86e8e..ae89b674b6a3 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h @@ -112,6 +112,10 @@ class MapBuffer { // array within the dynamic data section. IntBuffer = 6, DoubleBuffer = 7, + // A homogeneous, ordered array of nested MapBuffers. Distinct from `Map` so + // that a list of MapBuffers is self-describing (a single Map and a list are + // byte-distinct in payload but previously shared the `Map` type tag). + MapBufferList = 8, }; explicit MapBuffer(std::vector data); diff --git a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp index 781204a16d8a..26c47e1b749c 100644 --- a/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp @@ -153,10 +153,11 @@ void MapBufferBuilder::putMapBufferList( mapBufferSize); } - // Store Key and pointer to the string + // Store Key and pointer to the list. Uses the dedicated MapBufferList type so + // the entry is self-describing and distinguishable from a single Map. storeKeyValue( key, - MapBuffer::DataType::Map, + MapBuffer::DataType::MapBufferList, reinterpret_cast(&offset), INT_SIZE); } diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index 7be967c85f14..0a984daf969b 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -3268,6 +3268,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index fe60f7c77d6e..65351c333fbc 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -3177,6 +3177,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 48d57a0ef37f..06661314eaa6 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -3265,6 +3265,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index bc86a085fdbe..15c679395815 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -5498,6 +5498,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 7980fccad7b4..8778ca8d0cf2 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -5422,6 +5422,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 493db5dda3bb..795cd689e185 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -5495,6 +5495,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index adc358e565f5..7435516a8def 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -2183,6 +2183,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index 89589ef3f882..e35665e59652 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -2119,6 +2119,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index 1962940950d0..dc816db5f380 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -2180,6 +2180,7 @@ enum facebook::react::MapBuffer::DataType : uint16_t { IntBuffer, Long, Map, + MapBufferList, String, }