please have a look at below example (in VIP 8 build 801). It creates a number of instances of an object type. The object has a nondeterm fact named keyValFact. In the object's constructor one exemplary key-value pair is asserted to the fact. In the finalizer it is checked whether the pair is still there. The outcomes of the checks are recorded in class facts okCount and errList.
My tests revealed random behavior. Please try in 32/64 bit modes and with various values for ObjCount.
Code: Select all
interface obj
end interface obj
%---
class obj : obj
open core
properties
okCount : unsigned (o).
errList : tuple{unsigned Key, unsigned Val}** (o).
end class obj
%---
implement obj
open core
class facts
okCount : unsigned := 0.
errList : tuple{unsigned Key, unsigned Val}** := [].
facts
keyValFact : (unsigned Key, unsigned Val) nondeterm.
clauses
new() :-
Key = 1,
Val = 2,
assert(keyValFact(Key, Val)).
clauses
finalize() :-
KeyValList = [ tuple(Key, Val) || keyValFact(Key, Val) ],
if KeyValList = [tuple(1, 2)] then
okCount := okCount + 1
else
errList := [KeyValList | errList]
end if.
end implement obj
%===
implement main
clauses
run() :-
ObjCount = 10000,
foreach _ = std::cIterate(ObjCount) do
_ = obj::new()
end foreach,
memory::garbageCollect(),
ErrListLen = list::length(obj::errList),
%stdIO::write(obj::errList, '\n\n'),
stdIO::writeF("objects: %10u\n", ObjCount),
stdIO::writeF("still alive: %10u\n", ObjCount - (obj::okCount + ErrListLen)),
stdIO::writeF("finalized ok: %10u\n", obj::okCount),
stdIO::writeF("finalized err:%10u\n", ErrListLen).
end implement main
Code: Select all
interface obj
end interface obj
%---
class obj : obj
open core
properties
okCount : unsigned (o).
errList : tuple{unsignedNative Key, unsigned Val}** (o).
end class obj
%---
implement obj
open core
class facts
okCount : unsigned := 0.
errList : tuple{unsignedNative Key, unsigned Val}** := [].
facts
keyToValDict : radixTree::dictionary{unsigned Val} := radixTree::empty.
clauses
new() :-
Key = 1,
Val = 2,
keyToValDict := radixTree::insert({ (K1, _K2) = K1 }, keyToValDict, Key, Val).
clauses
finalize() :-
KeyValList = [ tuple(Key, Val) || radixTree::get_nd(keyToValDict, Key, Val) ],
if KeyValList = [tuple(1, 2)] then
okCount := okCount + 1
else
errList := [KeyValList | errList]
end if.
end implement obj
%===
implement main
clauses
run() :-
ObjCount = 10000,
foreach _ = std::cIterate(ObjCount) do
_ = obj::new()
end foreach,
memory::garbageCollect(),
ErrListLen = list::length(obj::errList),
%stdIO::write(obj::errList, '\n\n'),
stdIO::writeF("objects: %10u\n", ObjCount),
stdIO::writeF("still alive: %10u\n", ObjCount - (obj::okCount + ErrListLen)),
stdIO::writeF("finalized ok: %10u\n", obj::okCount),
stdIO::writeF("finalized err:%10u\n", ErrListLen).
end implement main
Code: Select all
interface obj
end interface obj
%---
class obj : obj
open core
properties
okCount : unsigned (o).
errList : tuple{unsigned Key, unsigned Val}** (o).
end class obj
%---
implement obj
open core
class facts
okCount : unsigned := 0.
errList : tuple{unsigned Key, unsigned Val}** := [].
facts
keyToValMapM : mapM{unsigned Key, unsigned Val} := mapM_redBlack::new().
clauses
new() :-
Key = 1,
Val = 2,
keyToValMapM:set(Key, Val).
clauses
finalize() :-
KeyValList = keyToValMapM:asList,
if KeyValList = [tuple(1, 2)] then
okCount := okCount + 1
else
errList := [KeyValList | errList]
end if.
end implement obj
%===
implement main
clauses
run() :-
ObjCount = 10000,
foreach _ = std::cIterate(ObjCount) do
_ = obj::new()
end foreach,
memory::garbageCollect(),
ErrListLen = list::length(obj::errList),
%stdIO::write(obj::errList, '\n\n'),
stdIO::writeF("objects: %10u\n", ObjCount),
stdIO::writeF("still alive: %10u\n", ObjCount - (obj::okCount + ErrListLen)),
stdIO::writeF("finalized ok: %10u\n", obj::okCount),
stdIO::writeF("finalized err:%10u\n", ErrListLen).
end implement main
Code: Select all
interface obj
end interface obj
%---
class obj : obj
open core
properties
okCount : unsigned (o).
errList : tuple{unsigned Key, unsigned Val}** (o).
end class obj
%---
implement obj
open core
class facts
okCount : unsigned := 0.
errList : tuple{unsigned Key, unsigned Val}** := [].
facts
keyValList : tuple{unsigned Key, unsigned Val}* := [].
clauses
new() :-
Key = 1,
Val = 2,
keyValList := [tuple(Key, Val) | keyValList].
clauses
finalize() :-
if keyValList = [tuple(1, 2)] then
okCount := okCount + 1
else
errList := [keyValList | errList]
end if.
end implement obj
%===
implement main
clauses
run() :-
ObjCount = 10000,
foreach _ = std::cIterate(ObjCount) do
_ = obj::new()
end foreach,
memory::garbageCollect(),
ErrListLen = list::length(obj::errList),
%stdIO::write(obj::errList, '\n\n'),
stdIO::writeF("objects: %10u\n", ObjCount),
stdIO::writeF("still alive: %10u\n", ObjCount - (obj::okCount + ErrListLen)),
stdIO::writeF("finalized ok: %10u\n", obj::okCount),
stdIO::writeF("finalized err:%10u\n", ErrListLen).
end implement main
Code: Select all
interface obj
end interface obj
%---
class obj : obj
properties
finalizeCount : unsigned (o).
end class obj
%---
implement obj
class facts
finalizeCount : unsigned := 0.
clauses
finalize() :-
finalizeCount := finalizeCount + 1,
if finalizeCount > 0 then
exception::raise_error()
end if.
end implement obj
%===
implement main
clauses
run() :-
foreach _N = std::cIterate(10) do
_ = obj::new()
end foreach,
memory::garbageCollect(),
stdIO::write(obj::finalizeCount).
end implement main