it occurs to me that we could easily create a prefetch pattern for the btree tuple iterator and cursor. We had a read fetch pool integration at one point with no benefit. I am thinking of an iterator flag used for queries without limit and index key range scans and otherwise disabled. When true the iterator would be wrapped with an iterator having a fixed array of lookahead completions. These would be backed by a single fixed size thread pool backed by the journal service (so perhaps using a LatchedExecutor). Since all index reads hit a memoizer we do need those lookahead buffers to be serviced by a thread pool. Probably 20+ threads to schedule IOs. This seems like an easy and general purpose optimization that would reduce next index page latency substantially for index scans touching more than one leaf and that would be easy to integrate into the AccessPath class using IPredicate.Options.
This came to mind in the context of bulk loading the SPO index into RAM for transfer to the GPU. But it would help multi-leaf scans as well.
Note: Some similar concepts were previously explored. See Journal.Options.READ_POOL_SIZE, Journal.getReadExecutor(), and callers of Journal.getReadExecutor() in AbstractBTree and friends.