1 import Base 2 import entity_key.bend as Key 3 import ./world.bend as W 4 import ./schema_fragments.bend as Fragment 5 import ./ordinary_dump_filter.bend as Filter 6 # Presence derives from the ordinary count traversal on one actual alive handle. 7 def present_choice(~S:Data,key:String,tail:List<&2,Filter.Value>,absent:Bool) -> List<&2,Filter.Value>: 8 match absent: 9 case True{}:tail 10 case False{}:Filter.Value{key,""} <> tail 11 def present(~S:Data,pairs:List<&1,Fragment.Entry & Maybe<&2,U32>>) -> List<&2,Filter.Value>: 12 match pairs: 13 case []:[] 14 case (Fragment.Entry{Fragment.Component{},key,_},Some{count}) <> rest:present_choice(~S,key,present(~S,rest),U32.is_eq(count,0)) 15 case _ <> rest:present(~S,rest) 16 def kept(~S:Data,~C:Type,handle:W.Handle,result:C & List<&2,W.Handle>) -> C & List<&2,W.Handle>: 17 match result: 18 case (store,after):(store,handle <> after) 19 def required(~S:Data,~C:Type,handle:W.Handle,limit:Maybe<&2,Nat>,rest:C -> Maybe<&2,Nat> -> C & List<&2,W.Handle>,store:C,include:Bool) -> C & List<&2,W.Handle>: 20 match include: 21 case True{}:kept(~S,~C,handle,rest(store,Filter.decrement(limit))) 22 case False{}:rest(store,limit) 23 def selected(~S:Data,~C:Type,entries:List<&2,Fragment.Entry>,criteria:List<&2,Filter.Component>,handle:W.Handle,limit:Maybe<&2,Nat>,rest:C -> Maybe<&2,Nat> -> C & List<&2,W.Handle>,result:C & List<&2,Maybe<&2,U32>>) -> C & List<&2,W.Handle>: 24 match result: 25 case (store,slots):required(~S,~C,handle,limit,rest,store,Filter.requirements(~S,criteria,present(~S,List.zip(&2,Fragment.Entry,&2,Maybe<&2,U32>,Fragment.bare_entries(~S,entries),slots)))) 26 def included(~S:Data,~C:Type,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,entries:List<&2,Fragment.Entry>,criteria:List<&2,Filter.Component>,+handle:W.Handle,limit:Maybe<&2,Nat>,rest:C -> Maybe<&2,Nat> -> C & List<&2,W.Handle>,store:C,include:Bool) -> C & List<&2,W.Handle>: 27 match include: 28 case False{}:rest(store,limit) 29 case True{}:selected(~S,~C,entries,criteria,handle,limit,rest,count(store,[handle])) 30 def scan(~S:Data,~C:Type,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,handles:List<&2,W.Handle>,+entries:List<&2,Fragment.Entry>,+ids:Maybe<&2,List<&2,Key.Key>>,+criteria:List<&2,Filter.Component>,limit:Maybe<&2,Nat>,store:C) -> C & List<&2,W.Handle>: 31 match handles limit: 32 case _ Some{0n}:(store,[]) 33 case [] _:(store,[]) 34 case +handle <> rest limit:included(~S,~C,~count,entries,criteria,handle,limit,next => remaining => scan(~S,~C,~count,rest,entries,ids,criteria,remaining,next),store,Filter.includes(~S,ids,handle))