1616import com .the_qa_company .qendpoint .core .options .HDTOptionsFile ;
1717import com .the_qa_company .qendpoint .core .options .HDTOptionsKeys ;
1818import com .the_qa_company .qendpoint .core .options .HDTSpecification ;
19+ import com .the_qa_company .qendpoint .core .rdf .parsers .BlankNodeIdMapper ;
20+ import com .the_qa_company .qendpoint .core .rdf .parsers .NTriplesChunkedSource ;
1921import com .the_qa_company .qendpoint .core .rdf .RDFFluxStop ;
2022import com .the_qa_company .qendpoint .core .rdf .RDFParserCallback ;
2123import com .the_qa_company .qendpoint .core .rdf .RDFParserFactory ;
2224import com .the_qa_company .qendpoint .core .rdf .TripleWriter ;
25+ import com .the_qa_company .qendpoint .core .iterator .utils .SizedSupplier ;
2326import com .the_qa_company .qendpoint .core .triples .TripleString ;
2427import com .the_qa_company .qendpoint .core .util .BitUtil ;
2528import com .the_qa_company .qendpoint .core .util .Profiler ;
4043import java .io .IOException ;
4144import java .io .InputStream ;
4245import java .io .OutputStream ;
46+ import java .io .UncheckedIOException ;
4347import java .nio .file .Files ;
4448import java .nio .file .NoSuchFileException ;
4549import java .nio .file .Path ;
4650import java .nio .file .StandardOpenOption ;
4751import java .util .Iterator ;
4852import java .util .List ;
53+ import java .util .NoSuchElementException ;
4954
5055public class HDTManagerImpl extends HDTManager {
5156 private static final Logger logger = LoggerFactory .getLogger (HDTManagerImpl .class );
@@ -334,13 +339,23 @@ public HDTResult doGenerateHDT(String rdfFileName, String baseURI, RDFNotation r
334339 @ Override
335340 public HDTResult doGenerateHDT (InputStream fileStream , String baseURI , RDFNotation rdfNotation ,
336341 CompressionType compressionType , HDTOptions hdtFormat , ProgressListener listener ) throws IOException {
342+ boolean keepBNode = hdtFormat .getBoolean (HDTOptionsKeys .PARSER_KEEP_BNODE_KEY , true );
343+ if (HDTOptionsKeys .LOADER_TYPE_VALUE_DISK .equals (hdtFormat .get (HDTOptionsKeys .LOADER_TYPE_KEY ))
344+ && (rdfNotation == RDFNotation .NTRIPLES || rdfNotation == RDFNotation .NQUAD )
345+ && RDFParserFactory .useSimple (hdtFormat )) {
346+ try {
347+ return doGenerateHDTDisk (fileStream , baseURI , rdfNotation , compressionType , hdtFormat , listener );
348+ } catch (ParserException e ) {
349+ throw new IOException (e );
350+ }
351+ }
337352 // uncompress the stream if required
338353 fileStream = IOUtil .asUncompressed (fileStream , compressionType );
339354 // create a parser for this rdf stream
340- RDFParserCallback parser = RDFParserFactory .getParserCallback (rdfNotation );
355+ RDFParserCallback parser = RDFParserFactory .getParserCallback (rdfNotation , hdtFormat );
341356 // read the stream as triples
342357 try (PipedCopyIterator <TripleString > iterator = RDFParserFactory .readAsIterator (parser , fileStream , baseURI ,
343- true , rdfNotation , hdtFormat )) {
358+ keepBNode , rdfNotation , hdtFormat )) {
344359 return doGenerateHDT (iterator , baseURI , hdtFormat , listener );
345360 }
346361 }
@@ -410,10 +425,24 @@ public HDTResult doGenerateHDT(Iterator<TripleString> triples, String baseURI, H
410425 public HDTResult doGenerateHDTDisk (String rdfFileName , String baseURI , RDFNotation rdfNotation ,
411426 CompressionType compressionType , HDTOptions hdtFormat , ProgressListener listener )
412427 throws IOException , ParserException {
428+ boolean keepBNode = hdtFormat .getBoolean (HDTOptionsKeys .PARSER_KEEP_BNODE_KEY , true );
413429 if (compressionType == CompressionType .NONE ) {
430+ if ((rdfNotation == RDFNotation .NTRIPLES || rdfNotation == RDFNotation .NQUAD )
431+ && RDFParserFactory .useSimple (hdtFormat )) {
432+ if (!IOUtil .isRemoteURL (rdfFileName ) && !"-" .equals (rdfFileName )) {
433+ long chunkBudget = resolveDiskChunkBudget (hdtFormat );
434+ try (NTriplesChunkedSource chunked = new NTriplesChunkedSource (Path .of (rdfFileName ), rdfNotation ,
435+ chunkBudget , createBNodeMapper (keepBNode ))) {
436+ return doGenerateHDTDisk0 (asIterator (chunked ), false , baseURI , hdtFormat , listener );
437+ }
438+ }
439+ try (InputStream stream = IOUtil .getFileInputStream (rdfFileName , false )) {
440+ return doGenerateHDTDisk (stream , baseURI , rdfNotation , compressionType , hdtFormat , listener );
441+ }
442+ }
414443 RDFParserCallback parser = RDFParserFactory .getParserCallback (rdfNotation , hdtFormat );
415444 try (PipedCopyIterator <TripleString > iterator = RDFParserFactory .readAsIterator (parser , rdfFileName ,
416- baseURI , true , rdfNotation , hdtFormat )) {
445+ baseURI , keepBNode , rdfNotation , hdtFormat )) {
417446 return doGenerateHDTDisk0 (iterator , true , baseURI , hdtFormat , listener );
418447 }
419448 }
@@ -428,15 +457,82 @@ public HDTResult doGenerateHDTDisk(InputStream fileStream, String baseURI, RDFNo
428457 throws IOException , ParserException {
429458 // uncompress the stream if required
430459 fileStream = IOUtil .asUncompressed (fileStream , compressionType );
460+ boolean keepBNode = hdtFormat .getBoolean (HDTOptionsKeys .PARSER_KEEP_BNODE_KEY , true );
461+ if ((rdfNotation == RDFNotation .NTRIPLES || rdfNotation == RDFNotation .NQUAD )
462+ && RDFParserFactory .useSimple (hdtFormat )) {
463+ long chunkBudget = resolveDiskChunkBudget (hdtFormat );
464+ try (NTriplesChunkedSource chunked = new NTriplesChunkedSource (fileStream , rdfNotation , chunkBudget ,
465+ 8L * 1024 * 1024 , 8192 , createBNodeMapper (keepBNode ))) {
466+ return doGenerateHDTDisk0 (asIterator (chunked ), false , baseURI , hdtFormat , listener );
467+ }
468+ }
431469 // create a parser for this rdf stream
432470 RDFParserCallback parser = RDFParserFactory .getParserCallback (rdfNotation , hdtFormat );
433471 // read the stream as triples
434472 try (PipedCopyIterator <TripleString > iterator = RDFParserFactory .readAsIterator (parser , fileStream , baseURI ,
435- true , rdfNotation , hdtFormat )) {
473+ keepBNode , rdfNotation , hdtFormat )) {
436474 return doGenerateHDTDisk0 (iterator , true , baseURI , hdtFormat , listener );
437475 }
438476 }
439477
478+ private static long resolveDiskChunkBudget (HDTOptions hdtFormat ) {
479+ return hdtFormat .getInt (HDTOptionsKeys .LOADER_DISK_CHUNK_SIZE_KEY , HDTManagerImpl ::getMaxChunkSize );
480+ }
481+
482+ private static BlankNodeIdMapper createBNodeMapper (boolean keepBNode ) {
483+ return keepBNode ? null : BlankNodeIdMapper .create ();
484+ }
485+
486+ private static Iterator <TripleString > asIterator (NTriplesChunkedSource chunked ) {
487+ return new Iterator <>() {
488+ private SizedSupplier <TripleString > currentChunk ;
489+ private TripleString next ;
490+ private boolean finished ;
491+
492+ @ Override
493+ public boolean hasNext () {
494+ pullNext ();
495+ return next != null ;
496+ }
497+
498+ @ Override
499+ public TripleString next () {
500+ pullNext ();
501+ if (next == null ) {
502+ throw new NoSuchElementException ();
503+ }
504+ TripleString value = next ;
505+ next = null ;
506+ return value ;
507+ }
508+
509+ private void pullNext () {
510+ if (finished || next != null ) {
511+ return ;
512+ }
513+ try {
514+ while (true ) {
515+ if (currentChunk == null ) {
516+ currentChunk = chunked .get ();
517+ if (currentChunk == null ) {
518+ finished = true ;
519+ return ;
520+ }
521+ }
522+ TripleString value = currentChunk .get ();
523+ if (value != null ) {
524+ next = value .tripleToString ();
525+ return ;
526+ }
527+ currentChunk = null ;
528+ }
529+ } catch (IOException e ) {
530+ throw new UncheckedIOException (e );
531+ }
532+ }
533+ };
534+ }
535+
440536 /**
441537 * @return a theoretical maximum amount of memory the JVM will attempt to
442538 * use
0 commit comments