12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091(*
* Copyright (c) 2023 Tarides <contact@tarides.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openImportmoduleInternal=Irmin.Backend.Lru.Make(structincludeInt63lethash=Hashtbl.hashend)typekey=int63typevalue=Irmin_pack.Pack_value.kindedtypeweighted_value={v:value;weight:int}typet={lru:weighted_valueInternal.t;weight_limit:intoption;mutabletotal_weight:int;}letcreateconfig=letlru_max_memory=Irmin_pack.Conf.lru_max_memoryconfiginletlru_size,weight_limit=matchlru_max_memorywith|None->(Irmin_pack.Conf.lru_sizeconfig,None)|Someb->(-42,Someb)inletlru=Internal.createlru_sizein{lru;weight_limit;total_weight=0}letlru_enabledt=matcht.weight_limitwithNone->true|Somex->x>0(** [exceeds_entry_weight_limit] attempts to filter out entries that are "too
large".
Since we do not necessarily want to incur a cost for calculating the weight
for every entry when [lru_max_memory] is not configured, the control for
this is in the caller of [add]. Only [Irmin_pack.Pack_value.Immediate]
weight's are checked.
The current entry weight limit is hard-coded to 20kB. *)letexceeds_entry_weight_limit=function|Irmin_pack.Pack_value.Immediatew->w>20_000|Deferred_->falseletresolve_weight=function|Irmin_pack.Pack_value.Immediatew->w|Deferredw->w()letaddtkwv=iflru_enabledt=falsethen()elseifexceeds_entry_weight_limitwthen()elseletaddtkvw=letn={v;weight=w}int.total_weight<-t.total_weight+w;Internal.addt.lrukninmatcht.weight_limitwith|None->addtkv0|Somelimit->addtkv(resolve_weightw);whilet.total_weight>limitdomatchInternal.dropt.lruwith|None->t.total_weight<-0|Somen->t.total_weight<-t.total_weight-n.weightdoneletvv=v.vletfind{lru;_}k=Internal.findlruk|>vletmem{lru;_}k=Internal.memlrukletcleart=Internal.cleart.lru;t.total_weight<-0letiter{lru;_}f=Internal.iterlru(funkwv->fk(vwv))