Skip to content

Commit

Permalink
It does.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ostrzyciel committed Jul 18, 2024
1 parent fff572f commit 9789607
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 429 deletions.
31 changes: 15 additions & 16 deletions core/src/main/java/eu/ostrzyciel/jelly/core/NodeEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
import scala.collection.mutable.ListBuffer;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

public class NodeEncoder<TNode> {
public final static class DependentNode {
public RdfTerm encoded;
public static final class DependentNode {
public UniversalTerm encoded;
// 1: datatypes and IRI names
public int lookupPointer1;
public int lookupSerial1;
Expand Down Expand Up @@ -40,7 +38,7 @@ protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
NewEncoderLookup prefixLookup;
NewEncoderLookup nameLookup;
NodeCache<Object, DependentNode> dependentNodeCache;
NodeCache<TNode, RdfTerm> nodeCache;
NodeCache<Object, UniversalTerm> nodeCache;

static final RdfIri zeroIri = new RdfIri(0, 0);

Expand All @@ -54,26 +52,24 @@ public NodeEncoder(RdfStreamOptions opt, int nodeCacheSize, int dependentNodeCac
dependentNodeCache = new NodeCache<>(dependentNodeCacheSize);
nodeCache = new NodeCache<>(nodeCacheSize);
}

// if returned object.encoded = null -> set it to new RdfLiteral.
// else, use it to write on the wire
public DependentNode encodeDtLiteral(TNode key, ListBuffer<RdfStreamRow> rowsBuffer, Supplier<String> dtSupplier) {
public UniversalTerm encodeDtLiteral(
TNode key, String lex, String datatypeName, ListBuffer<RdfStreamRow> rowsBuffer
) {
var cachedNode = dependentNodeCache.get(key);
if (cachedNode != null) {
// Check if the value is still valid
if (cachedNode.lookupSerial1 == datatypeLookup.table[cachedNode.lookupPointer1 * 3 + 2]) {
datatypeLookup.onAccess(cachedNode.lookupPointer1);
return cachedNode;
return cachedNode.encoded;
}
cachedNode.encoded = null;
} else {
cachedNode = new DependentNode();
// We can already put the node in the map, we will update it later using our reference
dependentNodeCache.put(key, cachedNode);
}

// The node is not encoded, but we may already have the datatype encoded
var datatypeName = dtSupplier.get();
var dtEntry = datatypeLookup.addEntry(datatypeName);
if (dtEntry.newEntry) {
rowsBuffer.append(new RdfStreamRow(
Expand All @@ -84,11 +80,14 @@ public DependentNode encodeDtLiteral(TNode key, ListBuffer<RdfStreamRow> rowsBuf
}
cachedNode.lookupPointer1 = dtEntry.getId;
cachedNode.lookupSerial1 = dtEntry.serial;
cachedNode.encoded = new RdfLiteral(
lex, new RdfLiteral$LiteralKind$Datatype(dtEntry.getId)
);

return cachedNode;
return cachedNode.encoded;
}

public RdfTerm encodeIri(String iri, ListBuffer<RdfStreamRow> rowsBuffer) {
public UniversalTerm encodeIri(String iri, ListBuffer<RdfStreamRow> rowsBuffer) {
var cachedNode = dependentNodeCache.get(iri);
if (cachedNode != null) {
// Check if the value is still valid
Expand Down Expand Up @@ -166,7 +165,7 @@ public RdfTerm encodeIri(String iri, ListBuffer<RdfStreamRow> rowsBuffer) {
return outputIri(cachedNode);
}

private RdfTerm outputIri(DependentNode cachedNode) {
private UniversalTerm outputIri(DependentNode cachedNode) {
if (lastIriPrefixId == cachedNode.lookupPointer2) {
if (lastIriNameId + 1 == cachedNode.lookupPointer1) {
lastIriNameId = cachedNode.lookupPointer1;
Expand All @@ -187,7 +186,7 @@ private RdfTerm outputIri(DependentNode cachedNode) {
}
}

public RdfTerm encodeOther(TNode key, Function<TNode, RdfTerm> encoder) {
public UniversalTerm encodeOther(Object key, Function<Object, UniversalTerm> encoder) {
return nodeCache.computeIfAbsent(key, encoder);
}
}
41 changes: 0 additions & 41 deletions core/src/main/scala/eu/ostrzyciel/jelly/core/EncoderLookup.scala

This file was deleted.

126 changes: 0 additions & 126 deletions core/src/main/scala/eu/ostrzyciel/jelly/core/NameEncoder.scala

This file was deleted.

41 changes: 13 additions & 28 deletions core/src/main/scala/eu/ostrzyciel/jelly/core/ProtoEncoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,46 +124,31 @@ abstract class ProtoEncoder[TNode, -TTriple, -TQuad, -TQuoted](val options: RdfS

// *** 3. THE PROTECTED INTERFACE ***
// **********************************
protected final inline def makeIriNode(iri: String): SpoTerm =
iriEncoder.encodeIri(iri, extraRowsBuffer)
protected final inline def makeIriNode(iri: String): UniversalTerm =
nodeEncoder.encodeIri(iri, extraRowsBuffer)

protected final inline def makeBlankNode(label: String): SpoTerm =
RdfTerm.Bnode(label)
protected final inline def makeBlankNode(label: String): UniversalTerm =
nodeEncoder.encodeOther(label, _ => RdfTerm.Bnode(label))

protected final inline def makeSimpleLiteral(lex: String): SpoTerm =
RdfLiteral(lex, RdfLiteral.LiteralKind.Empty)
protected final inline def makeSimpleLiteral(lex: String): UniversalTerm =
nodeEncoder.encodeOther(lex, _ => RdfLiteral(lex, RdfLiteral.LiteralKind.Empty))

protected final inline def makeLangLiteral(lex: String, lang: String): SpoTerm =
RdfLiteral(lex, RdfLiteral.LiteralKind.Langtag(lang))
protected final inline def makeLangLiteral(lit: TNode, lex: String, lang: String): UniversalTerm =
nodeEncoder.encodeOther(lit, _ => RdfLiteral(lex, RdfLiteral.LiteralKind.Langtag(lang)))

protected final inline def makeDtLiteral(lex: String, dt: String): SpoTerm =
RdfLiteral(lex, iriEncoder.encodeDatatype(dt, extraRowsBuffer))
protected final inline def makeDtLiteral(lit: TNode, lex: String, dt: String): UniversalTerm =
nodeEncoder.encodeDtLiteral(lit, lex, dt, extraRowsBuffer)

protected final inline def makeTripleNode(triple: TQuoted): SpoTerm =
protected final inline def makeTripleNode(triple: TQuoted): RdfTriple =
quotedToProto(triple)

protected final inline def makeIriNodeGraph(iri: String): GraphTerm =
iriEncoder.encodeIri(iri, extraRowsBuffer)

protected final inline def makeBlankNodeGraph(label: String): GraphTerm =
RdfTerm.Bnode(label)

protected final inline def makeSimpleLiteralGraph(lex: String): GraphTerm =
RdfLiteral(lex, RdfLiteral.LiteralKind.Empty)

protected final inline def makeLangLiteralGraph(lex: String, lang: String): GraphTerm =
RdfLiteral(lex, RdfLiteral.LiteralKind.Langtag(lang))

protected final inline def makeDtLiteralGraph(lex: String, dt: String): GraphTerm =
RdfLiteral(lex, iriEncoder.encodeDatatype(dt, extraRowsBuffer))

protected final inline def makeDefaultGraph: GraphTerm =
protected final inline def makeDefaultGraph: RdfDefaultGraph =
RdfDefaultGraph.defaultInstance

// *** 3. PRIVATE FIELDS AND METHODS ***
// *************************************
private var extraRowsBuffer = new ListBuffer[RdfStreamRow]()
private val iriEncoder = new NameEncoder(options)
private val nodeEncoder = new NodeEncoder[TNode](options, 1024, 1024)
private var emittedOptions = false

private val lastSubject: LastNodeHolder[TNode] = new LastNodeHolder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ trait SpoTerm extends RdfTerm:
trait GraphTerm extends RdfTerm:
def isDefaultGraph: Boolean = false
def defaultGraph: RdfDefaultGraph = null


trait UniversalTerm extends SpoTerm, GraphTerm

object RdfTerm:
/**
* Wrapper class for blank nodes, because in the proto they are simply represented as strings, and
* we cannot inherit from String. We must use a wrapper.
*/
final case class Bnode(override val bnode: String) extends SpoTerm, GraphTerm:
final case class Bnode(override val bnode: String) extends UniversalTerm:
override def isBnode: Boolean = true

// Methods below are used in RdfTriple, RdfQuad, and RdfGraphStart instead of generated code. They are all
Expand Down
Loading

0 comments on commit 9789607

Please sign in to comment.