The generation number idea you have shown is an excellent idea. It immediately enables several new capabilities compared with just mutation:
* You are now able to determine which data is older and which is newer without resorting to an external clock.
* If your mutation takes a long time, there is no longer a need to use a long-held mutex to ensure thread safety which would prevent concurrent reads; you can create a new generation separately and then atomically CAS it. Writers don't block readers.
* If you suddenly need undo/redo functionality, it's suddenly trivial. Or diff'ing between versions. Or understanding the reason for changes (basics of auditing).