This list is closed, nobody may subscribe to it.
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(139) |
Aug
(94) |
Sep
(232) |
Oct
(143) |
Nov
(138) |
Dec
(55) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(127) |
Feb
(90) |
Mar
(101) |
Apr
(74) |
May
(148) |
Jun
(241) |
Jul
(169) |
Aug
(121) |
Sep
(157) |
Oct
(199) |
Nov
(281) |
Dec
(75) |
2012 |
Jan
(107) |
Feb
(122) |
Mar
(184) |
Apr
(73) |
May
(14) |
Jun
(49) |
Jul
(26) |
Aug
(103) |
Sep
(133) |
Oct
(61) |
Nov
(51) |
Dec
(55) |
2013 |
Jan
(59) |
Feb
(72) |
Mar
(99) |
Apr
(62) |
May
(92) |
Jun
(19) |
Jul
(31) |
Aug
(138) |
Sep
(47) |
Oct
(83) |
Nov
(95) |
Dec
(111) |
2014 |
Jan
(125) |
Feb
(60) |
Mar
(119) |
Apr
(136) |
May
(270) |
Jun
(83) |
Jul
(88) |
Aug
(30) |
Sep
(47) |
Oct
(27) |
Nov
(23) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
(4) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <tho...@us...> - 2014-07-10 18:35:42
|
Revision: 8534 http://sourceforge.net/p/bigdata/code/8534 Author: thompsonbry Date: 2014-07-10 18:35:39 +0000 (Thu, 10 Jul 2014) Log Message: ----------- Generalized the stored query service to allow arbitrary task logic while holding a connection that reads on the KB. See #989 (Support stored query service). Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/SimpleStoredQueryService.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-003.rq Removed Paths: ------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/SimpleStoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/SimpleStoredQueryService.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/SimpleStoredQueryService.java 2014-07-10 18:35:39 UTC (rev 8534) @@ -0,0 +1,71 @@ +/* + + Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + + Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ +package com.bigdata.rdf.sparql.ast.service.storedquery; + +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQueryResult; + +import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; +import com.bigdata.rdf.sail.BigdataSailTupleQuery; +import com.bigdata.rdf.sparql.ast.eval.ServiceParams; +import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; + +/** + * Simple stored query consisting of a parameterized SPARQL query. + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + */ +abstract public class SimpleStoredQueryService extends StoredQueryService { + + /** + * Return the SPARQL query to be evaluated. + */ + abstract protected String getQuery( + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams); + + /** + * Executes the SPARQL query returned by + * {@link #getQuery(ServiceCallCreateParams, ServiceParams)} + */ + @Override + protected TupleQueryResult doQuery( + final BigdataSailRepositoryConnection cxn, + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) throws Exception { + + final String queryStr = getQuery(createParams, serviceParams); + + final String baseURI = createParams.getServiceURI().stringValue(); + + final BigdataSailTupleQuery query = (BigdataSailTupleQuery) cxn + .prepareTupleQuery(QueryLanguage.SPARQL, queryStr, baseURI); + + return query.evaluate(); + + } + +} // SimpleStoredQueryService \ No newline at end of file Deleted: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java 2014-07-10 15:47:26 UTC (rev 8533) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java 2014-07-10 18:35:39 UTC (rev 8534) @@ -1,393 +0,0 @@ -/** - -Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. - -Contact: - SYSTAP, LLC - 4501 Tower Road - Greensboro, NC 27410 - lic...@bi... - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -package com.bigdata.rdf.sparql.ast.service.storedquery; - -import java.util.Arrays; -import java.util.concurrent.Future; - -import org.apache.log4j.Logger; -import org.openrdf.query.BindingSet; -import org.openrdf.query.QueryEvaluationException; -import org.openrdf.query.QueryLanguage; -import org.openrdf.query.TupleQueryResult; - -import com.bigdata.rdf.internal.IV; -import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; -import com.bigdata.rdf.sail.BigdataSailTupleQuery; -import com.bigdata.rdf.sail.Sesame2BigdataIterator; -import com.bigdata.rdf.sparql.ast.eval.ASTEvalHelper; -import com.bigdata.rdf.sparql.ast.eval.ServiceParams; -import com.bigdata.rdf.sparql.ast.service.ExternalServiceCall; -import com.bigdata.rdf.sparql.ast.service.IServiceOptions; -import com.bigdata.rdf.sparql.ast.service.OpenrdfNativeServiceOptions; -import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; -import com.bigdata.rdf.sparql.ast.service.ServiceFactory; -import com.bigdata.rdf.sparql.ast.service.ServiceNode; -import com.bigdata.rdf.sparql.ast.service.ServiceRegistry; -import com.bigdata.rdf.store.AbstractTripleStore; -import com.bigdata.rdf.task.AbstractApiTask; - -import cutthecrap.utils.striterators.ICloseableIterator; - -/** - * A SERVICE that exposes a stored query for execution. The stored query may be - * a SPARQL query or arbitrary procedural application logic, but it must - * evaluate to a solution multi-set. The service interface is written to the - * openrdf interfaces in order to remove the burden of dealing with bigdata - * {@link IV}s from the application. - * <p> - * In order to use a stored query, a concrete instance of this class must be - * registered against the {@link ServiceRegistry}: - * - * <pre> - * final URI serviceURI = new URIImpl(StoredQueryService.Options.NAMESPACE - * + "my-service"); - * - * ServiceRegistry.getInstance().add(serviceURI, new MyStoredQueryService()); - * </pre> - * - * Thereafter, the stored query may be referenced from SPARQL using its assigned - * service URI: - * - * <pre> - * SELECT * { - * SERVICE <http://www.bigdata.com/rdf/stored-query#my-service> { } - * } - * </pre> - * - * The SERVICE invocation may include a group graph pattern that will be parsed - * and made accessible to the stored query service as a {@link ServiceParams} - * object. For example: - * - * <pre> - * SELECT * { - * SERVICE <http://www.bigdata.com/rdf/stored-query#my-service> { - * bd:serviceParam :color :"blue" . - * bd:serviceParam :color :"green" . - * bd:serviceParam :size :"large" . - * } - * } - * </pre> - * - * will provide the stored query with two bindings for the - * <code>:color = {"blue", "green"}</code> and one binding for - * <code>:size = {"large"}</code>. The value key names, the allowed value types - * for each key name, and the interpretation of those values are all specific to - * a given stored query service implementation class. They will be provided to - * that class as a {@link ServiceParams} object. - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * - * @see <a href="http://trac.bigdata.com/ticket/989">Stored Query Service</a> - * - * TODO Wiki page. - * - * TODO Implicit prefix declaration for bsq. - * - * TODO Reconcile with the REST API (group commit task pattern). - * - * TODO Why does this work? - * - * <pre> - * SELECT ?book ?title ?price - * { - * SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_001> { - * } - * } - * </pre> - * - * while this does not work - * - * <pre> - * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> - * - * SELECT ?book ?title ?price - * { - * SERVICE <bsq#test_stored_query_001> { - * } - * } - * </pre> - * - * TODO Example - * - * <pre> - * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> - * #... - * SERVICE <bsq#my-service> { - * bsq:queryParam bsq:gasClass "com.bigdata.rdf.graph.analytics.BFS" . - * gas:program gas:in <IRI> . # one or more times, specifies the initial frontier. - * gas:program gas:out ?out . # exactly once - will be bound to the visited vertices. - * gas:program gas:maxIterations 4 . # optional limit on breadth first expansion. - * gas:program gas:maxVisited 2000 . # optional limit on the #of visited vertices. - * gas:program gas:nthreads 4 . # specify the #of threads to use (optional) - * } - * </pre> - * - */ -abstract public class StoredQueryService implements ServiceFactory { - - public interface Options { - - /** - * The namespace used for stored query service. - */ - String NAMESPACE = "http://www.bigdata.com/rdf/stored-query#"; - - } - - static private transient final Logger log = Logger - .getLogger(StoredQueryService.class); - - private final OpenrdfNativeServiceOptions serviceOptions; - - public StoredQueryService() { - - serviceOptions = new OpenrdfNativeServiceOptions(); - -// /* -// * TODO This should probably be metadata set for each specific -// * stored query. -// */ -// serviceOptions.setRunFirst(true); - - } - - @Override - public IServiceOptions getServiceOptions() { - - return serviceOptions; - - } - - @Override - final public ExternalServiceCall create(final ServiceCallCreateParams params) { - - if (params == null) - throw new IllegalArgumentException(); - - final AbstractTripleStore store = params.getTripleStore(); - - if (store == null) - throw new IllegalArgumentException(); - - final ServiceNode serviceNode = params.getServiceNode(); - - if (serviceNode == null) - throw new IllegalArgumentException(); - - final ServiceParams serviceParams = ServiceParams.gatherServiceParams(params); - - return create(params, serviceParams); - - } - - public ExternalServiceCall create( - final ServiceCallCreateParams createParams, - final ServiceParams serviceParams) { - - /* - * Create and return the ServiceCall object which will execute this - * query. - */ - - return new StoredQueryServiceCall(createParams, serviceParams); - - } - - /** - * Return the SPARQL query to be evaluated. - */ - abstract protected String getQuery( - final ServiceCallCreateParams createParams, - final ServiceParams serviceParams); - - private class StoredQueryServiceCall implements ExternalServiceCall { - - private final ServiceCallCreateParams createParams; - private final ServiceParams serviceParams; - - public StoredQueryServiceCall( - final ServiceCallCreateParams createParams, - final ServiceParams serviceParams) { - - if (createParams == null) - throw new IllegalArgumentException(); - - if (serviceParams == null) - throw new IllegalArgumentException(); - - this.createParams = createParams; - this.serviceParams = serviceParams; - - } - - @Override - public IServiceOptions getServiceOptions() { - - return createParams.getServiceOptions(); - - } - - /** - * TODO We could use {@link ASTEvalHelper} to evaluate at the bigdata - * level without forcing the materialization of any variable bindings - * from the lexicon indices. This would be faster for some purposes, - * especially if the stored procedure is only used to JOIN into an outer - * query as in <code>SELECT * { SERVICE bsq:my-service {} }</code> - * - * FIXME Generalize to allow arbitrary application logic that has easy - * methods permitting it to invoke multiple queries and operate on the - * results. - * - * FIXME Generalize to support groovy scripting. - */ - @Override - public ICloseableIterator<BindingSet> call(final BindingSet[] bindingSets) - throws Exception { - - if (log.isInfoEnabled()) { - log.info(bindingSets.length); - log.info(Arrays.toString(bindingSets)); - log.info(serviceParams); - } - - final String queryStr = getQuery(createParams, serviceParams); - - // TODO Should the baseURI be the SERVICE URI? Decide and document. - final String baseURI = createParams.getServiceURI().stringValue(); - - final AbstractTripleStore tripleStore = createParams.getTripleStore(); - - final Future<TupleQueryResult> ft = AbstractApiTask.submitApiTask( - tripleStore.getIndexManager(), - new SparqlApiTask(tripleStore.getNamespace(), tripleStore - .getTimestamp(), queryStr, baseURI, bindingSets)); - - try { - - final TupleQueryResult tupleQueryResult = ft.get(); - - return new Sesame2BigdataIterator<BindingSet, QueryEvaluationException>( - tupleQueryResult); - - } finally { - - ft.cancel(true/* mayInterruptIfRunning */); - - } - - } - - } // StoredQueryServiceCall - - /** - * Task to execute a SPARQL query. - * - * @author <a href="mailto:tho...@us...">Bryan - * Thompson</a> - */ - private static class SparqlApiTask extends - AbstractApiTask<TupleQueryResult> { - - private final String queryStr; - private final String baseURI; - - /** - * - * FIXME This is ignoring the exogenous bindings. This is more or less - * equivalent to bottom-up evaluation. It would be more efficient if we - * could flow in the exogenous bindings but this is not supported before - * openrdf 2.7 (we hack this in {@link BigdataSailTupleQuery}). - */ - private final BindingSet[] bindingSets; - - public SparqlApiTask(final String namespace, final long timestamp, - final String queryStr, final String baseURI, - final BindingSet[] bindingSets) { - - super(namespace, timestamp); - - this.queryStr = queryStr; - this.baseURI = baseURI; - this.bindingSets = bindingSets; - - } - - @Override - public TupleQueryResult call() throws Exception { - BigdataSailRepositoryConnection cxn = null; - boolean success = false; - try { - // Note: Will be UPDATE connection if UPDATE request!!! - cxn = getQueryConnection(); - if (log.isTraceEnabled()) - log.trace("Query running..."); - final TupleQueryResult ret = doQuery(cxn); - success = true; - if (log.isTraceEnabled()) - log.trace("Query done."); - return ret; - } finally { - if (cxn != null) { - if (!success && !cxn.isReadOnly()) { - /* - * Force rollback of the connection. - * - * Note: It is possible that the commit has already - * been processed, in which case this rollback() - * will be a NOP. This can happen when there is an - * IO error when communicating with the client, but - * the database has already gone through a commit. - */ - try { - // Force rollback of the connection. - cxn.rollback(); - } catch (Throwable t) { - log.error(t, t); - } - } - try { - // Force close of the connection. - cxn.close(); - } catch (Throwable t) { - log.error(t, t); - } - } - } - } - - protected TupleQueryResult doQuery( - final BigdataSailRepositoryConnection cxn) throws Exception { - - final BigdataSailTupleQuery query = (BigdataSailTupleQuery) cxn - .prepareTupleQuery(QueryLanguage.SPARQL, queryStr, - baseURI); - - return query.evaluate(); - - } - - } // SparqlApiTask - -} Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java 2014-07-10 18:35:39 UTC (rev 8534) @@ -0,0 +1,359 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.rdf.sparql.ast.service.storedquery; + +import java.util.Arrays; +import java.util.concurrent.Future; + +import org.apache.log4j.Logger; +import org.openrdf.query.BindingSet; +import org.openrdf.query.QueryEvaluationException; +import org.openrdf.query.TupleQueryResult; + +import com.bigdata.rdf.internal.IV; +import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; +import com.bigdata.rdf.sail.BigdataSailTupleQuery; +import com.bigdata.rdf.sail.Sesame2BigdataIterator; +import com.bigdata.rdf.sparql.ast.eval.ASTEvalHelper; +import com.bigdata.rdf.sparql.ast.eval.ServiceParams; +import com.bigdata.rdf.sparql.ast.service.ExternalServiceCall; +import com.bigdata.rdf.sparql.ast.service.IServiceOptions; +import com.bigdata.rdf.sparql.ast.service.OpenrdfNativeServiceOptions; +import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; +import com.bigdata.rdf.sparql.ast.service.ServiceFactory; +import com.bigdata.rdf.sparql.ast.service.ServiceNode; +import com.bigdata.rdf.sparql.ast.service.ServiceRegistry; +import com.bigdata.rdf.store.AbstractTripleStore; +import com.bigdata.rdf.task.AbstractApiTask; + +import cutthecrap.utils.striterators.ICloseableIterator; + +/** + * A SERVICE that exposes a stored query for execution. The stored query may be + * a SPARQL query or arbitrary procedural application logic, but it must + * evaluate to a solution multi-set. The service interface is written to the + * openrdf interfaces in order to remove the burden of dealing with bigdata + * {@link IV}s from the application. The effective value of the baseURI during + * query evaluation will be the SERVICE URI. + * <p> + * In order to use a stored query, a concrete instance of this class must be + * registered against the {@link ServiceRegistry}: + * + * <pre> + * final URI serviceURI = new URIImpl(StoredQueryService.Options.NAMESPACE + * + "my-service"); + * + * ServiceRegistry.getInstance().add(serviceURI, new MyStoredQueryService()); + * </pre> + * + * Thereafter, the stored query may be referenced from SPARQL using its assigned + * service URI: + * + * <pre> + * SELECT * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#my-service> { } + * } + * </pre> + * + * The SERVICE invocation may include a group graph pattern that will be parsed + * and made accessible to the stored query service as a {@link ServiceParams} + * object. For example: + * + * <pre> + * SELECT * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#my-service> { + * bd:serviceParam :color :"blue" . + * bd:serviceParam :color :"green" . + * bd:serviceParam :size :"large" . + * } + * } + * </pre> + * + * will provide the stored query with two bindings for the + * <code>:color = {"blue", "green"}</code> and one binding for + * <code>:size = {"large"}</code>. The value key names, the allowed value types + * for each key name, and the interpretation of those values are all specific to + * a given stored query service implementation class. They will be provided to + * that class as a {@link ServiceParams} object. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * + * @see <a href="http://trac.bigdata.com/ticket/989">Stored Query Service</a> + * + * TODO Wiki page. + * + * TODO Implicit prefix declaration for bsq. + * + * TODO Why does this work? + * + * <pre> + * SELECT ?book ?title ?price + * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_001> { + * } + * } + * </pre> + * + * while this does not work + * + * <pre> + * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> + * + * SELECT ?book ?title ?price + * { + * SERVICE <bsq#test_stored_query_001> { + * } + * } + * </pre> + * + * TODO We could use {@link ASTEvalHelper} to evaluate at the bigdata level + * without forcing the materialization of any variable bindings from the + * lexicon indices. This would be faster for some purposes, especially if + * the stored procedure is only used to JOIN into an outer query as in + * <code>SELECT * { SERVICE bsq:my-service {} }</code> + * + * FIXME Generalize to support groovy scripting. + */ +abstract public class StoredQueryService implements ServiceFactory { + + public interface Options { + + /** + * The namespace used for stored query service. + */ + String NAMESPACE = "http://www.bigdata.com/rdf/stored-query#"; + + } + + static private transient final Logger log = Logger + .getLogger(StoredQueryService.class); + + private final OpenrdfNativeServiceOptions serviceOptions; + + public StoredQueryService() { + + serviceOptions = new OpenrdfNativeServiceOptions(); + + } + + @Override + public IServiceOptions getServiceOptions() { + + return serviceOptions; + + } + + @Override + final public ExternalServiceCall create(final ServiceCallCreateParams params) { + + if (params == null) + throw new IllegalArgumentException(); + + final AbstractTripleStore store = params.getTripleStore(); + + if (store == null) + throw new IllegalArgumentException(); + + final ServiceNode serviceNode = params.getServiceNode(); + + if (serviceNode == null) + throw new IllegalArgumentException(); + + final ServiceParams serviceParams = ServiceParams + .gatherServiceParams(params); + + return create(params, serviceParams); + + } + + public ExternalServiceCall create( + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) { + + /* + * Create and return the ServiceCall object which will execute this + * query. + */ + + return new StoredQueryServiceCall(createParams, serviceParams); + + } + + /** + * Abstract method for core application logic. The implementation may + * execute a SPARQL query, or a series or SPARQL or other operations under + * application control. + * + * @param cxn + * The connection that should be used to read on the SPARQL + * database. + * @param createParams + * The SERVICE creation parameters. + * @param serviceParams + * The SERVICE invocation parameters. + * @return The solution multi-set. + * + * @throws Exception + */ + abstract protected TupleQueryResult doQuery( + final BigdataSailRepositoryConnection cxn, + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) throws Exception; + + private class StoredQueryServiceCall implements ExternalServiceCall { + + private final ServiceCallCreateParams createParams; + private final ServiceParams serviceParams; + + public StoredQueryServiceCall( + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) { + + if (createParams == null) + throw new IllegalArgumentException(); + + if (serviceParams == null) + throw new IllegalArgumentException(); + + this.createParams = createParams; + this.serviceParams = serviceParams; + + } + + @Override + public IServiceOptions getServiceOptions() { + + return createParams.getServiceOptions(); + + } + + @Override + public ICloseableIterator<BindingSet> call( + final BindingSet[] bindingSets) throws Exception { + + if (log.isInfoEnabled()) { + log.info(bindingSets.length); + log.info(Arrays.toString(bindingSets)); + log.info(serviceParams); + } + + final AbstractTripleStore tripleStore = createParams + .getTripleStore(); + + final Future<TupleQueryResult> ft = AbstractApiTask.submitApiTask( + tripleStore.getIndexManager(), + new StoredQueryTask(tripleStore.getNamespace(), tripleStore + .getTimestamp(), bindingSets)); + + try { + + final TupleQueryResult tupleQueryResult = ft.get(); + + return new Sesame2BigdataIterator<BindingSet, QueryEvaluationException>( + tupleQueryResult); + + } finally { + + ft.cancel(true/* mayInterruptIfRunning */); + + } + + } + + /** + * Task to execute the stored query. + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + */ + private class StoredQueryTask extends AbstractApiTask<TupleQueryResult> { + + /** + * + * FIXME This is ignoring the exogenous bindings. This is more or + * less equivalent to bottom-up evaluation. It would be more + * efficient if we could flow in the exogenous bindings but this is + * not supported before openrdf 2.7 (we hack this in + * {@link BigdataSailTupleQuery}). + */ + private final BindingSet[] bindingSets; + + public StoredQueryTask(final String namespace, + final long timestamp, final BindingSet[] bindingSets) { + + super(namespace, timestamp); + + this.bindingSets = bindingSets; + + } + + @Override + public TupleQueryResult call() throws Exception { + BigdataSailRepositoryConnection cxn = null; + boolean success = false; + try { + // Note: Will be UPDATE connection if UPDATE request!!! + cxn = getQueryConnection(); + if (log.isTraceEnabled()) + log.trace("Query running..."); + final TupleQueryResult ret = doQuery(cxn, createParams, + serviceParams); + success = true; + if (log.isTraceEnabled()) + log.trace("Query done."); + return ret; + } finally { + if (cxn != null) { + if (!success && !cxn.isReadOnly()) { + /* + * Force rollback of the connection. + * + * Note: It is possible that the commit has already + * been processed, in which case this rollback() + * will be a NOP. This can happen when there is an + * IO error when communicating with the client, but + * the database has already gone through a commit. + */ + try { + // Force rollback of the connection. + cxn.rollback(); + } catch (Throwable t) { + log.error(t, t); + } + } + try { + // Force close of the connection. + cxn.close(); + } catch (Throwable t) { + log.error(t, t); + } + } + } + } + + } // StoredQueryApiTask + + } // StoredQueryServiceCall + +} // StoredQueryService Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-003.rq =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-003.rq (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-003.rq 2014-07-10 18:35:39 UTC (rev 8534) @@ -0,0 +1,9 @@ +PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> +PREFIX : <http://example.org/book/> + +SELECT ?book ?title ?price +{ + SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_003> { + bd:serviceParam :book :book1 + } +} Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java 2014-07-10 15:47:26 UTC (rev 8533) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java 2014-07-10 18:35:39 UTC (rev 8534) @@ -28,7 +28,11 @@ import org.openrdf.model.URI; import org.openrdf.model.impl.URIImpl; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQueryResult; +import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; +import com.bigdata.rdf.sail.BigdataSailTupleQuery; import com.bigdata.rdf.sparql.ast.eval.AbstractDataDrivenSPARQLTestCase; import com.bigdata.rdf.sparql.ast.eval.ServiceParams; import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; @@ -78,7 +82,7 @@ */ public void test_stored_query_001() throws Exception { - class MyStoredQueryService extends StoredQueryService { + class MyStoredQueryService extends SimpleStoredQueryService { @Override public String getQuery(final ServiceCallCreateParams createParams, @@ -140,7 +144,7 @@ */ public void test_stored_query_002() throws Exception { - class MyStoredQueryService extends StoredQueryService { + class MyStoredQueryService extends SimpleStoredQueryService { @Override public String getQuery(final ServiceCallCreateParams createParams, @@ -187,4 +191,81 @@ } + /** + * Complex stored query test like the above, but does not extend + * {@link SimpleStoredQueryService}. + * + * <pre> + * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> + * PREFIX : <http://example.org/book/> + * + * SELECT ?book ?title ?price + * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_003> { + * bd:serviceParam :book :book1 + * } + * } + * </pre> + * + * @throws Exception + */ + public void test_stored_query_003() throws Exception { + + class MyStoredQueryService extends StoredQueryService { + + @Override + protected TupleQueryResult doQuery( + BigdataSailRepositoryConnection cxn, + ServiceCallCreateParams createParams, + ServiceParams serviceParams) throws Exception { + + final URI val = serviceParams.getAsURI(new URIImpl( + "http://example.org/book/book")); + + final StringBuilder sb = new StringBuilder(); + sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"); + sb.append("PREFIX : <http://example.org/book/> \n"); + sb.append("PREFIX ns: <http://example.org/ns#> \n"); + sb.append("SELECT ?book ?title ?price { \n"); + sb.append(" BIND( <"+val.stringValue()+"> as ?book ) . \n"); + sb.append(" ?book dc:title ?title ; \n"); + sb.append(" ns:price ?price . \n"); + sb.append("} \n"); + + final String queryStr = sb.toString(); + + final String baseURI = createParams.getServiceURI().stringValue(); + + final BigdataSailTupleQuery query = (BigdataSailTupleQuery) cxn + .prepareTupleQuery(QueryLanguage.SPARQL, queryStr, baseURI); + + return query.evaluate(); + } + + } + + final URI serviceURI = new URIImpl(StoredQueryService.Options.NAMESPACE + getName()); + try { + + // register the service. + ServiceRegistry.getInstance().add(serviceURI, + new MyStoredQueryService()); + + final TestHelper h = new TestHelper("stored-query-003", // testURI, + "stored-query-003.rq",// queryFileURL + "stored-query-001.ttl",// dataFileURL + "stored-query-001.srx" // resultFileURL, + // false, // laxCardinality + // true // checkOrder + ); + + h.runTest(); + + } finally { + // unregister the service. + ServiceRegistry.getInstance().remove(serviceURI); + } + + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-10 15:47:32
|
Revision: 8533 http://sourceforge.net/p/bigdata/code/8533 Author: thompsonbry Date: 2014-07-10 15:47:26 +0000 (Thu, 10 Jul 2014) Log Message: ----------- Javadoc around bd:serviceParam and ServiceParams. Second test case for the stored query service. See #989 (stored query service). Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BD.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-002.rq Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java 2014-07-10 15:11:48 UTC (rev 8532) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java 2014-07-10 15:47:26 UTC (rev 8533) @@ -47,8 +47,20 @@ import com.bigdata.rdf.store.BD; /** - * The service parameters. Can be multi-valued. Map from predicate to - * one or more {@link TermNode} values. + * Helper class for parsing an extracting SERVICE parameters. The SERVICE group + * graph pattern should consist of zero or triples whose Subject is + * {@link BD#SERVICE_PARAM}. There may be zero or more such triple patterns. The + * Predicate (key) and Object (val) positions for those triple patterns are + * extracted into a {@link ServiceParams} object. For each key, there may be one + * or more values. + * + * <pre> + * SERVICE <uri> { + * bd:serviceParam :key1 :val1 . + * bd:serviceParam :key1 :val2 . + * bd:serviceParam :key2 :val3 . + * } + * </pre> */ public class ServiceParams { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java 2014-07-10 15:11:48 UTC (rev 8532) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java 2014-07-10 15:47:26 UTC (rev 8533) @@ -32,25 +32,71 @@ import org.openrdf.query.QueryLanguage; import org.openrdf.query.TupleQueryResult; +import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; import com.bigdata.rdf.sail.BigdataSailTupleQuery; import com.bigdata.rdf.sail.Sesame2BigdataIterator; import com.bigdata.rdf.sparql.ast.eval.ASTEvalHelper; import com.bigdata.rdf.sparql.ast.eval.ServiceParams; -import com.bigdata.rdf.sparql.ast.service.BigdataNativeServiceOptions; import com.bigdata.rdf.sparql.ast.service.ExternalServiceCall; import com.bigdata.rdf.sparql.ast.service.IServiceOptions; +import com.bigdata.rdf.sparql.ast.service.OpenrdfNativeServiceOptions; import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; import com.bigdata.rdf.sparql.ast.service.ServiceFactory; import com.bigdata.rdf.sparql.ast.service.ServiceNode; +import com.bigdata.rdf.sparql.ast.service.ServiceRegistry; import com.bigdata.rdf.store.AbstractTripleStore; import com.bigdata.rdf.task.AbstractApiTask; import cutthecrap.utils.striterators.ICloseableIterator; /** - * A SERVICE that exposes a stored query for execution. + * A SERVICE that exposes a stored query for execution. The stored query may be + * a SPARQL query or arbitrary procedural application logic, but it must + * evaluate to a solution multi-set. The service interface is written to the + * openrdf interfaces in order to remove the burden of dealing with bigdata + * {@link IV}s from the application. + * <p> + * In order to use a stored query, a concrete instance of this class must be + * registered against the {@link ServiceRegistry}: * + * <pre> + * final URI serviceURI = new URIImpl(StoredQueryService.Options.NAMESPACE + * + "my-service"); + * + * ServiceRegistry.getInstance().add(serviceURI, new MyStoredQueryService()); + * </pre> + * + * Thereafter, the stored query may be referenced from SPARQL using its assigned + * service URI: + * + * <pre> + * SELECT * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#my-service> { } + * } + * </pre> + * + * The SERVICE invocation may include a group graph pattern that will be parsed + * and made accessible to the stored query service as a {@link ServiceParams} + * object. For example: + * + * <pre> + * SELECT * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#my-service> { + * bd:serviceParam :color :"blue" . + * bd:serviceParam :color :"green" . + * bd:serviceParam :size :"large" . + * } + * } + * </pre> + * + * will provide the stored query with two bindings for the + * <code>:color = {"blue", "green"}</code> and one binding for + * <code>:size = {"large"}</code>. The value key names, the allowed value types + * for each key name, and the interpretation of those values are all specific to + * a given stored query service implementation class. They will be provided to + * that class as a {@link ServiceParams} object. + * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * * @see <a href="http://trac.bigdata.com/ticket/989">Stored Query Service</a> @@ -59,7 +105,7 @@ * * TODO Implicit prefix declaration for bsq. * - * TODO Reconcile with the REST API (group commit task pattern). + * TODO Reconcile with the REST API (group commit task pattern). * * TODO Why does this work? * @@ -113,11 +159,11 @@ static private transient final Logger log = Logger .getLogger(StoredQueryService.class); - private final BigdataNativeServiceOptions serviceOptions; + private final OpenrdfNativeServiceOptions serviceOptions; public StoredQueryService() { - serviceOptions = new BigdataNativeServiceOptions(); + serviceOptions = new OpenrdfNativeServiceOptions(); // /* // * TODO This should probably be metadata set for each specific @@ -172,8 +218,10 @@ /** * Return the SPARQL query to be evaluated. */ - abstract protected String getQuery(); - + abstract protected String getQuery( + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams); + private class StoredQueryServiceCall implements ExternalServiceCall { private final ServiceCallCreateParams createParams; @@ -224,18 +272,13 @@ log.info(serviceParams); } - final AbstractTripleStore tripleStore = createParams.getTripleStore(); + final String queryStr = getQuery(createParams, serviceParams); - final String queryStr = getQuery(); - - /* - * FIXME What about incoming bindings? They need to flow into the - * SERVICE. - */ - // TODO Should the baseURI be the SERVICE URI? Decide and document. final String baseURI = createParams.getServiceURI().stringValue(); + final AbstractTripleStore tripleStore = createParams.getTripleStore(); + final Future<TupleQueryResult> ft = AbstractApiTask.submitApiTask( tripleStore.getIndexManager(), new SparqlApiTask(tripleStore.getNamespace(), tripleStore Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BD.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BD.java 2014-07-10 15:11:48 UTC (rev 8532) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BD.java 2014-07-10 15:47:26 UTC (rev 8533) @@ -35,7 +35,7 @@ import org.openrdf.model.vocabulary.SESAME; import com.bigdata.rdf.sparql.ast.cache.DescribeServiceFactory; -import com.bigdata.rdf.sparql.ast.eval.AbstractServiceFactory; +import com.bigdata.rdf.sparql.ast.eval.ServiceParams; /** @@ -177,10 +177,21 @@ // URI ATOMIC_UPDATE_SEPARATOR_KEY = new URIImpl(NAMESPACE + "atomicUpdateSeparatorKey"); /** - * URI that can be used as the subject of any magic triple patterns for - * bigdata services. + * URI that can be used as the Subject of magic triple patterns for bigdata + * SERVICEs. There may be zero or more such triple patterns. The Predicate + * (key) and Object (val) positions for those triple patterns are extracted + * into a {@link ServiceParams} object. For each key, there may be one or + * more values. * - * @see {@link AbstractServiceFactory}. + * <pre> + * SERVICE <uri> { + * bd:serviceParam :key1 :val1 . + * bd:serviceParam :key1 :val2 . + * bd:serviceParam :key2 :val3 . + * } + * </pre> + * + * @see ServiceParams. */ URI SERVICE_PARAM = new URIImpl(NAMESPACE + "serviceParam"); Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-002.rq =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-002.rq (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-002.rq 2014-07-10 15:47:26 UTC (rev 8533) @@ -0,0 +1,9 @@ +PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> +PREFIX : <http://example.org/book/> + +SELECT ?book ?title ?price +{ + SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_002> { + bd:serviceParam :book :book1 + } +} Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java 2014-07-10 15:11:48 UTC (rev 8532) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java 2014-07-10 15:47:26 UTC (rev 8533) @@ -30,6 +30,8 @@ import org.openrdf.model.impl.URIImpl; import com.bigdata.rdf.sparql.ast.eval.AbstractDataDrivenSPARQLTestCase; +import com.bigdata.rdf.sparql.ast.eval.ServiceParams; +import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; import com.bigdata.rdf.sparql.ast.service.ServiceRegistry; /** @@ -76,6 +78,24 @@ */ public void test_stored_query_001() throws Exception { + class MyStoredQueryService extends StoredQueryService { + + @Override + public String getQuery(final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) { + final StringBuilder sb = new StringBuilder(); + sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"); + sb.append("PREFIX : <http://example.org/book/> \n"); + sb.append("PREFIX ns: <http://example.org/ns#> \n"); + sb.append("SELECT ?book ?title ?price { \n"); + sb.append(" ?book dc:title ?title ; \n"); + sb.append(" ns:price ?price . \n"); + sb.append("} \n"); + return sb.toString(); + } + + } + final URI serviceURI = new URIImpl(StoredQueryService.Options.NAMESPACE + getName()); try { @@ -100,21 +120,71 @@ } - private static class MyStoredQueryService extends StoredQueryService { + /** + * Simple stored query test verifies that the stored query has access to the + * {@link ServiceParams}. + * + * <pre> + * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> + * PREFIX : <http://example.org/book/> + * + * SELECT ?book ?title ?price + * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_002> { + * bd:serviceParam :book :book1 + * } + * } + * </pre> + * + * @throws Exception + */ + public void test_stored_query_002() throws Exception { + + class MyStoredQueryService extends StoredQueryService { - @Override - public String getQuery() { - final StringBuilder sb = new StringBuilder(); - sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"); - sb.append("PREFIX : <http://example.org/book/> \n"); - sb.append("PREFIX ns: <http://example.org/ns#> \n"); - sb.append("SELECT ?book ?title ?price { \n"); - sb.append(" ?book dc:title ?title ; \n"); - sb.append(" ns:price ?price . \n"); - sb.append("} \n"); - return sb.toString(); + @Override + public String getQuery(final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) { + + final URI val = serviceParams.getAsURI(new URIImpl( + "http://example.org/book/book")); + + final StringBuilder sb = new StringBuilder(); + sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> \n"); + sb.append("PREFIX : <http://example.org/book/> \n"); + sb.append("PREFIX ns: <http://example.org/ns#> \n"); + sb.append("SELECT ?book ?title ?price { \n"); + sb.append(" BIND( <"+val.stringValue()+"> as ?book ) . \n"); + sb.append(" ?book dc:title ?title ; \n"); + sb.append(" ns:price ?price . \n"); + sb.append("} \n"); + return sb.toString(); + } + } + final URI serviceURI = new URIImpl(StoredQueryService.Options.NAMESPACE + getName()); + try { + + // register the service. + ServiceRegistry.getInstance().add(serviceURI, + new MyStoredQueryService()); + + final TestHelper h = new TestHelper("stored-query-002", // testURI, + "stored-query-002.rq",// queryFileURL + "stored-query-001.ttl",// dataFileURL + "stored-query-001.srx" // resultFileURL, + // false, // laxCardinality + // true // checkOrder + ); + + h.runTest(); + + } finally { + // unregister the service. + ServiceRegistry.getInstance().remove(serviceURI); + } + } - + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-10 15:11:54
|
Revision: 8532 http://sourceforge.net/p/bigdata/code/8532 Author: thompsonbry Date: 2014-07-10 15:11:48 +0000 (Thu, 10 Jul 2014) Log Message: ----------- Check-point on the stored-query service. A simple service has been implemented that can execute a single SPARQL query. I am going to refactor to allow stored queries to do complex application processing including the submission of multiple queries while holding a set of locks. I moved the core code for the group commit interfaces used by the REST API into a different package and am reusing them for the stored query service. I pulled out the ServiceParams helper class so it can be used with services that use the openrdf data structures (BindingSet[]) versus the bigdata data structures (IBindingSet[]). See #989 (stored query service) Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AbstractServiceFactory.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SampleServiceFactory.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SliceServiceFactory.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ValuesServiceFactory.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/CustomServiceFactory.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/ServiceCall.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/TestAll.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/service/BigdataNativeMockServiceFactory.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/BigdataRDFContext.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/BigdataServlet.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/BlueprintsServlet.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/DeleteServlet.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/InsertServlet.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/QueryServlet.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/UpdateServlet.java Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/package.html branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/AbstractApiTask.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/ApiTaskForIndexManager.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/ApiTaskForJournal.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/IApiTask.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/package.html branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-001.rq branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-001.srx branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/stored-query-001.ttl branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestAll.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/service/storedquery/TestStoredQueryService.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/AbstractRestApiTask.java Removed Paths: ------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/RestApiTask.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/RestApiTaskForIndexManager.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/RestApiTaskForJournal.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AbstractServiceFactory.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AbstractServiceFactory.java 2014-07-10 00:00:48 UTC (rev 8531) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AbstractServiceFactory.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -27,418 +27,30 @@ package com.bigdata.rdf.sparql.ast.eval; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; -import org.openrdf.model.Literal; -import org.openrdf.model.URI; -import org.openrdf.model.Value; - -import com.bigdata.bop.IVariable; -import com.bigdata.rdf.internal.IV; -import com.bigdata.rdf.sparql.ast.GraphPatternGroup; -import com.bigdata.rdf.sparql.ast.IGroupMemberNode; -import com.bigdata.rdf.sparql.ast.StatementPatternNode; -import com.bigdata.rdf.sparql.ast.TermNode; import com.bigdata.rdf.sparql.ast.service.BigdataServiceCall; import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; import com.bigdata.rdf.sparql.ast.service.ServiceFactory; import com.bigdata.rdf.sparql.ast.service.ServiceNode; import com.bigdata.rdf.store.AbstractTripleStore; -import com.bigdata.rdf.store.BD; /** - * An abstract ServiceFactory that deals with service parameters (magic - * predicates that connfigure the service). + * An abstract {@link ServiceFactory} that deals with service parameters (magic + * predicates that configure the service) in a standardized manner using the + * {@link ServiceParams} helper class. */ public abstract class AbstractServiceFactory implements ServiceFactory { - private static final Logger log = Logger - .getLogger(AbstractServiceFactory.class); - - /** - * The service parameters. Can be multi-valued. Map from predicate to - * one or more TermNode values. - */ - public static class ServiceParams { - - /** - * The map of service params. - */ - final Map<URI, List<TermNode>> params; - - public ServiceParams() { - - this.params = new LinkedHashMap<URI, List<TermNode>>(); - - } - - /** - * Add. - */ - public void add(final URI param, final TermNode value) { - - if (!params.containsKey(param)) { - - params.put(param, new LinkedList<TermNode>()); - - } - - params.get(param).add(value); - - } - - /** - * Set (clear and add). - */ - public void set(final URI param, final TermNode value) { - - clear(param); - - add(param, value); - - } - - /** - * Clear. - */ - public void clear(final URI param) { - - params.remove(param); - - } - - /** - * Check for existence. - */ - public boolean contains(final URI param) { - - return params.containsKey(param); - - } - - /** - * Get a singleton value for the specified param. - */ - public TermNode get(final URI param, final TermNode defaultValue) { - - if (params.containsKey(param)) { - - final List<TermNode> values = params.get(param); - - if (values.size() > 1) { - - throw new RuntimeException("not a singleton param"); - - } - - return values.get(0); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public Boolean getAsBoolean(final URI param) { - - return getAsBoolean(param, null); - - } - - /** - * Helper. - */ - public Boolean getAsBoolean(final URI param, final Boolean defaultValue) { - - final Literal term = getAsLiteral(param, null); - - if (term != null) { - - return term.booleanValue(); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public Integer getAsInt(final URI param) { - - return getAsInt(param, null); - - } - - /** - * Helper. - */ - public Integer getAsInt(final URI param, final Integer defaultValue) { - - final Literal term = getAsLiteral(param, null); - - if (term != null) { - - return term.intValue(); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public Long getAsLong(final URI param) { - - return getAsLong(param, null); - - } - - /** - * Helper. - */ - public Long getAsLong(final URI param, final Long defaultValue) { - - final Literal term = getAsLiteral(param, null); - - if (term != null) { - - return term.longValue(); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public String getAsString(final URI param) { - - return getAsString(param, null); - - } - - /** - * Helper. - */ - public String getAsString(final URI param, final String defaultValue) { - - final Literal term = getAsLiteral(param, null); - - if (term != null) { - - return term.stringValue(); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public Literal getAsLiteral(final URI param) { - - return getAsLiteral(param, null); - - } - - /** - * Helper. - */ - public Literal getAsLiteral(final URI param, final Literal defaultValue) { - - final TermNode term = get(param, null); - - if (term != null) { - - if (term.isVariable()) { - - throw new IllegalArgumentException("not a constant"); - - } - - final Value v = term.getValue(); - - if (!(v instanceof Literal)) { - - throw new IllegalArgumentException("not a literal"); - - } - - return ((Literal) v); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public URI getAsURI(final URI param) { - - return getAsURI(param, null); - - } - - /** - * Helper. - */ - public URI getAsURI(final URI param, final URI defaultValue) { - - final TermNode term = get(param, null); - - if (term != null) { - - if (term.isVariable()) { - - throw new IllegalArgumentException("not a constant"); - - } - - final Value v = term.getValue(); - - if (!(v instanceof URI)) { - - throw new IllegalArgumentException("not a uri"); - - } - - return ((URI) v); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public IVariable<IV> getAsVar(final URI param) { - - return getAsVar(param, null); - - } - - /** - * Helper. - */ - public IVariable<IV> getAsVar(final URI param, final IVariable<IV> defaultValue) { - - final TermNode term = get(param, null); - - if (term != null) { - - if (!term.isVariable()) { - - throw new IllegalArgumentException("not a var"); - - } - - return (IVariable<IV>) term.getValueExpression(); - - } - - return defaultValue; - - } - - /** - * Helper. - */ - public List<TermNode> get(final URI param) { - - if (params.containsKey(param)) { - - return params.get(param); - - } - - return Collections.EMPTY_LIST; - - } - - /** - * Iterator. - */ - public Iterator<Map.Entry<URI, List<TermNode>>> iterator() { - - return params.entrySet().iterator(); - - } - - public String toString() { - - final StringBuilder sb = new StringBuilder(); - - sb.append("["); - - for (Map.Entry<URI, List<TermNode>> e : params.entrySet()) { - - final URI param = e.getKey(); - - final List<TermNode> terms = e.getValue(); - - sb.append(param).append(": "); - - if (terms.size() == 1) { - - sb.append(terms.get(0)); - - } else { - - sb.append("["); - for (TermNode t : terms) { - - sb.append(t).append(", "); - - } - sb.setLength(sb.length()-2); - sb.append("]"); - - } - - sb.append(", "); - - } - - if (sb.length() > 1) - sb.setLength(sb.length()-2); - sb.append("]"); - - return sb.toString(); - - } - - } + public AbstractServiceFactory() { - public AbstractServiceFactory() { } - + /** * Create a {@link BigdataServiceCall}. Does the work of collecting * the service parameter triples and then delegates to * {@link #create(ServiceCallCreateParams, ServiceParams)}. */ - public BigdataServiceCall create(final ServiceCallCreateParams params) { + @Override + final public BigdataServiceCall create(final ServiceCallCreateParams params) { if (params == null) throw new IllegalArgumentException(); @@ -453,12 +65,8 @@ if (serviceNode == null) throw new IllegalArgumentException(); - final ServiceParams serviceParams = gatherServiceParams(params); + final ServiceParams serviceParams = ServiceParams.gatherServiceParams(params); - if (log.isDebugEnabled()) { - log.debug(serviceParams); - } - return create(params, serviceParams); } @@ -470,68 +78,4 @@ final ServiceCallCreateParams params, final ServiceParams serviceParams); - /** - * Gather the service params (any statement patterns with the subject - * of {@link BD#SERVICE_PARAM}. - */ - protected ServiceParams gatherServiceParams( - final ServiceCallCreateParams createParams) { - - if (createParams == null) - throw new IllegalArgumentException(); - - final AbstractTripleStore store = createParams.getTripleStore(); - - if (store == null) - throw new IllegalArgumentException(); - - final ServiceNode serviceNode = createParams.getServiceNode(); - - if (serviceNode == null) - throw new IllegalArgumentException(); - - final GraphPatternGroup<IGroupMemberNode> group = - serviceNode.getGraphPattern(); - - if (group == null) - throw new IllegalArgumentException(); - - final ServiceParams serviceParams = new ServiceParams(); - - final Iterator<IGroupMemberNode> it = group.iterator(); - - while (it.hasNext()) { - - final IGroupMemberNode node = it.next(); - - if (node instanceof StatementPatternNode) { - - final StatementPatternNode sp = (StatementPatternNode) node; - - final TermNode s = sp.s(); - - if (s.isConstant() && BD.SERVICE_PARAM.equals(s.getValue())) { - - if (sp.p().isVariable()) { - - throw new RuntimeException( - "not a valid service param triple pattern, " + - "predicate must be constant: " + sp); - - } - - final URI param = (URI) sp.p().getValue(); - - serviceParams.add(param, sp.o()); - - } - - } - - } - - return serviceParams; - - } - } Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SampleServiceFactory.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SampleServiceFactory.java 2014-07-10 00:00:48 UTC (rev 8531) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SampleServiceFactory.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -137,7 +137,6 @@ } - /* * Note: This could extend the base class to allow for search service * configuration options. @@ -158,6 +157,7 @@ } + @Override public BigdataServiceCall create( final ServiceCallCreateParams params, final ServiceParams serviceParams) { Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ServiceParams.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -0,0 +1,493 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.rdf.sparql.ast.eval; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.openrdf.model.Literal; +import org.openrdf.model.URI; +import org.openrdf.model.Value; + +import com.bigdata.bop.IVariable; +import com.bigdata.rdf.internal.IV; +import com.bigdata.rdf.sparql.ast.GraphPatternGroup; +import com.bigdata.rdf.sparql.ast.IGroupMemberNode; +import com.bigdata.rdf.sparql.ast.StatementPatternNode; +import com.bigdata.rdf.sparql.ast.TermNode; +import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; +import com.bigdata.rdf.sparql.ast.service.ServiceNode; +import com.bigdata.rdf.store.AbstractTripleStore; +import com.bigdata.rdf.store.BD; + +/** + * The service parameters. Can be multi-valued. Map from predicate to + * one or more {@link TermNode} values. + */ +public class ServiceParams { + + private static final Logger log = Logger + .getLogger(AbstractServiceFactory.class); + + /** + * The map of service params. + */ + private final Map<URI, List<TermNode>> params; + + public ServiceParams() { + + this.params = new LinkedHashMap<URI, List<TermNode>>(); + + } + + /** + * Add. + */ + public void add(final URI param, final TermNode value) { + + if (!params.containsKey(param)) { + + params.put(param, new LinkedList<TermNode>()); + + } + + params.get(param).add(value); + + } + + /** + * Set (clear and add). + */ + public void set(final URI param, final TermNode value) { + + clear(param); + + add(param, value); + + } + + /** + * Clear. + */ + public void clear(final URI param) { + + params.remove(param); + + } + + /** + * Check for existence. + */ + public boolean contains(final URI param) { + + return params.containsKey(param); + + } + + /** + * Get a singleton value for the specified param. + */ + public TermNode get(final URI param, final TermNode defaultValue) { + + if (params.containsKey(param)) { + + final List<TermNode> values = params.get(param); + + if (values.size() > 1) { + + throw new RuntimeException("not a singleton param"); + + } + + return values.get(0); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public Boolean getAsBoolean(final URI param) { + + return getAsBoolean(param, null); + + } + + /** + * Helper. + */ + public Boolean getAsBoolean(final URI param, final Boolean defaultValue) { + + final Literal term = getAsLiteral(param, null); + + if (term != null) { + + return term.booleanValue(); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public Integer getAsInt(final URI param) { + + return getAsInt(param, null); + + } + + /** + * Helper. + */ + public Integer getAsInt(final URI param, final Integer defaultValue) { + + final Literal term = getAsLiteral(param, null); + + if (term != null) { + + return term.intValue(); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public Long getAsLong(final URI param) { + + return getAsLong(param, null); + + } + + /** + * Helper. + */ + public Long getAsLong(final URI param, final Long defaultValue) { + + final Literal term = getAsLiteral(param, null); + + if (term != null) { + + return term.longValue(); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public String getAsString(final URI param) { + + return getAsString(param, null); + + } + + /** + * Helper. + */ + public String getAsString(final URI param, final String defaultValue) { + + final Literal term = getAsLiteral(param, null); + + if (term != null) { + + return term.stringValue(); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public Literal getAsLiteral(final URI param) { + + return getAsLiteral(param, null); + + } + + /** + * Helper. + */ + public Literal getAsLiteral(final URI param, final Literal defaultValue) { + + final TermNode term = get(param, null); + + if (term != null) { + + if (term.isVariable()) { + + throw new IllegalArgumentException("not a constant"); + + } + + final Value v = term.getValue(); + + if (!(v instanceof Literal)) { + + throw new IllegalArgumentException("not a literal"); + + } + + return ((Literal) v); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public URI getAsURI(final URI param) { + + return getAsURI(param, null); + + } + + /** + * Helper. + */ + public URI getAsURI(final URI param, final URI defaultValue) { + + final TermNode term = get(param, null); + + if (term != null) { + + if (term.isVariable()) { + + throw new IllegalArgumentException("not a constant"); + + } + + final Value v = term.getValue(); + + if (!(v instanceof URI)) { + + throw new IllegalArgumentException("not a uri"); + + } + + return ((URI) v); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + @SuppressWarnings("rawtypes") + public IVariable<IV> getAsVar(final URI param) { + + return getAsVar(param, null); + + } + + /** + * Helper. + */ + @SuppressWarnings("rawtypes") + public IVariable<IV> getAsVar(final URI param, + final IVariable<IV> defaultValue) { + + final TermNode term = get(param, null); + + if (term != null) { + + if (!term.isVariable()) { + + throw new IllegalArgumentException("not a var"); + + } + + return (IVariable<IV>) term.getValueExpression(); + + } + + return defaultValue; + + } + + /** + * Helper. + */ + public List<TermNode> get(final URI param) { + + if (params.containsKey(param)) { + + return params.get(param); + + } + + return Collections.emptyList(); + + } + + /** + * Iterator. + */ + public Iterator<Map.Entry<URI, List<TermNode>>> iterator() { + + return params.entrySet().iterator(); + + } + + @Override + public String toString() { + + final StringBuilder sb = new StringBuilder(); + + sb.append("["); + + for (Map.Entry<URI, List<TermNode>> e : params.entrySet()) { + + final URI param = e.getKey(); + + final List<TermNode> terms = e.getValue(); + + sb.append(param).append(": "); + + if (terms.size() == 1) { + + sb.append(terms.get(0)); + + } else { + + sb.append("["); + for (TermNode t : terms) { + + sb.append(t).append(", "); + + } + sb.setLength(sb.length() - 2); + sb.append("]"); + + } + + sb.append(", "); + + } + + if (sb.length() > 1) + sb.setLength(sb.length() - 2); + sb.append("]"); + + return sb.toString(); + + } + + /** + * Gather the service params (any statement patterns with the subject of + * {@link BD#SERVICE_PARAM}. + */ + static public ServiceParams gatherServiceParams( + final ServiceCallCreateParams createParams) { + + if (createParams == null) + throw new IllegalArgumentException(); + + final AbstractTripleStore store = createParams.getTripleStore(); + + if (store == null) + throw new IllegalArgumentException(); + + final ServiceNode serviceNode = createParams.getServiceNode(); + + if (serviceNode == null) + throw new IllegalArgumentException(); + + final GraphPatternGroup<IGroupMemberNode> group = serviceNode + .getGraphPattern(); + + if (group == null) + throw new IllegalArgumentException(); + + final ServiceParams serviceParams = new ServiceParams(); + + final Iterator<IGroupMemberNode> it = group.iterator(); + + while (it.hasNext()) { + + final IGroupMemberNode node = it.next(); + + if (node instanceof StatementPatternNode) { + + final StatementPatternNode sp = (StatementPatternNode) node; + + final TermNode s = sp.s(); + + if (s.isConstant() && BD.SERVICE_PARAM.equals(s.getValue())) { + + if (sp.p().isVariable()) { + + throw new RuntimeException( + "not a valid service param triple pattern, " + + "predicate must be constant: " + sp); + + } + + final URI param = (URI) sp.p().getValue(); + + serviceParams.add(param, sp.o()); + + } + + } + + } + + if (log.isDebugEnabled()) { + + log.debug(serviceParams); + + } + + return serviceParams; + + } + +} // class ServiceParams Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SliceServiceFactory.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SliceServiceFactory.java 2014-07-10 00:00:48 UTC (rev 8531) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/SliceServiceFactory.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -65,7 +65,6 @@ import com.bigdata.rdf.sparql.ast.service.BigdataServiceCall; import com.bigdata.rdf.sparql.ast.service.IServiceOptions; import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; -import com.bigdata.rdf.sparql.ast.service.ServiceFactory; import com.bigdata.rdf.sparql.ast.service.ServiceNode; import com.bigdata.rdf.spo.DistinctMultiTermAdvancer; import com.bigdata.rdf.spo.ISPO; @@ -100,8 +99,7 @@ * * @see RangeBOp */ -public class SliceServiceFactory extends AbstractServiceFactory - implements ServiceFactory { +public class SliceServiceFactory extends AbstractServiceFactory { private static final Logger log = Logger .getLogger(SliceServiceFactory.class); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ValuesServiceFactory.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ValuesServiceFactory.java 2014-07-10 00:00:48 UTC (rev 8531) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/ValuesServiceFactory.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -81,8 +81,7 @@ * ... * } */ -public class ValuesServiceFactory extends AbstractServiceFactory - implements ServiceFactory { +public class ValuesServiceFactory extends AbstractServiceFactory { private static final Logger log = Logger .getLogger(ValuesServiceFactory.class); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/CustomServiceFactory.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/CustomServiceFactory.java 2014-07-10 00:00:48 UTC (rev 8531) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/CustomServiceFactory.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -39,7 +39,6 @@ * Federated Query and Custom Services</a> * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public interface CustomServiceFactory extends ServiceFactory { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/ServiceCall.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/ServiceCall.java 2014-07-10 00:00:48 UTC (rev 8531) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/ServiceCall.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -44,7 +44,6 @@ * common ancestor other than {@link Object}. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public interface ServiceCall<E> { Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/StoredQueryService.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -0,0 +1,350 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.rdf.sparql.ast.service.storedquery; + +import java.util.Arrays; +import java.util.concurrent.Future; + +import org.apache.log4j.Logger; +import org.openrdf.query.BindingSet; +import org.openrdf.query.QueryEvaluationException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQueryResult; + +import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; +import com.bigdata.rdf.sail.BigdataSailTupleQuery; +import com.bigdata.rdf.sail.Sesame2BigdataIterator; +import com.bigdata.rdf.sparql.ast.eval.ASTEvalHelper; +import com.bigdata.rdf.sparql.ast.eval.ServiceParams; +import com.bigdata.rdf.sparql.ast.service.BigdataNativeServiceOptions; +import com.bigdata.rdf.sparql.ast.service.ExternalServiceCall; +import com.bigdata.rdf.sparql.ast.service.IServiceOptions; +import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams; +import com.bigdata.rdf.sparql.ast.service.ServiceFactory; +import com.bigdata.rdf.sparql.ast.service.ServiceNode; +import com.bigdata.rdf.store.AbstractTripleStore; +import com.bigdata.rdf.task.AbstractApiTask; + +import cutthecrap.utils.striterators.ICloseableIterator; + +/** + * A SERVICE that exposes a stored query for execution. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * + * @see <a href="http://trac.bigdata.com/ticket/989">Stored Query Service</a> + * + * TODO Wiki page. + * + * TODO Implicit prefix declaration for bsq. + * + * TODO Reconcile with the REST API (group commit task pattern). + * + * TODO Why does this work? + * + * <pre> + * SELECT ?book ?title ?price + * { + * SERVICE <http://www.bigdata.com/rdf/stored-query#test_stored_query_001> { + * } + * } + * </pre> + * + * while this does not work + * + * <pre> + * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> + * + * SELECT ?book ?title ?price + * { + * SERVICE <bsq#test_stored_query_001> { + * } + * } + * </pre> + * + * TODO Example + * + * <pre> + * PREFIX bsq: <http://www.bigdata.com/rdf/stored-query#> + * #... + * SERVICE <bsq#my-service> { + * bsq:queryParam bsq:gasClass "com.bigdata.rdf.graph.analytics.BFS" . + * gas:program gas:in <IRI> . # one or more times, specifies the initial frontier. + * gas:program gas:out ?out . # exactly once - will be bound to the visited vertices. + * gas:program gas:maxIterations 4 . # optional limit on breadth first expansion. + * gas:program gas:maxVisited 2000 . # optional limit on the #of visited vertices. + * gas:program gas:nthreads 4 . # specify the #of threads to use (optional) + * } + * </pre> + * + */ +abstract public class StoredQueryService implements ServiceFactory { + + public interface Options { + + /** + * The namespace used for stored query service. + */ + String NAMESPACE = "http://www.bigdata.com/rdf/stored-query#"; + + } + + static private transient final Logger log = Logger + .getLogger(StoredQueryService.class); + + private final BigdataNativeServiceOptions serviceOptions; + + public StoredQueryService() { + + serviceOptions = new BigdataNativeServiceOptions(); + +// /* +// * TODO This should probably be metadata set for each specific +// * stored query. +// */ +// serviceOptions.setRunFirst(true); + + } + + @Override + public IServiceOptions getServiceOptions() { + + return serviceOptions; + + } + + @Override + final public ExternalServiceCall create(final ServiceCallCreateParams params) { + + if (params == null) + throw new IllegalArgumentException(); + + final AbstractTripleStore store = params.getTripleStore(); + + if (store == null) + throw new IllegalArgumentException(); + + final ServiceNode serviceNode = params.getServiceNode(); + + if (serviceNode == null) + throw new IllegalArgumentException(); + + final ServiceParams serviceParams = ServiceParams.gatherServiceParams(params); + + return create(params, serviceParams); + + } + + public ExternalServiceCall create( + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) { + + /* + * Create and return the ServiceCall object which will execute this + * query. + */ + + return new StoredQueryServiceCall(createParams, serviceParams); + + } + + /** + * Return the SPARQL query to be evaluated. + */ + abstract protected String getQuery(); + + private class StoredQueryServiceCall implements ExternalServiceCall { + + private final ServiceCallCreateParams createParams; + private final ServiceParams serviceParams; + + public StoredQueryServiceCall( + final ServiceCallCreateParams createParams, + final ServiceParams serviceParams) { + + if (createParams == null) + throw new IllegalArgumentException(); + + if (serviceParams == null) + throw new IllegalArgumentException(); + + this.createParams = createParams; + this.serviceParams = serviceParams; + + } + + @Override + public IServiceOptions getServiceOptions() { + + return createParams.getServiceOptions(); + + } + + /** + * TODO We could use {@link ASTEvalHelper} to evaluate at the bigdata + * level without forcing the materialization of any variable bindings + * from the lexicon indices. This would be faster for some purposes, + * especially if the stored procedure is only used to JOIN into an outer + * query as in <code>SELECT * { SERVICE bsq:my-service {} }</code> + * + * FIXME Generalize to allow arbitrary application logic that has easy + * methods permitting it to invoke multiple queries and operate on the + * results. + * + * FIXME Generalize to support groovy scripting. + */ + @Override + public ICloseableIterator<BindingSet> call(final BindingSet[] bindingSets) + throws Exception { + + if (log.isInfoEnabled()) { + log.info(bindingSets.length); + log.info(Arrays.toString(bindingSets)); + log.info(serviceParams); + } + + final AbstractTripleStore tripleStore = createParams.getTripleStore(); + + final String queryStr = getQuery(); + + /* + * FIXME What about incoming bindings? They need to flow into the + * SERVICE. + */ + + // TODO Should the baseURI be the SERVICE URI? Decide and document. + final String baseURI = createParams.getServiceURI().stringValue(); + + final Future<TupleQueryResult> ft = AbstractApiTask.submitApiTask( + tripleStore.getIndexManager(), + new SparqlApiTask(tripleStore.getNamespace(), tripleStore + .getTimestamp(), queryStr, baseURI, bindingSets)); + + try { + + final TupleQueryResult tupleQueryResult = ft.get(); + + return new Sesame2BigdataIterator<BindingSet, QueryEvaluationException>( + tupleQueryResult); + + } finally { + + ft.cancel(true/* mayInterruptIfRunning */); + + } + + } + + } // StoredQueryServiceCall + + /** + * Task to execute a SPARQL query. + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + */ + private static class SparqlApiTask extends + AbstractApiTask<TupleQueryResult> { + + private final String queryStr; + private final String baseURI; + + /** + * + * FIXME This is ignoring the exogenous bindings. This is more or less + * equivalent to bottom-up evaluation. It would be more efficient if we + * could flow in the exogenous bindings but this is not supported before + * openrdf 2.7 (we hack this in {@link BigdataSailTupleQuery}). + */ + private final BindingSet[] bindingSets; + + public SparqlApiTask(final String namespace, final long timestamp, + final String queryStr, final String baseURI, + final BindingSet[] bindingSets) { + + super(namespace, timestamp); + + this.queryStr = queryStr; + this.baseURI = baseURI; + this.bindingSets = bindingSets; + + } + + @Override + public TupleQueryResult call() throws Exception { + BigdataSailRepositoryConnection cxn = null; + boolean success = false; + try { + // Note: Will be UPDATE connection if UPDATE request!!! + cxn = getQueryConnection(); + if (log.isTraceEnabled()) + log.trace("Query running..."); + final TupleQueryResult ret = doQuery(cxn); + success = true; + if (log.isTraceEnabled()) + log.trace("Query done."); + return ret; + } finally { + if (cxn != null) { + if (!success && !cxn.isReadOnly()) { + /* + * Force rollback of the connection. + * + * Note: It is possible that the commit has already + * been processed, in which case this rollback() + * will be a NOP. This can happen when there is an + * IO error when communicating with the client, but + * the database has already gone through a commit. + */ + try { + // Force rollback of the connection. + cxn.rollback(); + } catch (Throwable t) { + log.error(t, t); + } + } + try { + // Force close of the connection. + cxn.close(); + } catch (Throwable t) { + log.error(t, t); + } + } + } + } + + protected TupleQueryResult doQuery( + final BigdataSailRepositoryConnection cxn) throws Exception { + + final BigdataSailTupleQuery query = (BigdataSailTupleQuery) cxn + .prepareTupleQuery(QueryLanguage.SPARQL, queryStr, + baseURI); + + return query.evaluate(); + + } + + } // SparqlApiTask + +} Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/package.html =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/package.html (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/service/storedquery/package.html 2014-07-10 15:11:48 UTC (rev 8532) @@ -0,0 +1,18 @@ +<html> +<head> +<title>A SPARQL Stored Query Service</title> +</head> +<body> + +<p> + + An embedded SERVICE that permits an application to register and execute + stored queries. A stored query may be as simple as a single SPARQL + query. However, it may also involve arbitrary application logic that + coordinates some set of related queries before returning a result to + the caller. + +</p> + +</body> +</html> Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/AbstractApiTask.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/AbstractApiTask.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/task/AbstractApiTask.java 2014-07-10 15:11:48 UTC (rev 8532) @@ -0,0 +1,407 @@ +/* + + Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + + Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ +package com.bigdata.rdf.task; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.atomic.AtomicReference; + +import org.openrdf.repository.RepositoryException; +import org.openrdf.sail.SailException; + +import com.bigdata.BigdataStatics; +import com.bigdata.journal.IConcurrencyManager; +import com.bigdata.journal.IIndexManager; +import com.bigdata.journal.ITx; +import com.bigdata.journal.Journal; +import com.bigdata.journal.TimestampUtility; +import com.bigdata.rdf.sail.BigdataSail; +import com.bigdata.rdf.sail.BigdataSailRepository; +import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; +import com.bigdata.rdf.sail.webapp.DatasetNotFoundException; +import com.bigdata.rdf.store.AbstractTripleStore; +import com.bigdata.resources.IndexManager; +import com.bigdata.service.IBigdataFederation; + +/** + * Base class is non-specific. Directly derived classes are suitable for + * internal tasks (stored queries, stored procedures, etc) while REST API tasks + * are based on a specialized subclass that also provides for access to the HTTP + * request and response. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @see <a href="- http://sourceforge.net/apps/trac/bigdata/ticket/566" > + * Concurrent unisolated operations against multiple KBs </a> + */ +abstract public class AbstractApiTask<T> implements IApiTask<T> { + + /** The reference to the {@link IIndexManager} is set before the task is executed. */ + private final AtomicReference<IIndexManager> indexManagerRef = new AtomicReference<IIndexManager>(); + + /** The namespace of the target KB instance. */ + protected final String namespace; + + /** The timestamp of the view of that KB instance. */ + protected final long timestamp; + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public long getTimestamp() { + return timestamp; + } + + /** + * @param namespace + * The namespace of the target KB instance. + * @param timestamp + * The timestamp of the view of that KB instance. + */ + protected AbstractApiTask(final String namespace, + final long timestamp) { + this.namespace = namespace; + this.timestamp = timestamp; + } + + protected void clearIndexManager() { + + indexManagerRef.set(null); + + } + + protected void setIndexManager(final IIndexManager indexManager) { + + if (!indexManagerRef + .compareAndSet(null/* expect */, indexManager/* update */)) { + + throw new IllegalStateException(); + + } + + } + + protected IIndexManager getIndexManager() { + + final IIndexManager tmp = indexManagerRef.get(); + + if (tmp == null) + throw new IllegalStateException(); + + return tmp; + + } + + /** + * Return a read-only view of the {@link AbstractTripleStore} for the given + * namespace will read from the commit point associated with the given + * timestamp. + * + * @param namespace + * The namespace. + * @param timestamp + * The timestamp. + * + * @return The {@link AbstractTripleStore} -or- <code>null</code> if none is + * found for that namespace and timestamp. + * + * TODO Enforce historical query by making sure timestamps conform + * (we do not want to allow read/write tx queries unless update + * semantics are introduced ala SPARQL 1.1). + */ + protected AbstractTripleStore getTripleStore(final String namespace, + final long timestamp) { + + // if (timestamp == ITx.UNISOLATED) + // throw new IllegalArgumentException("UNISOLATED reads disallowed."); + + // resolve the default namespace. + final AbstractTripleStore tripleStore = (AbstractTripleStore) getIndexManager() + .getResourceLocator().locate(namespace, timestamp); + + return tripleStore; + + } + + /** + * Return a connection transaction, which may be either read-only or support + * mutation depending on the timestamp associated with the task's view. When + * the timestamp is associated with a historical commit point, this will be + * a read-only connection. When it is associated with the + * {@link ITx#UNISOLATED} view or a read-write transaction, this will be a + * mutable connection. + * + * @throws RepositoryException + */ + protected BigdataSailRepositoryConnection getQueryConnection() + throws RepositoryException { + + /* + * Note: [timestamp] will be a read-only tx view of the triple store if + * a READ_LOCK was specified when the NanoSparqlServer was started + * (unless the query explicitly overrides the timestamp of the view on + * which it will operate). + */ + final AbstractTripleStore tripleStore = getTripleStore(namespace, + timestamp); + + if (tripleStore == null) { + + throw new DatasetNotFoundException("Not found: namespace=" + + namespace + ", timestamp=" + + TimestampUtility.toString(timestamp)); + + } + + // Wrap with SAIL. + final BigdataSail sail = new BigdataSail(tripleStore); + + final BigdataSailRepository repo = new BigdataSailRepository(sail); + + repo.initialize(); + + if (TimestampUtility.isReadOnly(timestamp)) { + + return (BigdataSailRepositoryConnection) repo + .getReadOnlyConnection(timestamp); + + } + + // Read-write connection. + final BigdataSailRepositoryConnection conn = repo.getConnection(); + + conn.setAutoCommit(false); + + return conn; + + } + + /** + * Return an UNISOLATED connection. + * + * @return The UNISOLATED connection. + * + * @throws SailException + * @throws RepositoryException + */ + protected BigdataSailRepositoryConnection getUnisolatedConnection() + throws SailException, RepositoryException { + + // resolve the default namespace. + final AbstractTripleStore tripleStore = (AbstractTripleStore) getIndexManager() + .getResourceLocator().locate(namespace, ITx.UNISOLATED); + + if (tripleStore == null) { + + throw new RuntimeException("Not found: namespace=" + namespace); + + } + + // Wrap with SAIL. + final BigdataSail sail = new BigdataSail(tripleStore); + + final BigdataSailRepository repo = new BigdataSailRepository(sail); + + repo.initialize(); + + final BigdataSailRepositoryConnection conn = (BigdataSailRepositoryConnection) repo + .getUnisolatedConnection(); + + conn.setAutoCommit(false); + + return conn; + + } + + /** + * Submit a task and return a {@link Future} for that task. The task will be + * run on the appropriate executor service depending on the nature of the + * backing database and the view required by the task. + * + * @param indexManager + * The {@link IndexManager}. + * @param task + * The task. + * + * @return The {@link Future} for that task. + * + * @throws DatasetNotFoundException + * + * @see <a href="http://sourceforge.net/apps/trac/bigdata/ticket/753" > HA + * doLocalAbort() should interrupt NSS requests and AbstractTasks </a> + * @see <a href="- http://sourceforge.net/apps/trac/bigdata/ticket/566" > + * Concurrent unisolated operations against multiple KBs </a> + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + static public <T> Future<T> submitApiTask( + final IIndexManager indexManager, final AbstractApiTask<T> task) + throws DatasetNotFoundException { + + final String namespace = task.getNamespace(); + + final long timestamp = task.getTimestamp(); + + if (!BigdataStatics.NSS_GROUP_COMMIT || indexManager instanceof IBigdataFederation + || TimestampUtility.isReadOnly(timestamp) + ) { + + /* + * Execute the REST API task. + * + * Note: For scale-out, the operation will be applied using + * client-side global views of the indices. + * + * Note: This can be used for operations on read-only views (even on + * a Journal). This is helpful since we can avoid some overhead + * associated the AbstractTask lock declarations. + */ + // Wrap Callable. + final FutureTask<T> ft = new FutureTask<T>( + new ApiTaskForIndexManager(indexManager, task)); + + if (true) { + + /* + * Caller runs (synchronous execution) + * + * Note: By having the caller run the task here we avoid + * consuming another thread. + */ + ft.run(); + + } else { + + /* + * Run on a normal executor service. + */ + indexManager.getExecutorService().submit(ft); + + } + + return ft; + + } else { + + /** + * Run on the ConcurrencyManager of the Journal. + * + * Mutation operations will be scheduled based on the pre-declared + * locks and will have exclusive access to the resources guarded by + * those locks when they run. + * + * FIXME GROUP COMMIT: The {@link AbstractTask} was written to + * require the exact set of resource lock declarations. However, for + * the REST API, we want to operate on all indices associated with a + * KB instance. This requires either: + * <p> + * (a) pre-resolving the names of those indices and passing them all + * into the AbstractTask; or + * <P> + * (b) allowing the caller to only declare the namespace and then to + * be granted access to all indices whose names are in that + * namespace. + * + * (b) is now possible with the fix to the Name2Addr prefix scan. + */ + + // Obtain the necessary locks for R/w access to KB indices. + final String[] locks = getLocksForKB((Journal) indexManager, + namespace); + + final IConcurrencyManager cc = ((Journal) indexManager) + .getConcurrencyManager(); + + // Submit task to ConcurrencyManager. Will acquire locks and run. + return cc.submit(new ApiTaskForJournal(cc, task.getTimestamp(), + locks, task)); + + } + + } + + /** + * Acquire the locks for the named indices associated with the specified KB. + * + * @param indexManager + * The {@link Journal}. + * @param namespace + * The namespace of the KB instance. + * + * @return The locks for the named indices associated with that KB instance. + * + * @throws DatasetNotFoundException + * + * FIXME GROUP COMMIT : [This should be replaced by the use of + * the namespace and hierarchical locking support in + * AbstractTask.] This could fail to discover a recently create + * KB between the time when the KB is created and when the group + * commit for that create becomes visible. This data race exists + * because we are using [lastCommitTime] rather than the + * UNISOLATED view of the GRS. + * <p> + * Note: This data race MIGHT be closed by the default locator + * cache. If it records the new KB properties when they are + * created, then they should be visible. If they are not + * visible, then we have a data race. (But if it records them + * before the group commit for the KB create, then the actual KB + * indices will not be durable until the that group commit...). + * <p> + * Note: The problem can obviously be resolved by using the + * UNISOLATED index to obtain the KB properties, but that would + * serialize ALL updates. What we need is a suitable caching + * mechanism that (a) ensures that newly create KB instances are + * visible; and (b) has high concurrency for read-only requests + * for the properties for those KB instances. + */ + private static String[] getLocksForKB(final Journal indexManager, + final String namespace) throws DatasetNotFoundException { + + final long timestamp = indexManager.getLastCommitTime(); + + final AbstractTripleStore tripleStore = (AbstractTripleStore) indexManager + .getResourceLocator().locate(namespace, timestamp); + + if (tripleStore == null) + throw new DatasetNotFoundException("Not found: namespace=" + + namespace + ", timestamp=" + + TimestampUtility.toString(timestamp)); + + final Set<String> lockSet = new HashSet<String>(); + + lockSet.addAll(tripleStore.getSPORelation().getIndexNames()); + + lockSet.addAll(tripleStore.getLexiconRelation().... [truncated message content] |
Revision: 8531 http://sourceforge.net/p/bigdata/code/8531 Author: thompsonbry Date: 2014-07-10 00:00:48 +0000 (Thu, 10 Jul 2014) Log Message: ----------- Updated some unit tests of the expected behavior of an optimizer that were broken by #988. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/optimizers/TestASTExistsAndJoinOrderByTypeOptimizers.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/optimizers/TestASTExistsAndJoinOrderByTypeOptimizers.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/optimizers/TestASTExistsAndJoinOrderByTypeOptimizers.java 2014-07-09 19:03:07 UTC (rev 8530) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/optimizers/TestASTExistsAndJoinOrderByTypeOptimizers.java 2014-07-10 00:00:48 UTC (rev 8531) @@ -28,6 +28,8 @@ package com.bigdata.rdf.sparql.ast.optimizers; import com.bigdata.rdf.sparql.ast.ArbitraryLengthPathNode; +import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.SubqueryRoot; /** * Test suite for {@link ASTUnionFiltersOptimizer}. @@ -64,9 +66,10 @@ ) ) ) ); + final SubqueryRoot askQuery; expected = select( varNode(w), where (joinGroupNode( - ask(varNode(y), + askQuery=ask(varNode(y), joinGroupNode( statementPatternNode(constantNode(a),constantNode(b),varNode(w)) ) ), @@ -74,7 +77,7 @@ statementPatternNode(constantNode(a),constantNode(b),varNode(w)))) ) ) ) ); - + askQuery.setFilterExistsMode(QueryHints.DEFAULT_FILTER_EXISTS); }}.test(); } @@ -91,13 +94,14 @@ ) ) ) ); + final SubqueryRoot askQuery1, askQuery2; expected = select( varNode(w), where (joinGroupNode( - ask(varNode(y), + askQuery1=ask(varNode(y), joinGroupNode( statementPatternNode(constantNode(a),constantNode(b),varNode(w)) ) ), - ask(varNode(z), + askQuery2=ask(varNode(z), joinGroupNode( statementPatternNode(constantNode(a),constantNode(c),varNode(w)) ) ), @@ -110,7 +114,8 @@ ) ) ) ); - + askQuery1.setFilterExistsMode(QueryHints.DEFAULT_FILTER_EXISTS); + askQuery2.setFilterExistsMode(QueryHints.DEFAULT_FILTER_EXISTS); }}.test(); } @@ -136,13 +141,14 @@ varCount = 0; final ArbitraryLengthPathNode alpp2 = arbitartyLengthPropertyPath(varNode(w), constantNode(b), HelperFlag.ONE_OR_MORE, joinGroupNode( statementPatternNode(leftVar(), constantNode(b), rightVar()) ) ); + final SubqueryRoot askQuery1, askQuery2; expected = select( varNode(w), where (joinGroupNode( - ask(varNode(y), + askQuery1=ask(varNode(y), joinGroupNode( alpp1 ) ), - ask(varNode(z), + askQuery2=ask(varNode(z), joinGroupNode( statementPatternNode(constantNode(a),constantNode(c),varNode(w)) ) ), @@ -157,7 +163,9 @@ ) ) ) ); - + askQuery1.setFilterExistsMode(QueryHints.DEFAULT_FILTER_EXISTS); + askQuery2.setFilterExistsMode(QueryHints.DEFAULT_FILTER_EXISTS); + }}.test(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2014-07-09 19:03:11
|
Revision: 8530 http://sourceforge.net/p/bigdata/code/8530 Author: jeremy_carroll Date: 2014-07-09 19:03:07 +0000 (Wed, 09 Jul 2014) Log Message: ----------- allow a bit longer for 988c - it is harder Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-09 19:02:50 UTC (rev 8529) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-09 19:03:07 UTC (rev 8530) @@ -912,7 +912,7 @@ final long elapsedNanos = System.nanoTime() - beginNanos; - final long timeoutNanos = TimeUnit.MILLISECONDS.toNanos(1500); + final long timeoutNanos = TimeUnit.MILLISECONDS.toNanos(2500); if (timeoutNanos < elapsedNanos) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2014-07-09 19:02:58
|
Revision: 8529 http://sourceforge.net/p/bigdata/code/8529 Author: jeremy_carroll Date: 2014-07-09 19:02:50 +0000 (Wed, 09 Jul 2014) Log Message: ----------- Also a case where the filter must reject a solution Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.rq branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.srx Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-09 19:02:33 UTC (rev 8528) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-09 19:02:50 UTC (rev 8529) @@ -921,4 +921,50 @@ } } + /** + * Performance related test for EXISTS. + * + * <pre> + * prefix eg: <eg:> + * SELET DISTINCT ?a + * FROM eg:g + * { { BIND( eg:d as ?a ) } + * UNION + * { BIND ( eg:z as ?a ) } + * FILTER EXISTS { + * ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b + * } + * } + * + * <pre> + * + * @throws Exception + * + * @see <a href="http://trac.bigdata.com/ticket/988"> bad + * performance for FILTER EXISTS </a> + */ + public void test_exists_988d() throws Exception { + + final long beginNanos = System.nanoTime(); + + new TestHelper( + "exists-988d", // testURI, + "exists-988d.rq",// queryFileURL + "exists-988.trig",// dataFileURL + "exists-988d.srx" // resultFileURL, +// false, // laxCardinality +// true // checkOrder + ).runTest(); + + final long elapsedNanos = System.nanoTime() - beginNanos; + + final long timeoutNanos = TimeUnit.MILLISECONDS.toNanos(1500); + + if (timeoutNanos < elapsedNanos) { + + fail("Timeout exceeded: Query hint not recognized?"); + + } + + } } Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.rq =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.rq (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.rq 2014-07-09 19:02:50 UTC (rev 8529) @@ -0,0 +1,13 @@ +prefix eg: <http://www.bigdata.com/> + +SELECT DISTINCT ?a +FROM eg:g +{ { BIND( eg:d as ?a ) } + UNION + { BIND ( eg:z as ?a ) } + FILTER EXISTS { + ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b . + # Note: Query hint specifies sub-query LIMIT ONE plan. + hint:SubQuery hint:filterExists "SubQueryLimitOne" . + } +} \ No newline at end of file Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.srx =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.srx (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988d.srx 2014-07-09 19:02:50 UTC (rev 8529) @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<sparql + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:xs="http://www.w3.org/2001/XMLSchema#" + xmlns="http://www.w3.org/2005/sparql-results#" > + <head> + <variable name="a"/> + </head> + <results> + <result> + <binding name="a"><uri>http://www.bigdata.com/d</uri></binding> + </result> + </results> +</sparql> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2014-07-09 19:02:42
|
Revision: 8528 http://sourceforge.net/p/bigdata/code/8528 Author: jeremy_carroll Date: 2014-07-09 19:02:33 +0000 (Wed, 09 Jul 2014) Log Message: ----------- Additional test for trac 988 including a bound variable as well as free variables in the EXIST clause Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.rq branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.srx Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-09 15:22:24 UTC (rev 8527) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-09 19:02:33 UTC (rev 8528) @@ -876,5 +876,49 @@ } } - + + /** + * Performance related test for EXISTS. + * + * <pre> + * prefix eg: <eg:> + * SELET DISTINCT ?a + * FROM eg:g + * { ?a eg:p ?c + * FILTER EXISTS { + * ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b + * } + * } + * + * <pre> + * + * @throws Exception + * + * @see <a href="http://trac.bigdata.com/ticket/988"> bad + * performance for FILTER EXISTS </a> + */ + public void test_exists_988c() throws Exception { + + final long beginNanos = System.nanoTime(); + + new TestHelper( + "exists-988c", // testURI, + "exists-988c.rq",// queryFileURL + "exists-988.trig",// dataFileURL + "exists-988c.srx" // resultFileURL, +// false, // laxCardinality +// true // checkOrder + ).runTest(); + + final long elapsedNanos = System.nanoTime() - beginNanos; + + final long timeoutNanos = TimeUnit.MILLISECONDS.toNanos(1500); + + if (timeoutNanos < elapsedNanos) { + + fail("Timeout exceeded: Query hint not recognized?"); + + } + + } } Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.rq =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.rq (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.rq 2014-07-09 19:02:33 UTC (rev 8528) @@ -0,0 +1,11 @@ +prefix eg: <http://www.bigdata.com/> + +SELECT DISTINCT ?a +FROM eg:g +{ ?a eg:p ?c + FILTER EXISTS { + ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b . + # Note: Query hint specifies sub-query LIMIT ONE plan. + hint:SubQuery hint:filterExists "SubQueryLimitOne" . + } +} \ No newline at end of file Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.srx =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.srx (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988c.srx 2014-07-09 19:02:33 UTC (rev 8528) @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<sparql + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:xs="http://www.w3.org/2001/XMLSchema#" + xmlns="http://www.w3.org/2005/sparql-results#" > + <head> + <variable name="a"/> + </head> + <results> + <result> + <binding name="a"><uri>http://www.bigdata.com/a</uri></binding> + </result> + <result> + <binding name="a"><uri>http://www.bigdata.com/b</uri></binding> + </result> + <result> + <binding name="a"><uri>http://www.bigdata.com/c</uri></binding> + </result> + <result> + <binding name="a"><uri>http://www.bigdata.com/d</uri></binding> + </result> + <result> + <binding name="a"><uri>http://www.bigdata.com/e</uri></binding> + </result> + <result> + <binding name="a"><uri>http://www.bigdata.com/f</uri></binding> + </result> + </results> +</sparql> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-09 15:22:26
|
Revision: 8527 http://sourceforge.net/p/bigdata/code/8527 Author: thompsonbry Date: 2014-07-09 15:22:24 +0000 (Wed, 09 Jul 2014) Log Message: ----------- Potential fix for #983 (Concurrent insert data with boolean object causes IllegalArgumentException). This fix always sets the IV on TRUE and FALSE constants used by the BigdataValueFactoryImpl rather than having them be set dynamically during evaluate. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/model/BigdataValueFactoryImpl.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/model/BigdataValueFactoryImpl.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/model/BigdataValueFactoryImpl.java 2014-07-09 14:07:47 UTC (rev 8526) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/model/BigdataValueFactoryImpl.java 2014-07-09 15:22:24 UTC (rev 8527) @@ -36,7 +36,6 @@ import org.openrdf.model.BNode; import org.openrdf.model.Literal; import org.openrdf.model.Resource; -import org.openrdf.model.Statement; import org.openrdf.model.URI; import org.openrdf.model.Value; import org.openrdf.model.datatypes.XMLDatatypeUtil; @@ -44,6 +43,7 @@ import com.bigdata.cache.WeakValueCache; import com.bigdata.rdf.internal.IV; +import com.bigdata.rdf.internal.impl.literal.XSDBooleanIV; import com.bigdata.rdf.internal.impl.literal.XSDUnsignedByteIV; import com.bigdata.rdf.internal.impl.literal.XSDUnsignedIntIV; import com.bigdata.rdf.internal.impl.literal.XSDUnsignedLongIV; @@ -64,12 +64,12 @@ * @todo Consider a {@link WeakValueCache} to shortcut recently used statements? * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public class BigdataValueFactoryImpl implements BigdataValueFactory { private final String namespace; + @Override public String getNamespace() { return namespace; @@ -81,10 +81,18 @@ */ private BigdataValueFactoryImpl(final String namespace) { - this.namespace = namespace; - - xsdMap = getXSDMap(); + this.namespace = namespace; + + xsdMap = getXSDMap(); + /** + * Cache the IV on the BigdataValue for these boolean constants. + * + * @see <a href="http://trac.bigdata.com/ticket/983"> Concurrent insert + * data with boolean object causes IllegalArgumentException </a> + */ + TRUE.setIV(XSDBooleanIV.TRUE); + FALSE.setIV(XSDBooleanIV.FALSE); } /** @@ -182,6 +190,7 @@ */ // * @param namespace // * The namespace of the {@link LexiconRelation}. + @Override public void remove(/*final String namespace*/) { // if (namespace == null) @@ -197,6 +206,7 @@ } + @Override public BNodeContextFactory newBNodeContext() { return new BNodeContextFactory(this); @@ -215,6 +225,7 @@ * * @see #newBNodeContext() */ + @Override public BigdataBNodeImpl createBNode() { return createBNode(nextID()); @@ -230,18 +241,21 @@ } + @Override public BigdataBNodeImpl createBNode(final String id) { return new BigdataBNodeImpl(this, id); } + @Override public BigdataBNodeImpl createBNode(final BigdataStatement stmt) { return new BigdataBNodeImpl(this, nextID(), stmt); } + @Override public BigdataLiteralImpl createLiteral(final String label) { return new BigdataLiteralImpl(this, label, null, null); @@ -331,72 +345,84 @@ } + @Override public BigdataLiteralImpl createLiteral(boolean arg0) { return (arg0 ? TRUE : FALSE); } + @Override public BigdataLiteralImpl createLiteral(byte arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_byte); } + @Override public BigdataLiteralImpl createLiteral(byte arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedByteIV.promote(arg0) : arg0), null, unsigned ? xsd_ubyte : xsd_byte); } + @Override public BigdataLiteralImpl createLiteral(short arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_short); } + @Override public BigdataLiteralImpl createLiteral(short arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedShortIV.promote(arg0) : arg0), null, unsigned ? xsd_ushort :xsd_short); } + @Override public BigdataLiteralImpl createLiteral(int arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_int); } + @Override public BigdataLiteralImpl createLiteral(int arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedIntIV.promote(arg0) : arg0), null, unsigned ? xsd_uint :xsd_int); } + @Override public BigdataLiteralImpl createLiteral(long arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_long); } + @Override public BigdataLiteralImpl createLiteral(long arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedLongIV.promote(arg0) : arg0), null, unsigned ? xsd_ulong : xsd_long); } + @Override public BigdataLiteralImpl createLiteral(float arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_float); } + @Override public BigdataLiteralImpl createLiteral(double arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_double); } + @Override public BigdataLiteralImpl createLiteral(final XMLGregorianCalendar arg0) { /* @@ -411,12 +437,14 @@ } + @Override public BigdataLiteralImpl createLiteral(final String label, final String language) { return new BigdataLiteralImpl(this, label, language, null/* datatype */); } + @Override public BigdataLiteralImpl createLiteral(final String label, URI datatype) { /* @@ -435,6 +463,7 @@ } + @Override public BigdataURIImpl createURI(final String uriString) { final String str = uriString; @@ -456,18 +485,21 @@ } + @Override public BigdataURIImpl createURI(final String namespace, final String localName) { return new BigdataURIImpl(this, namespace + localName); } + @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o) { return createStatement(s, p, o, null/* c */, null/* type */); } + @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o, Resource c) { @@ -475,6 +507,7 @@ } + @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o, Resource c, StatementEnum type) { @@ -482,6 +515,7 @@ } + @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o, Resource c, StatementEnum type, final boolean userFlag) { @@ -496,6 +530,7 @@ } + @Override final public BigdataValue asValue(final Value v) { if (v == null) @@ -566,30 +601,35 @@ private final transient BigdataValueSerializer<BigdataValue> valueSer = new BigdataValueSerializer<BigdataValue>( this); + @Override public BigdataValueSerializer<BigdataValue> getValueSerializer() { return valueSer; } + @Override public BigdataResource asValue(Resource v) { return (BigdataResource) asValue((Value) v); } + @Override public BigdataURI asValue(URI v) { return (BigdataURI)asValue((Value)v); } + @Override public BigdataLiteral asValue(Literal v) { return (BigdataLiteral)asValue((Value)v); } + @Override public BigdataBNode asValue(BNode v) { return (BigdataBNode)asValue((Value)v); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-09 14:07:59
|
Revision: 8526 http://sourceforge.net/p/bigdata/code/8526 Author: thompsonbry Date: 2014-07-09 14:07:47 +0000 (Wed, 09 Jul 2014) Log Message: ----------- Added query hint "filterExists" to control the behavior. The default is still the VectoredSubPlan. You can specify the SubQueryLimitOne behavior like this: {{{ prefix eg: <http://www.bigdata.com/> SELECT ?t FROM eg:g { BIND (1 as ?t) FILTER EXISTS { ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b . hint:SubQuery hint:filterExists "SubQueryLimitOne" . # <<< OVERRIDE THE DEFAULT BEHAVIOR. } }}}} The unit test now verifies that the execution time is within target in order to verify that the query hint was correctly interpreted. I had to modify the ASTQueryHintOptimizer to flow the QueryRoot into the IQueryHint handler method. This caused all of the IQueryHint implementations to be touched. I also had to expose the method on StaticAnalysis to locate the FILTER for a join group by entering in through the QueryRoot. I fixed the problem where the ASTQueryHintOptimizer was not interpreting query hints in a FILTER. I have not tried to introduce the DISTINCT SOLUTIONS into the VectoredSubPlan. The core AST evaluation test suite is green. See #988 (FILTER (NOT) EXISTS optimization) See #990 (Query hint not recognized in FILTER) Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterNode.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/GroupMemberNodeBase.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/QueryHints.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/StaticAnalysis.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryFunctionNodeBase.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryRoot.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpContext.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AbstractChunkSizeHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathSampleLimitHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathScanAndFilterHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AnalyticQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AtOnceHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicBooleanQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicDoubleQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicIntQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicLongQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicStringQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BufferChunkOfChunksCapacityHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/CutoffLimitHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeIterationLimitHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeModeHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeStatementLimitHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/HashJoinHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/IQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/KeyOrderHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/MergeJoinHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOThresholdHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeHashJoinsHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimisticQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimizerQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxMessagesPerTaskHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxParallelHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineQueueCapacityHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryHintRegistry.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryIdHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTOLimitQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTONEdgesQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTOSampleTypeQueryHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RangeHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RemoteAPHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RunFirstHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RunLastHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RunOnceHint.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/optimizers/ASTExistsOptimizer.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/optimizers/ASTQueryHintOptimizer.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.rq Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterExistsModeEnum.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/FilterExistsHint.java Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterExistsModeEnum.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterExistsModeEnum.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterExistsModeEnum.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -0,0 +1,71 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Aug 28, 2012 + */ +package com.bigdata.rdf.sparql.ast; + +import com.bigdata.bop.controller.SubqueryOp; + +/** + * Used to specify the query plan for FILTER (NOT) EXISTS. There are two basic + * plans: vectored sub-plan and subquery with LIMIT ONE. Each plan has its + * advantages. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance for FILTER + * EXISTS </a> + */ +public enum FilterExistsModeEnum { + + /** + * This evaluation mode builds a hash index from all source solutions, + * vectors the solutions from the hash index into the sub-plan, and the does + * a hash join of the sub-plan with the hash index to determine which + * solutions pass the filter. + * <p> + * This plan solves the FILTER (NOT) EXISTS for multiple source solutions at + * the same time (vectoring). It is more efficient if the sub-plan requires + * relatively little work per solution to fully evaluate the sub-plan and + * there are a large number of solutions flowing into the FILTER (NOT) + * EXISTS. + */ + VectoredSubPlan, + + /** + * This evaluation mode routes each source solution (one by one) into a + * separate {@link SubqueryOp subquery} and imposes a LIMIT ONE. + * <p> + * This plan is more efficient if there are many solutions to the FILTER for + * each source solution, if it is relatively expensive to find all such + * solutions, and if there are relatively few source solutions. Under these + * conditions, the FILTER (NOT) EXISTS sub-query is cutoff once it finds the + * first solution to each source solution and the overhead of submitting + * multiple sub-queries is modest because there are not that many source + * solution that need to flow into the FILTER. + */ + SubQueryLimitOne; + +} Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterNode.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterNode.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/FilterNode.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -74,6 +74,7 @@ } + @Override public IValueExpressionNode getValueExpressionNode() { return (IValueExpressionNode) get(0); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/GroupMemberNodeBase.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/GroupMemberNodeBase.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/GroupMemberNodeBase.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,14 +30,11 @@ import java.util.Map; import com.bigdata.bop.BOp; -import com.bigdata.bop.ModifiableBOpBase; /** * Anything which can appear in an {@link IGroupNode}. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id: GroupMemberNodeBase.java 5174 2011-09-11 20:18:18Z thompsonbry - * $ */ abstract public class GroupMemberNodeBase<E extends IGroupMemberNode> extends QueryNodeBase implements IGroupMemberNode { @@ -50,12 +47,14 @@ private IGroupNode<IGroupMemberNode> parent; + @Override final public IGroupNode<IGroupMemberNode> getParent() { return parent; } + @Override final public void setParent(final IGroupNode<IGroupMemberNode> parent) { this.parent = parent; @@ -83,6 +82,7 @@ } + @Override public TermNode getContext() { final IQueryNode parent = getParent(); @@ -104,6 +104,7 @@ } + @Override public JoinGroupNode getParentJoinGroup() { IGroupNode<?> parent = getParent(); @@ -121,6 +122,7 @@ } + @Override @SuppressWarnings("unchecked") public GraphPatternGroup<IGroupMemberNode> getParentGraphPatternGroup() { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/QueryHints.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/QueryHints.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/QueryHints.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -56,7 +56,6 @@ * @see QueryHintRegistry * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ * * @see <a href="http://sourceforge.net/apps/trac/bigdata/ticket/791" > Clean up * query hints </a> @@ -550,5 +549,22 @@ * @see Annotations#CUTOFF_LIMIT */ String CUTOFF_LIMIT = "cutoffLimit"; - + + /** + * Used to specify the query plan for FILTER (NOT) EXISTS. There are two + * basic plans: vectored sub-plan and subquery with LIMIT ONE. Each plan has + * its advantages. + * + * @see FilterExistsModeEnum + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance for + * FILTER EXISTS </a> + */ + String FILTER_EXISTS = "filterExists"; + + /** + * Note: The historical behavior up through bigdata release 1.3.1 is + * {@link FilterExistsModeEnum#VectoredSubPlan}. + */ + FilterExistsModeEnum DEFAULT_FILTER_EXISTS = FilterExistsModeEnum.VectoredSubPlan; + } \ No newline at end of file Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/StaticAnalysis.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/StaticAnalysis.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/StaticAnalysis.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -322,6 +322,13 @@ */ public IQueryNode findParent(final GraphPatternGroup<?> group) { + return findParent(queryRoot, group); + + } + + public static IQueryNode findParent(final QueryRoot queryRoot, + final GraphPatternGroup<?> group) { + if (group == null) throw new IllegalArgumentException(); @@ -399,7 +406,7 @@ * @return The {@link QueryBase}, {@link ServiceNode}, or {@link FilterNode} * which is the "parent" of <i>theGroup</i>. */ - private IQueryNode findParent2( + static public IQueryNode findParent2( final GraphPatternGroup<IGroupMemberNode> aGroup, final GraphPatternGroup<?> theGroup) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryFunctionNodeBase.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryFunctionNodeBase.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryFunctionNodeBase.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -32,7 +32,7 @@ import org.openrdf.model.URI; import com.bigdata.bop.BOp; -import com.bigdata.bop.IValueExpression; +import com.bigdata.rdf.sparql.ast.SubqueryRoot.Annotations; /** * A special function node for modeling value expression nodes which are @@ -41,7 +41,6 @@ * subquery result. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ abstract public class SubqueryFunctionNodeBase extends FunctionNode implements IGraphPatternContainer { @@ -53,6 +52,22 @@ interface Annotations extends FunctionNode.Annotations, IGraphPatternContainer.Annotations { + + /** + * Used to specify the query plan for FILTER (NOT) EXISTS. There are two + * basic plans: vectored sub-plan and subquery with LIMIT ONE. Each plan + * has its advantages. + * <p> + * Note: This annotation gets propagated to the {@link SubqueryRoot} + * when the FILTER (NOT) EXISTS is turned into an ASK subquery. + * + * @see FilterExistsModeEnum + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance + * for FILTER EXISTS </a> + */ + String FILTER_EXISTS = QueryHints.FILTER_EXISTS; + + FilterExistsModeEnum DEFAULT_FILTER_EXISTS = QueryHints.DEFAULT_FILTER_EXISTS; } @@ -96,6 +111,7 @@ } + @Override @SuppressWarnings("unchecked") public GraphPatternGroup<IGroupMemberNode> getGraphPattern() { @@ -103,6 +119,7 @@ } + @Override public void setGraphPattern( final GraphPatternGroup<IGroupMemberNode> graphPattern) { @@ -120,9 +137,31 @@ } + /** + * + * @see Annotations#FILTER_EXISTS + */ + public void setFilterExistsMode(final FilterExistsModeEnum newVal) { + + setProperty(Annotations.FILTER_EXISTS, newVal); + + } + + /** + * @see Annotations#FILTER_EXISTS + */ + public FilterExistsModeEnum getFilterExistsMode() { + + return getProperty(Annotations.FILTER_EXISTS, + Annotations.DEFAULT_FILTER_EXISTS); + + } + @Override protected void annotationValueToString(final StringBuilder sb, final BOp val, int i) { - sb.append(val.toString(i)); + + sb.append(val.toString(i)); + } } Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryRoot.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryRoot.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/SubqueryRoot.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.bop.BOp; import com.bigdata.bop.IVariable; +import com.bigdata.rdf.sparql.ast.SubqueryFunctionNodeBase.Annotations; import com.bigdata.rdf.sparql.ast.optimizers.ASTSparql11SubqueryOptimizer; /** @@ -60,6 +61,24 @@ */ String ASK_VAR = "askVar"; + /** + * Used to specify the query plan for FILTER (NOT) EXISTS. There are two + * basic plans: vectored sub-plan and subquery with LIMIT ONE. Each plan + * has its advantages. + * <p> + * Note: This annotation is propagated to the {@link SubqueryRoot} when + * the FILTER (NOT) EXISTS for a {@link SubqueryFunctionNodeBase} is + * turned into an ASK subquery. + * + * @see SubqueryFunctionNodeBase + * @see FilterExistsModeEnum + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance + * for FILTER EXISTS </a> + */ + String FILTER_EXISTS = QueryHints.FILTER_EXISTS; + + FilterExistsModeEnum DEFAULT_FILTER_EXISTS = QueryHints.DEFAULT_FILTER_EXISTS; + } /** @@ -136,6 +155,26 @@ } /** + * + * @see Annotations#FILTER_EXISTS + */ + public void setFilterExistsMode(final FilterExistsModeEnum newVal) { + + setProperty(Annotations.FILTER_EXISTS, newVal); + + } + + /** + * @see Annotations#FILTER_EXISTS + */ + public FilterExistsModeEnum getFilterExistsMode() { + + return getProperty(Annotations.FILTER_EXISTS, + Annotations.DEFAULT_FILTER_EXISTS); + + } + + /** * Returns <code>false</code>. */ @Override Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpContext.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpContext.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpContext.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -325,6 +325,9 @@ /** * Static analysis object initialized once we apply the AST optimizers and * used by {@link AST2BOpUtility}. + * <p> + * Note: This is not initialized earlier since it holds a reference to the + * optimized AST. */ StaticAnalysis sa = null; Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -103,6 +103,7 @@ import com.bigdata.rdf.sparql.ast.ComputedMaterializationRequirement; import com.bigdata.rdf.sparql.ast.ConstantNode; import com.bigdata.rdf.sparql.ast.DatasetNode; +import com.bigdata.rdf.sparql.ast.FilterExistsModeEnum; import com.bigdata.rdf.sparql.ast.FilterNode; import com.bigdata.rdf.sparql.ast.FunctionNode; import com.bigdata.rdf.sparql.ast.FunctionRegistry; @@ -1839,12 +1840,19 @@ final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, final AST2BOpContext ctx) { - if (true) { // TODO Add query hint to allow choice of strategy. + final FilterExistsModeEnum filterExistsMode = subqueryRoot + .getFilterExistsMode(); + + switch (filterExistsMode) { + case VectoredSubPlan: // Vectored sub-plan evaluation. return addExistsSubqueryFast(left, subqueryRoot, doneSet, ctx); - } else { + case SubQueryLimitOne: // Non-vectored sub-query evaluation. return addExistsSubquerySubquery(left, subqueryRoot, doneSet, ctx); + default: + throw new UnsupportedOperationException(QueryHints.FILTER_EXISTS + + "=" + filterExistsMode); } } Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AbstractChunkSizeHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AbstractChunkSizeHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AbstractChunkSizeHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.bop.BufferAnnotations; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.IQueryNode; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -47,7 +48,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { if (op instanceof IQueryNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathSampleLimitHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathSampleLimitHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathSampleLimitHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.bop.IPredicate; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.StatementPatternNode; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; @@ -53,7 +54,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { if (op instanceof StatementPatternNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathScanAndFilterHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathScanAndFilterHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AccessPathScanAndFilterHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.StatementPatternNode; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; @@ -46,7 +47,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (op instanceof StatementPatternNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AnalyticQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AnalyticQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AnalyticQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -34,6 +34,7 @@ import com.bigdata.htree.HTree; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -56,7 +57,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { switch (scope) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AtOnceHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AtOnceHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/AtOnceHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -32,6 +32,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.IQueryNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -57,7 +58,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (op instanceof IQueryNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicBooleanQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicBooleanQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicBooleanQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -28,6 +28,7 @@ package com.bigdata.rdf.sparql.ast.hints; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -40,7 +41,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { _setQueryHint(context, scope, op, getName(), value); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicDoubleQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicDoubleQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicDoubleQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -28,6 +28,7 @@ package com.bigdata.rdf.sparql.ast.hints; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -40,7 +41,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Double value) { _setQueryHint(context, scope, op, getName(), value); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicIntQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicIntQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicIntQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -28,6 +28,7 @@ package com.bigdata.rdf.sparql.ast.hints; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -40,7 +41,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { _setQueryHint(context, scope, op, getName(), value); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicLongQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicLongQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicLongQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -28,6 +28,7 @@ package com.bigdata.rdf.sparql.ast.hints; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -40,7 +41,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Long value) { _setQueryHint(context, scope, op, getName(), value); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicStringQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicStringQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BasicStringQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -28,6 +28,7 @@ package com.bigdata.rdf.sparql.ast.hints; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -40,7 +41,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final String value) { _setQueryHint(context, scope, op, getName(), value); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BufferChunkOfChunksCapacityHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BufferChunkOfChunksCapacityHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/BufferChunkOfChunksCapacityHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.bop.BufferAnnotations; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.IQueryNode; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -48,7 +49,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { if (op instanceof IQueryNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/CutoffLimitHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/CutoffLimitHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/CutoffLimitHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.StatementPatternNode; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; @@ -44,9 +45,8 @@ } @Override - public void handle(final AST2BOpContext context, - final QueryHintScope scope, final ASTBase op, - final Long value) { + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, + final QueryHintScope scope, final ASTBase op, final Long value) { if (op instanceof StatementPatternNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeIterationLimitHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeIterationLimitHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeIterationLimitHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.ProjectionNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -49,6 +50,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeModeHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeModeHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeModeHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -31,6 +31,7 @@ import com.bigdata.rdf.sparql.ast.DescribeModeEnum; import com.bigdata.rdf.sparql.ast.ProjectionNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -50,6 +51,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final DescribeModeEnum value) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeStatementLimitHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeStatementLimitHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/DescribeStatementLimitHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.ProjectionNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -49,6 +50,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/FilterExistsHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/FilterExistsHint.java (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/FilterExistsHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -0,0 +1,103 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Nov 27, 2011 + */ + +package com.bigdata.rdf.sparql.ast.hints; + +import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.FilterExistsModeEnum; +import com.bigdata.rdf.sparql.ast.FilterNode; +import com.bigdata.rdf.sparql.ast.IQueryNode; +import com.bigdata.rdf.sparql.ast.IValueExpressionNode; +import com.bigdata.rdf.sparql.ast.JoinGroupNode; +import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; +import com.bigdata.rdf.sparql.ast.StaticAnalysis; +import com.bigdata.rdf.sparql.ast.SubqueryFunctionNodeBase; +import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; + +/** + * Used to specify the query plan for FILTER (NOT) EXISTS. There are two basic + * plans: vectored sub-plan and subquery with LIMIT ONE. Each plan has its + * advantages. + * + * @see FilterExistsModeEnum + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance for FILTER + * EXISTS </a> + */ +final class FilterExistsHint extends AbstractQueryHint<FilterExistsModeEnum> { + + protected FilterExistsHint() { + super(QueryHints.FILTER_EXISTS, + QueryHints.DEFAULT_FILTER_EXISTS); + } + + @Override + public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, + final QueryHintScope scope, final ASTBase op, + final FilterExistsModeEnum value) { + + if (op instanceof JoinGroupNode + && ((JoinGroupNode) op).getParent() == null) { + /* + * This is the top-level join group inside of the FILTER. It does + * not have a direct parent. We resolve the parent ExistsNode or + * NotExistsNode by searching from the top-level query root. + */ + + final JoinGroupNode filterGroup = (JoinGroupNode) op; + + final IQueryNode p = StaticAnalysis.findParent(queryRoot, + filterGroup); + + if (p instanceof FilterNode) { + + final IValueExpressionNode n = ((FilterNode) p) + .getValueExpressionNode(); + + if (n instanceof SubqueryFunctionNodeBase) { + + ((SubqueryFunctionNodeBase) n).setFilterExistsMode(value); + + } + + } + +// _setAnnotation(context, scope, op, getName(), value); + + } + + } + + @Override + public FilterExistsModeEnum validate(final String value) { + + return FilterExistsModeEnum.valueOf(value); + + } + +} \ No newline at end of file Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/HashJoinHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/HashJoinHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/HashJoinHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.StatementPatternNode; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; @@ -44,6 +45,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (op instanceof StatementPatternNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/IQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/IQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/IQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -28,6 +28,7 @@ package com.bigdata.rdf.sparql.ast.hints; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -79,13 +80,22 @@ * * @param ctx * The query evaluation context. + * @param queryRoot + * The root of the query. This is required to resolve the parent + * of a query hint inside of a FILTER. * @param scope * The {@link QueryHintScope} specified for the query hint. * @param op * An AST node to which the hint should bind. * @param value * The value specified for the query hint. + * + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance for + * FILTER EXISTS </a> + * @see <a href="http://trac.bigdata.com/ticket/990"> Query hint not + * recognized in FILTER</a> */ - void handle(AST2BOpContext ctx, QueryHintScope scope, ASTBase op, T value); + void handle(AST2BOpContext ctx, QueryRoot queryRoot, QueryHintScope scope, + ASTBase op, T value); } Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/KeyOrderHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/KeyOrderHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/KeyOrderHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.bop.IPredicate; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.StatementPatternNode; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; import com.bigdata.rdf.spo.SPOKeyOrder; @@ -45,6 +46,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final SPOKeyOrder value) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/MergeJoinHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/MergeJoinHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/MergeJoinHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -42,6 +43,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (scope == QueryHintScope.Query) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -31,6 +31,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -57,7 +58,7 @@ } @Override - public void handle(final AST2BOpContext context, + public void handle(final AST2BOpContext context, final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (scope == QueryHintScope.Query) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.bop.rdf.filter.NativeDistinctFilter; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -44,6 +45,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (scope == QueryHintScope.Query) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOThresholdHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOThresholdHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeDistinctSPOThresholdHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.bop.rdf.filter.NativeDistinctFilter; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -44,6 +45,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Long value) { if (scope == QueryHintScope.Query) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeHashJoinsHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeHashJoinsHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/NativeHashJoinsHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.htree.HTree; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -45,6 +46,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Boolean value) { if (scope == QueryHintScope.Query) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimisticQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimisticQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimisticQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.JoinGroupNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; import com.bigdata.rdf.sparql.ast.optimizers.ASTStaticJoinOptimizer; @@ -45,6 +46,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Double value) { if (op instanceof JoinGroupNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimizerQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimizerQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/OptimizerQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -31,6 +31,7 @@ import com.bigdata.rdf.sparql.ast.JoinGroupNode; import com.bigdata.rdf.sparql.ast.QueryHints; import com.bigdata.rdf.sparql.ast.QueryOptimizerEnum; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -51,7 +52,9 @@ } @Override - public void handle(final AST2BOpContext ctx, final QueryHintScope scope, + public void handle(final AST2BOpContext ctx, + final QueryRoot queryRoot, + final QueryHintScope scope, final ASTBase op, final QueryOptimizerEnum value) { switch (scope) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxMessagesPerTaskHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxMessagesPerTaskHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxMessagesPerTaskHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -29,6 +29,7 @@ import com.bigdata.bop.PipelineOp; import com.bigdata.rdf.sparql.ast.ASTBase; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.StatementPatternNode; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; @@ -47,6 +48,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { if (op instanceof StatementPatternNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxParallelHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxParallelHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineMaxParallelHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -31,6 +31,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.IJoinNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -56,6 +57,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { if (op instanceof IJoinNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineQueueCapacityHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineQueueCapacityHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/PipelineQueueCapacityHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -30,6 +30,7 @@ import com.bigdata.bop.PipelineOp; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.IQueryNode; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -49,6 +50,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final Integer value) { if (op instanceof IQueryNode) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryHintRegistry.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryHintRegistry.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryHintRegistry.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -41,7 +41,6 @@ * {@link IHashJoinUtility} implementation classes). * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public class QueryHintRegistry { @@ -94,6 +93,7 @@ add(new QueryIdHint()); + // Optimizer hints. add(new RunFirstHint()); add(new RunLastHint()); add(new RunOnceHint()); @@ -103,17 +103,22 @@ add(new RTONEdgesQueryHint()); add(new OptimisticQueryHint()); + // Analytic query mode. add(new AnalyticQueryHint()); add(new NativeDistinctQueryHint()); add(new NativeDistinctSPOHint()); add(new NativeDistinctSPOThresholdHint()); add(new NativeHashJoinsHint()); + + // JOIN hints. add(new MergeJoinHint()); add(new HashJoinHint()); add(new KeyOrderHint()); add(new RemoteAPHint()); add(new AccessPathSampleLimitHint()); add(new AccessPathScanAndFilterHint()); + + // DESCRIBE add(new DescribeModeHint()); add(new DescribeIterationLimitHint()); add(new DescribeStatementLimitHint()); @@ -157,6 +162,11 @@ */ add(new CutoffLimitHint()); + /** + * FILTER (NOT) EXISTS evaluation strategy hint. + */ + add(new FilterExistsHint()); + } } Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryIdHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryIdHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/QueryIdHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -65,6 +65,7 @@ @Override public void handle(final AST2BOpContext context, + final QueryRoot queryRoot, final QueryHintScope scope, final ASTBase op, final UUID value) { /* Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTOLimitQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTOLimitQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTOLimitQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -31,6 +31,7 @@ import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.JoinGroupNode; import com.bigdata.rdf.sparql.ast.QueryHints; +import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext; /** @@ -59,7 +60,9 @@ } @Override - public void handle(final AST2BOpContext ctx, final QueryHintScope scope, + public void handle(final AST2BOpContext ctx, + final QueryRoot queryRoot, + final QueryHintScope scope, final ASTBase op, final Integer value) { switch (scope) { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTONEdgesQueryHint.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTONEdgesQueryHint.java 2014-07-08 21:25:15 UTC (rev 8525) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/hints/RTONEdgesQueryHint.java 2014-07-09 14:07:47 UTC (rev 8526) @@ -31,6 +3... [truncated message content] |
From: <tho...@us...> - 2014-07-08 21:25:23
|
Revision: 8525 http://sourceforge.net/p/bigdata/code/8525 Author: thompsonbry Date: 2014-07-08 21:25:15 +0000 (Tue, 08 Jul 2014) Log Message: ----------- Bug fixes to the test suite for #988. I spoke with Jeremy and am now able to replicate the observed performance issue. I have also verified that changing from the vectored sub-plan to the subquery LIMIT ONE approach fixes the performance problem for this query. The next step is to create a query hint to direct the query plan generator to use the appropriate plan. After that we can figure out if we can make the right decision automatically and also take a look at using DISTINCT over the variables in the FILTER in the vectored sub-plan to accelerate that code path. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig 2014-07-08 13:52:46 UTC (rev 8524) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig 2014-07-08 21:25:15 UTC (rev 8525) @@ -1,6 +1,6 @@ @prefix eg: <http://www.bigdata.com/> . -eg: { +eg:g { eg:a eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . eg:b eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . eg:c eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx 2014-07-08 13:52:46 UTC (rev 8524) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx 2014-07-08 21:25:15 UTC (rev 8525) @@ -2,5 +2,5 @@ <sparql xmlns="http://www.w3.org/2005/sparql-results#"> <head> </head> - <boolean>false</boolean> + <boolean>true</boolean> </sparql> Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx 2014-07-08 13:52:46 UTC (rev 8524) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx 2014-07-08 21:25:15 UTC (rev 8525) @@ -7,5 +7,10 @@ <variable name="t"/> </head> <results> + <result> + <binding name="t"> + <literal datatype="http://www.w3.org/2001/XMLSchema#integer">1</literal> + </binding> + </result> </results> </sparql> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-08 13:52:51
|
Revision: 8524 http://sourceforge.net/p/bigdata/code/8524 Author: thompsonbry Date: 2014-07-08 13:52:46 +0000 (Tue, 08 Jul 2014) Log Message: ----------- See #988 (EXISTS is slow) As indicated off-list, we have existing code paths that support a non-vectored subquery per source solution for (NOT) EXISTS using the SubqueryOp. I have reenabled this code and verified that it passes the test suite (except for one detailed check of the physical operator plan that is generated for NOT EXISTS). I have also added a LIMIT ONE when using the sub-query version. However, I observe that the run time for the test described above is a constant .18 seconds regardless of which code path is used. In neither case do I observe the slow performance described on this ticket of 5 seconds. That is, the test case does not demonstrate the performance problem. Please check the committed test cases in TestNegation.java. See the test_exists_988a() and test_exists_988b() methods at the end of that file. The sub-query plan is currently OFF {{{ private static PipelineOp addExistsSubquery(PipelineOp left, final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, final AST2BOpContext ctx) { if (true) { // Vectored sub-plan evaluation. return addExistsSubqueryFast(left, subqueryRoot, doneSet, ctx); } else { // Non-vectored sub-query evaluation. return addExistsSubquerySubquery(left, subqueryRoot, doneSet, ctx); } } }}} I have not tested the use of a DISTINCT solutions operator in the sub-plan, but I have marked the code for where that operator should be introduced. {{{ * FIXME EXISTS: Try DISTINCT in the sub-plan and compare to correctness * without for (NOT) EXISTS and to performance of the non-vectored code * path for EXISTS> }}} Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryJoinAnnotations.java branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryOp.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNamedGraphs.java branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java Added Paths: ----------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.rq branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.rq branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryJoinAnnotations.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryJoinAnnotations.java 2014-07-03 17:48:19 UTC (rev 8523) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryJoinAnnotations.java 2014-07-08 13:52:46 UTC (rev 8524) @@ -33,11 +33,6 @@ * Annotations for joins against a subquery. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id: SubqueryJoinAnnotations.java 5491 2011-11-02 20:11:07Z - * thompsonbry $ - * - * @deprecated With {@link SubqueryOp}, which is the sole class which extends - * this interface. */ public interface SubqueryJoinAnnotations extends JoinAnnotations, SubqueryAnnotations { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryOp.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryOp.java 2014-07-03 17:48:19 UTC (rev 8523) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/bop/controller/SubqueryOp.java 2014-07-08 13:52:46 UTC (rev 8524) @@ -92,20 +92,28 @@ * evaluation semantics under these conditions. This is handled by "projecting" * only those variables into the subquery which it will project out. * + * <h3>Efficiency</h3> + * + * This non-vectored operator issues one sub-query per source solution flowing + * into the operator. In general, it is MUCH more efficient to vector the + * solutions into a sub-plan. The latter is accomplished by building a hash + * index over the source solutions, flooding them into the sub-plan, and then + * executing the appropriate hash join back against the source solutions after + * the sub-plan. + * <p> + * There are a few cases where it may make sense to use the non-vectored + * operator. For example, for EXISTS where LIMIT ONE can be imposed on the + * subquery. However, there can still be cases where the vectored sub-plan is + * more efficient. + * * @see AbstractSubqueryOp * @see JVMNamedSubqueryOp * @see HTreeNamedSubqueryOp * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * - * @deprecated This operator is no longer in use. The last use case which we had - * for this was in support of ASK subquery evaluation for (NOT) - * EXISTS. - * <p> - * It is possible that another use case MIGHT be found to support - * parallel evaluation of named subqueries. However, that also might - * be handled by a thread pool if we move to interleaved query plan - * generation and query plan evaluation in support of the RTO. + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance for FILTER + * EXISTS </a> */ public class SubqueryOp extends PipelineOp { @@ -222,6 +230,7 @@ } + @Override public FutureTask<Void> eval(final BOpContext<IBindingSet> context) { return new FutureTask<Void>(new ControllerTask(this, context)); @@ -287,6 +296,7 @@ /** * Evaluate the subquery. */ + @Override public Void call() throws Exception { try { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java 2014-07-03 17:48:19 UTC (rev 8523) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/sparql/ast/eval/AST2BOpUtility.java 2014-07-08 13:52:46 UTC (rev 8524) @@ -47,6 +47,7 @@ import com.bigdata.bop.controller.NamedSetAnnotations; import com.bigdata.bop.controller.ServiceCallJoin; import com.bigdata.bop.controller.Steps; +import com.bigdata.bop.controller.SubqueryOp; import com.bigdata.bop.controller.Union; import com.bigdata.bop.engine.QueryEngine; import com.bigdata.bop.join.HTreeHashIndexOp; @@ -159,7 +160,6 @@ * {@link PipelineOp}s. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ * * @see <a href= * "https://sourceforge.net/apps/mediawiki/bigdata/index.php?title=QueryEvaluation" @@ -1831,24 +1831,37 @@ * @see <a href="https://sourceforge.net/apps/trac/bigdata/ticket/515"> * Query with two "FILTER NOT EXISTS" expressions returns no * results</a> + * @see <a href="http://trac.bigdata.com/ticket/988"> bad performance for + * FILTER EXISTS </a> * @see http://www.w3.org/2009/sparql/wiki/Design:Negation */ private static PipelineOp addExistsSubquery(PipelineOp left, final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, final AST2BOpContext ctx) { -// if (true) { -// return addExistsSubqueryFast(left, subqueryRoot, doneSet, ctx); -// } else { -// return addExistsSubquerySubquery(left, subqueryRoot, doneSet, ctx); -// } -// -// } -// -// private static PipelineOp addExistsSubqueryFast(PipelineOp left, -// final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, -// final AST2BOpContext ctx) { + if (true) { // TODO Add query hint to allow choice of strategy. + // Vectored sub-plan evaluation. + return addExistsSubqueryFast(left, subqueryRoot, doneSet, ctx); + } else { + // Non-vectored sub-query evaluation. + return addExistsSubquerySubquery(left, subqueryRoot, doneSet, ctx); + } + + } + /** + * (NOT) EXISTS code path using a vectored sub-plan. + * + * @param left + * @param subqueryRoot + * @param doneSet + * @param ctx + * @return + */ + private static PipelineOp addExistsSubqueryFast(PipelineOp left, + final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, + final AST2BOpContext ctx) { + // Only Sub-Select is supported by this code path. switch (subqueryRoot.getQueryType()) { case ASK: @@ -1973,6 +1986,12 @@ // new NV(ProjectionOp.Annotations.SELECT, projectedVars)// // ); + /* + * FIXME EXISTS: Try DISTINCT in the sub-plan and compare to correctness + * without for (NOT) EXISTS and to performance of the non-vectored code + * path for EXISTS> + */ + // Append the subquery plan. // left = convertQueryBase(left, subqueryRoot, doneSet, ctx); left = convertJoinGroupOrUnion(left, subqueryRoot.getWhereClause(), @@ -2027,66 +2046,80 @@ } -// /** -// * A slow implementation using one {@link SubqueryOp} per source solution. -// * -// * @deprecated by -// * {@link #addExistsSubqueryFast(PipelineOp, SubqueryRoot, Set, AST2BOpContext)} -// */ -// private static PipelineOp addExistsSubquerySubquery(PipelineOp left, -// final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, -// final AST2BOpContext ctx) { -// -// // Only "ASK" subqueries are allowed. -// switch (subqueryRoot.getQueryType()) { -// case ASK: -// break; -// default: -// throw new UnsupportedOperationException(); -// } -// -// @SuppressWarnings("rawtypes") -// final Map<IConstraint, Set<IVariable<IV>>> needsMaterialization = new LinkedHashMap<IConstraint, Set<IVariable<IV>>>(); -// -// final IConstraint[] joinConstraints = getJoinConstraints( -// getJoinConstraints(subqueryRoot), needsMaterialization); -// -// final boolean aggregate = StaticAnalysis.isAggregate(subqueryRoot); -// -// /* -// * The anonymous variable which gets bound based on the (NOT) EXISTS -// * graph pattern. -// */ -// final IVariable<?> askVar = subqueryRoot.getAskVar(); -// -// if (askVar == null) -// throw new UnsupportedOperationException(); -// -// final PipelineOp subqueryPlan = convertQueryBase(null/* left */, -// subqueryRoot, doneSet, ctx); -// -// left = new SubqueryOp(leftOrEmpty(left),// SUBQUERY -// new NV(Predicate.Annotations.BOP_ID, ctx.nextId()),// -// new NV(SubqueryOp.Annotations.SUBQUERY, subqueryPlan),// -// new NV(SubqueryOp.Annotations.JOIN_TYPE, JoinTypeEnum.Normal),// -// new NV(SubqueryOp.Annotations.ASK_VAR, askVar),// -// new NV(SubqueryOp.Annotations.SELECT, subqueryRoot.getProjection().getProjectionVars()),// -// new NV(SubqueryOp.Annotations.CONSTRAINTS, joinConstraints),// -// new NV(SubqueryOp.Annotations.IS_AGGREGATE, aggregate)// -// ); -// -// /* -// * For each filter which requires materialization steps, add the -// * materializations steps to the pipeline and then add the filter to the -// * pipeline. -// */ -// left = addMaterializationSteps(ctx, left, doneSet, -// needsMaterialization, subqueryRoot.getQueryHints()); -// -// return left; -// -// } + /** + * A non-vectored implementation for (NOT) EXISTS using one + * {@link SubqueryOp} per source solution. + */ + private static PipelineOp addExistsSubquerySubquery(PipelineOp left, + final SubqueryRoot subqueryRoot, final Set<IVariable<?>> doneSet, + final AST2BOpContext ctx) { + // Only "ASK" subqueries are allowed. + switch (subqueryRoot.getQueryType()) { + case ASK: + break; + default: + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("rawtypes") + final Map<IConstraint, Set<IVariable<IV>>> needsMaterialization = new LinkedHashMap<IConstraint, Set<IVariable<IV>>>(); + + final IConstraint[] joinConstraints = getJoinConstraints( + getJoinConstraints(subqueryRoot), needsMaterialization); + + final boolean aggregate = StaticAnalysis.isAggregate(subqueryRoot); + + /* + * The anonymous variable which gets bound based on the (NOT) EXISTS + * graph pattern. + */ + final IVariable<?> askVar = subqueryRoot.getAskVar(); + + if (askVar == null) + throw new UnsupportedOperationException(); + + /* + * Impose LIMIT ONE on the non-vectored sub-query. + * + * Note: This reduces the amount of work for the sub-query. + * + * For EXISTS, this means that we stop if we find at least one solution. + * The askVar becomes bound to true. The IConstraint associated with the + * EXISTS FILTER will therefore evaluate to true. + * + * For NOT EXISTS, this means that we stop if we find at least one + * solution. The askVar becomes bound to true (this is the same as for + * EXISTS). The IConstraint associated with the NOT EXISTS FILTER will + * therefore evaluate to false since it tests !askVar. + */ + subqueryRoot.setSlice(new SliceNode(0L/* offset */, 1L/* limit */)); + + final PipelineOp subqueryPlan = convertQueryBase(null/* left */, + subqueryRoot, doneSet, ctx); + + left = new SubqueryOp(leftOrEmpty(left),// SUBQUERY + new NV(Predicate.Annotations.BOP_ID, ctx.nextId()),// + new NV(SubqueryOp.Annotations.SUBQUERY, subqueryPlan),// + new NV(SubqueryOp.Annotations.JOIN_TYPE, JoinTypeEnum.Normal),// + new NV(SubqueryOp.Annotations.ASK_VAR, askVar),// + new NV(SubqueryOp.Annotations.SELECT, subqueryRoot.getProjection().getProjectionVars()),// + new NV(SubqueryOp.Annotations.CONSTRAINTS, joinConstraints),// + new NV(SubqueryOp.Annotations.IS_AGGREGATE, aggregate)// + ); + + /* + * For each filter which requires materialization steps, add the + * materializations steps to the pipeline and then add the filter to the + * pipeline. + */ + left = addMaterializationSteps3(left, doneSet, needsMaterialization, + subqueryRoot.getQueryHints(), ctx); + + return left; + + } + /** * Generate the query plan for a join group or union. This is invoked for * the top-level "WHERE" clause and may be invoked recursively for embedded Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNamedGraphs.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNamedGraphs.java 2014-07-03 17:48:19 UTC (rev 8523) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNamedGraphs.java 2014-07-08 13:52:46 UTC (rev 8524) @@ -35,7 +35,6 @@ * Test suite for named and default graph stuff. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public class TestNamedGraphs extends AbstractDataDrivenSPARQLTestCase { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-03 17:48:19 UTC (rev 8523) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/TestNegation.java 2014-07-08 13:52:46 UTC (rev 8524) @@ -32,8 +32,6 @@ import org.openrdf.model.vocabulary.RDF; -import com.bigdata.bop.IVariable; -import com.bigdata.bop.Var; import com.bigdata.rdf.model.BigdataURI; import com.bigdata.rdf.model.BigdataValue; import com.bigdata.rdf.model.BigdataValueFactory; @@ -59,7 +57,6 @@ * Test suite for SPARQL negation (EXISTS and MINUS). * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public class TestNegation extends AbstractDataDrivenSPARQLTestCase { @@ -798,4 +795,70 @@ } + /** + * Performance related test for EXISTS. This is NOT an EXISTS query. + * However, EXISTS is translated into an ASK sub-query. This runs the + * equivalent ASK query. + * + * <pre> + * prefix eg: <eg:> + * ASK + * FROM eg:g + * { BIND (1 as ?t) + * ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b + * } + * + * <pre> + * + * @throws Exception + * + * @see <a href="http://trac.bigdata.com/ticket/988"> bad + * performance for FILTER EXISTS </a> + */ + public void test_exists_988a() throws Exception { + + new TestHelper( + "exists-988a", // testURI, + "exists-988a.rq",// queryFileURL + "exists-988.trig",// dataFileURL + "exists-988a.srx" // resultFileURL, +// false, // laxCardinality +// true // checkOrder + ).runTest(); + + } + + /** + * Performance related test for EXISTS. + * + * <pre> + * prefix eg: <eg:> + * SELET * + * FROM eg:g + * { BIND (1 as ?t) + * FILTER EXISTS { + * ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b + * } + * } + * + * <pre> + * + * @throws Exception + * + * @see <a href="http://trac.bigdata.com/ticket/988"> bad + * performance for FILTER EXISTS </a> + */ + public void test_exists_988b() throws Exception { + + new TestHelper( + "exists-988b", // testURI, + "exists-988b.rq",// queryFileURL + "exists-988.trig",// dataFileURL + "exists-988b.srx" // resultFileURL, +// false, // laxCardinality +// true // checkOrder + ).runTest(); + + } + } Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988.trig 2014-07-08 13:52:46 UTC (rev 8524) @@ -0,0 +1,10 @@ +@prefix eg: <http://www.bigdata.com/> . + +eg: { + eg:a eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . + eg:b eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . + eg:c eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . + eg:d eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . + eg:e eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . + eg:f eg:p eg:a, eg:b, eg:c, eg:d, eg:e, eg:f . +} Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.rq =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.rq (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.rq 2014-07-08 13:52:46 UTC (rev 8524) @@ -0,0 +1,7 @@ +prefix eg: <http://www.bigdata.com/> + +ASK +FROM eg:g +{ BIND (1 as ?t) + ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b +} \ No newline at end of file Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988a.srx 2014-07-08 13:52:46 UTC (rev 8524) @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<sparql xmlns="http://www.w3.org/2005/sparql-results#"> + <head> + </head> + <boolean>false</boolean> +</sparql> Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.rq =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.rq (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.rq 2014-07-08 13:52:46 UTC (rev 8524) @@ -0,0 +1,9 @@ +prefix eg: <http://www.bigdata.com/> + +SELECT ?t +FROM eg:g +{ BIND (1 as ?t) + FILTER EXISTS { + ?a eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p/eg:p ?b + } +} \ No newline at end of file Added: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx (rev 0) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/test/com/bigdata/rdf/sparql/ast/eval/exists-988b.srx 2014-07-08 13:52:46 UTC (rev 8524) @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<sparql + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:xs="http://www.w3.org/2001/XMLSchema#" + xmlns="http://www.w3.org/2005/sparql-results#" > + <head> + <variable name="t"/> + </head> + <results> + </results> +</sparql> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tob...@us...> - 2014-07-03 17:48:27
|
Revision: 8523 http://sourceforge.net/p/bigdata/code/8523 Author: tobycraig Date: 2014-07-03 17:48:19 +0000 (Thu, 03 Jul 2014) Log Message: ----------- Flipped incoming & outgoing on explore tab Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html 2014-07-03 17:37:27 UTC (rev 8522) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html 2014-07-03 17:48:19 UTC (rev 8523) @@ -184,8 +184,8 @@ <div id="explore-results"> <div class="box" id="explore-header"></div> + <div class="box" id="explore-outgoing"></div> <div class="box" id="explore-incoming"></div> - <div class="box" id="explore-outgoing"></div> <div class="box" id="explore-attributes"></div> </div> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tob...@us...> - 2014-07-03 17:37:38
|
Revision: 8522 http://sourceforge.net/p/bigdata/code/8522 Author: tobycraig Date: 2014-07-03 17:37:27 +0000 (Thu, 03 Jul 2014) Log Message: ----------- Added query history delete, made queries obviously clickable Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css 2014-07-03 10:21:20 UTC (rev 8521) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css 2014-07-03 17:37:27 UTC (rev 8522) @@ -327,6 +327,10 @@ border: 1px solid #e1e1e1; } +#query-history .query { + white-space: pre; +} + #query-export-container { text-align: right; } Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html 2014-07-03 10:21:20 UTC (rev 8521) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html 2014-07-03 17:37:27 UTC (rev 8522) @@ -140,9 +140,9 @@ <thead> <tr> <th>Time</th> - <th>Namespace</th> <th>Query</th> <th>Results</th> + <th>Delete</th> </tr> </thead> <tbody></tbody> Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js 2014-07-03 10:21:20 UTC (rev 8521) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js 2014-07-03 17:37:27 UTC (rev 8522) @@ -652,14 +652,23 @@ }); EDITORS.query.addKeyMap({'Ctrl-Enter': submitQuery}); -$('#query-history').on('click', '.query', loadHistory); +$('#query-history').on('click', '.query a', loadHistory); +$('#query-history').on('click', '.query-delete a', deleteHistoryRow) -function loadHistory() { +function loadHistory(e) { + e.preventDefault(); EDITORS.query.setValue(this.innerText); - useNamespace($(this).prev('.query-namespace').text()); EDITORS.query.focus(); } +function deleteHistoryRow(e) { + e.preventDefault(); + $(this).parents('tr').remove(); + if($('#query-history tbody tr').length == 0) { + $('#query-history').hide(); + } +} + function submitQuery(e) { try { e.preventDefault(); @@ -669,8 +678,8 @@ EDITORS.query.save(); // do nothing if query is empty - var query = $('#query-box').val().trim(); - if(query == '') { + var query = $('#query-box').val(); + if(query.trim() == '') { return; } @@ -693,11 +702,12 @@ // add this query to the history var row = $('<tr>').prependTo($('#query-history tbody')); row.append('<td class="query-time">' + new Date().toISOString() + '</td>'); - row.append('<td class="query-namespace">' + NAMESPACE + '</td>'); var cell = $('<td class="query">').appendTo(row); - cell.text(query); - cell.html(cell.html().replace('\n', '<br>')); + var a = $('<a href="#">').appendTo(cell); + a.text(query); + a.html(a.html().replace(/\n/g, '<br>')); row.append('<td class="query-results">...</td>'); + row.append('<td class="query-delete"><a href="#">X</a></td>') } $('#query-history').show(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2014-07-03 10:21:32
|
Revision: 8521 http://sourceforge.net/p/bigdata/code/8521 Author: martyncutcher Date: 2014-07-03 10:21:20 +0000 (Thu, 03 Jul 2014) Log Message: ----------- Added CommitState to ensure that the RWStore is able to reset/abort following an error following or during the RWStore.commit() call - ticket #973. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java branches/BIGDATA_RELEASE_1_3_0/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-07-02 22:44:27 UTC (rev 8520) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-07-03 10:21:20 UTC (rev 8521) @@ -343,7 +343,7 @@ String META_BITS_DEMI_SPACE = RWStore.class.getName() + ".metabitsDemispace"; String DEFAULT_META_BITS_DEMI_SPACE = "false"; - + /** * Defines the number of bits that must be free in a FixedAllocator for * it to be added to the free list. This is used to ensure a level @@ -824,8 +824,7 @@ m_metaBits = new int[m_metaBitsSize]; m_metaTransientBits = new int[m_metaBitsSize]; - - + m_quorum = quorum; m_fd = fileMetadata.file; @@ -1488,7 +1487,6 @@ "Incompatible RWStore header version: storeVersion=" + storeVersion + ", cVersion=" + cVersion); } - m_lastDeferredReleaseTime = strBuf.readLong(); if (strBuf.readInt() != cDefaultMetaBitsSize) { throw new IllegalStateException("Store opened with unsupported metabits size"); @@ -2880,15 +2878,19 @@ // } /** - * The semantics of reset are to revert unisolated writes to committed state. - * + * The semantics of reset are to revert unisolated writes to committed + * state. + * <p> * Unisolated writes must also be removed from the write cache. - * + * <p> * The AllocBlocks of the FixedAllocators maintain the state to determine * the correct reset behavior. - * + * <p> * If the store is using DirectFixedAllocators then an IllegalStateException - * is thrown + * is thrown. + * <p> + * If there is an active {@link #m_commitStateRef}, then this indicates a + * failure after the {@link RWStore#commit()} had "succeeded". */ public void reset() { @@ -2899,7 +2901,16 @@ try { assertOpen(); // assertNoRebuild(); + + final CommitState commitState = m_commitStateRef + .getAndSet(null/* newValue */); + + if (commitState != null) { + commitState.reset(); // restore state values on RWStore. + + } + boolean isolatedWrites = false; /** * Clear all allocators, not just dirty allocators, since we also @@ -3101,23 +3112,89 @@ return requiresCommit(); } -// static final float s_version = 3.0f; -// -// public String getVersionString() { -// return "RWStore " + s_version; -// } + /** + * Object recording the undo state for the {@link RWStore#commit()} ... + * {@link RWStore#postCommit()} sequence. The {@link CommitState} must + * either {@link CommitState#commit()} or {@link CommitState#reset()}. Those + * {@link CommitState} methods are invoked out of the corresponding + * {@link RWStore} methods. + * + * @see <a href="http://trac.bigdata.com/ticket/973" >RWStore commit is not + * robust to internal failure.</a> + */ + private class CommitState { + /* + * Critical pre-commit state that must be restored if a commit is + * discarded. + */ + private final int m_lastCommittedNextAllocation; + private final long m_storageStatsAddr; + private final int m_metaBitsAddr; + CommitState() { + // retain copy of critical pre-commit state + if (!m_allocationWriteLock.isHeldByCurrentThread()) + throw new IllegalMonitorStateException(); + m_lastCommittedNextAllocation = RWStore.this.m_committedNextAllocation; + m_storageStatsAddr = RWStore.this.m_storageStatsAddr; + m_metaBitsAddr = RWStore.this.m_metaBitsAddr; + } + + void postCommit() { + + // NOP + + } + + /** Reset pre-commit state to support reset/abort/rollback. */ + void reset() { + if (!m_allocationWriteLock.isHeldByCurrentThread()) + throw new IllegalMonitorStateException(); + RWStore.this.m_storageStatsAddr = m_storageStatsAddr; + RWStore.this.m_committedNextAllocation = m_lastCommittedNextAllocation; + RWStore.this.m_metaBitsAddr = m_metaBitsAddr; + } + + } + + /** + * @see <a href="http://trac.bigdata.com/ticket/973" >RWStore commit is not + * robust to internal failure.</a> + */ + private final AtomicReference<CommitState> m_commitStateRef = new AtomicReference<CommitState>(); + + /** + * Package private method used by the test suite. + */ + void clearCommitStateRef() { + + m_commitStateRef.set(null/* newValue */); + + } + + @Override public void commit() { assertOpen(); // assertNoRebuild(); checkCoreAllocations(); - // take allocation lock to prevent other threads allocating during commit + // take allocation lock to prevent other threads allocating during commit m_allocationWriteLock.lock(); try { + /* + * Create a transient object to retain values of previous + * commitState to support abort/reset/rollback if requested after + * this commit() is requested. + */ + if (!m_commitStateRef.compareAndSet(null/* expect */, + new CommitState())) { + throw new IllegalStateException( + "RWStore commitState found, incomplete previous commit must be rolled back/aborted"); + } + // final int totalFreed = checkDeferredFrees(true, journal); // free now if possible // // if (totalFreed > 0 && log.isInfoEnabled()) { @@ -3150,20 +3227,20 @@ if ((!m_useMetabitsDemispace) && reqmbc < m_maxFixedAlloc) { nmbaddr = alloc(reqmbc, null); } - + // If existing allocation, then free it - if (m_metaBitsAddr < 0) { - + if (m_metaBitsAddr < 0) { + final int oldMetaBitsSize = (m_metaBits.length + m_allocSizes.length + 1) * 4; - // Call immediateFree - no need to defer freeof metaBits, this - // has to stop somewhere! - // No more allocations must be made - immediateFree((int) m_metaBitsAddr, oldMetaBitsSize); - - } - + // Call immediateFree - no need to defer freeof metaBits, this + // has to stop somewhere! + // No more allocations must be made + immediateFree((int) m_metaBitsAddr, oldMetaBitsSize); + + } + m_metaBitsAddr = nmbaddr; } @@ -3188,8 +3265,8 @@ } if (m_metaBitsAddr > 0) { // Demi-Space - // Now "toggle" m_metaBitsAddr - 64K boundary - m_metaBitsAddr ^= 0x01; // toggle zero or 64K offset + // Now "toggle" m_metaBitsAddr - 64K boundary + m_metaBitsAddr ^= 0x01; // toggle zero or 64K offset } if (log.isDebugEnabled()) { @@ -3199,7 +3276,7 @@ } else { mbaddr = convertAddr(-m_metaBitsAddr); // maximum 48 bit address range } - + log.debug("Writing metabits at " + mbaddr); } @@ -3254,9 +3331,6 @@ throw new RuntimeException(e); } - // Now remember the committed next allocation that will be checked in reset() - m_committedNextAllocation = m_nextAllocation; - // Should not write rootBlock, this is responsibility of client // to provide control // writeFileSpec(); @@ -3291,12 +3365,13 @@ log.debug(showAllocatorList()); } - + } /** * {@inheritDoc} */ + @Override public Lock getCommitLock() { return m_allocationWriteLock; @@ -3308,11 +3383,25 @@ * <p> * Commits the FixedAllocator bits */ + @Override public void postCommit() { if (!m_allocationWriteLock.isHeldByCurrentThread()) throw new IllegalMonitorStateException(); + final CommitState commitState = m_commitStateRef.getAndSet(null/* newValue */); + + if (commitState == null) { + + throw new IllegalStateException( + "No current CommitState found on postCommit"); + + } else { + + commitState.postCommit(); + + } + for (FixedAllocator fa : m_commitList) { fa.postCommit(); @@ -3323,6 +3412,7 @@ } + @Override public int checkDeferredFrees(final AbstractJournal journal) { if (journal == null) @@ -4150,7 +4240,7 @@ try { if (addr >= 0) { - + return addr & 0xFFFFFFE0; } else { @@ -4277,31 +4367,31 @@ * * @return long representation of metaBitsAddr PLUS the size */ - public long getMetaBitsAddr() { + public long getMetaBitsAddr() { long ret = 0; - + if (m_metaBitsAddr < 0) { ret = physicalAddress((int) m_metaBitsAddr); } else { - // long ret = physicalAddress((int) m_metaBitsAddr); + // long ret = physicalAddress((int) m_metaBitsAddr); ret = convertAddr(-m_metaBitsAddr); // maximum 48 bit address range } - ret <<= 16; - + ret <<= 16; + // include space for version, allocSizes and deferred free info AND // cDefaultMetaBitsSize final int metaBitsSize = cMetaHdrFields + m_metaBits.length + m_allocSizes.length; - ret += metaBitsSize; + ret += metaBitsSize; + + if (log.isTraceEnabled()) + log.trace("Returning metabitsAddr: " + ret + ", for " + + m_metaBitsAddr + " - " + m_metaBits.length + ", " + + metaBitsSize); - if (log.isTraceEnabled()) - log.trace("Returning metabitsAddr: " + ret + ", for " - + m_metaBitsAddr + " - " + m_metaBits.length + ", " - + metaBitsSize); + return ret; + } - return ret; - } - /** * * @return the address of the metaBits @@ -5178,7 +5268,7 @@ checkRootBlock(rootBlock); assertOpen(); - + if (log.isTraceEnabled()) { log.trace("Writing new rootblock with commitCounter: " + rootBlock.getCommitCounter() + ", commitRecordAddr: " @@ -7242,7 +7332,7 @@ return ret; } - + /** * Forces a reset of the metabits allocation on the next commit. * <p> Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2014-07-02 22:44:27 UTC (rev 8520) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2014-07-03 10:21:20 UTC (rev 8521) @@ -27,24 +27,16 @@ package com.bigdata.rwstore; -import java.io.EOFException; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; import java.util.Properties; import java.util.Random; import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; import junit.extensions.proxy.ProxyTestSuite; import junit.framework.Test; @@ -577,8 +569,6 @@ * * @author <a href="mailto:tho...@us...">Bryan * Thompson</a> - * @version $Id: TestRWJournal.java 4010 2010-12-16 12:44:43Z martyncutcher - * $ */ public static class TestRawStore extends AbstractRestartSafeTestCase { @@ -1540,116 +1530,23 @@ public void test_metaAlloc() { Journal store = (Journal) getStore(); - try { + try { - final RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + final RWStrategy bs = (RWStrategy) store.getBufferStrategy(); - final RWStore rw = bs.getStore(); - long realAddr = 0; - for (int r = 0; r < 100; r++) { - for (int i = 0; i < 1000; i++) { - int allocAddr = rw.metaAlloc(); - - realAddr = rw.metaBit2Addr(allocAddr); - } - rw.commit(); + final RWStore rw = bs.getStore(); + long realAddr = 0; + for (int i = 0; i < 100000; i++) { + int allocAddr = rw.metaAlloc(); + + realAddr = rw.metaBit2Addr(allocAddr); } - - if (log.isInfoEnabled()) - log.info("metaAlloc lastAddr: " + realAddr); + if(log.isInfoEnabled())log.info("metaAlloc lastAddr: " + realAddr); } finally { store.destroy(); } } - - /** - * Tests the MetabitsUtil to switch the demispace. - * - * If the address is a demispace then addr % 64K == 0. - * - * If the address is NOT a demispace then it should be less than first - * demispace - */ - public void test_metabitsDemispace() { - Journal store = (Journal) getStore(); - try { - RWStrategy bs = (RWStrategy) store.getBufferStrategy(); - RWStore rw = bs.getStore(); - final String fname = rw.getStoreFile().getAbsolutePath(); - - store.commit(); - - final long fa1 = rw.getMetaBitsStoreAddress(); - - rw.ensureMetabitsDemispace(true); - store.commit(); - - final long ds1 = rw.getMetaBitsStoreAddress(); - - assertTrue((ds1 & 0xFFFF) == 0); // MOD 64K - assertTrue(ds1 > fa1); - - rw.ensureMetabitsDemispace(false); - store.commit(); - - final long fa2 = rw.getMetaBitsStoreAddress(); - - assertTrue(ds1 > fa2); - - rw.ensureMetabitsDemispace(true); - store.commit(); - - final long ds2 = rw.getMetaBitsStoreAddress(); - - assertTrue((ds2 & 0xFFFF) == 0); - assertTrue(ds2 > ds1); - - // Now use MetaBitsUtil - - store.close(); - - MetabitsUtil.main(new String[] { "-store", fname, "-usedemispace", "false"}); - - store = getExplicitStore(fname); - - bs = (RWStrategy) store.getBufferStrategy(); - rw = bs.getStore(); - final long fa3 = rw.getMetaBitsStoreAddress(); - - assertTrue(fa3 < ds1); - - store.close(); - - MetabitsUtil.main(new String[] { "-store", fname, "-usedemispace", "true"}); - - store = getExplicitStore(fname); - - bs = (RWStrategy) store.getBufferStrategy(); - rw = bs.getStore(); - - final long ds3 = rw.getMetaBitsStoreAddress(); - assertTrue((ds3 & 0xFFFF) == 0); - assertTrue(ds3 > ds2); - - } finally { - store.destroy(); - } - } - - Journal getExplicitStore(String storeFile) { - - final Properties properties = new Properties(); - - properties.setProperty(Options.FILE, storeFile); - - properties.setProperty(Options.BUFFER_MODE, - BufferMode.DiskRW.toString()); - - return new Journal(properties);// .getBufferStrategy(); - - } - static class DummyAllocationContext implements IAllocationContext { } @@ -2104,7 +2001,136 @@ store.destroy(); } } + + /** + * Verify that we correctly restore the RWStore commit state if + * {@link RWStore#commit()} is followed by {@link RWStore#reset()} + * rather than {@link RWStore#postCommit()}. + * + * @see <a href="http://trac.bigdata.com/ticket/973" >RWStore commit is + * not robust to internal failure.</a> + */ + public void test_commitState() { + Journal store = (Journal) getStore(); + try { + + final RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + final RWStore rws = bs.getStore(); + + final long addr = bs.write(randomData(78)); + + // do 1st half of the RWStore commit protocol. + rws.commit(); + + // then discard write set. + store.abort(); + + assertFalse(bs.isCommitted(addr)); // rolled back + + // now cycle standard commit to confirm correct reset + for (int c = 0; c < 50; c++) { + bs.write(randomData(78)); + store.commit(); + } + + + } finally { + store.destroy(); + } + } + /** + * Test verifies that a failure to retain the commit state in + * {@link RWStore#commit()} will cause problems if the write set is + * discarded by {@link RWStore#reset()} such that subsequent write sets + * run into persistent addressing errors. + * + * @see <a href="http://trac.bigdata.com/ticket/973" >RWStore commit is + * not robust to internal failure.</a> + */ + public void test_commitStateError() { + Journal store = (Journal) getStore(); + try { + + RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + RWStore rws = bs.getStore(); + + final long addr = bs.write(randomData(78)); + + // do first half of the RWStore protocol. + rws.commit(); + + /* + * remove the commit state such that subsequent abort()/reset() + * will fail to correctly restore the pre-commit state. + */ + rws.clearCommitStateRef(); + + // abort() succeeds because it is allowed even if commit() was + // not called. + store.abort(); + + assertFalse(bs.isCommitted(addr)); // rolled back + + try { + // now cycle standard commit to force an error from bad reset + for (int c = 0; c < 50; c++) { + bs.write(randomData(78)); + store.commit(); + } + fail("Expected failure"); + } catch (Exception e) { + // expected + log.info("Expected!"); + } + + } finally { + store.destroy(); + } + } + + /** + * Verify that a double-commit causes an illegal state exception. + * Further verify that an {@link RWStore#reset()} allwos us to then + * apply and commit new write sets. + * + * @see <a href="http://trac.bigdata.com/ticket/973" >RWStore commit is + * not robust to internal failure.</a> + */ + public void test_commitStateIllegal() { + final Journal store = (Journal) getStore(); + try { + + final RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + final RWStore rws = bs.getStore(); + + bs.write(randomData(78)); + + rws.commit(); + + try { + store.commit(); + + fail("Expected failure"); + } catch (Exception ise) { + if (InnerCause.isInnerCause(ise, IllegalStateException.class)) { + store.abort(); + + store.commit(); + } else { + fail("Unexpected Exception"); + } + } + + + } finally { + store.destroy(); + } + } + public void test_allocCommitFreeWithHistory() { Journal store = (Journal) getStore(4); try { @@ -3052,8 +3078,6 @@ * * @author <a href="mailto:tho...@us...">Bryan * Thompson</a> - * @version $Id: TestRWJournal.java 4010 2010-12-16 12:44:43Z martyncutcher - * $ */ public static class TestMROW extends AbstractMROWTestCase { @@ -3065,15 +3089,11 @@ super(name); } - protected IRawStore getStore(String storeFile) { + protected IRawStore getStore() { final Properties properties = getProperties(); - if (storeFile == null) { - properties.setProperty(Options.CREATE_TEMP_FILE, "true"); - } else { - properties.setProperty(Options.FILE, storeFile); - } + properties.setProperty(Options.CREATE_TEMP_FILE, "true"); properties.setProperty(Options.DELETE_ON_EXIT, "true"); @@ -3085,86 +3105,6 @@ } - protected IRawStore getStore() { - - return getStore(null); // no file provided by default - - } - - static long getLongArg(final String[] args, final String arg, final long def) { - final String sv = getArg(args, arg, null); - - return sv == null ? def : Long.parseLong(sv); - } - - static String getArg(final String[] args, final String arg, final String def) { - for (int p = 0; p < args.length; p+=2) { - if (arg.equals(args[p])) - return args[p+1]; - } - - return def; - } - - /** - * Stress variant to support multiple parameterised runs - * - * Arguments - * - * -file - optional explicit file path - * -clients - reader threads - * -nwrites - number of records written - * -reclen - size of record written - * -ntrials - number of readers - * -nreads - number of reads made by each reader - * -nruns - number of times to repeat process with reopen each time - */ - public static void main(final String[] args) throws Exception { - final TestMROW test = new TestMROW("main"); - - final String storeFile = getArg(args, "-file", null); - - Journal store = (Journal) test.getStore(storeFile); - try { - - final long timeout = 20; - - final int nclients = (int) getLongArg(args, "-clients", 20); // 20 - - final long nwrites = getLongArg(args, "-nwrites", 100000); //1000000; - - final int writeDelayMillis = 1; - - final long ntrials = getLongArg(args, "-ntrials", 100000); // 100000; - - final int reclen = (int) getLongArg(args, "-reclen", 128); // 128; - - final long nreads = getLongArg(args, "-nreads", 1000); // 1000; - - final long nruns = getLongArg(args, "-nruns", 1); // 1000; - - final AtomicInteger nerr = new AtomicInteger(); - - for (int i = 0; i < nruns; i++) { - doMROWTest(store, nwrites, writeDelayMillis, timeout, nclients, - ntrials, reclen, nreads, nerr, true /*readAll*/); - - store.commit(); - - store = (new TestRWJournal()).reopenStore(store); - - System.out.println("Completed run: " + i); - } - - } finally { - - if (storeFile == null) - store.destroy(); - - } - - } - } /** @@ -3172,8 +3112,6 @@ * * @author <a href="mailto:tho...@us...">Bryan * Thompson</a> - * @version $Id: TestRWJournal.java 4010 2010-12-16 12:44:43Z martyncutcher - * $ */ public static class TestMRMW extends AbstractMRMWTestCase { @@ -3208,8 +3146,6 @@ * * @author <a href="mailto:tho...@us...">Bryan * Thompson</a> - * @version $Id: TestRWJournal.java 4010 2010-12-16 12:44:43Z martyncutcher - * $ */ public static class TestInterrupts extends AbstractInterruptsTestCase { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tob...@us...> - 2014-07-02 22:44:36
|
Revision: 8520 http://sourceforge.net/p/bigdata/code/8520 Author: tobycraig Date: 2014-07-02 22:44:27 +0000 (Wed, 02 Jul 2014) Log Message: ----------- Added padding to health boxes Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html 2014-07-02 22:33:22 UTC (rev 8519) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/index.html 2014-07-02 22:44:27 UTC (rev 8520) @@ -203,11 +203,13 @@ <div class="tab" id="health-tab"> <div class="box" id="health-overview"> - <h1>Overview</h1> - <p class="health-status">Status: <span></span></p> - <p class="health-details">Details: <span></span></p> - <p class="health-version">Version: <span></span></p> - <p class="health-timestamp">Timestamp: <span></span></p> + <div class="box"> + <h1>Overview</h1> + <p class="health-status">Status: <span></span></p> + <p class="health-details">Details: <span></span></p> + <p class="health-version">Version: <span></span></p> + <p class="health-timestamp">Timestamp: <span></span></p> + </div> </div> <div id="health-services"></div> Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js 2014-07-02 22:33:22 UTC (rev 8519) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js 2014-07-02 22:44:27 UTC (rev 8520) @@ -1421,7 +1421,9 @@ $('#health-services div').remove(); for(var i=0; i<data.services.length; i++) { - var div = $('<div>'); + var container = $('<div>'); + var div = $('<div class="box">'); + div.appendTo(container); div.append('<p>ID: ' + data.services[i].id + '</p>'); div.append('<p>Status: ' + data.services[i].status + '</p>'); var health; @@ -1436,8 +1438,8 @@ default: health = 'warning'; } - div.addClass('box health-' + health); - div.appendTo($('#health-services')); + container.addClass('box health-' + health); + container.appendTo($('#health-services')); } }) } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tob...@us...> - 2014-07-02 22:33:26
|
Revision: 8519 http://sourceforge.net/p/bigdata/code/8519 Author: tobycraig Date: 2014-07-02 22:33:22 +0000 (Wed, 02 Jul 2014) Log Message: ----------- Fixed health for standalone deployments, set unjoined services to red, added replication factor to healthy status Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/StatusServlet.java branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java 2014-07-02 19:18:15 UTC (rev 8518) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java 2014-07-02 22:33:22 UTC (rev 8519) @@ -903,55 +903,67 @@ public void doHealthStatus(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { - if (!(indexManager instanceof HAJournal)) - return; - - final HAJournal journal = (HAJournal) indexManager; - - final Quorum<HAGlue, QuorumService<HAGlue>> quorum = journal.getQuorum(); - StringWriter writer = new StringWriter(); JsonFactory factory = new JsonFactory(); JsonGenerator json = factory.createGenerator(writer); json.writeStartObject(); - json.writeStringField("version", Banner.getVersion()); json.writeNumberField("timestamp", new Date().getTime()); - if (quorum.isQuorumFullyMet(quorum.token())) { - json.writeStringField("status", "Good"); - json.writeStringField("details", "All servers joined"); + + if (!(indexManager instanceof HAJournal)) { + + // standalone + json.writeStringField("deployment", "standalone"); + } else { - // at least one server is not available - // status is either Warning or Bad - if (quorum.isQuorumMet()) { - json.writeStringField("status", "Warning"); + + // HA + json.writeStringField("deployment", "HA"); + + final HAJournal journal = (HAJournal) indexManager; + + final Quorum<HAGlue, QuorumService<HAGlue>> quorum = journal + .getQuorum(); + + if (quorum.isQuorumFullyMet(quorum.token())) { + json.writeStringField("status", "Good"); + json.writeStringField("details", + "All servers (" + quorum.replicationFactor() + ") joined"); } else { - json.writeStringField("status", "Bad"); + // at least one server is not available + // status is either Warning or Bad + if (quorum.isQuorumMet()) { + json.writeStringField("status", "Warning"); + } else { + json.writeStringField("status", "Bad"); + } + json.writeStringField( + "details", + "Only " + quorum.getJoined().length + " of target " + + quorum.replicationFactor() + " servers joined"); } - json.writeStringField("details", "Only " + quorum.getJoined().length - + " of target " + quorum.replicationFactor() - + " servers joined"); - } - json.writeFieldName("services"); - json.writeStartArray(); + json.writeFieldName("services"); + json.writeStartArray(); - final UUID[] pipeline = quorum.getPipeline(); - final UUID[] joined = quorum.getJoined(); + final UUID[] members = quorum.getMembers(); + final UUID[] joined = quorum.getJoined(); - for (UUID serviceId : pipeline) { - final boolean isLeader = serviceId.equals(quorum.getLeaderId()); - final boolean isFollower = indexOf(serviceId, joined) > 0; + for (UUID serviceId : members) { + final boolean isLeader = serviceId.equals(quorum.getLeaderId()); + final boolean isFollower = indexOf(serviceId, joined) > 0; - json.writeStartObject(); - json.writeStringField("id", serviceId.toString()); - json.writeStringField("status", isLeader ? "leader" - : (isFollower ? "follower" : "unready")); - json.writeEndObject(); + json.writeStartObject(); + json.writeStringField("id", serviceId.toString()); + json.writeStringField("status", isLeader ? "leader" + : (isFollower ? "follower" : "unready")); + json.writeEndObject(); + } + + json.writeEndArray(); } - json.writeEndArray(); json.writeEndObject(); json.close(); Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/StatusServlet.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/StatusServlet.java 2014-07-02 19:18:15 UTC (rev 8518) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/StatusServlet.java 2014-07-02 22:33:22 UTC (rev 8519) @@ -401,14 +401,13 @@ return; } - if (req.getParameter(HEALTH) != null - && getIndexManager() instanceof AbstractJournal - && ((AbstractJournal) getIndexManager()).getQuorum() != null) { // for HA1 - new HAStatusServletUtil(getIndexManager()).doHealthStatus(req, resp); - - return; - } + if (req.getParameter(HEALTH) != null) { + new HAStatusServletUtil(getIndexManager()).doHealthStatus(req, resp); + + return; + } + // IRunningQuery objects currently running on the query controller. final boolean showQueries = req.getParameter(SHOW_QUERIES) != null; Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css 2014-07-02 19:18:15 UTC (rev 8518) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/css/style.css 2014-07-02 22:33:22 UTC (rev 8519) @@ -352,7 +352,7 @@ } .health-bad { - background-color: red; + background-color: tomato; } #links { Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js 2014-07-02 19:18:15 UTC (rev 8518) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-war/src/html/js/workbench.js 2014-07-02 22:33:22 UTC (rev 8519) @@ -1406,6 +1406,13 @@ function getHealth(e) { e.preventDefault(); $.get('/status?health', function(data) { + + if(data.deployment == 'standalone') { + $('#health-tab').html('<div class="box">Server operating in standalone mode.</div>'); + $('#tab-selector a[data-target=health]').unbind('click'); + return; + } + $('#health-overview .health-status span').html(data.status); $('#health-overview').removeClass('health-good health-warning health-bad').addClass('health-' + data.status.toLowerCase()); $('#health-overview .health-details span').html(data.details); @@ -1424,10 +1431,10 @@ health = 'good'; break; case 'unready': - health = 'warning'; + health = 'bad'; break; default: - health = 'bad'; + health = 'warning'; } div.addClass('box health-' + health); div.appendTo($('#health-services')); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-02 19:18:18
|
Revision: 8518 http://sourceforge.net/p/bigdata/code/8518 Author: thompsonbry Date: 2014-07-02 19:18:15 +0000 (Wed, 02 Jul 2014) Log Message: ----------- removed the old (dead) maven repo for aduna. See #987 (broken maven build) Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/pom.xml Modified: branches/BIGDATA_RELEASE_1_3_0/pom.xml =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/pom.xml 2014-07-02 18:58:15 UTC (rev 8517) +++ branches/BIGDATA_RELEASE_1_3_0/pom.xml 2014-07-02 19:18:15 UTC (rev 8518) @@ -187,10 +187,6 @@ <id>nxparser-snapshots</id> <url>http://nxparser.googlecode.com/svn/snapshots</url> </repository> - <repository> - <id>aduna-opensource.releases</id> - <url>http://repo.aduna-software.org/maven2/releases/</url> - </repository> <!-- <repository> <id>jetty.releases</id> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-02 18:58:18
|
Revision: 8517 http://sourceforge.net/p/bigdata/code/8517 Author: thompsonbry Date: 2014-07-02 18:58:15 +0000 (Wed, 02 Jul 2014) Log Message: ----------- Bug fix for jackson support. The library is now correctly staged for CI and staging based deployments. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/build.properties branches/BIGDATA_RELEASE_1_3_0/build.xml Modified: branches/BIGDATA_RELEASE_1_3_0/build.properties =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/build.properties 2014-07-02 14:02:27 UTC (rev 8516) +++ branches/BIGDATA_RELEASE_1_3_0/build.properties 2014-07-02 18:58:15 UTC (rev 8517) @@ -69,9 +69,9 @@ fastutil.version=5.1.5 dsiutils.version=1.0.6-020610 lgplutils.version=1.0.7-270114 -ganglia-version=1.0.4 -gas-version=0.1.0 -jackson-version=2.2.3 +ganglia.version=1.0.4 +gas.version=0.1.0 +jackson.version=2.2.3 blueprints.version=2.5.0 jettison.version=1.3.3 rexster.version=2.5.0 Modified: branches/BIGDATA_RELEASE_1_3_0/build.xml =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/build.xml 2014-07-02 14:02:27 UTC (rev 8516) +++ branches/BIGDATA_RELEASE_1_3_0/build.xml 2014-07-02 18:58:15 UTC (rev 8517) @@ -986,7 +986,7 @@ tofile="${dist.lib}/lgplutils.jar" /> <copy file="${bigdata.lib}/unimi/fastutil-${fastutil.version}.jar" tofile="${dist.lib}/fastutil.jar" /> - <copy file="${bigdata.lib}/bigdata-ganglia-${ganglia-version}.jar" + <copy file="${bigdata.lib}/bigdata-ganglia-${ganglia.version}.jar" tofile="${dist.lib}/bigdata-ganglia.jar" /> <!--copy file="${bigdata.lib}/bigdata-gas-${gas.version}.jar" tofile="${dist.lib}/bigdata-gas.jar" --> @@ -1016,8 +1016,11 @@ <!-- Blueprints library --> <copy file="${bigdata-blueprints.lib}/blueprints-core-${blueprints.version}.jar" tofile="${dist.lib}/blueprints-core.jar" /> - + <!-- JSON --> + <copy file="${bigdata-sails.lib}/jackson-core-${jackson.version}.jar" + tofile="${dist.lib}/jackson-core.jar" /> + <!-- jetty library --> <copy file="${bigdata-jetty.lib}/jetty-continuation-${jetty.version}.jar" tofile="${dist.lib}/jetty-continuation.jar" /> @@ -1869,7 +1872,7 @@ <!-- TODO ${path.separator}${dist.lib}/bigdata-gas.jar --> <property name="javac.test.classpath" - value="${classes.dir}${path.separator}${junit.jar}${path.separator}${junit-ext.jar}${path.separator}${sesame-sparql-test.jar}${path.separator}${sesame-store-test.jar}${path.separator}${sesame-rio-test.jar}${path.separator}${dist.lib}/classserver.jar${path.separator}${dist.lib}/highscalelib.jar${path.separator}${dist.lib}/dsiutils.jar${path.separator}${dist.lib}/lgplutils.jar${path.separator}${dist.lib}/fastutil.jar${path.separator}${dist.lib}/bigdata-ganglia.jar${path.separator}${dist.lib}/icu4j.jar${path.separator}${dist.lib}/icu4j-charset.jar${path.separator}${dist.lib}/log4j.jar${path.separator}${dist.lib}/lucene-analyzer.jar${path.separator}${dist.lib}/lucene-core.jar${path.separator}${path.separator}${dist.lib}/openrdf-sesame.jar${path.separator}${dist.lib}/slf4j.jar${path.separator}${dist.lib}/jsk-lib.jar${path.separator}${dist.lib}/jsk-platform.jar${path.separator}${dist.lib}/nxparser.jar${path.separator}${dist.lib}/zookeeper.jar${path.separator}${dist.lib}/jetty-continuation.jar${path.separator}${dist.lib}/jetty-http.jar${path.separator}${dist.lib}/jetty-io.jar${path.separator}${dist.lib}/jetty-jmx.jar${path.separator}${dist.lib}/jetty-jndi.jar${path.separator}${dist.lib}/jetty-server.jar${path.separator}${dist.lib}/jetty-util.jar${path.separator}${dist.lib}/jetty-webapp.jar${path.separator}${dist.lib}/jetty-servlet.jar${path.separator}${dist.lib}/jetty-security.jar${path.separator}${dist.lib}/jetty-xml.jar${path.separator}${dist.lib}/jetty-rewrite.jar${path.separator}${dist.lib}/jetty-client.jar${path.separator}${dist.lib}/jetty-proxy.jar${path.separator}${dist.lib}/servlet-api.jar${path.separator}${dist.lib}/commons-codec.jar${path.separator}${dist.lib}/commons-fileupload.jar${path.separator}${dist.lib}/commons-io.jar${path.separator}${dist.lib}/commons-logging.jar${path.separator}${dist.lib}/httpclient.jar${path.separator}${dist.lib}/httpclient-cache.jar${path.separator}${dist.lib}/httpcore.jar${path.separator}${dist.lib}/httpmime.jar${path.separator}${dist.lib}/blueprints-core.jar${path.separator}${blueprints-test.jar}${path.separator}${jettison.jar}" /> + value="${classes.dir}${path.separator}${junit.jar}${path.separator}${junit-ext.jar}${path.separator}${sesame-sparql-test.jar}${path.separator}${sesame-store-test.jar}${path.separator}${sesame-rio-test.jar}${path.separator}${dist.lib}/classserver.jar${path.separator}${dist.lib}/highscalelib.jar${path.separator}${dist.lib}/dsiutils.jar${path.separator}${dist.lib}/lgplutils.jar${path.separator}${dist.lib}/fastutil.jar${path.separator}${dist.lib}/bigdata-ganglia.jar${path.separator}${dist.lib}/icu4j.jar${path.separator}${dist.lib}/icu4j-charset.jar${path.separator}${dist.lib}/log4j.jar${path.separator}${dist.lib}/lucene-analyzer.jar${path.separator}${dist.lib}/lucene-core.jar${path.separator}${path.separator}${dist.lib}/openrdf-sesame.jar${path.separator}${dist.lib}/slf4j.jar${path.separator}${dist.lib}/jsk-lib.jar${path.separator}${dist.lib}/jsk-platform.jar${path.separator}${dist.lib}/nxparser.jar${path.separator}${dist.lib}/zookeeper.jar${path.separator}${dist.lib}/jetty-continuation.jar${path.separator}${dist.lib}/jetty-http.jar${path.separator}${dist.lib}/jetty-io.jar${path.separator}${dist.lib}/jetty-jmx.jar${path.separator}${dist.lib}/jetty-jndi.jar${path.separator}${dist.lib}/jetty-server.jar${path.separator}${dist.lib}/jetty-util.jar${path.separator}${dist.lib}/jetty-webapp.jar${path.separator}${dist.lib}/jetty-servlet.jar${path.separator}${dist.lib}/jetty-security.jar${path.separator}${dist.lib}/jetty-xml.jar${path.separator}${dist.lib}/jetty-rewrite.jar${path.separator}${dist.lib}/jetty-client.jar${path.separator}${dist.lib}/jetty-proxy.jar${path.separator}${dist.lib}/servlet-api.jar${path.separator}${dist.lib}/commons-codec.jar${path.separator}${dist.lib}/commons-fileupload.jar${path.separator}${dist.lib}/commons-io.jar${path.separator}${dist.lib}/commons-logging.jar${path.separator}${dist.lib}/httpclient.jar${path.separator}${dist.lib}/httpclient-cache.jar${path.separator}${dist.lib}/httpcore.jar${path.separator}${dist.lib}/httpmime.jar${path.separator}${dist.lib}/blueprints-core.jar${path.separator}${dist.lib}/jackson-core.jar${path.separator}${blueprints-test.jar}${path.separator}${jettison.jar}" /> <echo>javac </echo> @@ -2257,12 +2260,13 @@ <pathelement location="${dist.lib}/httpcore.jar" /> <pathelement location="${dist.lib}/httpmime.jar" /> <pathelement location="${dist.lib}/blueprints-core.jar" /> + <pathelement location="${dist.lib}/jackson-core.jar" /> <pathelement location="${blueprints-test.jar}" /> <pathelement location="${jettison.jar}" /> </path> <property name="run.class.path" - value="${junit.jar}${path.separator}${bigdata-test.jar}${path.separator}${junit-ext.jar}${path.separator}${sesame-sparql-test.jar}${path.separator}${sesame-store-test.jar}${path.separator}${sesame-rio-test.jar}${path.separator}${dist.lib}/bigdata.jar${path.separator}${dist.lib}/colt.jar${path.separator}${dist.lib}/highscalelib.jar${path.separator}${dist.lib}/dsiutils.jar${path.separator}${dist.lib}/lgplutils.jar${path.separator}${dist.lib}/fastutil.jar${path.separator}${dist.lib}/bigdata-ganglia.jar${path.separator}${dist.lib}/bigdata-gas${path.separator}${dist.lib}/icu4j.jar${path.separator}${dist.lib}/icu4j-charset.jar${path.separator}${dist.lib}/jsk-lib.jar${path.separator}${dist.lib}/jsk-platform.jar${path.separator}${dist.lib}/log4j.jar${path.separator}${dist.lib}/lucene-analyzer.jar${path.separator}${dist.lib}/lucene-core.jar${path.separator}${dist.lib}/openrdf-sesame.jar${path.separator}${dist.lib}/slf4j.jar${path.separator}${dist.lib}/slf4j-log4j.jar${path.separator}${dist.lib}/nxparser.jar${path.separator}${dist.lib}/zookeeper.jar${path.separator}${dist.lib}/jetty-continuation.jar${path.separator}${dist.lib}/jetty-http.jar${path.separator}${dist.lib}/jetty-io.jar${path.separator}${dist.lib}/jetty-jmx.jar${path.separator}${dist.lib}/jetty-jndi.jar${path.separator}${dist.lib}/jetty-server.jar${path.separator}${dist.lib}/jetty-util.jar${path.separator}${dist.lib}/jetty-webapp.jar${path.separator}${dist.lib}/jetty-servlet.jar${path.separator}${dist.lib}/jetty-security.jar${path.separator}${dist.lib}/jetty-xml.jar${path.separator}${dist.lib}/jetty-rewrite.jar${path.separator}${dist.lib}/jetty-client.jar${path.separator}${dist.lib}/jetty-proxy.jar${path.separator}${dist.lib}/servlet-api.jar${path.separator}${dist.lib}/commons-codec.jar${path.separator}${dist.lib}/commons-fileupload.jar${path.separator}${dist.lib}/commons-io.jar${path.separator}${dist.lib}/commons-logging.jar${path.separator}${dist.lib}/httpclient.jar${path.separator}${dist.lib}/httpclient-cache.jar${path.separator}${dist.lib}/httpcore.jar${path.separator}${dist.lib}/httpmime.jar${path.separator}${dist.lib}/blueprints-core.jar${path.separator}${blueprints-test.jar}${path.separator}${jettison.jar}" /> + value="${junit.jar}${path.separator}${bigdata-test.jar}${path.separator}${junit-ext.jar}${path.separator}${sesame-sparql-test.jar}${path.separator}${sesame-store-test.jar}${path.separator}${sesame-rio-test.jar}${path.separator}${dist.lib}/bigdata.jar${path.separator}${dist.lib}/colt.jar${path.separator}${dist.lib}/highscalelib.jar${path.separator}${dist.lib}/dsiutils.jar${path.separator}${dist.lib}/lgplutils.jar${path.separator}${dist.lib}/fastutil.jar${path.separator}${dist.lib}/bigdata-ganglia.jar${path.separator}${dist.lib}/bigdata-gas${path.separator}${dist.lib}/icu4j.jar${path.separator}${dist.lib}/icu4j-charset.jar${path.separator}${dist.lib}/jsk-lib.jar${path.separator}${dist.lib}/jsk-platform.jar${path.separator}${dist.lib}/log4j.jar${path.separator}${dist.lib}/lucene-analyzer.jar${path.separator}${dist.lib}/lucene-core.jar${path.separator}${dist.lib}/openrdf-sesame.jar${path.separator}${dist.lib}/slf4j.jar${path.separator}${dist.lib}/slf4j-log4j.jar${path.separator}${dist.lib}/nxparser.jar${path.separator}${dist.lib}/zookeeper.jar${path.separator}${dist.lib}/jetty-continuation.jar${path.separator}${dist.lib}/jetty-http.jar${path.separator}${dist.lib}/jetty-io.jar${path.separator}${dist.lib}/jetty-jmx.jar${path.separator}${dist.lib}/jetty-jndi.jar${path.separator}${dist.lib}/jetty-server.jar${path.separator}${dist.lib}/jetty-util.jar${path.separator}${dist.lib}/jetty-webapp.jar${path.separator}${dist.lib}/jetty-servlet.jar${path.separator}${dist.lib}/jetty-security.jar${path.separator}${dist.lib}/jetty-xml.jar${path.separator}${dist.lib}/jetty-rewrite.jar${path.separator}${dist.lib}/jetty-client.jar${path.separator}${dist.lib}/jetty-proxy.jar${path.separator}${dist.lib}/servlet-api.jar${path.separator}${dist.lib}/commons-codec.jar${path.separator}${dist.lib}/commons-fileupload.jar${path.separator}${dist.lib}/commons-io.jar${path.separator}${dist.lib}/commons-logging.jar${path.separator}${dist.lib}/httpclient.jar${path.separator}${dist.lib}/httpclient-cache.jar${path.separator}${dist.lib}/httpcore.jar${path.separator}${dist.lib}/httpmime.jar${path.separator}${dist.lib}/blueprints-core.jar${path.separator}${dist.lib}/jackson-core.jar${path.separator}${blueprints-test.jar}${path.separator}${jettison.jar}" /> <echo> classpath: ${run.class.path} </echo> @@ -2424,6 +2428,7 @@ <sysproperty key="jetty-proxy.jar" value="${dist.lib}/jetty-proxy.jar" /> <sysproperty key="servlet-api.jar" value="${dist.lib}/servlet-api.jar" /> <sysproperty key="blueprints-core.jar" value="${dist.lib}/blueprints-core.jar" /> + <sysproperty key="jackson-core.jar" value="${dist.lib}/jackson-core.jar" /> <!-- Jini group name --> <sysproperty key="bigdata.fedname" value="${bigdata.fedname}" /> @@ -2628,7 +2633,14 @@ </java> </target> - <target name="start-bigdata" depends="compile" description="Start the Bigdata Server (triples mode)."> + <!-- This is NOT recommended for development or deployment. It is a --> + <!-- fast and simple bootstrap for people getting started with bigdata --> + <!-- for the first time. bigdata is developed using eclipse, so that --> + <!-- makes the most sense for development. The recommended deployers --> + <!-- are documented at the following links: --> + <!-- http://wiki.bigdata.com/wiki/index.php/NanoSparqlServer --> + <!-- http://wiki.bigdata.com/wiki/index.php/HAJournalServer --> + <target name="start-bigdata" depends="compile" description="Start the Bigdata Server (simple triples mode start)."> <java classname="com.bigdata.rdf.sail.webapp.NanoSparqlServer" failonerror="true" fork="true" logerror="true"> <classpath refid="runtime.classpath" /> <jvmarg value="-server"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2014-07-02 14:02:32
|
Revision: 8516 http://sourceforge.net/p/bigdata/code/8516 Author: martyncutcher Date: 2014-07-02 14:02:27 +0000 (Wed, 02 Jul 2014) Log Message: ----------- Now generates an IllegalStateException if commit() is called twice on an RWStore without either a call to postCommit() or reset(). Modified Paths: -------------- branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java Modified: branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java =================================================================== --- branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-07-02 11:38:12 UTC (rev 8515) +++ branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-07-02 14:02:27 UTC (rev 8516) @@ -3148,8 +3148,7 @@ // transient object to retain values of previous commitState to support abort/reset/rollback if // requested after this commit() is requested. if (m_commitState != null) { - m_commitState = null; // clear it down - log.warn("previous CommitState object found"); + throw new IllegalStateException("RWStore commitState found, incomplete previous commit must be rolled back/aborted"); } m_commitState = new CommitState(); @@ -3352,10 +3351,9 @@ throw new IllegalMonitorStateException(); if (m_commitState == null) { - log.warn("No current CommitState found on writeRootBlock call"); + log.warn("No current CommitState found on postCommit"); } else { m_commitState.commit(); - m_commitState = null; } for (FixedAllocator fa : m_commitList) { Modified: branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java =================================================================== --- branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2014-07-02 11:38:12 UTC (rev 8515) +++ branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2014-07-02 14:02:27 UTC (rev 8516) @@ -2077,6 +2077,38 @@ } } + public void test_commitStateIllegal() { + Journal store = (Journal) getStore(); + try { + + RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + RWStore rws = bs.getStore(); + + bs.write(randomData(78)); + + rws.commit(); + + try { + store.commit(); + + fail("Expected failure"); + } catch (Exception ise) { + if (InnerCause.isInnerCause(ise, IllegalStateException.class)) { + store.abort(); + + store.commit(); + } else { + fail("Unexpected Exception"); + } + } + + + } finally { + store.destroy(); + } + } + public void test_allocCommitFreeWithHistory() { Journal store = (Journal) getStore(4); try { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-02 11:38:15
|
Revision: 8515 http://sourceforge.net/p/bigdata/code/8515 Author: thompsonbry Date: 2014-07-02 11:38:12 +0000 (Wed, 02 Jul 2014) Log Message: ----------- Javadoc fix. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java 2014-07-02 11:06:04 UTC (rev 8514) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java 2014-07-02 11:38:12 UTC (rev 8515) @@ -55,7 +55,6 @@ * the copyright banner is always written out on bigdata startup. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public class Banner { @@ -70,7 +69,6 @@ * Environment variables understood by the {@link Banner} class. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ */ public interface Options { @@ -384,7 +382,7 @@ * <code>build.xml</code> and is NOT available from the IDE. It is correct * discovered using reflection. * - * @return Build version if available and <code>unknown</code> otherwise. + * @return Build version if available and <code>null</code> otherwise. * * @see #getBuildInfo() */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2014-07-02 11:06:13
|
Revision: 8514 http://sourceforge.net/p/bigdata/code/8514 Author: martyncutcher Date: 2014-07-02 11:06:04 +0000 (Wed, 02 Jul 2014) Log Message: ----------- Provide a CommitState to retain critical "pre-commit" data to support correct reset/abort/rollback if requested after the RWStore commit() has been called. Modified Paths: -------------- branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java Modified: branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java =================================================================== --- branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-07-01 18:44:22 UTC (rev 8513) +++ branches/RWSTORE_COMMITSTATE_973/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-07-02 11:06:04 UTC (rev 8514) @@ -342,7 +342,7 @@ */ String META_BITS_DEMI_SPACE = RWStore.class.getName() + ".metabitsDemispace"; - String DEFAULT_META_BITS_DEMI_SPACE = "true"; + String DEFAULT_META_BITS_DEMI_SPACE = "false"; /** * Defines the number of bits that must be free in a FixedAllocator for @@ -1477,7 +1477,12 @@ // Can handle minor store version incompatibility final int storeVersion = strBuf.readInt(); - if ((storeVersion & 0xFF00) != (cVersion & 0xFF00)) { + + switch ((storeVersion & 0xFF00)) { + case (cVersion & 0xFF00): + case (cVersionDemispace & 0xFF00): + break; + default: throw new IllegalStateException( "Incompatible RWStore header version: storeVersion=" + storeVersion + ", cVersion=" + cVersion); @@ -2881,7 +2886,11 @@ * the correct reset behavior. * * If the store is using DirectFixedAllocators then an IllegalStateException - * is thrown + * is thrown. + * + * If there is an active m_commitState, then this indicates a failure after + * the RWStore commit had "succeeded". FIXME: If this is the case then the + * FixedAllocators will have been committed. */ public void reset() { @@ -2893,6 +2902,12 @@ assertOpen(); // assertNoRebuild(); + if (m_commitState != null) { + log.warn("CommitState found, resetting committedNextAllocation"); + + m_commitState.reset(); // clear state values + } + boolean isolatedWrites = false; /** * Clear all allocators, not just dirty allocators, since we also @@ -3030,7 +3045,7 @@ final FixedOutputStream str = new FixedOutputStream(buf); try { - str.writeInt(cVersion); + str.writeInt(m_metaBitsAddr > 0 ? cVersionDemispace : cVersion); str.writeLong(m_lastDeferredReleaseTime); str.writeInt(cDefaultMetaBitsSize); str.writeInt(m_allocSizes.length); @@ -3067,7 +3082,7 @@ * writeMetaBits(). */ //final long addr = physicalAddress(m_metaBitsAddr); - final long addr = ((long) m_metaBitsAddr) << ALLOCATION_SCALEUP; + final long addr = m_metaBitsAddr < 0 ? physicalAddress(m_metaBitsAddr) : ((long) m_metaBitsAddr) << ALLOCATION_SCALEUP; if (addr == 0) { throw new IllegalStateException("Invalid metabits address: " + m_metaBitsAddr); } @@ -3080,7 +3095,7 @@ // Similar to writeMetaBits, we are no longer writing to a FixedAllocator managed region, // so no latched address is provided - m_writeCacheService.write(addr, ByteBuffer.wrap(buf), 0/*chk*/, false/*useChecksum*/, 0 /*latchedAddr*/); + m_writeCacheService.write(addr, ByteBuffer.wrap(buf), 0/*chk*/, false/*useChecksum*/, m_metaBitsAddr < 0 ? m_metaBitsAddr : 0 /*latchedAddr*/); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -3094,19 +3109,52 @@ return requiresCommit(); } -// static final float s_version = 3.0f; -// -// public String getVersionString() { -// return "RWStore " + s_version; -// } + class CommitState { + + final int m_lastCommittedNextAllocation; + final long m_storageStatsAddr; + final int m_metaBitsAddr; + + CommitState() { + // retain copy of critical pre-commit state + m_lastCommittedNextAllocation = RWStore.this.m_committedNextAllocation; + m_storageStatsAddr = RWStore.this.m_storageStatsAddr; + m_metaBitsAddr = RWStore.this.m_metaBitsAddr; + } + void commit() { + RWStore.this.m_commitState = null; + } + + void reset() { + // reset pre-commit state to support reset/abort/rollback + RWStore.this.m_storageStatsAddr = m_storageStatsAddr; + RWStore.this.m_committedNextAllocation = m_lastCommittedNextAllocation; + RWStore.this.m_metaBitsAddr = m_metaBitsAddr; + + RWStore.this.m_commitState = null; + } + + } + + CommitState m_commitState = null; + public void commit() { assertOpen(); // assertNoRebuild(); checkCoreAllocations(); - // take allocation lock to prevent other threads allocating during commit + // transient object to retain values of previous commitState to support abort/reset/rollback if + // requested after this commit() is requested. + if (m_commitState != null) { + m_commitState = null; // clear it down + log.warn("previous CommitState object found"); + } + + m_commitState = new CommitState(); + + // take allocation lock to prevent other threads allocating during commit m_allocationWriteLock.lock(); try { @@ -3133,42 +3181,69 @@ * that we do not need to reallocate the metabits region when we are * writing out the updated versions of the FixedAllocators). */ -// final long oldMetaBits = m_metaBitsAddr; -// final int oldMetaBitsSize = (m_metaBits.length + m_allocSizes.length + 1) * 4; -// m_metaBitsAddr = alloc(getRequiredMetaBitsStorage(), null); + if (m_metaBitsAddr > 0) { + // already using demi-space, remove from WCS + m_writeCacheService.removeWriteToAddr(convertAddr(-m_metaBitsAddr), 0); + } else { + final int reqmbc = getRequiredMetaBitsStorage(); + int nmbaddr = 0; + // if > max alloc or explicitly use the demi-space, then drop through for demi-space + if ((!m_useMetabitsDemispace) && reqmbc < m_maxFixedAlloc) { + nmbaddr = alloc(reqmbc, null); + } - /* - * If m_metaBitsAddr < 0 then was allocated from FixedAllocators (for existing-store compatibility) - */ + // If existing allocation, then free it if (m_metaBitsAddr < 0) { - if (physicalAddress(m_metaBitsAddr) == 0) { - throw new IllegalStateException("Returned MetaBits Address not valid!"); - } - final int oldMetaBitsSize = (m_metaBits.length + m_allocSizes.length + 1) * 4; + final int oldMetaBitsSize = (m_metaBits.length + + m_allocSizes.length + 1) * 4; + // Call immediateFree - no need to defer freeof metaBits, this // has to stop somewhere! // No more allocations must be made immediateFree((int) m_metaBitsAddr, oldMetaBitsSize); - m_metaBitsAddr = 0; } + m_metaBitsAddr = nmbaddr; + } + if (m_metaBitsAddr == 0) { // Allocate special region to be able to store maximum metabits (128k of 2 64K demi-space // Must be aligned on 128K boundary and allocations are made in units of 64K. + // + // May need to extend the file for teh demi-space! while (m_nextAllocation % 2 != 0) { m_nextAllocation--; } m_metaBitsAddr = -m_nextAllocation; // must be positive to differentiate from FixedAllocator address m_nextAllocation -= 2; // allocate 2 * 64K - } else { // remove previous write from WCS - m_writeCacheService.removeWriteToAddr(convertAddr(-m_metaBitsAddr), 0); + + // Check for file extension + while (m_nextAllocation <= m_fileSize) { + extendFile(); + } + + if (log.isInfoEnabled()) + log.info("Using Demi-space metabits"); } + if (m_metaBitsAddr > 0) { // Demi-Space // Now "toggle" m_metaBitsAddr - 64K boundary m_metaBitsAddr ^= 0x01; // toggle zero or 64K offset + } + + if (log.isDebugEnabled()) { + final long mbaddr; + if (m_metaBitsAddr < 0) { + mbaddr = physicalAddress((int) m_metaBitsAddr); + } else { + mbaddr = convertAddr(-m_metaBitsAddr); // maximum 48 bit address range + } + log.debug("Writing metabits at " + mbaddr); + } + // There must be no buffered deferred frees // assert m_deferredFreeOut.getBytesWritten() == 0; @@ -3220,9 +3295,6 @@ throw new RuntimeException(e); } - // Now remember the committed next allocation that will be checked in reset() - m_committedNextAllocation = m_nextAllocation; - // Should not write rootBlock, this is responsibility of client // to provide control // writeFileSpec(); @@ -3257,7 +3329,7 @@ log.debug(showAllocatorList()); } - + } /** @@ -3279,6 +3351,13 @@ if (!m_allocationWriteLock.isHeldByCurrentThread()) throw new IllegalMonitorStateException(); + if (m_commitState == null) { + log.warn("No current CommitState found on writeRootBlock call"); + } else { + m_commitState.commit(); + m_commitState = null; + } + for (FixedAllocator fa : m_commitList) { fa.postCommit(); @@ -3450,8 +3529,10 @@ * Versions * 0x0300 - extended header to include reserved ints * 0x0400 - removed explicit BlobAllocators + * 0x0500 - using metaBits demi-space */ final private int cVersion = 0x0400; + final private int cVersionDemispace = 0x0500; /** * cReservedMetaBits is the reserved space in the metaBits header @@ -4103,24 +4184,10 @@ lock.lock(); try { - if (addr == 0) { - return 0L; - } else if (addr > 0) { - /* - * It used to be that a positive address indicated an - * absolute address. But this is no longer utilised - * by the RWStore use cases. - * - * Instead we intend to use a positive address to reference - * a ConstantAllocator. In such a scenario the 32 bit - * address is not sufficient. we need the full 64 bit value - * that includes the length in the low 16 bits, so that we - * can access a 48 bit value to identify the correct - * constant allocation. - */ + if (addr >= 0) { - throw new IllegalArgumentException("Address cannot be positive"); + return addr & 0xFFFFFFE0; } else { @@ -4247,14 +4314,20 @@ * @return long representation of metaBitsAddr PLUS the size */ public long getMetaBitsAddr() { - assert m_metaBitsAddr > 0; + long ret = 0; + if (m_metaBitsAddr < 0) { + ret = physicalAddress((int) m_metaBitsAddr); + } else { // long ret = physicalAddress((int) m_metaBitsAddr); - long ret = convertAddr(-m_metaBitsAddr); // maximum 48 bit address range + ret = convertAddr(-m_metaBitsAddr); // maximum 48 bit address range + } ret <<= 16; - // include space for version, allocSizes and deferred free info AND cDefaultMetaBitsSize - final int metaBitsSize = cMetaHdrFields + m_metaBits.length + m_allocSizes.length; + // include space for version, allocSizes and deferred free info AND + // cDefaultMetaBitsSize + final int metaBitsSize = cMetaHdrFields + m_metaBits.length + + m_allocSizes.length; ret += metaBitsSize; if (log.isTraceEnabled()) @@ -4267,10 +4340,14 @@ /** * - * @return the address of the metaBits demi-space + * @return the address of the metaBits */ - public long getMetaBitsDemiSpace() { - return convertAddr(-m_metaBitsAddr); + public long getMetaBitsStoreAddress() { + if (m_metaBitsAddr < 0) { + return physicalAddress((int) m_metaBitsAddr); + } else { + return convertAddr(-m_metaBitsAddr); // maximum 48 bit address range + } } /** @@ -7202,6 +7279,31 @@ return ret; } + /** + * Forces a reset of the metabits allocation on the next commit. + * <p> + * Note that a side-effect of this is that there will be a memory leak + * of either a FixedAllocation slot or an existing demi-space. + * <p> + * @param useDemispace + * @return whether the storage has been modified. + */ + public boolean ensureMetabitsDemispace(final boolean useDemispace) { + final boolean isDemispace = m_metaBitsAddr > 0; + + if (isDemispace != useDemispace || m_useMetabitsDemispace != useDemispace) { + m_useMetabitsDemispace = useDemispace; + + m_metaBitsAddr = 0; + + m_recentAlloc = true; // force commit + + return true; + } else { + return false; + } + } + // public void prepareForRebuild(final HARebuildRequest req) { // assert m_rebuildRequest == null; // Modified: branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java =================================================================== --- branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2014-07-01 18:44:22 UTC (rev 8513) +++ branches/RWSTORE_COMMITSTATE_973/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2014-07-02 11:06:04 UTC (rev 8514) @@ -2012,6 +2012,71 @@ } } + public void test_commitState() { + Journal store = (Journal) getStore(); + try { + + RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + RWStore rws = bs.getStore(); + + final long addr = bs.write(randomData(78)); + + rws.commit(); + + store.abort(); + + assertFalse(bs.isCommitted(addr)); // rolled back + + // now cycle standard commit to confirm correct reset + for (int c = 0; c < 50; c++) { + bs.write(randomData(78)); + store.commit(); + } + + + } finally { + store.destroy(); + } + } + + public void test_commitStateError() { + Journal store = (Journal) getStore(); + try { + + RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + RWStore rws = bs.getStore(); + + final long addr = bs.write(randomData(78)); + + rws.commit(); + + // remove the commit state that ensures correct reset + rws.m_commitState = null; + + store.abort(); + + assertFalse(bs.isCommitted(addr)); // rolled back + + try { + // now cycle standard commit to force an error from bad reset + for (int c = 0; c < 50; c++) { + bs.write(randomData(78)); + store.commit(); + } + fail("Expected failure"); + } catch (Exception e) { + // expected + log.info("Expected!"); + } + + + } finally { + store.destroy(); + } + } + public void test_allocCommitFreeWithHistory() { Journal store = (Journal) getStore(4); try { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-07-01 18:44:30
|
Revision: 8513 http://sourceforge.net/p/bigdata/code/8513 Author: thompsonbry Date: 2014-07-01 18:44:22 +0000 (Tue, 01 Jul 2014) Log Message: ----------- Bug fix for deadlock that could arise in the BigdataTriplePatternMaterializer if an input chunk produced more than one output chunk. The fix changes the queue type from blocking (fixed capacity) to linked (no fixed capacity). Note: This could create a problem if the caller fails to drain the output queue and fails to cancel the operation since a high cardinality result could cause the output queue to grow without bound. See #985 (Deadlock in BigdataTriplePatternMaterializer) Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BigdataTriplePatternMaterializer.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BigdataTriplePatternMaterializer.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BigdataTriplePatternMaterializer.java 2014-06-30 17:39:05 UTC (rev 8512) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-rdf/src/java/com/bigdata/rdf/store/BigdataTriplePatternMaterializer.java 2014-07-01 18:44:22 UTC (rev 8513) @@ -26,9 +26,9 @@ import java.util.LinkedList; import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; +import java.util.Queue; import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -118,14 +118,17 @@ if (helperService == null) throw new IllegalStateException(); - /* + /** * The output will be at most sizeof(chunk) arrays. Each array will have * one or more statements. Any triple patterns that have no intersection * in the data will be dropped and will not put anything into this * output queue. + * + * @see <a href="http://trac.bigdata.com/ticket/985" > Deadlock in + * BigdataTriplePatternMaterializer </a> */ - final BlockingQueue<ISPO[]> out = new ArrayBlockingQueue<ISPO[]>( - chunk.length); + final Queue<ISPO[]> out = new ConcurrentLinkedQueue<ISPO[]>( + /*chunk.length*/); final List<FutureTask<Long>> tasks = new LinkedList<FutureTask<Long>>(); @@ -151,6 +154,7 @@ * Hook future to count down the latch when the task is * done. */ + @Override public void run() { try { super.run(); @@ -223,10 +227,10 @@ private class ResolveTriplePatternTask implements Callable<Long> { private final BigdataTriplePattern stmt; - private final BlockingQueue<ISPO[]> out; + private final Queue<ISPO[]> out; public ResolveTriplePatternTask(final BigdataTriplePattern stmt, - final BlockingQueue<ISPO[]> out) { + final Queue<ISPO[]> out) { this.stmt = stmt; this.out = out; } @@ -273,7 +277,14 @@ // throw new AssertionError(Arrays.toString(a)); // } // } - out.put(a); + /** + * This will never fail for a ConcurrentLinkedQueue. + * + * @see <a href="http://trac.bigdata.com/ticket/985" > + * Deadlock in BigdataTriplePatternMaterializer </a> + */ + final boolean result = out.offer(a); + assert result : "insertion failed - expects an unbounded queue"; n += a.length; } return n; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tob...@us...> - 2014-06-30 17:39:15
|
Revision: 8512 http://sourceforge.net/p/bigdata/code/8512 Author: tobycraig Date: 2014-06-30 17:39:05 +0000 (Mon, 30 Jun 2014) Log Message: ----------- Made Banner.getVersion return null instead of "unknown" and fixed formatting Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java 2014-06-30 13:10:31 UTC (rev 8511) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/Banner.java 2014-06-30 17:39:05 UTC (rev 8512) @@ -378,27 +378,27 @@ } - /** - * Attempts to return the build version (aka the release version) from the - * <code>com.bigdata.BuildInfo</code> class. This class is generated by - * <code>build.xml</code> and is NOT available from the IDE. It is correct - * discovered using reflection. - * - * @return Build version if available and <code>unknown</code> otherwise. - * - * @see #getBuildInfo() - */ - public final static String getVersion() { + /** + * Attempts to return the build version (aka the release version) from the + * <code>com.bigdata.BuildInfo</code> class. This class is generated by + * <code>build.xml</code> and is NOT available from the IDE. It is correct + * discovered using reflection. + * + * @return Build version if available and <code>unknown</code> otherwise. + * + * @see #getBuildInfo() + */ + public final static String getVersion() { - if (getBuildInfo().isEmpty()) { - - return "unknown"; - - } + if (getBuildInfo().isEmpty()) { - return getBuildInfo().get(BuildInfoMeta.buildVersion); + return null; - } + } + + return getBuildInfo().get(BuildInfoMeta.buildVersion); + + } /** * Outputs the banner and exits. Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java 2014-06-30 13:10:31 UTC (rev 8511) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java 2014-06-30 17:39:05 UTC (rev 8512) @@ -890,78 +890,80 @@ } - /** - * Basic server health info - * - * @param req - * @param resp - * @throws TimeoutException - * @throws InterruptedException - * @throws AsynchronousQuorumCloseException - * @throws IOException - */ - public void doHealthStatus(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { + /** + * Basic server health info + * + * @param req + * @param resp + * @throws TimeoutException + * @throws InterruptedException + * @throws AsynchronousQuorumCloseException + * @throws IOException + */ + public void doHealthStatus(final HttpServletRequest req, + final HttpServletResponse resp) throws IOException { - if (!(indexManager instanceof HAJournal)) - return; + if (!(indexManager instanceof HAJournal)) + return; - final HAJournal journal = (HAJournal) indexManager; + final HAJournal journal = (HAJournal) indexManager; - final Quorum<HAGlue, QuorumService<HAGlue>> quorum = journal - .getQuorum(); - - StringWriter writer = new StringWriter(); - JsonFactory factory = new JsonFactory(); - JsonGenerator json = factory.createGenerator(writer); - - json.writeStartObject(); - - json.writeStringField("version", Banner.getVersion()); - json.writeNumberField("timestamp", new Date().getTime()); - if(quorum.isQuorumFullyMet(quorum.token())) { - json.writeStringField("status", "Good"); - json.writeStringField("details", "All servers joined"); - } else { - // at least one server is not available, so status is either Warning or Bad - if(quorum.isQuorumMet()) { - json.writeStringField("status", "Warning"); - } else { - json.writeStringField("status", "Bad"); - } - json.writeStringField("details", "Only " + quorum.getJoined().length + " of target " + - quorum.replicationFactor() + " servers joined"); - } + final Quorum<HAGlue, QuorumService<HAGlue>> quorum = journal.getQuorum(); - json.writeFieldName("services"); - json.writeStartArray(); - - final UUID[] joined = quorum.getJoined(); - final UUID[] pipeline = quorum.getPipeline(); + StringWriter writer = new StringWriter(); + JsonFactory factory = new JsonFactory(); + JsonGenerator json = factory.createGenerator(writer); - for (UUID serviceId : pipeline) { - final boolean isLeader = serviceId.equals(quorum.getLeaderId()); - final boolean isFollower = indexOf(serviceId, joined) > 0; + json.writeStartObject(); - json.writeStartObject(); - json.writeStringField("id", serviceId.toString()); - json.writeStringField("status", isLeader ? "leader" : (isFollower ? "follower" : "unready")); - json.writeEndObject(); - } - - json.writeEndArray(); - json.writeEndObject(); - json.close(); - - // TODO Alternatively "max-age=1" for max-age in seconds. - resp.addHeader("Cache-Control", "no-cache"); + json.writeStringField("version", Banner.getVersion()); + json.writeNumberField("timestamp", new Date().getTime()); + if (quorum.isQuorumFullyMet(quorum.token())) { + json.writeStringField("status", "Good"); + json.writeStringField("details", "All servers joined"); + } else { + // at least one server is not available + // status is either Warning or Bad + if (quorum.isQuorumMet()) { + json.writeStringField("status", "Warning"); + } else { + json.writeStringField("status", "Bad"); + } + json.writeStringField("details", "Only " + quorum.getJoined().length + + " of target " + quorum.replicationFactor() + + " servers joined"); + } - BigdataRDFServlet.buildResponse(resp, BigdataRDFServlet.HTTP_OK, - BigdataRDFServlet.MIME_APPLICATION_JSON, writer.toString()); + json.writeFieldName("services"); + json.writeStartArray(); - return; - - } + final UUID[] pipeline = quorum.getPipeline(); + final UUID[] joined = quorum.getJoined(); + + for (UUID serviceId : pipeline) { + final boolean isLeader = serviceId.equals(quorum.getLeaderId()); + final boolean isFollower = indexOf(serviceId, joined) > 0; + + json.writeStartObject(); + json.writeStringField("id", serviceId.toString()); + json.writeStringField("status", isLeader ? "leader" + : (isFollower ? "follower" : "unready")); + json.writeEndObject(); + } + + json.writeEndArray(); + json.writeEndObject(); + json.close(); + + // TODO Alternatively "max-age=1" for max-age in seconds. + resp.addHeader("Cache-Control", "no-cache"); + + BigdataRDFServlet.buildResponse(resp, BigdataRDFServlet.HTTP_OK, + BigdataRDFServlet.MIME_APPLICATION_JSON, writer.toString()); + + return; + + } // /** // * Impose a lexical ordering on the file names. This is used for the HALog This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-06-30 13:10:34
|
Revision: 8511 http://sourceforge.net/p/bigdata/code/8511 Author: thompsonbry Date: 2014-06-30 13:10:31 +0000 (Mon, 30 Jun 2014) Log Message: ----------- javadoc on the metabits util and linked it to the ticket and the data migration pages. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-06-30 13:09:38 UTC (rev 8510) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2014-06-30 13:10:31 UTC (rev 8511) @@ -3487,6 +3487,15 @@ * 0x0500 - using metaBits demi-space */ final private int cVersion = 0x0400; + /** + * The {@link #cVersion} value corresponding to the use of the demi-space + * for the metabits. + * + * @see <a href="http://trac.bigdata.com/ticket/936"> Support larger metabit + * allocations</a> + * @see <a href="http://wiki.bigdata.com/wiki/index.php/DataMigration" > + * Data migration </a> + */ final private int cVersionDemispace = 0x0500; /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2014-06-30 13:09:45
|
Revision: 8510 http://sourceforge.net/p/bigdata/code/8510 Author: thompsonbry Date: 2014-06-30 13:09:38 +0000 (Mon, 30 Jun 2014) Log Message: ----------- javadoc on the metabits util and linked it to the ticket and the data migration pages. Modified Paths: -------------- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/MetabitsUtil.java Modified: branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/MetabitsUtil.java =================================================================== --- branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/MetabitsUtil.java 2014-06-30 13:03:14 UTC (rev 8509) +++ branches/BIGDATA_RELEASE_1_3_0/bigdata/src/java/com/bigdata/rwstore/MetabitsUtil.java 2014-06-30 13:09:38 UTC (rev 8510) @@ -27,10 +27,9 @@ import java.util.Properties; import com.bigdata.journal.BufferMode; -import com.bigdata.journal.RWStrategy; import com.bigdata.journal.Journal; import com.bigdata.journal.Journal.Options; -import com.bigdata.rawstore.IRawStore; +import com.bigdata.journal.RWStrategy; /** * A utility class to explicitly change the metabits storage to allow for @@ -40,9 +39,16 @@ * support stores with large numbers of allocations. If such a store needs to be * opened by an earlier code-base, then the store must be amended to store the * metabits in a standard allocation. + * <p> + * It is only possible to set the metabits demi-space mode to <code>false</code> + * if the size of the metabits region is less than or equal to the maximum slot + * size for the declared alloctors. * * @author Martyn Cutcher - * + * @see <a href="http://trac.bigdata.com/ticket/936"> Support larger metabit + * allocations</a> + * @see <a href="http://wiki.bigdata.com/wiki/index.php/DataMigration" > Data + * migration </a> */ public class MetabitsUtil { @@ -55,7 +61,7 @@ return def; } - static Journal getStore(String storeFile) { + static Journal getStore(final String storeFile) { final Properties properties = new Properties(); @@ -68,12 +74,14 @@ } - /** - * Example usage: - * <p> - * MatabitsUtil -store "/path/store.jnl" -usedemispace true - */ - static public void main(final String[] args) { + /** + * Example usage: + * + * <pre> + * MatabitsUtil -store "/path/store.jnl" -usedemispace true + * </pre> + */ + static public void main(final String[] args) { final String store = getArg(args, "-store", null); if (store == null) { System.err.println("file must be specificed with -store"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |