:- ensure_loaded(common).
cvs_id('$Id: pagein.pl,v 1.11 2004/10/21 21:05:19 sandro Exp $').
/*

  
*/

:- ensure_loaded(library(debug)).

:- dynamic(graph_paged_in/1).
:- volatile(graph_paged_in/1).

%%  this is rather slow; we should probably have another qsaved
%%  copy of this stuff..... somehow?   can we qsave a bunch of
%%  rdfpages at once?     qsave_where(....)
%%
pagein_latest_meta :-
	write('reloading meta: '), flush_output,
	forall( (   address_latest_ret(_, Ret)
		;   address_latest_successful_ret(_, Ret)),
		(   (   pagein_meta(Ret)
                    ->  write('.'), 	    
                        flush_output
                    ;   print_message(warning, cant_pagein(Ret))
                    )
		)
	      ),
	nl.

pagein_latest :-
	write('reloading: '), flush_output,
	forall( (   address_latest_ret(_, Ret)
		;   address_latest_successful_ret(_, Ret)),
		(   (   pagein(Ret)
                    ->  write('.'), 	    
                        flush_output
                    ;   print_message(warning, cant_pagein(Ret))
                    )
		)
	      ),
	nl.

pagein(Ret) :-
	(   rdfpage(Ret, retr:initialResource, URI),
	    rdfpage(Ret, retr:graph, Graph),
	    graph_paged_in(Graph)
	->  debug(pagein, 'already paged ~q ~q ~q', [Ret, URI, Graph])
	;   (   rdfpage_sub_uri(Page, _, Ret)
	    ->
		debug(precache, 'reloading ~w', [Page]),
		rdfpage_unload(Page),
		rdfpage_load(Page),
		rdfpage(Ret, retr:initialResource, URI),
		debug(pagein, 'pagein ~q ~q', [Ret, URI]),
		forall(rdfpage(Ret, retr:inference, Proof),
		       (   print_message(informational, pagein_proof(Proof)),
			   rdfpage_load(Proof)
		       )
		      ),
		(   rdfpage(Ret, retr:graph, Graph)
		->  rdfpage_unload(Graph),
		    rdfpage_load(Graph),
		    %ret_set_status(Ret, retr:rdf_loaded),
		    assert(graph_paged_in(Graph))
		;   debug(pagein, '... not rdf', []) %,
		    %ret_set_status(Ret, retr:no_rdf)
		)
	    ;   print_message(error, pagein_not_rdfpage(Ret))
	    )
	).

pagein_meta(Ret) :-
	(   rdfpage(Ret, retr:initialResource, URI)
	->  true
	;   (   rdfpage_sub_uri(Page, _, Ret)
	    ->
		debug(pagein, 'reloading ~w', [Page]),
		rdfpage_unload(Page),
		rdfpage_load(Page),
		rdfpage(Ret, retr:initialResource, URI),
		debug(pagein, 'pagein_meta ~q ~q', [Ret, URI])
	    )
	;   print_message(error, pagein_not_rdfpage(Ret))
	).

pagein_around(Focus) :-
	get_time(Now),
	forall( subj_graph(Focus, Graph), pagein_graph_time(Graph, Now) ),
	forall( obj_graph(Focus, Graph), pagein_graph_time(Graph, Now) ).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%   newer approach
%%
%%   Ret info always in -- or handled differently at least
%%   (in shelves?)
%%


% rdf_with_pagein(+S, -P, -O, -G)
%
% this is very cool -- it uses persistent predicate subj_graph
% and obj_graph 
% to pull pages off disk as needed to get more and more graphs
% with information about this subject -- and it works well with
% findsome/setofsome, only paging in as many graphs as we need.
%

rdf_with_pagein(S, P, O, G) :-
	ground(S),
	get_time(StartTime),
	subj_graph(S, G),
	pagein_graph_time(G,StartTime),
	rdf(S,P,O,G).

rdf_with_pagein(S, P, O, G) :-
	ground(O),
	get_time(StartTime),
	obj_graph(O, G),
	pagein_graph_time(G,StartTime),
	rdf(S,P,O,G).



% does NOT bring in the Ret;  assume it's in.
%
% maybe: give graphs names like   page/3424-23423 so we can find the Ret
%
pagein_graph(Graph) :-
	get_time(Now),
	pagein_graph_time(Graph, Now).
	
pagein_graph_time(Graph, Now) :-
	(   graph_paged_in(Graph)
	->  true
	;   assume(\+sub_atom(Graph, _, _, _, '#')),
	    rdfpage_load(Graph),    % ugh -- this might fail if data
	                            % is missing from rdfpage but still
	                            % in index.   this happened once due
	                            % to a bug, but I'm not sure the
	                            % general solution.
	    assert(graph_paged_in(Graph))
	),
	retractall(touched(Graph, _)),
	assert(touched(Graph, Now)),
	!.
pagein_graph_time(A,B) :-
	throw(failed(pagein_graph_time(A,B))).

paged_in_by_parser(Graph) :-
	assert(graph_paged_in(Graph)),
	get_time(Now),
	retractall(touched(Graph, _)),
	assert(touched(Graph, Now)).
	
	