long (final int recordId) { //recordId is 1-based, convert to 0-based recordNo: final int recordNo = recordId - 1; final int recordsOnHeaderPage = (pageSize - HEADER_SIZE) / RecordLayout.RECORD_SIZE_IN_BYTES; if (recordNo < recordsOnHeaderPage) { return HEADER_SIZE + recordNo * (long)RecordLayout.RECORD_SIZE_IN_BYTES; } //as-if there were no header: final int fullPages = recordNo / recordsPerPage; final int recordsOnLastPage = recordNo % recordsPerPage; //header on the first page "push out" few records: final int recordsExcessBecauseOfHeader = recordsPerPage - recordsOnHeaderPage; //so the last page could turn into +1 page: final int recordsReallyOnLastPage = recordsOnLastPage + recordsExcessBecauseOfHeader; return (long)(fullPages + recordsReallyOnLastPage / recordsPerPage) * pageSize + (long)(recordsReallyOnLastPage % recordsPerPage) * RecordLayout.RECORD_SIZE_IN_BYTES; }