123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162open!ImportmoduleStats=Index.Statslet(++)=Int63.addtypet={fd:Unix.file_descr}[@@unboxed]letvfd={fd}letreally_writefdfd_offsetbufferbuffer_offsetlength=letrecauxfd_offsetbuffer_offsetlength=letw=Syscalls.pwrite~fd~fd_offset~buffer~buffer_offset~lengthinifw=0||w=lengththen()else(aux[@tailcall])(fd_offset++Int63.of_intw)(buffer_offset+w)(length-w)inauxfd_offsetbuffer_offsetlengthletreally_readfdfd_offsetlengthbuffer=letrecauxfd_offsetbuffer_offsetlength=letr=Syscalls.pread~fd~fd_offset~buffer~buffer_offset~lengthinifr=0thenbuffer_offset(* end of file *)elseifr=lengththenbuffer_offset+relse(aux[@tailcall])(fd_offset++Int63.of_intr)(buffer_offset+r)(length-r)inauxfd_offset0lengthletfsynct=Unix.fsynct.fdletcloset=Unix.closet.fdletfstatt=Unix.fstatt.fdletunsafe_writet~offbufferbuffer_offsetlength=letbuffer=Bytes.unsafe_of_stringbufferinreally_writet.fdoffbufferbuffer_offsetlength;Stats.add_write(Bytes.lengthbuffer)letunsafe_readt~off~lenbuf=letn=really_readt.fdofflenbufinStats.add_readn;nletencode_int63n=letbuf=Bytes.createInt63.encoded_sizeinInt63.encodebuf~off:0n;Bytes.unsafe_to_stringbufletdecode_int63buf=Int63.decode~off:0bufexceptionNot_writtenletassert_read~lenn=ifn=0&&n<>lenthenraiseNot_written;assert(ifInt.equalnlenthentrueelse(Printf.eprintf"Attempted to read %d bytes, but got %d bytes instead!\n%!"lenn;false))[@@inlinealways]moduleOffset=structletoff=Int63.zeroletsettn=unsafe_writet~off(encode_int63n)08letgett=letlen=8inletbuf=Bytes.createleninletn=unsafe_readt~off~lenbufinassert_read~lenn;decode_int63(Bytes.unsafe_to_stringbuf)endmoduleVersion=structletoff=Int63.of_int8letgett=letlen=8inletbuf=Bytes.createleninletn=unsafe_readt~off~lenbufinassert_read~lenn;Bytes.unsafe_to_stringbufletsettv=unsafe_writet~offv08endmoduleGeneration=structletoff=Int63.of_int16letgett=letlen=8inletbuf=Bytes.createleninletn=unsafe_readt~off~lenbufinassert_read~lenn;decode_int63(Bytes.unsafe_to_stringbuf)letsettgen=unsafe_writet~off(encode_int63gen)08endmoduleFan=structletoff=Int63.of_int24letsettbuf=letbuf_len=String.lengthbufinletsize=encode_int63(Int63.of_intbuf_len)inunsafe_writet~offsize08;ifbuf<>""thenunsafe_writet~off:(off++Int63.of_int8)buf0buf_lenletget_sizet=letlen=8inletsize_buf=Bytes.createleninletn=unsafe_readt~off~lensize_bufinassert_read~lenn;decode_int63(Bytes.unsafe_to_stringsize_buf)letset_sizetsize=letbuf=encode_int63sizeinunsafe_writet~offbuf08letgett=letsize=Int63.to_int(get_sizet)inletbuf=Bytes.createsizeinletn=unsafe_readt~off:(off++Int63.of_int8)~len:sizebufinassert_read~len:sizen;Bytes.unsafe_to_stringbufendmoduleHeader=structtypet={offset:int63;version:string;generation:int63}(** NOTE: These functions must be equivalent to calling the above [set] /
[get] functions individually. *)lettotal_header_length=8+8+8letread_wordbufoff=letresult=Bytes.create8inBytes.blitbufoffresult08;Bytes.unsafe_to_stringresultletgett=letheader=Bytes.createtotal_header_lengthinletn=unsafe_readt~off:Int63.zero~len:total_header_lengthheaderinassert_read~len:total_header_lengthn;letoffset=read_wordheader0|>decode_int63inletversion=read_wordheader8inletgeneration=read_wordheader16|>decode_int63in{offset;version;generation}letsett{offset;version;generation}=assert(String.lengthversion=8);letb=Bytes.createtotal_header_lengthinBytes.blit_string(encode_int63offset)0b08;Bytes.blit_stringversion0b88;Bytes.blit_string(encode_int63generation)0b168;unsafe_writet~off:Int63.zero(Bytes.unsafe_to_stringb)0total_header_lengthend