Proposal for a CacheKV v2 store
- Dominant language
- Go
- Stars
- 116
- Forks
- 16
- PR merge metrics
- No merged PRs in 30d
Description
### Summary
This details a proposal for how to make a CacheKV store v2.
Right now it is hard to iterate on the CacheKV store. It mixes a lot of roles into the same data structure, is rather complex, and under-specified. This has led to large numbers of performance and liveness critical bugs, that would be vastly simplified with a redesign.
I claim that the way to best simplify this is to do an API compatible rewrite, that simplifies the roles of the differing components, and then drop-in replace this.
The cache KV store has two roles, each of which has roadmaps for improvement, and potential for tighter integration with gas counting. These are:
- ReadBuffers
- WriteBuffers
The proposal is to make a directory structure as follows:
`
store/cachekv2
store/cachekv2/readbuffer
store/cachekv2/writebuffer
`
Basically, separate packages, for ReadBuffer and WriteBuffers that allow us to flexibly iterate going forward, and making a for now "merged CacheKV store API" that has the exact API guarantees (aside from bug/perf improvements) as the existing one, so theres no break to users. As time goes on, this merged CacheKV store API gets less used.
The short-term roadmap proposed:
- Make a store/cachekv2 with identical external API guarantees as the existing CacheKV
- The semantic will always be, for reads and iterates, "attempt iterating over write buffer. If not in write buffer, go to read buffer"
- Create a ReadBuffer and WriteBuffer interface
- Make the first objects behind the interface, the equivalent object in CacheKV 1
- ReadBuffer only has data thats in parent, it has no "dirty" data.
- Swap cachekv usage with cachekv2
Then internal API roadmaps, that can far more simply progress after a basic split:
- Amend the ReadBuffer to have an interval tree, so it can know during repeated iterations, whether the iteration is already cached. (Today we always hit IAVL on repeat iterations)
- Ensure single threaded concurrency safety
- Make a new API for Gets, that is also aware of whether the data was in cache or not. Cache gets should be much cheaper than uncached ones.
- This will be short-term unused, but will get used when we are willing to do a larger API break with the gas store
- Make write buffer single threaded concurrency safe. (As far as I'm aware, a fix for this was merged into SDK, so maybe we just re-use that)
- Consider lifting concurrency safety to multi-threaded safety
- Make Cachewrap only layer a write buffer on top
- Add RAM bounds to ReadBuffer
- Create safer iter_mut API's
Whats nice about having these split out, is we can also make these re-usable components, as we explore more distinct concurrency designs. Furthermore, we should be expecting different read buffer and write buffer designs to emerge. A lot of performance suffering is had to support iteration, when really there could be flexibility in only making things that need iteration pay that cost.
If folks like this direction, I can get started on it.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by locating the existing CacheKV implementation and its tests, then compare its public API with the proposed store/cachekv2, store/cachekv2/readbuffer, and store/cachekv2/writebuffer structure. The proposal does not name a concrete entry point or test, so first map current ReadBuffer and WriteBuffers usage. Done would require an agreed design and an API-compatible replacement, not just one isolated edit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- database
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100