QueryCursor
The rows a query matched, in key order.
A candidate is not an answer, and this is where the difference is settled. An index reports what a segment's recorded version of a key carried; a partial scan reports what the sources it was given hold. Either can be out of date, because a newer version may live in a segment the index does not cover or in a memtable that has no sidecar. So every candidate is re-resolved against the version the snapshot can actually see — except in the two cases where that is provably a no-op, each of which checks its own preconditions rather than trusting the plan:
The scan already holds the deciding version. If no evaluated segment holds the key, then the sources the scan was given are the whole of what that key could be in, and the document in hand is the visible one. When the plan is a full scan this is every key, which is why a store with no index pays nothing for the machinery.
One segment holds the key and its index decided outright. With nothing unflushed and no other segment of this snapshot holding the key — a bisect over mapped key blocks, not a document read — that segment's recorded version is the visible version.
A row is a view. Its document reads straight out of a mapped segment and is valid until the next next, the same contract a DocumentCursor offers. Anything kept beyond that is copied by the caller, with Row.toJsonString or Variant.toByteArray.
Close it. The readers it holds pin index sidecars, and on Windows a mapped file cannot be deleted at all, so a cursor left open blocks reclamation of everything it touched.