:- use_module( library(lib) ). :- lib(os_lib). :- lib(options). :- lib(rocksdb). :- lib(stoics_lib:en_list/2). :- ensure_loaded( '../lib/bio_db_pl_info' ). :- ensure_loaded( '../lib/check_term' ). % /4. % :- debug( rocks ). /** pl_rocks( +PlFile ). Convert a prolog bio_db file to rocks database file. PlFile could be the full filename or the stem minus the extension 'pl'. */ pl_rocks( FoS ) :- en_list( FoS, Fos ), maplist( pl_rocks_file, Fos ). pl_rocks_file( FoS ) :- ( file_name_extension(_,pl,FoS) -> PlF = FoS ; file_name_extension( FoS, pl, PlF ) ), os_ext( pl, rocks, PlF, DbF ), os_remove( DbF, [exists(false),debug(true)] ), Mess = 'Prolog input: ~p, rocksdb output: ~p', debug( rocks, Mess, [PlF,DbF] ), pl_rocks_file_transcribe( PlF, DbF ), !. pl_rocks_file( FoS ) :- throw( failed_to_convert_to_rocks(FoS) ). pl_rocks_file_transcribe( PlF, DbF ) :- bio_db_pl_info( PlF, Pname, Arity, Infos, NexTerm, PlStream ), os_postfix( info, DbF, InfoF, sep('_') ), rocks_open( InfoF, InfoHandle, [key(atom),value(term)] ), findall( _, ( member(InfoTerm,Infos), arg(1,InfoTerm,InfoKey), arg(2,InfoTerm,InfoVal), rocks_put(InfoHandle,InfoKey,InfoVal) ), _), rocks_close( InfoHandle ), Arity > 1, atom_concat( Pname, '_info', InfoName ), RelTypeG =.. [InfoName,relation_type,RelType], memberchk( RelTypeG, Infos ), DataTypeG =.. [InfoName,data_types,DataTypeT], memberchk( DataTypeG, Infos ), bio_db_info_db_types( rocks, RelType, DataTypeT, Dup, _OpenTypes, KeyType, ValType ), % currently rocks doesn't allow duplicates % ( Dup == false -> KeyType = NoDupKeyType; NoDupKeyType = term ), % below is the second take, now single key maps to a list of values if there are duplicates ( Dup == false -> ValType = NoDupValType; NoDupValType = term ), NoDupOpenTypes = [key(KeyType),value(NoDupValType)], Open = rocks_open( DbF, Out, NoDupOpenTypes ), debug( rocks, 'Opening rocksdb for updating: ~w', Open ), % rocks_open( DbF, Out, NoDupOpenTypes ), call( Open ), pl_rocks_streams( NexTerm, PlStream, Pname/Arity, Dup, KeyType, ValType, Out ), close( PlStream ), rocks_close( Out ). pl_rocks_streams( end_of_file, _In, _Pid, _Dup, _Kt, _Vt, _Out ) :- !. pl_rocks_streams( InTerm, In, Pid, Dup, Kt, Vt, Out ) :- % debug( pl_rocks, 'Doing term: ~w', InTerm ), pl_rocks_term( InTerm, Pid, Dup, Kt, Vt, Out ), read( In, NxtTerm ), % debug( rocks, 'In term: ~w', NxtTerm ), pl_rocks_streams( NxtTerm, In, Pid, Dup, Kt, Vt, Out ). pl_rocks_term( InTerm, Pname/Arity, Dup, Kt, Vt, Out ) :- functor( InTerm, InPname, InArity ), check_term( InPname, Pname, InArity, Arity ), pl_rocks_pname_term( Arity, Pname, InTerm, Dup, Kt, Vt, Out ). pl_rocks_pname_term( 2, _Pname, Term, Dup, _Kt, _Vt, Handle ) :- !, arg( 1, Term, Key ), arg( 2, Term, Val ), rocks_dup_put( Dup, Handle, Key, Val ). pl_rocks_pname_term( _Arity, _Pname, Term, Dup, _Kt, _Vt, Out ) :- % then Arity > 2, Term =.. [_PnameP,Key|Vals], pl_rocks_vals_term( Vals, Val ), rocks_dup_put( Dup, Out, Key, Val ). rocks_dup_put( false, Handle, Key, Val ) :- rocks_put( Handle, Key, Val ). rocks_dup_put( true, Handle, Key, Val ) :- % ( rocks_get(Handle,Key,_) -> ... ) % second take, Multi valued keys go to list of vals now ( rocks_get(Handle,Key,Existing) -> % request rocsk_delete/3 that combines this and below: ( is_list(Existing) -> append(Existing,[Val],Vals); Vals = [Existing,Val] ), rocks_put( Handle, Key, Vals ) % according to the docs this replaces old value so need to delete % rocks_dup_put_iter( Key, 1, Handle, Val ) ; % debug( rocks, 'Puts in Rock : ~w - ~w', [Key,Val] ), rocks_put( Handle, Key, Val ) ). rocks_dup_put_iter( Key, I, Handle, Val ) :- rocks_get( Handle, Key:I, _ ), !, J is I + 1, rocks_dup_put_iter( Key, J, Handle, Val ). rocks_dup_put_iter( Key, I, Handle, Val ) :- % debug( rocks, 'Puts in Rock : ~w - ~w', [Key,Val] ), rocks_put( Handle, Key:I, Val ). pl_rocks_vals_term( [H], H ) :- !. pl_rocks_vals_term( [H|T], H+R ) :- pl_rocks_vals_term( T, R ).