| 224 | } |
| 225 | |
| 226 | internal TypeMeta ReadTypeMeta() |
| 227 | { |
| 228 | if (TryReadTypeMetaRef(out int index, out TypeMeta typeMeta)) |
| 229 | { |
| 230 | return typeMeta; |
| 231 | } |
| 232 | |
| 233 | ulong header = Reader.ReadUInt64(); |
| 234 | if (TryGetTypeMetaByHeader(header, out TypeMeta cachedTypeMeta)) |
| 235 | { |
| 236 | // Header-cache hits intentionally skip without rehashing. Entries reach this cache only |
| 237 | // after successful TypeMeta body validation. Do not add body/hash/schema-limit/exact-local |
| 238 | // checks here; the miss path owns them before cache publish. |
| 239 | TypeMeta.SkipBody(Reader, header); |
| 240 | StoreTypeMetaRef(cachedTypeMeta, index); |
| 241 | return cachedTypeMeta; |
| 242 | } |
| 243 | |
| 244 | Reader.MoveBack(sizeof(ulong)); |
| 245 | int typeMetaStart = Reader.Cursor; |
| 246 | typeMeta = DecodeTypeMeta(); |
| 247 | int typeMetaEnd = Reader.Cursor; |
| 248 | if (MatchesExactLocalTypeMeta(typeMeta, typeMetaStart, typeMetaEnd)) |
| 249 | { |
| 250 | StoreExactLocalTypeMeta(header, typeMeta); |
| 251 | } |
| 252 | else |
| 253 | { |
| 254 | StoreRemoteTypeMeta(header, typeMeta); |
| 255 | } |
| 256 | StoreTypeMetaRef(typeMeta, index); |
| 257 | return typeMeta; |
| 258 | } |
| 259 | |
| 260 | internal bool TryReadTypeMetaRef(out int index, out TypeMeta typeMeta) |
| 261 | { |