public Triple getSampleFromAnyEndpoint(Triple triplePattern) throws SADIException, IOException, NoSampleAvailableException, ExceededMaxAttemptsException { List<SPARQLEndpoint> endpoints = new ArrayList<SPARQLEndpoint>(getRegistry().findEndpointsByTriplePattern(triplePattern)); RandomDataImpl generator = new RandomDataImpl(); int attempts = 0; SPARQLEndpoint endpoint = null; while (attempts < MAX_ATTEMPTS) { if (endpoints.size() == 0) throw new NoSampleAvailableException( "there are no triples matching " + triplePattern + " in the data (without blank nodes)"); int endpointIndex = endpoints.size() > 1 ? generator.nextInt(0, endpoints.size() - 1) : 0; endpoint = endpoints.get(endpointIndex); if (getRegistry().getServiceStatus(endpoint.getURI()) == ServiceStatus.DEAD) { endpoints.remove(endpointIndex); continue; } try { return getSampleFromEndpoint(endpoint, triplePattern); } catch (NoSampleAvailableException e) { log.warn(String.format("failed to retrieve sample from %s", endpoint), e); } catch (IOException e) { log.warn(String.format("failed to retrieve sample from %s", endpoint), e); } endpoints.remove(endpointIndex); attempts++; } throw new ExceededMaxAttemptsException( "exceeded " + MAX_ATTEMPTS + " attempts when trying to retrieve triples matching " + triplePattern); }
protected Triple getSampleFromEndpoint( SPARQLEndpoint endpoint, Triple triplePattern, long sampleIndex) throws SADIException, IOException, NoSampleAvailableException { log.trace( "retrieving triple #" + sampleIndex + " for " + triplePattern + " from " + endpoint.getURI()); Query query = getConstructQuery( triplePattern); // SPARQLStringUtils.getConstructQuery(Collections.singletonList(triplePattern), Collections.singletonList(triplePattern)); query.setOffset(sampleIndex); query.setLimit(1); log.trace(String.format("sample query: %s", query.serialize())); Collection<Triple> triples = endpoint.constructQuery(query.serialize()); if (triples.size() == 0) { throw new RuntimeException("triple #" + sampleIndex + " doesn't exists in " + endpoint); } Triple triple = triples.iterator().next(); // Sanity check. If the index is incomplete or out of date, the sample triple may not satisfy // the predicate list / regular expressions for the endpoint. The simplest thing to do in // this case is to fail and take another sample. if (getRegistry() != null && !getRegistry().findEndpointsByTriplePattern(triple).contains(endpoint)) { throw new NoSampleAvailableException( "sample triple does not match the regular expressions for " + endpoint.getURI() + " (from which it was sampled!)"); } return triple; }
protected long getUpperSampleLimit(SPARQLEndpoint endpoint, Triple triplePattern) throws SADIException, IOException { String uri = endpoint.getURI(); log.trace("determining number of triples matching " + triplePattern + " in " + uri); ServiceStatus status = ServiceStatus.OK; if (getRegistry() != null) { status = getRegistry().getServiceStatus(endpoint.getURI()); } // check for a cached value first if (upperSampleLimitCache.contains(endpoint, triplePattern)) { log.trace("using previously cached value for upper sample limit"); return upperSampleLimitCache.get(endpoint, triplePattern); } ElementGroup whereClause = getWhereClauseWithBlankNodeFilter(triplePattern); /* Node s = triplePattern.getSubject(); Node o = triplePattern.getObject(); // Build a Jena representation of the WHERE clause ElementGroup whereClause = new ElementGroup(); whereClause.addTriplePattern(triplePattern); if(s.isVariable()) { whereClause.addElementFilter(new ElementFilter(new E_LogicalNot(new E_IsBlank(new ExprVar(s))))); } if(o.isVariable()) { whereClause.addElementFilter(new ElementFilter(new E_LogicalNot(new E_IsBlank(new ExprVar(o))))); } */ if (status != ServiceStatus.SLOW) { try { // issue a SELECT COUNT(*) query Query countStarQuery = new Query(); countStarQuery.setQuerySelectType(); countStarQuery.setQueryPattern(whereClause); countStarQuery.addResultVar(countStarQuery.allocAggregate(AggCount.get())); List<Map<String, String>> results = endpoint.selectQuery(countStarQuery.serialize()); Map<String, String> firstRow = results.iterator().next(); String firstColumn = firstRow.keySet().iterator().next(); long limit = Long.parseLong(firstRow.get(firstColumn)); upperSampleLimitCache.put(endpoint, triplePattern, limit); log.trace(String.format("successful upper limit query: %s", countStarQuery.serialize())); log.trace(String.format("upper limit: %d", limit)); return limit; } catch (IOException e) { log.warn( "failed to COUNT number of triples matching " + triplePattern + " in " + uri + ", trying for a lower bound instead."); } } Query selectStarQuery = new Query(); selectStarQuery.setQuerySelectType(); selectStarQuery.setQueryPattern(whereClause); selectStarQuery.setQueryResultStar(true); long limit = endpoint.getResultsCountLowerBound(selectStarQuery.serialize(), 50000); upperSampleLimitCache.put(endpoint, triplePattern, limit); log.trace(String.format("successful upper limit query: %s", selectStarQuery.serialize())); log.trace(String.format("upper limit: %d", limit)); return limit; }