http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfDAOException.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfDAOException.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfDAOException.java new file mode 100644 index 0000000..54444d4 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfDAOException.java @@ -0,0 +1,44 @@ +package mvm.rya.api.persist; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +/** + * Class RdfDAOException + * Date: Feb 28, 2012 + * Time: 3:39:36 PM + */ +public class RdfDAOException extends RuntimeException { + public RdfDAOException() { + } + + public RdfDAOException(String s) { + super(s); + } + + public RdfDAOException(String s, Throwable throwable) { + super(s, throwable); + } + + public RdfDAOException(Throwable throwable) { + super(throwable); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfEvalStatsDAO.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfEvalStatsDAO.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfEvalStatsDAO.java new file mode 100644 index 0000000..020464b --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/RdfEvalStatsDAO.java @@ -0,0 +1,54 @@ +package mvm.rya.api.persist; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import java.util.List; + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; + +import org.openrdf.model.Resource; +import org.openrdf.model.Value; + +/** + * Class RdfEvalStatsDAO + * Date: Feb 28, 2012 + * Time: 4:17:05 PM + */ +public interface RdfEvalStatsDAO<C extends RdfCloudTripleStoreConfiguration> { + public enum CARDINALITY_OF { + SUBJECT, PREDICATE, OBJECT, SUBJECTPREDICATE, SUBJECTOBJECT, PREDICATEOBJECT + } + + public void init() throws RdfDAOException; + + public boolean isInitialized() throws RdfDAOException; + + public void destroy() throws RdfDAOException; + + public double getCardinality(C conf, CARDINALITY_OF card, List<Value> val) throws RdfDAOException; + public double getCardinality(C conf, CARDINALITY_OF card, List<Value> val, Resource context) throws RdfDAOException; + + public void setConf(C conf); + + public C getConf(); + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaConfigured.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaConfigured.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaConfigured.java new file mode 100644 index 0000000..00c246e --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaConfigured.java @@ -0,0 +1,35 @@ +package mvm.rya.api.persist; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; + +/** + * Date: 7/17/12 + * Time: 8:24 AM + */ +public interface RyaConfigured<C extends RdfCloudTripleStoreConfiguration> { + + public void setConf(C conf); + + public C getConf(); +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAO.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAO.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAO.java new file mode 100644 index 0000000..e326f7d --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAO.java @@ -0,0 +1,126 @@ +package mvm.rya.api.persist; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import java.util.Iterator; + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.persist.query.RyaQueryEngine; + +/** + * Provides the access layer to the Rya triple store. + * + * Date: Feb 28, 2012 + * Time: 3:30:14 PM + */ +public interface RyaDAO<C extends RdfCloudTripleStoreConfiguration> extends RyaConfigured<C> { + + /** + * Initialize the RyaDAO. Should only be called once, otherwise, if already initialized, it will + * throw an exception. + * + * @throws RyaDAOException + */ + public void init() throws RyaDAOException; + + /** + * + * @return true if the store is already initiailized + * @throws RyaDAOException + */ + public boolean isInitialized() throws RyaDAOException; + + /** + * Shutdown the store. To reinitialize, call the init() method. + * + * @throws RyaDAOException + */ + public void destroy() throws RyaDAOException; + + /** + * Add and commit a single RyaStatement + * + * @param statement + * @throws RyaDAOException + */ + public void add(RyaStatement statement) throws RyaDAOException; + + /** + * Add and commit a collection of RyaStatements + * + * @param statement + * @throws RyaDAOException + */ + public void add(Iterator<RyaStatement> statement) throws RyaDAOException; + + /** + * Delete a RyaStatement. The Configuration should provide the auths to perform the delete + * + * @param statement + * @param conf + * @throws RyaDAOException + */ + public void delete(RyaStatement statement, C conf) throws RyaDAOException; + + /** + * Drop a set of Graphs. The Configuration should provide the auths to perform the delete + * + * @param conf + * @throws RyaDAOException + */ + public void dropGraph(C conf, RyaURI... graphs) throws RyaDAOException; + + /** + * Delete a collection of RyaStatements. + * + * @param statements + * @param conf + * @throws RyaDAOException + */ + public void delete(Iterator<RyaStatement> statements, C conf) throws RyaDAOException; + + /** + * Get the version of the store. + * + * @return + * @throws RyaDAOException + */ + public String getVersion() throws RyaDAOException; + + /** + * Get the Rya query engine + * @return + */ + public RyaQueryEngine<C> getQueryEngine(); + + /** + * Get the Rya Namespace Manager + * @return + */ + public RyaNamespaceManager<C> getNamespaceManager(); + + public void purge(RdfCloudTripleStoreConfiguration configuration); + + public void dropAndDestroy() throws RyaDAOException; +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAOException.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAOException.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAOException.java new file mode 100644 index 0000000..2322119 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaDAOException.java @@ -0,0 +1,43 @@ +package mvm.rya.api.persist; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +/** + * Date: 7/17/12 + * Time: 8:20 AM + */ +public class RyaDAOException extends Exception { + public RyaDAOException() { + } + + public RyaDAOException(String s) { + super(s); + } + + public RyaDAOException(String s, Throwable throwable) { + super(s, throwable); + } + + public RyaDAOException(Throwable throwable) { + super(throwable); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaNamespaceManager.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaNamespaceManager.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaNamespaceManager.java new file mode 100644 index 0000000..77cd4bd --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/RyaNamespaceManager.java @@ -0,0 +1,41 @@ +package mvm.rya.api.persist; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import org.openrdf.model.Namespace; + +/** + * Date: 7/17/12 + * Time: 8:23 AM + */ +public interface RyaNamespaceManager<C extends RdfCloudTripleStoreConfiguration> extends RyaConfigured<C> { + + public void addNamespace(String pfx, String namespace) throws RyaDAOException; + + public String getNamespace(String pfx) throws RyaDAOException; + + public void removeNamespace(String pfx) throws RyaDAOException; + + public CloseableIteration<? extends Namespace, RyaDAOException> iterateNamespace() throws RyaDAOException; +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java new file mode 100644 index 0000000..4047670 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java @@ -0,0 +1,63 @@ +package mvm.rya.api.persist.index; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import java.util.Collection; +import java.util.Set; + +import org.apache.hadoop.conf.Configurable; +import org.openrdf.model.URI; + +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaURI; + +public interface RyaSecondaryIndexer extends Closeable, Flushable, Configurable { + + /** + * Returns the table name if the implementation supports it. + * Note that some indexers use multiple tables, this only returns one. + * TODO recommend that we deprecate this method because it's a leaky interface. + * @return table name as a string. + */ + public String getTableName(); + + public void storeStatements(Collection<RyaStatement> statements) throws IOException; + + public void storeStatement(RyaStatement statement) throws IOException; + + public void deleteStatement(RyaStatement stmt) throws IOException; + + public void dropGraph(RyaURI... graphs); + + /** + * @return the set of predicates indexed by the indexer. + */ + public abstract Set<URI> getIndexablePredicates(); + + @Override + public abstract void flush() throws IOException; + + @Override + public abstract void close() throws IOException; +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/joinselect/SelectivityEvalDAO.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/joinselect/SelectivityEvalDAO.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/joinselect/SelectivityEvalDAO.java new file mode 100644 index 0000000..28f797b --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/joinselect/SelectivityEvalDAO.java @@ -0,0 +1,37 @@ +package mvm.rya.api.persist.joinselect; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.persist.RdfEvalStatsDAO; +import org.openrdf.query.algebra.StatementPattern; +import org.openrdf.query.algebra.TupleExpr; + +public interface SelectivityEvalDAO<C extends RdfCloudTripleStoreConfiguration> extends RdfEvalStatsDAO<C> { + + public double getJoinSelect(C conf, TupleExpr te1, TupleExpr te2) throws Exception; + + public long getCardinality(C conf, StatementPattern sp) throws Exception; + + public int getTableSize(C conf) throws Exception; + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/BatchRyaQuery.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/BatchRyaQuery.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/BatchRyaQuery.java new file mode 100644 index 0000000..113ce51 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/BatchRyaQuery.java @@ -0,0 +1,115 @@ +package mvm.rya.api.persist.query; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.domain.RyaStatement; + +/** + * Query domain object contains the query to run as a {@link mvm.rya.api.domain.RyaStatement} and options for running the query + */ +public class BatchRyaQuery extends RyaQueryOptions { + + //queries + private Iterable<RyaStatement> queries; + + //maximum number of ranges before we use a batchScanner + private int maxRanges = 2; + + public BatchRyaQuery(Iterable<RyaStatement> queries) { + Preconditions.checkNotNull(queries, "RyaStatement queries cannot be null"); + this.queries = queries; + } + + public static RyaBatchQueryBuilder builder(Iterable<RyaStatement> queries) { + return new RyaBatchQueryBuilder(queries); + } + + public static class RyaBatchQueryBuilder extends RyaOptionsBuilder<RyaBatchQueryBuilder> { + private BatchRyaQuery ryaQuery; + + public RyaBatchQueryBuilder(Iterable<RyaStatement> queries) { + this(new BatchRyaQuery(queries)); + } + + public RyaBatchQueryBuilder(BatchRyaQuery query) { + super(query); + this.ryaQuery = query; + } + + public RyaBatchQueryBuilder setMaxRanges(int maxRanges) { + ryaQuery.setMaxRanges(maxRanges); + return this; + } + + public BatchRyaQuery build() { + return ryaQuery; + } + } + + public Iterable<RyaStatement> getQueries() { + return queries; + } + + public void setQueries(Iterable<RyaStatement> queries) { + this.queries = queries; + } + + public int getMaxRanges() { + return maxRanges; + } + + public void setMaxRanges(int maxRanges) { + this.maxRanges = maxRanges; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + BatchRyaQuery that = (BatchRyaQuery) o; + + if (queries != null ? !queries.equals(that.queries) : that.queries != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (queries != null ? queries.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "BatchRyaQuery{" + + "queries=" + Iterables.toString(queries) + + "options={" + super.toString() + + '}' + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQuery.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQuery.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQuery.java new file mode 100644 index 0000000..5235989 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQuery.java @@ -0,0 +1,97 @@ +package mvm.rya.api.persist.query; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import com.google.common.base.Preconditions; +import mvm.rya.api.domain.RyaStatement; + +/** + * Query domain object contains the query to run as a {@link RyaStatement} and options for running the query + */ +public class RyaQuery extends RyaQueryOptions { + + //query + private RyaStatement query; + + public RyaQuery(RyaStatement query) { + Preconditions.checkNotNull(query, "RyaStatement query cannot be null"); + this.query = query; + } + + public static RyaQueryBuilder builder(RyaStatement query) { + return new RyaQueryBuilder(query); + } + + public static class RyaQueryBuilder extends RyaOptionsBuilder<RyaQueryBuilder> { + private RyaQuery ryaQuery; + + public RyaQueryBuilder(RyaStatement query) { + this(new RyaQuery(query)); + } + + public RyaQueryBuilder(RyaQuery query) { + super(query); + this.ryaQuery = query; + } + + public RyaQuery build() { + return ryaQuery; + } + } + + public RyaStatement getQuery() { + return query; + } + + public void setQuery(RyaStatement query) { + this.query = query; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + RyaQuery ryaQuery = (RyaQuery) o; + + if (query != null ? !query.equals(ryaQuery.query) : ryaQuery.query != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (query != null ? query.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "RyaQuery{" + + "query=" + query + + "options={" + super.toString() + + '}' + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryEngine.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryEngine.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryEngine.java new file mode 100644 index 0000000..7454eea --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryEngine.java @@ -0,0 +1,96 @@ +package mvm.rya.api.persist.query; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; + +import java.util.Collection; +import java.util.Map; + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.persist.RyaConfigured; +import mvm.rya.api.persist.RyaDAOException; + +import org.calrissian.mango.collect.CloseableIterable; +import org.openrdf.query.BindingSet; + +/** + * Rya Query Engine to perform queries against the Rya triple store. + * <p/> + * Date: 7/17/12 + * Time: 8:25 AM + */ +public interface RyaQueryEngine<C extends RdfCloudTripleStoreConfiguration> extends RyaConfigured<C> { + + /** + * Query the Rya store using the RyaStatement. The Configuration object provides information such as auths, ttl, etc + * + * @param stmt + * @param conf + * @return + * @throws RyaDAOException + * @deprecated + */ + public CloseableIteration<RyaStatement, RyaDAOException> query(RyaStatement stmt, C conf) throws RyaDAOException; + + /** + * Batch query + * + * @param stmts + * @param conf + * @return + * @throws RyaDAOException + */ + public CloseableIteration<? extends Map.Entry<RyaStatement, BindingSet>, RyaDAOException> + queryWithBindingSet(Collection<Map.Entry<RyaStatement, BindingSet>> stmts, C conf) throws RyaDAOException; + + /** + * Performs intersection joins. + * + * @param stmts + * @param conf + * @return + * @throws RyaDAOException + * @deprecated + */ + public CloseableIteration<RyaStatement, RyaDAOException> batchQuery(Collection<RyaStatement> stmts, C conf) throws RyaDAOException; + + /** + * Query with a {@link} RyaQuery. A single query that will return a {@link CloseableIterable} of RyaStatements + * + * @param ryaQuery + * @return + * @throws RyaDAOException + */ + public CloseableIterable<RyaStatement> query(RyaQuery ryaQuery) throws RyaDAOException; + + /** + * Run a batch rya query + * + * @param batchRyaQuery + * @return + * @throws RyaDAOException + */ + public CloseableIterable<RyaStatement> query(BatchRyaQuery batchRyaQuery) throws RyaDAOException; + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryOptions.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryOptions.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryOptions.java new file mode 100644 index 0000000..c77796e --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/RyaQueryOptions.java @@ -0,0 +1,246 @@ +package mvm.rya.api.persist.query; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +/** + */ +public class RyaQueryOptions { + private static final Logger logger = LoggerFactory.getLogger(RyaQueryOptions.class); + //options + protected String[] auths; + protected Long ttl; + protected Long currentTime; + protected Long maxResults; + protected Integer numQueryThreads = 4; + protected Integer batchSize = 1000; + protected String regexSubject; + protected String regexPredicate; + protected String regexObject; + protected RdfCloudTripleStoreConfiguration conf; + + public static class RyaOptionsBuilder<T extends RyaOptionsBuilder> { + private RyaQueryOptions options; + + public RyaOptionsBuilder(RyaQueryOptions query) { + this.options = query; + } + + public T load(RdfCloudTripleStoreConfiguration conf) { + options.setConf(conf); + return (T) this.setAuths(conf.getAuths()) + .setBatchSize(conf.getBatchSize()) + .setCurrentTime(conf.getStartTime()) + .setMaxResults(conf.getLimit()) + .setNumQueryThreads(conf.getNumThreads()) + .setRegexObject(conf.getRegexObject()) + .setRegexPredicate(conf.getRegexPredicate()) + .setRegexSubject(conf.getRegexSubject()) + .setTtl(conf.getTtl()); + } + + public T setAuths(String[] auths) { + options.setAuths(auths); + return (T) this; + } + + public T setRegexObject(String regexObject) { + options.setRegexObject(regexObject); + return (T) this; + } + + public T setRegexPredicate(String regexPredicate) { + options.setRegexPredicate(regexPredicate); + return (T) this; + } + + public T setRegexSubject(String regexSubject) { + options.setRegexSubject(regexSubject); + return (T) this; + } + + public T setBatchSize(Integer batchSize) { + options.setBatchSize(batchSize); + return (T) this; + } + + public T setNumQueryThreads(Integer numQueryThreads) { + options.setNumQueryThreads(numQueryThreads); + return (T) this; + } + + public T setMaxResults(Long maxResults) { + options.setMaxResults(maxResults); + return (T) this; + } + + public T setCurrentTime(Long currentTime) { + options.setCurrentTime(currentTime); + return (T) this; + } + + public T setTtl(Long ttl) { + options.setTtl(ttl); + return (T) this; + } + } + + public RdfCloudTripleStoreConfiguration getConf() { + return conf; + } + + public void setConf(RdfCloudTripleStoreConfiguration conf) { + this.conf = conf; + } + + public Long getTtl() { + return ttl; + } + + public void setTtl(Long ttl) { + this.ttl = ttl; + } + + public Long getCurrentTime() { + return currentTime; + } + + public void setCurrentTime(Long currentTime) { + this.currentTime = currentTime; + } + + public Integer getNumQueryThreads() { + return numQueryThreads; + } + + public void setNumQueryThreads(Integer numQueryThreads) { + this.numQueryThreads = numQueryThreads; + } + + public Long getMaxResults() { + return maxResults; + } + + public void setMaxResults(Long maxResults) { + this.maxResults = maxResults; + } + + public Integer getBatchSize() { + return batchSize; + } + + public void setBatchSize(Integer batchSize) { + this.batchSize = batchSize; + } + + public String getRegexSubject() { + return regexSubject; + } + + public void setRegexSubject(String regexSubject) { + this.regexSubject = regexSubject; + } + + public String getRegexPredicate() { + return regexPredicate; + } + + public void setRegexPredicate(String regexPredicate) { + this.regexPredicate = regexPredicate; + } + + public String getRegexObject() { + return regexObject; + } + + public void setRegexObject(String regexObject) { + this.regexObject = regexObject; + } + + public String[] getAuths() { + return auths; + } + + public void setAuths(String[] auths) { + if (auths == null) { + this.auths = new String[0]; + } else { + this.auths = auths.clone(); + } + } + + @Override + public String toString() { + return "RyaQueryOptions{" + + "auths=" + (auths == null ? null : Arrays.asList(auths)) + + ", ttl=" + ttl + + ", currentTime=" + currentTime + + ", maxResults=" + maxResults + + ", numQueryThreads=" + numQueryThreads + + ", batchSize=" + batchSize + + ", regexSubject='" + regexSubject + '\'' + + ", regexPredicate='" + regexPredicate + '\'' + + ", regexObject='" + regexObject + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RyaQueryOptions that = (RyaQueryOptions) o; + + if (!Arrays.equals(auths, that.auths)) return false; + if (batchSize != null ? !batchSize.equals(that.batchSize) : that.batchSize != null) return false; + if (currentTime != null ? !currentTime.equals(that.currentTime) : that.currentTime != null) return false; + if (maxResults != null ? !maxResults.equals(that.maxResults) : that.maxResults != null) return false; + if (numQueryThreads != null ? !numQueryThreads.equals(that.numQueryThreads) : that.numQueryThreads != null) + return false; + if (regexObject != null ? !regexObject.equals(that.regexObject) : that.regexObject != null) return false; + if (regexPredicate != null ? !regexPredicate.equals(that.regexPredicate) : that.regexPredicate != null) + return false; + if (regexSubject != null ? !regexSubject.equals(that.regexSubject) : that.regexSubject != null) return false; + if (ttl != null ? !ttl.equals(that.ttl) : that.ttl != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = auths != null ? Arrays.hashCode(auths) : 0; + result = 31 * result + (ttl != null ? ttl.hashCode() : 0); + result = 31 * result + (currentTime != null ? currentTime.hashCode() : 0); + result = 31 * result + (maxResults != null ? maxResults.hashCode() : 0); + result = 31 * result + (numQueryThreads != null ? numQueryThreads.hashCode() : 0); + result = 31 * result + (batchSize != null ? batchSize.hashCode() : 0); + result = 31 * result + (regexSubject != null ? regexSubject.hashCode() : 0); + result = 31 * result + (regexPredicate != null ? regexPredicate.hashCode() : 0); + result = 31 * result + (regexObject != null ? regexObject.hashCode() : 0); + return result; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/HashJoin.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/HashJoin.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/HashJoin.java new file mode 100644 index 0000000..286ea7a --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/HashJoin.java @@ -0,0 +1,158 @@ +package mvm.rya.api.persist.query.join; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.RdfCloudTripleStoreUtils; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaType; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.persist.query.RyaQueryEngine; +import mvm.rya.api.resolver.RyaContext; +import mvm.rya.api.utils.EnumerationWrapper; + +import java.util.Enumeration; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Use HashTable to do a HashJoin. + * <p/> + * TODO: Somehow make a more streaming way of doing this hash join. This will not support large sets. + * Date: 7/26/12 + * Time: 8:58 AM + */ +public class HashJoin<C extends RdfCloudTripleStoreConfiguration> implements Join<C> { + + private RyaContext ryaContext = RyaContext.getInstance(); + private RyaQueryEngine ryaQueryEngine; + + public HashJoin() { + } + + public HashJoin(RyaQueryEngine ryaQueryEngine) { + this.ryaQueryEngine = ryaQueryEngine; + } + + @Override + public CloseableIteration<RyaStatement, RyaDAOException> join(C conf, RyaURI... preds) throws RyaDAOException { + ConcurrentHashMap<Map.Entry<RyaURI, RyaType>, Integer> ht = new ConcurrentHashMap<Map.Entry<RyaURI, RyaType>, Integer>(); + int count = 0; + boolean first = true; + for (RyaURI pred : preds) { + count++; + //query + CloseableIteration<RyaStatement, RyaDAOException> results = ryaQueryEngine.query(new RyaStatement(null, pred, null), null); + //add to hashtable + while (results.hasNext()) { + RyaStatement next = results.next(); + RyaURI subject = next.getSubject(); + RyaType object = next.getObject(); + Map.Entry<RyaURI, RyaType> entry = new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(subject, object); + if (!first) { + if (!ht.containsKey(entry)) { + continue; //not in join + } + } + ht.put(entry, count); + } + //remove from hashtable values that are under count + if (first) { + first = false; + } else { + for (Map.Entry<Map.Entry<RyaURI, RyaType>, Integer> entry : ht.entrySet()) { + if (entry.getValue() < count) { + ht.remove(entry.getKey()); + } + } + } + } + final Enumeration<Map.Entry<RyaURI, RyaType>> keys = ht.keys(); + return new CloseableIteration<RyaStatement, RyaDAOException>() { + @Override + public void close() throws RyaDAOException { + + } + + @Override + public boolean hasNext() throws RyaDAOException { + return keys.hasMoreElements(); + } + + @Override + public RyaStatement next() throws RyaDAOException { + Map.Entry<RyaURI, RyaType> subjObj = keys.nextElement(); + return new RyaStatement(subjObj.getKey(), null, subjObj.getValue()); + } + + @Override + public void remove() throws RyaDAOException { + keys.nextElement(); + } + }; + } + + @Override + public CloseableIteration<RyaURI, RyaDAOException> join(C conf, Map.Entry<RyaURI, RyaType>... predObjs) throws RyaDAOException { + ConcurrentHashMap<RyaURI, Integer> ht = new ConcurrentHashMap<RyaURI, Integer>(); + int count = 0; + boolean first = true; + for (Map.Entry<RyaURI, RyaType> predObj : predObjs) { + count++; + RyaURI pred = predObj.getKey(); + RyaType obj = predObj.getValue(); + //query + CloseableIteration<RyaStatement, RyaDAOException> results = ryaQueryEngine.query(new RyaStatement(null, pred, obj), null); + //add to hashtable + while (results.hasNext()) { + RyaURI subject = results.next().getSubject(); + if (!first) { + if (!ht.containsKey(subject)) { + continue; //not in join + } + } + ht.put(subject, count); + } + //remove from hashtable values that are under count + if (first) { + first = false; + } else { + for (Map.Entry<RyaURI, Integer> entry : ht.entrySet()) { + if (entry.getValue() < count) { + ht.remove(entry.getKey()); + } + } + } + } + return new EnumerationWrapper<RyaURI, RyaDAOException>(ht.keys()); + } + + public RyaQueryEngine getRyaQueryEngine() { + return ryaQueryEngine; + } + + public void setRyaQueryEngine(RyaQueryEngine ryaQueryEngine) { + this.ryaQueryEngine = ryaQueryEngine; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/IterativeJoin.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/IterativeJoin.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/IterativeJoin.java new file mode 100644 index 0000000..3cb48a5 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/IterativeJoin.java @@ -0,0 +1,233 @@ +package mvm.rya.api.persist.query.join; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import com.google.common.base.Preconditions; +import info.aduna.iteration.CloseableIteration; +import info.aduna.iteration.ConvertingIteration; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.RdfCloudTripleStoreUtils; +import mvm.rya.api.domain.*; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.persist.query.RyaQueryEngine; +import mvm.rya.api.resolver.RyaContext; +import org.openrdf.query.BindingSet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +/** + * Date: 7/24/12 + * Time: 8:52 AM + */ +public class IterativeJoin<C extends RdfCloudTripleStoreConfiguration> implements Join<C> { + + private RyaContext ryaContext = RyaContext.getInstance(); + private RyaQueryEngine ryaQueryEngine; + + public IterativeJoin() { + } + + public IterativeJoin(RyaQueryEngine ryaQueryEngine) { + this.ryaQueryEngine = ryaQueryEngine; + } + + /** + * Return all statements that have input predicates. Predicates must not be null or ranges + * + * @param preds + * @return + */ + @Override + public CloseableIteration<RyaStatement, RyaDAOException> join(C conf, RyaURI... preds) + throws RyaDAOException { + Preconditions.checkNotNull(preds); + Preconditions.checkArgument(preds.length > 1, "Must join 2 or more"); + //TODO: Reorder predObjs based on statistics + + CloseableIteration<RyaStatement, RyaDAOException> iter = null; + for (RyaURI pred : preds) { + if (iter == null) { + iter = ryaQueryEngine.query(new RyaStatement(null, pred, null), null); + } else { + iter = join(iter, pred); + } + } + + return iter; + } + + /** + * Return all subjects that have the predicate objects associated. Predicate and objects must be not null or ranges + * to ensure sorting + * + * @param predObjs + * @return + * @throws mvm.rya.api.persist.RyaDAOException + * + */ + @Override + public CloseableIteration<RyaURI, RyaDAOException> join(C conf, Map.Entry<RyaURI, RyaType>... predObjs) + throws RyaDAOException { + Preconditions.checkNotNull(predObjs); + Preconditions.checkArgument(predObjs.length > 1, "Must join 2 or more"); + + //TODO: Reorder predObjs based on statistics + CloseableIteration<RyaStatement, RyaDAOException> first = null; + CloseableIteration<RyaURI, RyaDAOException> iter = null; + for (Map.Entry<RyaURI, RyaType> entry : predObjs) { + if (first == null) { + first = ryaQueryEngine.query(new RyaStatement(null, entry.getKey(), entry.getValue()), null); + } else if (iter == null) { + iter = join(new ConvertingIteration<RyaStatement, RyaURI, RyaDAOException>(first) { + + @Override + protected RyaURI convert(RyaStatement statement) throws RyaDAOException { + return statement.getSubject(); + } + }, entry); + } else { + iter = join(iter, entry); + } + } + + return iter; + } + + protected CloseableIteration<RyaURI, RyaDAOException> join(final CloseableIteration<RyaURI, RyaDAOException> iteration, + final Map.Entry<RyaURI, RyaType> predObj) { + //TODO: configure batch + //TODO: batch = 1, does not work + final int batch = 100; + return new CloseableIteration<RyaURI, RyaDAOException>() { + + private CloseableIteration<Map.Entry<RyaStatement, BindingSet>, RyaDAOException> query; + + @Override + public void close() throws RyaDAOException { + iteration.close(); + if (query != null) { + query.close(); + } + } + + @Override + public boolean hasNext() throws RyaDAOException { + return !(query == null || !query.hasNext()) || batchNext(); + } + + @Override + public RyaURI next() throws RyaDAOException { + if (query == null || !query.hasNext()) { + if (!batchNext()) return null; + } + if (query != null && query.hasNext()) { + return query.next().getKey().getSubject(); + } else { + return null; + } + } + + private boolean batchNext() throws RyaDAOException { + if (!iteration.hasNext()) { + return false; + } + Collection<Map.Entry<RyaStatement, BindingSet>> batchedResults = new ArrayList<Map.Entry<RyaStatement, BindingSet>>(); + for (int i = 0; i < batch && iteration.hasNext(); i++) { + batchedResults.add(new RdfCloudTripleStoreUtils.CustomEntry<RyaStatement, BindingSet>( + new RyaStatement(iteration.next(), predObj.getKey(), predObj.getValue()), null)); + } + query = ryaQueryEngine.queryWithBindingSet(batchedResults, null); + return query.hasNext(); + } + + @Override + public void remove() throws RyaDAOException { + this.next(); + } + }; + } + + protected CloseableIteration<RyaStatement, RyaDAOException> join( + final CloseableIteration<RyaStatement, RyaDAOException> iteration, final RyaURI pred) { + //TODO: configure batch + //TODO: batch = 1, does not work + final int batch = 100; + return new CloseableIteration<RyaStatement, RyaDAOException>() { + + private CloseableIteration<Map.Entry<RyaStatement, BindingSet>, RyaDAOException> query; + + @Override + public void close() throws RyaDAOException { + iteration.close(); + if (query != null) { + query.close(); + } + } + + @Override + public boolean hasNext() throws RyaDAOException { + return !(query == null || !query.hasNext()) || batchNext(); + } + + @Override + public RyaStatement next() throws RyaDAOException { + if (query == null || !query.hasNext()) { + if (!batchNext()) return null; + } + if (query != null && query.hasNext()) { + return query.next().getKey(); + } else { + return null; + } + } + + private boolean batchNext() throws RyaDAOException { + if (!iteration.hasNext()) { + return false; + } + Collection<Map.Entry<RyaStatement, BindingSet>> batchedResults = new ArrayList<Map.Entry<RyaStatement, BindingSet>>(); + for (int i = 0; i < batch && iteration.hasNext(); i++) { + RyaStatement next = iteration.next(); + batchedResults.add(new RdfCloudTripleStoreUtils.CustomEntry<RyaStatement, BindingSet>( + new RyaStatement(next.getSubject(), pred, next.getObject()), null)); + } + query = ryaQueryEngine.queryWithBindingSet(batchedResults, null); + return query.hasNext(); + } + + @Override + public void remove() throws RyaDAOException { + this.next(); + } + }; + } + + public RyaQueryEngine getRyaQueryEngine() { + return ryaQueryEngine; + } + + public void setRyaQueryEngine(RyaQueryEngine ryaQueryEngine) { + this.ryaQueryEngine = ryaQueryEngine; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/Join.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/Join.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/Join.java new file mode 100644 index 0000000..775af53 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/Join.java @@ -0,0 +1,44 @@ +package mvm.rya.api.persist.query.join; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaType; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.persist.RyaDAOException; + +import java.util.Map; + +/** + * Date: 7/24/12 + * Time: 4:28 PM + */ +public interface Join<C extends RdfCloudTripleStoreConfiguration> { + + CloseableIteration<RyaStatement, RyaDAOException> join(C conf, RyaURI... preds) + throws RyaDAOException; + + CloseableIteration<RyaURI, RyaDAOException> join(C conf, Map.Entry<RyaURI, RyaType>... predObjs) + throws RyaDAOException; +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/MergeJoin.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/MergeJoin.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/MergeJoin.java new file mode 100644 index 0000000..1dfcbf1 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/query/join/MergeJoin.java @@ -0,0 +1,244 @@ +package mvm.rya.api.persist.query.join; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import com.google.common.base.Preconditions; +import info.aduna.iteration.CloseableIteration; +import info.aduna.iteration.EmptyIteration; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.domain.*; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.persist.query.RyaQueryEngine; +import mvm.rya.api.resolver.RyaContext; +import mvm.rya.api.utils.PeekingCloseableIteration; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Date: 7/24/12 + * Time: 8:52 AM + */ +public class MergeJoin<C extends RdfCloudTripleStoreConfiguration> implements Join<C> { + + private RyaContext ryaContext = RyaContext.getInstance(); + private RyaQueryEngine ryaQueryEngine; + + public MergeJoin() { + } + + public MergeJoin(RyaQueryEngine ryaQueryEngine) { + this.ryaQueryEngine = ryaQueryEngine; + } + + /** + * Return all statements that have input predicates. Predicates must not be null or ranges + * + * @param preds + * @return + */ + @Override + public CloseableIteration<RyaStatement, RyaDAOException> join(C conf, RyaURI... preds) + throws RyaDAOException { + Preconditions.checkNotNull(preds); + Preconditions.checkArgument(preds.length > 1, "Must join 2 or more"); + //TODO: Reorder predObjs based on statistics + final List<CloseableIteration<RyaStatement, RyaDAOException>> iters = new ArrayList<CloseableIteration<RyaStatement, RyaDAOException>>(); + for (RyaURI predicate : preds) { + Preconditions.checkArgument(predicate != null && !(predicate instanceof RyaRange)); + + CloseableIteration<RyaStatement, RyaDAOException> iter = ryaQueryEngine.query(new RyaStatement(null, predicate, null), conf); + iters.add(iter); + } + Preconditions.checkArgument(iters.size() > 1, "Must join 2 or more"); + + final CloseableIteration<RyaStatement, RyaDAOException> first = iters.remove(0); + + //perform merge operation + + return new CloseableIteration<RyaStatement, RyaDAOException>() { + + private RyaStatement first_stmt; + private RyaType first_obj; + + @Override + public void close() throws RyaDAOException { + for (CloseableIteration<RyaStatement, RyaDAOException> iter : iters) { + iter.close(); + } + } + + @Override + public boolean hasNext() throws RyaDAOException { + return first_stmt != null || check(); + } + + @Override + public RyaStatement next() throws RyaDAOException { + if (first_stmt != null) { + RyaStatement temp = first_stmt; + first_stmt = null; + return temp; + } + if (check()) { + RyaStatement temp = first_stmt; + first_stmt = null; + return temp; + } + return null; + } + + @Override + public void remove() throws RyaDAOException { + this.next(); + } + + protected boolean check() throws RyaDAOException { + if (!first.hasNext()) return false; + first_stmt = first.next(); + first_obj = first_stmt.getObject(); + for (CloseableIteration<RyaStatement, RyaDAOException> iter : iters) { + if (!iter.hasNext()) return false; //no more left to join + RyaType iter_obj = iter.next().getObject(); + while (first_obj.compareTo(iter_obj) < 0) { + if (!first.hasNext()) return false; + first_obj = first.next().getObject(); + } + while (first_obj.compareTo(iter_obj) > 0) { + if (!iter.hasNext()) return false; + iter_obj = iter.next().getObject(); + } + } + return true; + } + }; + } + + /** + * Return all subjects that have the predicate objects associated. Predicate and objects must be not null or ranges + * to ensure sorting + * + * @param predObjs + * @return + * @throws RyaDAOException + */ + @Override + public CloseableIteration<RyaURI, RyaDAOException> join(C conf, Map.Entry<RyaURI, RyaType>... predObjs) + throws RyaDAOException { + Preconditions.checkNotNull(predObjs); + Preconditions.checkArgument(predObjs.length > 1, "Must join 2 or more"); + + //TODO: Reorder predObjs based on statistics + final List<CloseableIteration<RyaStatement, RyaDAOException>> iters = new ArrayList<CloseableIteration<RyaStatement, RyaDAOException>>(); + RyaURI earliest_subject = null; + for (Map.Entry<RyaURI, RyaType> predObj : predObjs) { + RyaURI predicate = predObj.getKey(); + RyaType object = predObj.getValue(); + Preconditions.checkArgument(predicate != null && !(predicate instanceof RyaRange)); + Preconditions.checkArgument(object != null && !(object instanceof RyaRange)); + + PeekingCloseableIteration<RyaStatement, RyaDAOException> iter = null; + if (earliest_subject == null) { + iter = new PeekingCloseableIteration<RyaStatement, RyaDAOException>( + ryaQueryEngine.query(new RyaStatement(null, predicate, object), conf)); + } else { + iter = new PeekingCloseableIteration<RyaStatement, RyaDAOException>( + ryaQueryEngine.query(new RyaStatement(new RyaURIRange(earliest_subject, RyaURIRange.LAST_URI), predicate, object), conf)); + } + if (!iter.hasNext()) { + return new EmptyIteration<RyaURI, RyaDAOException>(); + } + //setting up range to make performant query + earliest_subject = iter.peek().getSubject(); + iters.add(iter); + } + Preconditions.checkArgument(iters.size() > 1, "Must join 2 or more"); + + final CloseableIteration<RyaStatement, RyaDAOException> first = iters.remove(0); + + //perform merge operation + + return new CloseableIteration<RyaURI, RyaDAOException>() { + + private RyaURI first_subj; + + @Override + public void close() throws RyaDAOException { + for (CloseableIteration<RyaStatement, RyaDAOException> iter : iters) { + iter.close(); + } + } + + @Override + public boolean hasNext() throws RyaDAOException { + return first_subj != null || check(); + } + + @Override + public RyaURI next() throws RyaDAOException { + if (first_subj != null) { + RyaURI temp = first_subj; + first_subj = null; + return temp; + } + if (check()) { + RyaURI temp = first_subj; + first_subj = null; + return temp; + } + return null; + } + + @Override + public void remove() throws RyaDAOException { + this.next(); + } + + protected boolean check() throws RyaDAOException { + if (!first.hasNext()) return false; + first_subj = first.next().getSubject(); + for (CloseableIteration<RyaStatement, RyaDAOException> iter : iters) { + if (!iter.hasNext()) return false; //no more left to join + RyaURI iter_subj = iter.next().getSubject(); + while (first_subj.compareTo(iter_subj) < 0) { + if (!first.hasNext()) return false; + first_subj = first.next().getSubject(); + } + while (first_subj.compareTo(iter_subj) > 0) { + if (!iter.hasNext()) return false; + iter_subj = iter.next().getSubject(); + } + } + return true; + } + }; + } + + public RyaQueryEngine getRyaQueryEngine() { + return ryaQueryEngine; + } + + public void setRyaQueryEngine(RyaQueryEngine ryaQueryEngine) { + this.ryaQueryEngine = ryaQueryEngine; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDAOHelper.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDAOHelper.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDAOHelper.java new file mode 100644 index 0000000..81f42b4 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/utils/RyaDAOHelper.java @@ -0,0 +1,176 @@ +package mvm.rya.api.persist.utils; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.RdfCloudTripleStoreUtils; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.persist.RyaDAO; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.resolver.RdfToRyaConversions; +import mvm.rya.api.resolver.RyaToRdfConversions; +import mvm.rya.api.utils.NullableStatementImpl; +import org.openrdf.model.Resource; +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.query.BindingSet; +import org.openrdf.query.QueryEvaluationException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * Date: 7/20/12 + * Time: 10:36 AM + */ +public class RyaDAOHelper { + + public static CloseableIteration<Statement, QueryEvaluationException> query(RyaDAO ryaDAO, Resource subject, URI predicate, Value object, RdfCloudTripleStoreConfiguration conf, Resource... contexts) throws QueryEvaluationException { + return query(ryaDAO, new NullableStatementImpl(subject, predicate, object, contexts), conf); + } + + public static CloseableIteration<Statement, QueryEvaluationException> query(RyaDAO ryaDAO, Statement stmt, RdfCloudTripleStoreConfiguration conf) throws QueryEvaluationException { + final CloseableIteration<RyaStatement, RyaDAOException> query; + try { + query = ryaDAO.getQueryEngine().query(RdfToRyaConversions.convertStatement(stmt), + conf); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + //TODO: only support one context for now + return new CloseableIteration<Statement, QueryEvaluationException>() { //TODO: Create a new class struct for this + + private boolean isClosed = false; + @Override + public void close() throws QueryEvaluationException { + try { + isClosed = true; + query.close(); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + + @Override + public boolean hasNext() throws QueryEvaluationException { + try { + return query.hasNext(); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + + @Override + public Statement next() throws QueryEvaluationException { + if (!hasNext() || isClosed) { + throw new NoSuchElementException(); + } + + try { + RyaStatement next = query.next(); + if (next == null) { + return null; + } + return RyaToRdfConversions.convertStatement(next); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + + @Override + public void remove() throws QueryEvaluationException { + try { + query.remove(); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + }; + } + + public static CloseableIteration<? extends Map.Entry<Statement, BindingSet>, QueryEvaluationException> query(RyaDAO ryaDAO, Collection<Map.Entry<Statement, BindingSet>> statements, RdfCloudTripleStoreConfiguration conf) throws QueryEvaluationException { + Collection<Map.Entry<RyaStatement, BindingSet>> ryaStatements = new ArrayList<Map.Entry<RyaStatement, BindingSet>>(statements.size()); + for (Map.Entry<Statement, BindingSet> entry : statements) { + ryaStatements.add(new RdfCloudTripleStoreUtils.CustomEntry<RyaStatement, BindingSet> + (RdfToRyaConversions.convertStatement(entry.getKey()), entry.getValue())); + } + final CloseableIteration<? extends Map.Entry<RyaStatement, BindingSet>, RyaDAOException> query; + try { + query = ryaDAO.getQueryEngine().queryWithBindingSet(ryaStatements, conf); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + return new CloseableIteration<Map.Entry<Statement, BindingSet>, QueryEvaluationException>() { //TODO: Create a new class struct for this + private boolean isClosed = false; + + @Override + public void close() throws QueryEvaluationException { + isClosed = true; + try { + query.close(); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + + @Override + public boolean hasNext() throws QueryEvaluationException { + try { + return query.hasNext(); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + + @Override + public Map.Entry<Statement, BindingSet> next() throws QueryEvaluationException { + if (!hasNext() || isClosed) { + throw new NoSuchElementException(); + } + try { + + Map.Entry<RyaStatement, BindingSet> next = query.next(); + if (next == null) { + return null; + } + return new RdfCloudTripleStoreUtils.CustomEntry<Statement, BindingSet>(RyaToRdfConversions.convertStatement(next.getKey()), next.getValue()); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + + @Override + public void remove() throws QueryEvaluationException { + try { + query.remove(); + } catch (RyaDAOException e) { + throw new QueryEvaluationException(e); + } + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/AbstractTriplePatternStrategy.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/AbstractTriplePatternStrategy.java b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/AbstractTriplePatternStrategy.java new file mode 100644 index 0000000..5171feb --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/AbstractTriplePatternStrategy.java @@ -0,0 +1,93 @@ +package mvm.rya.api.query.strategy; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import com.google.common.base.Preconditions; +import mvm.rya.api.RdfCloudTripleStoreConstants; +import mvm.rya.api.resolver.RyaContext; +import mvm.rya.api.resolver.triple.TripleRowRegex; + +import static mvm.rya.api.RdfCloudTripleStoreConstants.DELIM; +import static mvm.rya.api.RdfCloudTripleStoreConstants.TYPE_DELIM; + +/** + * Date: 7/14/12 + * Time: 8:06 AM + */ +public abstract class AbstractTriplePatternStrategy implements TriplePatternStrategy { + public static final String ALL_REGEX = "([\\s\\S]*)"; + + public abstract RdfCloudTripleStoreConstants.TABLE_LAYOUT getLayout(); + + @Override + public TripleRowRegex buildRegex(String subject, String predicate, String object, String context, byte[] objectTypeInfo) { + RdfCloudTripleStoreConstants.TABLE_LAYOUT table_layout = getLayout(); + Preconditions.checkNotNull(table_layout); + if (subject == null && predicate == null && object == null && context == null && objectTypeInfo == null) { + return null; //no regex + } + StringBuilder sb = new StringBuilder(); + String first = subject; + String second = predicate; + String third = object; + if (table_layout == RdfCloudTripleStoreConstants.TABLE_LAYOUT.PO) { + first = predicate; + second = object; + third = subject; + } else if (table_layout == RdfCloudTripleStoreConstants.TABLE_LAYOUT.OSP) { + first = object; + second = subject; + third = predicate; + } + + if (first != null) { + sb.append(first); + } else { + sb.append(ALL_REGEX); + } + sb.append(DELIM); + + if (second != null) { + sb.append(second); + } else { + sb.append(ALL_REGEX); + } + sb.append(DELIM); + + if (third != null) { + sb.append(third); + if (objectTypeInfo == null) { + sb.append(TYPE_DELIM); + sb.append(ALL_REGEX); + }else { + sb.append(new String(objectTypeInfo)); + } + }else { + sb.append(ALL_REGEX); + if (objectTypeInfo != null) { + sb.append(new String(objectTypeInfo)); + } + } + + return new TripleRowRegex(sb.toString(), (context != null) ? (context + ALL_REGEX) : null, null); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/ByteRange.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/ByteRange.java b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/ByteRange.java new file mode 100644 index 0000000..6ebc722 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/ByteRange.java @@ -0,0 +1,45 @@ +package mvm.rya.api.query.strategy; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +/** + * Date: 1/10/13 + * Time: 12:47 PM + */ +public class ByteRange { + + private byte[] start; + private byte[] end; + + public ByteRange(byte[] start, byte[] end) { + this.start = start; + this.end = end; + } + + public byte[] getStart() { + return start; + } + + public byte[] getEnd() { + return end; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/TriplePatternStrategy.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/TriplePatternStrategy.java b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/TriplePatternStrategy.java new file mode 100644 index 0000000..7b7eb39 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/TriplePatternStrategy.java @@ -0,0 +1,49 @@ +package mvm.rya.api.query.strategy; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.domain.RyaType; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.resolver.triple.TripleRowRegex; + +import java.io.IOException; +import java.util.Map; + +import static mvm.rya.api.RdfCloudTripleStoreConstants.TABLE_LAYOUT; + +/** + * Date: 7/14/12 + * Time: 7:21 AM + */ +public interface TriplePatternStrategy { + + public Map.Entry<TABLE_LAYOUT, ByteRange> defineRange(RyaURI subject, RyaURI predicate, RyaType object, RyaURI context, + RdfCloudTripleStoreConfiguration conf) throws IOException; + + public TABLE_LAYOUT getLayout(); + + public boolean handles(RyaURI subject, RyaURI predicate, RyaType object, RyaURI context); + + public TripleRowRegex buildRegex(String subject, String predicate, String object, String context, byte[] objectTypeInfo); + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/wholerow/AbstractHashedTriplePatternStrategy.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/wholerow/AbstractHashedTriplePatternStrategy.java b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/wholerow/AbstractHashedTriplePatternStrategy.java new file mode 100644 index 0000000..9a1aef3 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/query/strategy/wholerow/AbstractHashedTriplePatternStrategy.java @@ -0,0 +1,90 @@ +package mvm.rya.api.query.strategy.wholerow; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import com.google.common.base.Preconditions; +import mvm.rya.api.RdfCloudTripleStoreConstants; +import mvm.rya.api.query.strategy.AbstractTriplePatternStrategy; +import mvm.rya.api.query.strategy.TriplePatternStrategy; +import mvm.rya.api.resolver.triple.TripleRowRegex; + +import static mvm.rya.api.RdfCloudTripleStoreConstants.DELIM; +import static mvm.rya.api.RdfCloudTripleStoreConstants.TYPE_DELIM; + +public abstract class AbstractHashedTriplePatternStrategy extends AbstractTriplePatternStrategy implements TriplePatternStrategy { + public static final String HASHED_ALL_REGEX = "([0-9a-f]{32})\u0000"; + + public abstract RdfCloudTripleStoreConstants.TABLE_LAYOUT getLayout(); + + @Override + public TripleRowRegex buildRegex(String subject, String predicate, String object, String context, byte[] objectTypeInfo) { + RdfCloudTripleStoreConstants.TABLE_LAYOUT table_layout = getLayout(); + Preconditions.checkNotNull(table_layout); + + //O is not hashed so kick out to super + if(table_layout == RdfCloudTripleStoreConstants.TABLE_LAYOUT.OSP) { + return super.buildRegex(subject, predicate, object, context, objectTypeInfo); + } + + if (subject == null && predicate == null && object == null && context == null && objectTypeInfo == null) { + return null; //no regex + } + StringBuilder sb = new StringBuilder(); + String first = subject; + String second = predicate; + String third = object; + if (table_layout == RdfCloudTripleStoreConstants.TABLE_LAYOUT.PO) { + first = predicate; + second = object; + third = subject; + } + + sb.append(HASHED_ALL_REGEX); + if (first != null) { + sb.append(first); + } else { + sb.append(ALL_REGEX); + } + sb.append(DELIM); + + if (second != null) { + sb.append(second); + } else { + sb.append(ALL_REGEX); + } + sb.append(DELIM); + + if (third != null) { + sb.append(third); + if (objectTypeInfo == null) { + sb.append(TYPE_DELIM); + sb.append(ALL_REGEX); + }else { + sb.append(new String(objectTypeInfo)); + } + }else { + sb.append(ALL_REGEX); + if (objectTypeInfo != null) { + sb.append(new String(objectTypeInfo)); + } + } + + return new TripleRowRegex(sb.toString(), (context != null) ? (context + ALL_REGEX) : null, null); + } +}