InitialState
The InitialStateContainer is a lookaside table used by a ComponentTree to create initial states for Components. The idea is that the onCreateInitialState result for each component will be cached and stored here so that we can guarantee it's not called multiple times on multiple threads. We keep the initial states cached as long as there is a layout happening for the ComponentTree. As soon as we detect that all in-flights layout have terminated we can clean up the initial states cache.
Locking discipline, as numbered invariants:
INV-1 (single monitor): every read or write of a Slot's contents happens inside
synchronized(slot.lock)for the slot returned by this invocation's slotFor.INV-2 (fetch-once): each public method calls slotFor exactly once, holds the result in a local, and never re-reads slots after acquiring the lock. Without this, a drain between the vend and the lock acquisition would let two threads hold different monitors over the same logical key.
INV-3 (co-drain): monitor and data are allocated together (Slot) and discarded together (
slots = null), so a drain cannot go partial. Any future per-key cache belongs inside Slot, never beside it. A thread still holding a pre-drain Slot keeps writing to it and its seed is discarded rather than resurrected into the new epoch -- safe only because a registeredStateHandlerkeepspendingStateHandlersnon-empty and so prevents the drain.
Functions
If an initial state for this component has already been created just return it, otherwise execute the initializer and cache the result. Uses HookKey-based identity instead of sequential index. The state is stored in a map-based KStateContainer.
True when nothing is cached for any key, in any storage.
Looks up the initial value for hookKey in the lookaside cache, with a deps-equivalence guard.
Called when the ComponentTree creates a new StateHandler for a new layout computation. We keep track of this new StateHandler so that we know that we need to wait for this layout computation to finish before we can clear the initial states map.
Called when a resolve or layout computation finishes and its result has been committed or discarded. Removes the StateHandler from the pending set and clears the cached initial states if no other computations are in-flight.