123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869(* Page geometry: the per-file, creation-time choice of page size and
reserved-bytes-per-page. See geometry.mli for the contract. *)typet={page_size:int;reserved_bytes_per_page:int}letheader_size=16letfreelist_entry_size=12letmin_page_size=4096letmax_page_size=65536(* Smallest usable data area we permit after carving off the common header and
the reserved bytes. Keeps the b-tree functional (a leaf must hold a few
small cells, an overflow page a useful chunk) even at the most aggressive
reserved-bytes setting; mirrors SQLite's floor on usable page size. *)letmin_usable_data_bytes=480letppfmtt=Format.fprintffmt"@[<hv>{ page_size = %d;@ reserved_bytes_per_page = %d }@]"t.page_sizet.reserved_bytes_per_page;;letdefault={page_size=4096;reserved_bytes_per_page=0}letmax_data_bytest=t.page_size-header_size-t.reserved_bytes_per_pageletmax_overflow_payload_bytest=max_data_bytest-2letmax_freelist_entries_per_paget=max_data_bytest/freelist_entry_sizetypeerror=|Bad_page_sizeofint|Bad_reservedofintletpp_errorfmt=function|Bad_page_sizen->Format.fprintffmt"Bad_page_size %d (must be a multiple of %d in [%d, %d])"nmin_page_sizemin_page_sizemax_page_size|Bad_reservedn->Format.fprintffmt"Bad_reserved %d (must be >= 0 and leave >= %d usable bytes)"nmin_usable_data_bytes;;letcreate~page_size~reserved_bytes_per_page=ifpage_size<min_page_size||page_size>max_page_size||page_sizemodmin_page_size<>0thenError(Bad_page_sizepage_size)elseifreserved_bytes_per_page<0||page_size-header_size-reserved_bytes_per_page<min_usable_data_bytesthenError(Bad_reservedreserved_bytes_per_page)elseOk{page_size;reserved_bytes_per_page};;[@@@ai_disclosure"ai-generated"][@@@ai_model"claude-opus-4-7"][@@@ai_provider"Anthropic"]