# MetadataRepo

Artifact: [androidx.emoji2:emoji2](https://developer.android.com/jetpack/androidx/releases/emoji2) [View Source](https://cs.android.com/search?q=file:androidx/emoji2/text/MetadataRepo.java+class:androidx.emoji2.text.MetadataRepo) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0)

*** ** * ** ***


```
@AnyThread
public final class MetadataRepo
```

<br />

*** ** * ** ***

Class to hold the emoji metadata required to process and draw emojis.

### Flat Trie Optimization Design

The trie data structure used to detect emoji sequences is packed into a single, contiguous primitive `int[]` array (`mTrieArray`) and a flat array of data references (`TypefaceEmojiRasterizer[]`). This design replaces the previous object-oriented trie representation (where every node allocated a Node object and a SparseArray) to eliminate startup memory spikes and runtime pointer-chasing.

#### 1. Flat Node Representation

A node starting at a given offset in `mTrieArray` is packed sequentially:

```
[offset + 0] : packedHeader   (Packs 16-bit dataIndex + 1 and childrenCount)
                              Note: Limits total emojis to 65,534.
[offset + 1] : codepoint_0    (Transition key)
[offset + 2] : childOffset_0  (Offset of child node in mTrieArray)
...
[offset + 1 + 2*i] : codepoint_i
[offset + 2 + 2*i] : childOffset_i
```

#### 2. Root Node Optimization

The root node has a high branching factor (\~900 children). To keep the start of searches O(1), we bypass the flat array for the root and keep flat jump tables as class fields:

- `mRootPlane1DirectOffset`: Direct offset lookup for Plane 1 codepoints (U+1F300 to U+1FFFF).
- `mRootPlane0DirectOffset`: Direct offset lookup for Plane 0 codepoints (U+2600 to U+27BF).
- `mRootSparseKeys` / `mRootSparseOffsets`: Sorted primitive arrays for remaining root children.

#### 3. Direct Allocation-Free Construction

To build the flat trie without temporary object overhead at startup:

1. We sort the indices of `mEmojiList` lexicographically by their codepoint sequences. Contiguous ranges in the sorted list naturally represent the prefix subranges.
2. We pre-calculate the exact final size of the flat trie array using a fast pre-scan pass, allocate `mTrieArray` to its exact size once, and write directly into it.
3. A stack-confined scratch buffer is used to track DFS recursion states inside `https://developer.android.com/reference/androidx/emoji2/text/FlatTrieBuilder`. This achieves absolute zero heap garbage during the traversal.
4. We lazily instantiate `TypefaceEmojiRasterizer` objects on demand during lookups and cache them in `mEmojiCache`, avoiding the creation of 7,025 objects at startup and saving \~168 KB of permanent heap overhead.

#### 4. Complexity \&Memory Comparison

- **Memory Footprint:** Reduced from \~488 KB (original OO Trie) to \~78 KB (Flat Trie). Heap objects reduced from 9,400+ to just 5 primitive arrays.
- **Search Complexity:** Root search is O(1) via direct plane tables. Non-root search is O(log C) via primitive binary search in `mTrieArray`.
- **Cache Locality:** Contiguous array slots eliminate pointer chasing across the heap, which is highly CPU-cache-friendly.

## Summary

| ### Public methods |
|---|---|
| `static @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/emoji2/text/MetadataRepo` | `https://developer.android.com/reference/androidx/emoji2/text/MetadataRepo#create(android.content.res.AssetManager,java.lang.String)(@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/content/res/AssetManager.html assetManager, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/lang/String.html assetPath)` Construct MetadataRepo from an asset. |
| `static @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/emoji2/text/MetadataRepo` | `https://developer.android.com/reference/androidx/emoji2/text/MetadataRepo#create(android.graphics.Typeface,java.nio.ByteBuffer)(@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/graphics/Typeface.html typeface, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/nio/ByteBuffer.html byteBuffer)` Construct MetadataRepo from a byte buffer. |
| `static @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/emoji2/text/MetadataRepo` | `https://developer.android.com/reference/androidx/emoji2/text/MetadataRepo#create(android.graphics.Typeface,java.io.InputStream)(@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/graphics/Typeface.html typeface, @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/io/InputStream.html inputStream)` Construct MetadataRepo from an input stream. |

## Public methods

### create

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0)

```
public static @NonNull MetadataRepo create(@NonNull AssetManager assetManager, @NonNull String assetPath)
```

Construct MetadataRepo from an asset.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/content/res/AssetManager.html assetManager` | AssetManager instance |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/lang/String.html assetPath` | asset manager path of the file that the Typeface and metadata will be created from |

| Throws |
|---|---|
| `https://developer.android.com/reference/java/io/IOException.html` |   |

### create

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0)

```
public static @NonNull MetadataRepo create(@NonNull Typeface typeface, @NonNull ByteBuffer byteBuffer)
```

Construct MetadataRepo from a byte buffer. The position of the ByteBuffer will change, it is caller's responsibility to reposition the buffer if required.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/graphics/Typeface.html typeface` | Typeface to be used to render emojis |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/nio/ByteBuffer.html byteBuffer` | ByteBuffer to read emoji metadata from |

| Throws |
|---|---|
| `https://developer.android.com/reference/java/io/IOException.html` |   |

### create

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0)

```
public static @NonNull MetadataRepo create(@NonNull Typeface typeface, @NonNull InputStream inputStream)
```

Construct MetadataRepo from an input stream. The library does not close the given InputStream, therefore it is caller's responsibility to properly close the stream.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/android/graphics/Typeface.html typeface` | Typeface to be used to render emojis |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/java/io/InputStream.html inputStream` | InputStream to read emoji metadata from |

| Throws |
|---|---|
| `https://developer.android.com/reference/java/io/IOException.html` |   |