module type Block = sig type data type block_id = Data of int | Check of int | Empty type block_type = { id : block_id; dt : data } val nul_block : block_type val xor: data -> data -> data end;; module Incremental_decoder = functor (B: Block) -> struct class incremental_decode (g: Graphlib.graph) = let last_data = List.fold_left max 5 g#dnodes and last_check = List.fold_left max 5 g#cnodes in object (self) (* val mutable waiting = g#dnodes *) val datas = Array.create last_data B.nul_block val checks = Array.create last_check B.nul_block val waiting = Array.create last_check [] val datas_targeted = Array.create last_data (-1) method get block_id = match block_id with B.Data d -> datas.(d) | B.Check c -> checks.(c) | B.Empty -> assert false method have block_id = (self#get block_id) != B.nul_block method add (blk : B.block_type) = match blk.id with B.Data d -> assert (datas.(d) == B.nul_block); datas.(d) <- block; let checks_to_simplify = List.filter (fun c -> checks.(c) != B.nul_block) (g#cnodes_of d) in let resolve c = match waiting.(c) with [] -> () | t :: [] -> assert (d=t); waiting.(c) <- []; datas_targeted.(d) <- -1; | t1 :: (t2 :: []) -> assert ((d=t1) || (d=t2)); let decode = if d=t1 then t2 else t1 in checks.(c) <- (B.Check c, B.xor (snd checks.(c)) cont); waiting.(c) <- []; datas_targeted.(d) <- -1; self#add (B.Check decode, snd checks.(c)); (* c = decode *) | l -> waiting.(c) <- List.filter (fun x -> d <> x) l; in List.iter resolve checks_to_simplify; | B.Check c -> () | B.Empty -> assert false end end;;