read method
Read page pageNo. The returned buffer is the live cache copy —
callers MUST NOT mutate it without calling markDirty; if you
want to modify a page, use getForWrite instead.
Implementation
Future<Uint8List> read(int pageNo) async {
_ensureOpen();
if (pageNo < 0 || pageNo >= _pageCount) {
throw RangeError.range(pageNo, 0, _pageCount - 1, 'pageNo');
}
final cached = _cache[pageNo];
if (cached != null) {
_touch(pageNo);
return cached;
}
// Make room BEFORE inserting the just-faulted page; otherwise it
// would be eligible for immediate eviction as the only clean page
// and the caller would be handed back a buffer no longer linked
// to the cache (so [getForWrite]/[markDirty] mutations would be
// silently lost).
await _makeRoomForOneMore();
final buf = Uint8List(pageSize);
await _data!.setPosition(pageNo * pageSize);
final n = await _data!.readInto(buf);
if (n != pageSize) {
throw StateError(
'short read on page $pageNo: expected $pageSize bytes, got $n');
}
_cache[pageNo] = buf;
_touch(pageNo);
return buf;
}