Minor performance improvements
Change-Id: I800cad429302752e9fdbfbd7b435c084c86f5c04
diff --git a/src/main/java/de/ids_mannheim/korap/Krill.java b/src/main/java/de/ids_mannheim/korap/Krill.java
index 0d02b79..72373db 100644
--- a/src/main/java/de/ids_mannheim/korap/Krill.java
+++ b/src/main/java/de/ids_mannheim/korap/Krill.java
@@ -63,6 +63,8 @@
private JsonNode request;
private String spanContext;
+ private final ObjectMapper mapper = new ObjectMapper();
+
// Logger
private final static Logger log = LoggerFactory.getLogger(Krill.class);
@@ -136,10 +138,9 @@
* @return The {@link Krill} object for chaining.
* @throws QueryException
*/
- public Krill fromJson (String query) {
+ public Krill fromJson (final String query) {
// Parse query string
try {
- ObjectMapper mapper = new ObjectMapper();
this.request = mapper.readTree(query);
this.fromJson(this.request);
}
@@ -166,10 +167,10 @@
// Parse "query" attribute
if (json.has("query")) {
try {
- KrillQuery kq = new KrillQuery("tokens");
+ final KrillQuery kq = new KrillQuery("tokens");
this.setQuery(kq);
- SpanQueryWrapper qw = kq.fromJson(json.get("query"));
+ final SpanQueryWrapper qw = kq.fromJson(json.get("query"));
// Throw an error, in case the query matches everywhere
if (qw.isEmpty())
@@ -208,7 +209,7 @@
// Parse "collection" or "collections" attribute
try {
if (json.has("collection")) {
- JsonNode collNode = json.get("collection");
+ final JsonNode collNode = json.get("collection");
// TODO: Temporary
if (collNode.fieldNames().hasNext()) {
diff --git a/src/main/java/de/ids_mannheim/korap/KrillCollection.java b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
index 14cbec1..d0789e3 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
@@ -44,7 +44,7 @@
* See http://mail-archives.apache.org/mod_mbox/lucene-java-user/
* 200805.mbox/%3C17080852.post@talk.nabble.com%3E
*/
-public class KrillCollection extends Notifications {
+public final class KrillCollection extends Notifications {
private KrillIndex index;
private JsonNode json;
private CollectionBuilder cb = new CollectionBuilder();
@@ -345,9 +345,7 @@
* @return The {@link KrillCollection} object for chaining.
*/
public KrillCollection filterUIDs (String ... uids) {
- CollectionBuilder.Interface root = this.getBuilder();
CollectionBuilder.Group cbg = this.cb.orGroup();
- CollectionBuilder.Group filter = this.cb.andGroup();
for (String uid : uids) {
cbg.with(this.cb.term("UID", uid));
};
diff --git a/src/main/java/de/ids_mannheim/korap/KrillIndex.java b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
index 7dc25ee..ef34cfd 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillIndex.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
@@ -107,7 +107,7 @@
-> search for frequencies of VVFIN/gehen
-> c:VVFIN:[^:]*?:gehen:past:...
*/
-public class KrillIndex {
+public final class KrillIndex {
// Logger
private final static Logger log = LoggerFactory.getLogger(KrillIndex.class);
@@ -1162,7 +1162,7 @@
public Result search (SpanQuery query, short count) {
- Krill krill = new Krill(query);
+ final Krill krill = new Krill(query);
krill.getMeta().setCount(count);
return this.search(krill);
};
@@ -1204,19 +1204,19 @@
this.termContexts = new HashMap<Term, TermContext>();
- KrillCollection collection = ks.getCollection();
+ final KrillCollection collection = ks.getCollection();
collection.setIndex(this);
// Get the spanquery from the Krill object
SpanQuery query = ks.getSpanQuery();
// Get the field of textual data and annotations ("tokens")
- String field = query.getField();
+ final String field = query.getField();
- KrillMeta meta = ks.getMeta();
+ final KrillMeta meta = ks.getMeta();
// Todo: Make kr subclassing ks - so ks has a method for a new Result!
- Result kr = new Result(query.toString(), meta.getStartIndex(),
+ final Result kr = new Result(query.toString(), meta.getStartIndex(),
meta.getCount(), meta.getContext());
// Set version info to result
@@ -1230,9 +1230,8 @@
fields.add(field);
// Lift all fields
- if (fields.contains("@all")) {
+ if (fields.contains("@all"))
fields = null;
- };
// Some initializations ...
int i = 0;
@@ -1256,13 +1255,13 @@
};
// Collect matches from atomic readers
- ArrayList<Match> atomicMatches = new ArrayList<Match>(
+ final ArrayList<Match> atomicMatches = new ArrayList<Match>(
kr.getItemsPerPage());
// Start time out thread
- TimeOutThread tthread = new TimeOutThread();
+ final TimeOutThread tthread = new TimeOutThread();
tthread.start();
- long timeout = meta.getTimeOut();
+ final long timeout = meta.getTimeOut();
// See: http://www.ibm.com/developerworks/java/library/j-benchmark1/index.html
long t1 = System.nanoTime();
@@ -1288,15 +1287,15 @@
* Todo: There may be a way to know early if the bitset is emty
* by using OpenBitSet - but this may not be as fast as I think.
*/
- Bits bitset = collection.bits(atomic);
-
- PositionsToOffset pto = new PositionsToOffset(atomic, field);
+ final Bits bitset = collection.bits(atomic);
+ final PositionsToOffset pto = new PositionsToOffset(atomic, field);
// Spans spans = NearSpansOrdered();
- Spans spans = query.getSpans(atomic, (Bits) bitset,
- termContexts);
+ final Spans spans = query.getSpans(atomic, (Bits) bitset,
+ termContexts);
- IndexReader lreader = atomic.reader();
+ final IndexReader lreader = atomic.reader();
+ int localDocID, docID;
// TODO: Get document information from Cache! Fieldcache?
for (; i < hits; i++) {
@@ -1314,7 +1313,7 @@
break;
};
- int localDocID = spans.doc();
+ localDocID = spans.doc();
// Count hits per resource
if (itemsPerResource > 0) {
@@ -1343,14 +1342,14 @@
if (startIndex > i)
continue;
- int docID = atomic.docBase + localDocID;
+ docID = atomic.docBase + localDocID;
// Do not load all of this, in case the doc is the same!
- Document doc = (fields != null) ? lreader.document(
+ final Document doc = (fields != null) ? lreader.document(
localDocID, fields) : lreader.document(localDocID);
// Create new Match
- Match match = new Match(pto, localDocID, spans.start(),
+ final Match match = new Match(pto, localDocID, spans.start(),
spans.end());
match.setContext(kr.getContext());
@@ -1398,7 +1397,7 @@
// Count hits per resource
if (itemsPerResource > 0) {
- int localDocID = spans.doc();
+ localDocID = spans.doc();
if (localDocID == DocIdSetIterator.NO_MORE_DOCS)
break;
diff --git a/src/main/java/de/ids_mannheim/korap/KrillMeta.java b/src/main/java/de/ids_mannheim/korap/KrillMeta.java
index 7be6a9f..c6bb0a4 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillMeta.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillMeta.java
@@ -15,7 +15,7 @@
import org.slf4j.LoggerFactory;
// Todo: Set timeout default value per config file
-public class KrillMeta extends Notifications {
+public final class KrillMeta extends Notifications {
// <legacy>
private boolean cutOff = false;
// </legacy>
diff --git a/src/main/java/de/ids_mannheim/korap/KrillQuery.java b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
index 07a3c3b..56fb027 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
@@ -66,7 +66,7 @@
[base=Der]([base=alte]|[base=junge])[base=Mann & p!=ADJA]![base=war | base=lag]
Search for all documents containing "s:Der" and ("s:alte" or "s:junge") and "s:Mann"
*/
-public class KrillQuery extends Notifications {
+public final class KrillQuery extends Notifications {
private QueryBuilder builder;
private String field;
private JsonNode json;
diff --git a/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java b/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
index 1f28383..0510437 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
@@ -339,7 +339,7 @@
throws IOException {
for (int i = 0; i < spanQueries.size(); i++) {
- SpanQuery query = (SpanQuery) spanQueries.get(i).rewrite(reader);
+ final SpanQuery query = (SpanQuery) spanQueries.get(i).rewrite(reader);
if (!query.equals(spanQueries.get(i))) {
if (clone == null)
clone = clone();
@@ -365,7 +365,7 @@
private SimpleSpanQuery updateClone (IndexReader reader,
SimpleSpanQuery clone, SpanQuery sq, int clauseNumber)
throws IOException {
- SpanQuery query = (SpanQuery) sq.rewrite(reader);
+ final SpanQuery query = (SpanQuery) sq.rewrite(reader);
if (!query.equals(sq)) {
if (clone == null)
clone = clone();
@@ -399,8 +399,7 @@
}
else if (clauseList != null) {
for (int i = 0; i < clauseList.size(); i++) {
- SpanQuery query = (SpanQuery) clauseList.get(i);
- if (!query.equals(q.getClauseList().get(i))) {
+ if (!clauseList.get(i).equals(q.getClauseList().get(i))) {
return false;
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanElementQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanElementQuery.java
index 6c2981b..937e9bc 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanElementQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanElementQuery.java
@@ -47,7 +47,7 @@
* @author diewald
* @author margaretha
*/
-public class SpanElementQuery extends SimpleSpanQuery {
+public final class SpanElementQuery extends SimpleSpanQuery {
private static Term elementTerm;
private String elementStr;
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ElementSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/ElementSpans.java
index d2ceffe..30515d5 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/ElementSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ElementSpans.java
@@ -27,14 +27,15 @@
* @author margaretha
* @author diewald
*/
-public class ElementSpans extends SimpleSpans {
- private TermSpans termSpans;
+public final class ElementSpans extends SimpleSpans {
+ private final TermSpans termSpans;
private boolean lazyLoaded = false;
private final Logger log = LoggerFactory.getLogger(ElementSpans.class);
// This advices the java compiler to ignore all loggings
public static final boolean DEBUG = false;
-
+
+ private byte[] b = new byte[8];
/**
* Constructs ElementSpans for the given {@link SpanElementQuery}.
@@ -112,8 +113,8 @@
if (!payload.isEmpty()) {
// Get payload one by one
- int length = payload.get(0).length;
- ByteBuffer bb = ByteBuffer.allocate(length);
+ final int length = payload.get(0).length;
+ final ByteBuffer bb = ByteBuffer.allocate(length);
bb.put(payload.get(0));
// set element end position from payload
@@ -129,7 +130,6 @@
}
// Copy the start and end character offsets
- byte[] b = new byte[8];
b = Arrays.copyOfRange(bb.array(), 0, 8);
this.matchPayload = Collections.singletonList(b);
return;
diff --git a/src/main/java/de/ids_mannheim/korap/response/MatchCollector.java b/src/main/java/de/ids_mannheim/korap/response/MatchCollector.java
index 46ad3dd..68cbdb6 100644
--- a/src/main/java/de/ids_mannheim/korap/response/MatchCollector.java
+++ b/src/main/java/de/ids_mannheim/korap/response/MatchCollector.java
@@ -13,7 +13,7 @@
private long totalTexts;
*/
- public void add (int uniqueDocID, int matchcount) {
+ public void add (final int uniqueDocID, final int matchcount) {
this.totalResultDocs++;
this.incrTotalResults(matchcount);
};
diff --git a/src/main/java/de/ids_mannheim/korap/response/Result.java b/src/main/java/de/ids_mannheim/korap/response/Result.java
index 067d0f6..01102a1 100644
--- a/src/main/java/de/ids_mannheim/korap/response/Result.java
+++ b/src/main/java/de/ids_mannheim/korap/response/Result.java
@@ -36,7 +36,7 @@
*/
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
-public class Result extends Krill {
+public final class Result extends Krill {
ObjectMapper mapper = new ObjectMapper();
@JsonIgnore
diff --git a/src/main/java/de/ids_mannheim/korap/response/collector/MatchCollectorDB.java b/src/main/java/de/ids_mannheim/korap/response/collector/MatchCollectorDB.java
index 2cfa252..0c5a604 100644
--- a/src/main/java/de/ids_mannheim/korap/response/collector/MatchCollectorDB.java
+++ b/src/main/java/de/ids_mannheim/korap/response/collector/MatchCollectorDB.java
@@ -13,7 +13,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class MatchCollectorDB extends MatchCollector {
+public final class MatchCollectorDB extends MatchCollector {
// Logger
private final static Logger log = LoggerFactory.getLogger(Node.class);
@@ -23,9 +23,10 @@
* the list should be synchrinized Collections.synchronizedList()
*/
private String databaseType;
- private List matchCollector;
- private int bufferSize, docCollect;
- private String resultID;
+ private final List matchCollector;
+ private final int bufferSize;
+ private int docCollect;
+ private final String resultID;
// private Connection connection;
private DataSource pool;
@@ -186,7 +187,7 @@
public void close (boolean close) {
if (close)
this.close();
- else
- this.commit();
+
+ this.commit();
};
};
diff --git a/src/main/java/de/ids_mannheim/korap/server/Resource.java b/src/main/java/de/ids_mannheim/korap/server/Resource.java
index bb047a5..52bfa11 100644
--- a/src/main/java/de/ids_mannheim/korap/server/Resource.java
+++ b/src/main/java/de/ids_mannheim/korap/server/Resource.java
@@ -41,7 +41,7 @@
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
-import java.sql.Connection;
+import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
@@ -63,12 +63,15 @@
private final static Logger log = LoggerFactory.getLogger(Node.class);
// This advices the java compiler to ignore all loggings
- public static final boolean DEBUG = false;
+ public final static boolean DEBUG = false;
// Slightly based on String::BooleanSimple
- static Pattern p = Pattern.compile("\\s*(?i:false|no|inactive|disabled|"
+ private final static Pattern p =
+ Pattern.compile("\\s*(?i:false|no|inactive|disabled|"
+ "off|n|neg(?:ative)?|not|null|undef)\\s*");
+ private KrillIndex index;
+
/**
* Return information on the node, like name etc.
@@ -76,7 +79,7 @@
@GET
@Produces(MediaType.APPLICATION_JSON)
public String info () {
- Response kresp = _initResponse();
+ final Response kresp = _initResponse();
if (kresp.hasErrors())
return kresp.toJsonString();
@@ -109,17 +112,17 @@
* See
* http://www.mkyong.com/webservices/jax-rs/file-upload-example-in-jersey/
*/
-
// Todo: Parameter for server node
if (DEBUG)
log.trace("Added new document with unique identifier {}", uid);
- Response kresp = _initResponse();
+ final Response kresp = _initResponse();
if (kresp.hasErrors())
return kresp.toJsonString();
// Get index
- KrillIndex index = Node.getIndex();
+ index = Node.getIndex();
+
FieldDocument fd = index.addDoc(uid, json);
if (fd == null) {
@@ -129,13 +132,12 @@
return kresp.toJsonString();
};
- String ID = "Unknown";
- ID = fd.getID();
-
// Set HTTP to 200
- kresp.addMessage(681, "Document was added successfully", ID);
-
- // System.err.println(kresp.toJsonString());
+ kresp.addMessage(
+ 681,
+ "Document was added successfully",
+ fd.getID() != null ? fd.getID() : "Unknown"
+ );
return kresp.toJsonString();
};
@@ -150,16 +152,13 @@
@Produces(MediaType.APPLICATION_JSON)
public String commit () {
- Response kresp = _initResponse();
+ final Response kresp = _initResponse();
if (kresp.hasErrors())
return kresp.toJsonString();
- // Get index
- KrillIndex index = Node.getIndex();
-
// There are documents to commit
try {
- index.commit();
+ Node.getIndex().commit();
kresp.addMessage(683, "Staged data committed");
}
catch (IOException e) {
@@ -185,15 +184,15 @@
@Consumes(MediaType.APPLICATION_JSON)
public String find (String json, @Context UriInfo uri) {
- Response kresp = _initResponse();
+ final Response kresp = _initResponse();
if (kresp.hasErrors())
return kresp.toJsonString();
// Search index
- Krill ks = new Krill(json);
+ final Krill ks = new Krill(json);
// Get query parameters
- MultivaluedMap<String, String> qp = uri.getQueryParameters();
+ final MultivaluedMap<String, String> qp = uri.getQueryParameters();
if (qp.get("uid") == null) {
kresp.addError(610,
@@ -203,13 +202,13 @@
};
// Build Collection based on a list of uids
- List<String> uids = qp.get("uid");
- KrillCollection kc = new KrillCollection();
- kc.filterUIDs(uids.toArray(new String[uids.size()]));
+ final List<String> uids = qp.get("uid");
// TODO: RESTRICT COLLECTION TO ONLY RESPECT SELF DOCS (REPLICATION)
- // Override old collection
+ // Ignore a Collection that may already be established
+ final KrillCollection kc = new KrillCollection();
+ kc.filterUIDs(uids.toArray(new String[uids.size()]));
ks.setCollection(kc);
// Only return the first match per text
@@ -238,15 +237,16 @@
// Get the database
try {
- MatchCollectorDB mc = new MatchCollectorDB(1000, "Res_" + resultID);
- Connection conn = Node.getDBPool().getConnection();
- mc.setDBPool("mysql", Node.getDBPool(), conn);
+ final MatchCollectorDB mc = new MatchCollectorDB(1000, "Res_" + resultID);
+ final ComboPooledDataSource pool = Node.getDBPool();
+ mc.setDBPool("mysql", pool, pool.getConnection());
// TODO: Only search in self documents (REPLICATION FTW!)
- Krill ks = new Krill(json);
+ final Krill ks = new Krill(json);
+
// TODO: Reuse response!
- MatchCollector result = Node.getIndex().collect(ks, mc);
+ final MatchCollector result = Node.getIndex().collect(ks, mc);
result.setNode(Node.getName());
return result.toJsonString();
@@ -422,7 +422,7 @@
if (value == null)
return true;
- Matcher m = p.matcher(value);
+ final Matcher m = p.matcher(value);
if (m.matches())
return true;
diff --git a/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSamples.java b/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSamples.java
new file mode 100644
index 0000000..69e8503
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSamples.java
@@ -0,0 +1,66 @@
+package de.ids_mannheim.korap.benchmark;
+
+import java.util.*;
+import java.io.*;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ids_mannheim.korap.KrillIndex;
+import de.ids_mannheim.korap.KrillQuery;
+import de.ids_mannheim.korap.KrillCollection;
+import de.ids_mannheim.korap.query.QueryBuilder;
+import de.ids_mannheim.korap.Krill;
+import de.ids_mannheim.korap.response.Result;
+import de.ids_mannheim.korap.util.QueryException;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.junit.Ignore;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+@RunWith(JUnit4.class)
+public class TestBenchmarkSamples {
+
+ private final ObjectMapper mapper = new ObjectMapper();
+ private final int rounds = 1000;
+ private long t1 = 0, t2 = 0;
+
+ @Test
+ public void simpleSegmentQuery () throws Exception {
+ // Construct index
+
+ KrillIndex ki = new KrillIndex();
+
+ // Indexing test files
+ for (String i : new String[] { "00001", "00002", "00003", "00004",
+ "00005", "00006", "02439" }) {
+ ki.addDoc(
+ getClass().getResourceAsStream("/wiki/" + i + ".json.gz"),
+ true);
+ };
+ ki.commit();
+
+ t1 = System.nanoTime();
+ for (int i = 1; i <= rounds; i++) {
+ final QueryBuilder qb = new QueryBuilder("tokens");
+ final Krill ks = new Krill(qb.seg("mate/m:gender:masc").toQuery());
+ final Result kr = ks.apply(ki);
+ assertEquals(kr.getTotalResults(), 497);
+ };
+ t2 = System.nanoTime();
+ double seconds = (double) (t2 - t1) / 1000000000.0;
+ System.err.println("Seconds: " + seconds);
+
+ // Seconds: 9.465514311
+ // Seconds: 9.302011468
+ // Seconds: 9.052496918
+ // Seconds: 9.0567007
+ // Seconds: 9.113724089
+ // Seconds: 8.700548842
+ // Seconds: 9.390980437
+ // Seconds: 8.817503952
+ };
+};
diff --git a/src/test/java/de/ids_mannheim/korap/server/TestResource.java b/src/test/java/de/ids_mannheim/korap/server/TestResource.java
index 643f081..4d4dd48 100644
--- a/src/test/java/de/ids_mannheim/korap/server/TestResource.java
+++ b/src/test/java/de/ids_mannheim/korap/server/TestResource.java
@@ -35,16 +35,20 @@
private HttpServer server;
private WebTarget target;
- ObjectMapper mapper = new ObjectMapper();
+ final ObjectMapper mapper = new ObjectMapper();
+ long t1 = 0, t2 = 0, t3 = 0, t4 = 0;
@Before
public void setUp () throws Exception {
// start the server
+ t1 = System.nanoTime();
server = Node.startServer("milena", (String) null);
// create the client
Client c = ClientBuilder.newClient();
+ t2 = System.nanoTime();
+
// uncomment the following line if you want to enable
// support for JSON in the client (you also have to uncomment
// dependency on jersey-media-json module in pom.xml and Main.startServer())
@@ -66,8 +70,20 @@
@After
public void tearDown () throws Exception {
+ t3 = System.nanoTime();
server.stop();
Node.closeDBPool();
+ t4 = System.nanoTime();
+
+ double startup = (double) (t2 - t1) / 1000000000.0;
+ double action = (double) (t3 - t2) / 1000000000.0;
+ double shutdown = (double) (t4 - t3) / 1000000000.0;
+
+ /*
+ System.err.println("Startup: " + startup + ", " +
+ "Action: " + action + ", " +
+ "Shutdown: " + shutdown);
+ */
};
@@ -92,11 +108,12 @@
};
@Test
- public void testResource () throws IOException {
+ public void testIndexing () throws IOException {
String resp;
JsonNode res;
- for (String i : new String[] { "00001", "00002", "00003", "00004",
+ for (String i : new String[] {
+ "00001", "00002", "00003", "00004",
"00005", "00006", "02439" }) {
String json = StringfromFile(getClass().getResource(
@@ -119,6 +136,7 @@
}
};
+ // Commit!
resp = target.path("/index").request("application/json")
.post(Entity.text(""), String.class);
res = mapper.readTree(resp);
@@ -130,6 +148,7 @@
@Test
public void testCollection () throws IOException {
+ // mate/l:sein
String json = getString(getClass().getResource(
"/queries/bsp-uid-example.jsonld").getFile());