The previous checkpoint implementation requires each checkpoint to maintain the list of keys, their values, and all of their meta data fields, which can cause very high memory overhead in case disk write throughput or replication is very slow.
Based on various use cases for checkpoint, it turns out that it is not necessary to maintain the strong consistency across checkpoints. This can simplify a checkpoint's item structure, which allows us to have keys and subset of their meta data fields only. Basically, a checkpoint only contains the information about which keys have been mutated and their operation types.
With this simplication, the memory overhead of a single checkpoint item (i.e., QueuedItem instance) is reduced from 88 bytes to 40 bytes. In addition, the closed checkpoint won't point to stale Blob value instances anymore.