12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182(**************************************************************************)(* *)(* Typerex Libraries *)(* *)(* Copyright 2011-2017 OCamlPro SAS *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)(* Reentrant buffers :
If you call a function that needs a buffer, you might want to use this
module to reuse such buffers, instead of reallocating them everytime.
This module is not thread-safe. Reentrance is only provided for a function
that uses a buffer, and might call another function using a similar
buffer.
Buffer sizes should be between 4kB and 1MB.
*)openEzCompatletnsizes=10letmax_queue_size=ref100letbuffers=Array.initnsizes(fun_->Queue.create())letlengths=Array.makensizes0letinvalid_sizesize=Printf.ksprintffailwith"ReentrantBuffer.get: size %d is not a power of two"sizeletget_powersize=letrecfind_powerpossize=ifsize=1thenposelseletsize2=sizelsr1inifsize2lsl1<>sizetheninvalid_sizesize;find_power(pos+1)size2inif(sizelsr10)lsl10<>sizetheninvalid_sizesize;find_power0(sizelsr10)let_=assert(get_power1024=0);assert(get_power2048=1);()letallocsize=letpos=get_powersizeinletnbuffers=lengths.(pos)inifnbuffers>0thenletb=Queue.takebuffers.(pos)inlengths.(pos)<-nbuffers-1;belseBytes.createsizeletfrees=letsize=Bytes.lengthsinletpos=get_powersizeinletnbuffers=lengths.(pos)inifnbuffers<!max_queue_sizethenbeginlengths.(pos)<-nbuffers+1;Queue.addsbuffers.(pos)endletset_max_queue_sizesize=if!max_queue_size>sizethenbeginforpos=0tonsizes-1doletnbuffers=lengths.(pos)inifnbuffers>sizethenbeginfor_i=size+1tonbuffersdoignore(Queue.takebuffers.(pos))done;lengths.(pos)<-sizeenddoneend;max_queue_size:=size