/*---------------------------------------------------------------------------- It is the garbadge collector of poor orders Some orders that frequently belong to refused cycles are removed from the database with the following algorithm: 1 - When a movement nr->np is created, a counter Q(np,nr) is incremented Q(np,nr) := treltried[np,nr].cnt +=1 done by fupdate_treltried(_commits int8[],_nbcommit int), called by fexecute_flow() 2- When an order nr->np is created, the counter Q(np,nr) is recorded at a position P torder[.].start := Q(np,nr) == P done by fget_treltried() called by finsert_toint() called by finsertorder() and fexecquote() 3- orders are removed from the market when their torder[.].start +MAXTRY < Q(np,nr), with MAXTRY defined in tconst This operation 3) is performed each time some movements are created. done by finvalidate_treltried() called by fexecquote() and finsertorder() 4- treltried must be truncated at market opening done by frenumbertables() Ainsi, on permet à chaque offre d'être mis en concurrence MAXTRY fois sans pénaliser les couple (np,nr) plus rares. Celà suppose que toutes les solutions soient parcourus, ce qui n'est pas le cas. */ INSERT INTO tconst (name,value) VALUES ('MAXTRY',10); -- life time of an order for a given couple (np,nr) -------------------------------------------------------------------------------- -- TRELTRIED -------------------------------------------------------------------------------- create table treltried ( np int, nr int, cnt bigint DEFAULT 0, PRIMARY KEY (np,nr), CHECK( np!=nr AND cnt >=0 ), CONSTRAINT creltried_np FOREIGN KEY (np) references tquality(id), CONSTRAINT creltried_nr FOREIGN KEY (nr) references tquality(id) ); -------------------------------------------------------------------------------- -- fupdate_treltried(_commits int8[],_nbcommit int) -- update treltried[np,nr].cnt -------------------------------------------------------------------------------- CREATE FUNCTION fupdate_treltried(_commits int8[],_nbcommit int) RETURNS void AS $$ DECLARE _i int; _np int; _nr int; _MAXTRY int := fgetconst('MAXTRY'); BEGIN IF(_MAXTRY=0) THEN RETURN; END IF; FOR _i IN 1 .. _nbcommit LOOP _nr := _commits[_i][3]::int; _np := _commits[_i][5]::int; LOOP UPDATE treltried SET cnt = cnt + 1 WHERE np=_np AND nr=_nr; IF FOUND THEN EXIT; ELSE BEGIN INSERT INTO treltried (np,nr,cnt) VALUES (_np,_nr,1); EXCEPTION WHEN check_violation THEN -- END; END IF; END LOOP; END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL; -------------------------------------------------------------------------------- -- fget_treltried(_np int,_nr int) -- sets torder[.].start -------------------------------------------------------------------------------- CREATE FUNCTION fget_treltried(_np int,_nr int) RETURNS int8 AS $$ DECLARE _cnt int8; _MAXTRY int := fgetconst('MAXTRY'); BEGIN IF(_MAXTRY=0) THEN RETURN 0; END IF; SELECT cnt into _cnt FROM treltried WHERE np=_np AND nr=_nr; IF NOT FOUND THEN _cnt := 0; END IF; RETURN _cnt; END; $$ LANGUAGE PLPGSQL; -------------------------------------------------------------------------------- -- finvalidate_treltried() -------------------------------------------------------------------------------- CREATE FUNCTION finvalidate_treltried() RETURNS void AS $$ DECLARE _o torder%rowtype; _MAXTRY int := fgetconst('MAXTRY'); _res int; _mvt_id int; _uuid text; BEGIN IF(_MAXTRY=0) THEN RETURN; END IF; FOR _o IN SELECT o.* FROM torder o,treltried r WHERE o.np=r.np AND o.nr=r.nr AND o.start IS NOT NULL AND o.start + _MAXTRY < r.cnt LOOP INSERT INTO tmvt (uuid,nb,oruuid,grp,own_src,own_dst,qtt,nat,created) VALUES('',1,_o.uuid,NULL,_o.own,_o.own,_o.qtt,_o.np,statement_timestamp()) RETURNING id INTO _mvt_id; _uuid := fgetuuid(_mvt_id); UPDATE tmvt SET uuid = _uuid WHERE id=_mvt_id; -- the order order.qtt != 0 perform fremoveorder_int(_o.id); END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL;