- The previous implementation of `putIfAbsent` made two calls to the
`backingMap`: `putIfAbsent` and `replace`. This breaks atomicity at
least in theory. Implementing the major compute operations in terms of
`backingMap.compute` allows us to restrict the critical section to
this single atomic `ConcurrentHashMap` operation, which is easier to
reason about.
- Using `backingMap.compute` also improves the guarantees we can make in
respect to `computeIfAbsent`'s computation function `f`. We can now
guarantee that the function is called exactly once iff the `key` is
absent, because it is only ever invoked inside `backingMap.compute`,
which makes this guarantee itself.
- Remove `putIfAbsent`, which isn't currently used by
`LLFirSessionCache`. It can easily be implemented using
`computeIfAbsent` in the future.
^KT-61222