Set() to return a value indicating whether the key already existed #75
Labels
kind/enhancement
A net-new feature or an improvement to an existing feature
need/triage
Needs initial labeling and prioritization
The
Set
method is implemented as blind upsert and does not return any indication of what value, if any, previously existed for the key in question. Callers that wish to leave any existing value intact, or save or report it elsewhere after it is overwritten, must first perform aGet
orHas
in order to establish if one exists.Set
could instead return an indication of whether the key previously existed.Some options:
Set
returns a boolean if the key existedSet
accepts a nillableout
parameter likeGet
, which receives any previous value (combined with the boolean)Set
or a variant of it accepts a callback receiving the bytes previously stored for the keySetIfAbsent
writes a key only if not previously present, and returns a boolean indicating whether it did soThe concrete motivating case is safety checks in the Miner actor. It contains a HAMT of pre-committed sectors by sector number. The
PreCommitSector
method wants to abort if a pre-commit collides with a sector number already pre-committed or proven. If it does, the method will abort and roll back all state changes. This method is expensive and we wish to remove all unnecessary state access. The usual case is no collision.A single boolean return value is sufficient here: even if the HAMT is internally modified by the
Set
, the modification will be thrown away. The more complicated options just provide more flexibility for future use cases.As it happens, the Miner actor has a separate bitfield of all allocated sector numbers so the HAMT check is redundant and will probably be removed (in filecoin-project/specs-actors#1241). But it would be more robust to keep it, if it were free in terms of state blocks accessed.
@ZenGround0 @Stebalien
The text was updated successfully, but these errors were encountered: