Add Possibility to prefetch TagTranslator-Cache
Problem For a large number of distinct tags the current implementation of the TagTranslator is inefficient because it needs to run on query per tag against its keytables-connection.
Possible solution This is of course inevitable if the tags to be fetched are unknown.
But the OSHDBQuery could be seperated into two queries with the first fetching all desired OSHDBTags. Then a method (e.g. TagTranslator.prefetch(List<OSHDBTag> tags) to query a large number of tags at once would be needed.
Additional context This link might be helpful on how to implement batch-tag-fetiching:
Looking at the TT it might be good to enhance it in general (e.g. prepare PreparedStatements only once etc.)
But any way, here is a possible start for an implementation of this Issue:
public void fetchAll(Set<OSHDBTag> set) throws SQLException {
try (Statement st = this.getConnection().createStatement();) {
st.executeUpdate("CREATE TEMPORARY TABLE tempTagFetcher(searchkey INTEGER, searchvalue INTEGER);");
}
try (PreparedStatement prepareStatement = this.getConnection()
.prepareStatement("INSERT INTO tempTagFetcher(searchkey,searchvalue) VALUES (?,?);");) {
for (OSHDBTag tag : set) {
prepareStatement.setInt(1, tag.getKey());
prepareStatement.setInt(2, tag.getValue());
prepareStatement.addBatch();
}
prepareStatement.executeBatch();
}
try (Statement st2 = this.getConnection().createStatement();
ResultSet executeQuery = st2.executeQuery(
"SELECT keyid,key.txt AS keytxt, valueid,keyvalue.txt AS valuetxt FROM keyvalue "
+ "INNER JOIN key ON keyid=key.id "
+ "INNER JOIN tempTagFetcher ON searchkey=keyid AND searchvalue=valueid;");) {
while (executeQuery.next()) {
int aInt = executeQuery.getInt("keyid");
int aInt1 = executeQuery.getInt("valueid");
OSHDBTag tag = new OSHDBTag(aInt, aInt1);
String string = executeQuery.getString("keytxt");
String string1 = executeQuery.getString("valuetxt");
OSMTag tag1 = new OSMTag(string, string1);
//this.tagToInt.put(tag1, tag);
this.tagToString.put(tag, tag1);
}
}
}