RYA-50 Updated Rya PCJs to support SPARQL queries with OPTIONALs.
Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/a24515b0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/a24515b0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/a24515b0 Branch: refs/heads/develop Commit: a24515b0d1c7c3e459d68a867160850aa7d451c1 Parents: c378f64 Author: Kevin Chilton <[email protected]> Authored: Tue Mar 22 14:49:54 2016 -0400 Committer: Kevin Chilton <[email protected]> Committed: Mon Apr 4 18:40:09 2016 -0400 ---------------------------------------------------------------------- .../accumulo/precompQuery/AccumuloPcjQuery.java | 40 +- .../indexing/external/PrecompJoinOptimizer.java | 20 + .../external/tupleSet/AccumuloIndexSet.java | 4 +- .../tupleSet/AccumuloPcjSerializer.java | 199 ++++++---- .../external/tupleSet/BindingSetConverter.java | 108 +++++ .../tupleSet/BindingSetStringConverter.java | 111 +++--- .../indexing/external/tupleSet/PcjTables.java | 26 +- .../indexing/external/PCJOptionalTestIT.java | 324 +++++++++++++++ .../external/PcjIntegrationTestingUtil.java | 9 +- .../external/PrecompJoinOptimizerTest.java | 2 + .../tupleSet/AccumuloPcjSerialzerTest.java | 154 +++++--- .../tupleSet/BindingSetStringConverterTest.java | 151 +++++-- .../tupleSet/PcjTablesIntegrationTests.java | 13 +- .../rya/indexing/pcj/fluo/api/CreatePcj.java | 15 +- .../indexing/pcj/fluo/app/BindingSetRow.java | 23 +- .../pcj/fluo/app/FilterResultUpdater.java | 10 +- .../pcj/fluo/app/FluoStringConverter.java | 152 ------- .../pcj/fluo/app/JoinResultUpdater.java | 395 +++++++++++++------ .../pcj/fluo/app/QueryResultUpdater.java | 10 +- .../fluo/app/observers/BindingSetUpdater.java | 7 +- .../pcj/fluo/app/observers/FilterObserver.java | 10 +- .../pcj/fluo/app/observers/JoinObserver.java | 10 +- .../fluo/app/observers/QueryResultObserver.java | 9 +- .../app/observers/StatementPatternObserver.java | 10 +- .../pcj/fluo/app/query/FluoQueryColumns.java | 2 + .../fluo/app/query/FluoQueryMetadataDAO.java | 7 + .../pcj/fluo/app/query/JoinMetadata.java | 35 ++ .../fluo/app/query/SparqlFluoQueryBuilder.java | 64 +-- .../pcj/fluo/app/FluoStringConverterTest.java | 74 ---- .../pcj/fluo/app/LeftOuterJoinTest.java | 174 ++++++++ .../indexing/pcj/fluo/app/NaturalJoinTest.java | 166 ++++++++ .../pcj/fluo/demo/FluoAndHistoricPcjsDemo.java | 7 +- .../apache/rya/indexing/pcj/fluo/ITBase.java | 9 +- .../fluo/app/query/FluoQueryMetadataDAOIT.java | 2 + .../indexing/pcj/fluo/integration/QueryIT.java | 44 +++ .../pcj/fluo/integration/RyaExportIT.java | 7 +- 36 files changed, 1730 insertions(+), 673 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/accumulo/precompQuery/AccumuloPcjQuery.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/accumulo/precompQuery/AccumuloPcjQuery.java b/extras/indexing/src/main/java/mvm/rya/accumulo/precompQuery/AccumuloPcjQuery.java index 08c0f78..dd1e9c9 100644 --- a/extras/indexing/src/main/java/mvm/rya/accumulo/precompQuery/AccumuloPcjQuery.java +++ b/extras/indexing/src/main/java/mvm/rya/accumulo/precompQuery/AccumuloPcjQuery.java @@ -37,7 +37,9 @@ import mvm.rya.api.resolver.RyaTypeResolverException; import mvm.rya.indexing.PcjQuery; import mvm.rya.indexing.external.tupleSet.AccumuloIndexSet; import mvm.rya.indexing.external.tupleSet.AccumuloPcjSerializer; +import mvm.rya.indexing.external.tupleSet.BindingSetConverter.BindingSetConversionException; import mvm.rya.indexing.external.tupleSet.ExternalTupleSet; +import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; import org.apache.accumulo.core.client.BatchScanner; import org.apache.accumulo.core.client.Connector; @@ -68,9 +70,11 @@ import com.google.common.collect.Sets; * */ public class AccumuloPcjQuery implements PcjQuery { + private static final AccumuloPcjSerializer converter = new AccumuloPcjSerializer(); + private final Connector accCon; private final String tableName; - + public AccumuloPcjQuery(Connector accCon, String tableName) { this.accCon = accCon; this.tableName = tableName; @@ -119,10 +123,9 @@ public class AccumuloPcjQuery implements PcjQuery { } } try { - rangePrefix = AccumuloPcjSerializer.serialize(rangeBs, - commonVars.toArray(new String[commonVars.size()])); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); + rangePrefix = converter.convert(rangeBs, new VariableOrder(commonVars)); + } catch (final BindingSetConversionException e) { + throw new QueryEvaluationException(e); } final Range r = Range.prefix(new Text(rangePrefix)); map.put(r, bSet); @@ -149,10 +152,9 @@ public class AccumuloPcjQuery implements PcjQuery { } } try { - rangePrefix = AccumuloPcjSerializer.serialize(rangeBs, - commonVars.toArray(new String[commonVars.size()])); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); + rangePrefix = converter.convert(rangeBs, new VariableOrder(commonVars)); + } catch (final BindingSetConversionException e) { + throw new QueryEvaluationException(e); } final Range r = Range.prefix(new Text(rangePrefix)); ranges.add(r); @@ -224,7 +226,7 @@ public class AccumuloPcjQuery implements PcjQuery { BindingSet bs; try { bs = getBindingSetWithoutConstants(k, tableVarMap); - } catch (final RyaTypeResolverException e) { + } catch (final BindingSetConversionException e) { throw new QueryEvaluationException(e); } currentSolutionBs = new QueryBindingSet(); @@ -239,7 +241,7 @@ public class AccumuloPcjQuery implements PcjQuery { try { rangePrefix = getPrefixByte(bs, constValMap, prefixVars); - } catch (final RyaTypeResolverException e) { + } catch (final BindingSetConversionException e) { throw new QueryEvaluationException(e); } final Range r = Range.prefix(new Text(rangePrefix)); @@ -312,7 +314,7 @@ public class AccumuloPcjQuery implements PcjQuery { */ private static byte[] getPrefixByte(BindingSet bs, Map<String, org.openrdf.model.Value> valMap, List<String> prefixVars) - throws RyaTypeResolverException { + throws BindingSetConversionException { final QueryBindingSet bSet = new QueryBindingSet(); for (final String var : prefixVars) { if (var.startsWith(ExternalTupleSet.CONST_PREFIX)) { @@ -322,8 +324,8 @@ public class AccumuloPcjQuery implements PcjQuery { bSet.addBinding(var, bs.getBinding(var).getValue()); } } - return AccumuloPcjSerializer.serialize(bSet, - prefixVars.toArray(new String[prefixVars.size()])); + + return converter.convert(bSet, new VariableOrder(prefixVars)); } /** @@ -331,15 +333,17 @@ public class AccumuloPcjQuery implements PcjQuery { * @param key - Accumulo key obtained from scan * @param tableVarMap - map that associated query variables and table variables * @return - BindingSet without values associated with constant constraints - * @throws RyaTypeResolverException + * @throws BindingSetConversionException */ private static BindingSet getBindingSetWithoutConstants(Key key, - Map<String, String> tableVarMap) throws RyaTypeResolverException { + Map<String, String> tableVarMap) throws BindingSetConversionException { final byte[] row = key.getRow().getBytes(); final String[] varOrder = key.getColumnFamily().toString() .split(ExternalTupleSet.VAR_ORDER_DELIM); - final QueryBindingSet temp = new QueryBindingSet( - AccumuloPcjSerializer.deSerialize(row, varOrder)); + + BindingSet bindingSet = converter.convert(row, new VariableOrder(varOrder)); + final QueryBindingSet temp = new QueryBindingSet(bindingSet); + final QueryBindingSet bs = new QueryBindingSet(); for (final String var : temp.getBindingNames()) { if (!tableVarMap.get(var).startsWith(ExternalTupleSet.CONST_PREFIX)) { http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/indexing/external/PrecompJoinOptimizer.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/indexing/external/PrecompJoinOptimizer.java b/extras/indexing/src/main/java/mvm/rya/indexing/external/PrecompJoinOptimizer.java index eb0f042..f8c6c77 100644 --- a/extras/indexing/src/main/java/mvm/rya/indexing/external/PrecompJoinOptimizer.java +++ b/extras/indexing/src/main/java/mvm/rya/indexing/external/PrecompJoinOptimizer.java @@ -20,6 +20,7 @@ package mvm.rya.indexing.external; */ import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -241,6 +242,25 @@ public class PrecompJoinOptimizer implements QueryOptimizer, Configurable { this.segmentFilters = segmentFilters; } + + // this handles the case when the optional/LeftJoin is the first node + // below the Projection node. Checks to see if any of the ExternalTupleSets + // match the LeftJoin exactly. + //TODO ExteranlTupleSet won't match this LeftJoin if query contains Filters and order of + //filters does not match order of filters in ExternalTupleSet after filters are pushed down + @Override + public void meet(LeftJoin node) { + + updateFilters(segmentFilters, true); + + List<TupleExpr> joinArgs = matchExternalTupleSets(Arrays.asList((TupleExpr) node), tupList); + if(joinArgs.size() == 1 && joinArgs.get(0) instanceof ExternalTupleSet) { + node.replaceWith(joinArgs.get(0)); + } + return; + } + + @Override public void meet(Join node) { http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloIndexSet.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloIndexSet.java b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloIndexSet.java index 9c1bc7b..6011a52 100644 --- a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloIndexSet.java +++ b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloIndexSet.java @@ -104,7 +104,7 @@ public class AccumuloIndexSet extends ExternalTupleSet implements ExternalBatchi @Override public String getSignature() { - return "AccumuloIndexSet(" + tablename + ") : " + Joiner.on(", ").join(this.getTupleExpr().getAssuredBindingNames()); + return "AccumuloIndexSet(" + tablename + ") : " + Joiner.on(", ").join(this.getTupleExpr().getBindingNames()); } /** @@ -130,7 +130,7 @@ public class AccumuloIndexSet extends ExternalTupleSet implements ExternalBatchi throw new MalformedQueryException("SPARQL query '" + sparql + "' does not contain a Projection."); } setProjectionExpr(projection.get()); - + Set<VariableOrder> orders = null; try { orders = pcj.getPcjMetadata(accCon, tablename).getVarOrders(); http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerializer.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerializer.java b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerializer.java index 452ea61..bb87d7f 100644 --- a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerializer.java +++ b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerializer.java @@ -19,104 +19,169 @@ package mvm.rya.indexing.external.tupleSet; * under the License. */ +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkArgument; import static mvm.rya.api.RdfCloudTripleStoreConstants.DELIM_BYTE; import static mvm.rya.api.RdfCloudTripleStoreConstants.DELIM_BYTES; import static mvm.rya.api.RdfCloudTripleStoreConstants.TYPE_DELIM_BYTE; -import java.util.ArrayList; +import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.LinkedList; import java.util.List; +import java.util.Set; + +import javax.annotation.ParametersAreNonnullByDefault; import mvm.rya.api.domain.RyaType; import mvm.rya.api.resolver.RdfToRyaConversions; import mvm.rya.api.resolver.RyaContext; import mvm.rya.api.resolver.RyaToRdfConversions; import mvm.rya.api.resolver.RyaTypeResolverException; +import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; import org.openrdf.model.Value; +import org.openrdf.query.Binding; import org.openrdf.query.BindingSet; import org.openrdf.query.algebra.evaluation.QueryBindingSet; -import com.google.common.base.Preconditions; import com.google.common.primitives.Bytes; /** - * AccumuloPcjSerializer provides two methods, serialize and deserialize, which - * are used for writing BindingSets to PCJ tables and reading serialized byte - * representations of BindingSets from PCJ tables. - * + * Converts {@link BindingSet}s to byte[]s and back again. The bytes do not + * include the binding names and are ordered with a {@link VariableOrder}. */ -public class AccumuloPcjSerializer { - - /** - * - * @param bs {@link BindingSet} to be serialized - * @param varOrder order in which binding values should be written to byte array - * @return byte array containing serialized values written in order indicated by varOrder - * @throws RyaTypeResolverException - */ - public static byte[] serialize(BindingSet bs, String[] varOrder) throws RyaTypeResolverException { - byte[] byteArray = null; - int i = 0; - Preconditions.checkNotNull(bs); - Preconditions.checkNotNull(varOrder); - Preconditions.checkArgument(bs.size() == varOrder.length); - for(final String varName: varOrder) { - final RyaType rt = RdfToRyaConversions.convertValue(bs.getBinding(varName).getValue()); - final byte[][] serializedVal = RyaContext.getInstance().serializeType(rt); - if(i == 0) { - byteArray = Bytes.concat(serializedVal[0], serializedVal[1], DELIM_BYTES); - } else { - byteArray = Bytes.concat(byteArray, serializedVal[0], serializedVal[1], DELIM_BYTES); +@ParametersAreNonnullByDefault +public class AccumuloPcjSerializer implements BindingSetConverter<byte[]> { + + @Override + public byte[] convert(BindingSet bindingSet, VariableOrder varOrder) throws BindingSetConversionException { + checkNotNull(bindingSet); + checkNotNull(varOrder); + checkBindingsSubsetOfVarOrder(bindingSet, varOrder); + + // A list that holds all of the byte segments that will be concatenated at the end. + // This minimizes byte[] construction. + final List<byte[]> byteSegments = new LinkedList<>(); + + try { + for(final String varName: varOrder) { + // Only write information for a variable name if the binding set contains it. + if(bindingSet.hasBinding(varName)) { + final RyaType rt = RdfToRyaConversions.convertValue(bindingSet.getBinding(varName).getValue()); + final byte[][] serializedVal = RyaContext.getInstance().serializeType(rt); + byteSegments.add(serializedVal[0]); + byteSegments.add(serializedVal[1]); + } + + // But always write the value delimiter. If a value is missing, you'll see two delimiters next to each-other. + byteSegments.add(DELIM_BYTES); } - i++; - } + + return concat(byteSegments); + } catch (RyaTypeResolverException e) { + throw new BindingSetConversionException("Could not convert the BindingSet into a byte[].", e); + } + } - return byteArray; - } + @Override + public BindingSet convert(byte[] bindingSetBytes, VariableOrder varOrder) throws BindingSetConversionException { + checkNotNull(bindingSetBytes); + checkNotNull(varOrder); + + try { + // Slice the row into bindings. + List<byte[]> values = splitlByDelimByte(bindingSetBytes); + String[] varOrderStrings = varOrder.toArray(); + checkArgument(values.size() == varOrderStrings.length); + + // Convert the Binding bytes into a BindingSet. + final QueryBindingSet bindingSet = new QueryBindingSet(); + + for(int i = 0; i < varOrderStrings.length; i++) { + byte[] valueBytes = values.get(i); + if(valueBytes.length > 0) { + String name = varOrderStrings[i]; + Value value = deserializeValue(valueBytes); + bindingSet.addBinding(name, value); + } + } + + return bindingSet; + } catch (RyaTypeResolverException e) { + throw new BindingSetConversionException("Could not convert the byte[] into a BindingSet.", e); + } + } + + /** + * Checks to see if the names of all the {@link Binding}s in the {@link BindingSet} + * are a subset of the variables names in {@link VariableOrder}. + * + * @param bindingSet - The binding set whose Bindings will be inspected. (not null) + * @param varOrder - The names of the bindings that may appear in the BindingSet. (not null) + * @throws IllegalArgumentException Indicates the names of the bindings are + * not a subset of the variable order. + */ + private static void checkBindingsSubsetOfVarOrder(BindingSet bindingSet, VariableOrder varOrder) throws IllegalArgumentException { + checkNotNull(bindingSet); + checkNotNull(varOrder); - /** - * - * @param row byte rowId (read from Accumulo {@link Key}) - * @param varOrder indicates the order in which values are written in row - * @return {@link BindingSet} formed from serialized values in row and variables in varOrder - * @throws RyaTypeResolverException - */ - public static BindingSet deSerialize(byte[] row, String[] varOrder) throws RyaTypeResolverException { - Preconditions.checkNotNull(row); - Preconditions.checkNotNull(varOrder); - final int lastIndex = Bytes.lastIndexOf(row, DELIM_BYTE); - Preconditions.checkArgument(lastIndex >= 0); - final List<byte[]> byteList = getByteValues(Arrays.copyOf(row, lastIndex), new ArrayList<byte[]>()); - final QueryBindingSet bs = new QueryBindingSet(); - Preconditions.checkArgument(byteList.size() == varOrder.length); - for(int i = 0; i < byteList.size(); i++) { - bs.addBinding(varOrder[i], getValue(byteList.get(i))); - } - return bs; - } + Set<String> bindingNames = bindingSet.getBindingNames(); + List<String> varNames = varOrder.getVariableOrders(); + checkArgument(varNames.containsAll(bindingNames), "The BindingSet contains a Binding whose name is not part of the VariableOrder."); + } + + private static final byte[] concat(Iterable<byte[]> byteSegments) { + checkNotNull(byteSegments); - private static List<byte[]> getByteValues(byte[] row, List<byte[]> byteList) { - final int firstIndex = Bytes.indexOf(row, DELIM_BYTE); - if(firstIndex < 0) { - byteList.add(row); - return byteList; - } else { - byteList.add(Arrays.copyOf(row, firstIndex)); - getByteValues(Arrays.copyOfRange(row, firstIndex+1, row.length), byteList); - } + // Allocate a byte array that is able to hold the segments. + int length = 0; + for(byte[] byteSegment : byteSegments) { + length += byteSegment.length; + } + byte[] result = new byte[length]; + + // Copy the segments to the byte array and return it. + ByteBuffer buff = ByteBuffer.wrap(result); + for(byte[] byteSegment : byteSegments) { + buff.put(byteSegment); + } + return result; + } + + private static List<byte[]> splitlByDelimByte(byte[] bindingSetBytes) { + checkNotNull(bindingSetBytes); - return byteList; + List<byte[]> values = new LinkedList<>(); + + ByteBuffer buff = ByteBuffer.wrap(bindingSetBytes); + int start = 0; + while(buff.hasRemaining()) { + if(buff.get() == DELIM_BYTE) { + // Mark the position of the value delimiter. + int end = buff.position(); + + // Move to the start of the value and copy the bytes into an array. + byte[] valueBytes = new byte[(end - start) -1]; + buff.position(start); + buff.get(valueBytes); + buff.position(end); + values.add(valueBytes); + + // Move the start of the next value to the end of this one. + start = end; + } + } + + return values; } - private static Value getValue(byte[] byteVal) throws RyaTypeResolverException { - + private static Value deserializeValue(byte[] byteVal) throws RyaTypeResolverException { final int typeIndex = Bytes.indexOf(byteVal, TYPE_DELIM_BYTE); - Preconditions.checkArgument(typeIndex >= 0); + checkArgument(typeIndex >= 0); final byte[] data = Arrays.copyOf(byteVal, typeIndex); final byte[] type = Arrays.copyOfRange(byteVal, typeIndex, byteVal.length); final RyaType rt = RyaContext.getInstance().deserialize(Bytes.concat(data,type)); return RyaToRdfConversions.convertValue(rt); - } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetConverter.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetConverter.java b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetConverter.java new file mode 100644 index 0000000..9c10dfa --- /dev/null +++ b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetConverter.java @@ -0,0 +1,108 @@ +/* + * 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. + */ +package mvm.rya.indexing.external.tupleSet; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.openrdf.query.Binding; +import org.openrdf.query.BindingSet; + +import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; + +/** + * Converts {@link BindingSet}s into other representations. This library is + * intended to convert between BindingSet and whatever format it is being + * stored as. These formats are often optimized for query evaluation. + * + * @param <T> Defines the type of model {@link BindingSet}s will be converted into/from. + */ +@ParametersAreNonnullByDefault +public interface BindingSetConverter<T> { + + /** + * Converts a {@link BindingSet} into the target model. The target model + * may not include every {@link Binding} that was in the original BindingSet, + * it may not include the binding names, and it may order the binding values. + * All of this information is specified using a {@link VariableOrder}. + * </p> + * Because the resulting model may not include the binding names from the + * original object, you must hold onto that information if you want to + * convert the resulting model back into a BindingSet later. Because the + * resulting model may only contain a subset of the original BindingSet's + * bindings, some information may be lost, so you may not be able to convert + * the target model back into the original BindingSet. + * + * @param bindingSet - The BindingSet that will be converted. (not null) + * @param varOrder - Which bindings and in what order they will appear in the + * resulting model. (not null) + * @return The BindingSet formatted as the target model. + * @throws BindingSetConversionException The BindingSet was unable to be + * converted into the target model. This will happen if the BindingSet has + * a binding whose name is not in the VariableOrder or if one of the values + * could not be converted into the target model. + */ + public T convert(BindingSet bindingSet, VariableOrder varOrder) throws BindingSetConversionException; + + /** + * Converts the target model representation of a {@link BindingSet} as is + * created by {@link #convert(BindingSet, VariableOrder)} back into a + * BindingSet. + * </p> + * You must provide the Binding names and the order they were written to + * by using a {@link VariableOrder}. + * </p> + * If there is no value for one of the variable order names, then that binding + * will be missing from the resulting BindingSet. + * + * @param bindingSet - The BindingSet formatted as the target model that will + * be converted. (not null) + * @param varOrder - The VariableOrder that was used to create the target model. (not null) + * @return The {@link BindingSet} representation of the target model. + * @throws BindingSetConversionException The target model was unable to be + * converted back into a BindingSet. + */ + public BindingSet convert(T bindingSet, VariableOrder varOrder) throws BindingSetConversionException; + + /** + * One of the conversion methods of {@link BindingSetConverter} was unable to + * to convert the {@link BindingSet} to/from the converted model. + */ + public static class BindingSetConversionException extends Exception { + private static final long serialVersionUID = 1L; + + /** + * Constructs an instance of {@link BindingSetConversionException}. + * + * @param message - Describes why this exception was thrown. + */ + public BindingSetConversionException(String message) { + super(message); + } + + /** + * BindingSetConversionException + * + * @param message - Describes why this exception was thrown. + * @param cause - The exception that caused this one to be thrown. + */ + public BindingSetConversionException(String message, Throwable cause) { + super(message, cause); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverter.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverter.java b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverter.java index d28186d..6d69d5b 100644 --- a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverter.java +++ b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverter.java @@ -16,16 +16,17 @@ * specific language governing permissions and limitations * under the License. */ - package mvm.rya.indexing.external.tupleSet; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import java.util.Iterator; +import java.util.ArrayList; import java.util.List; import java.util.Set; +import javax.annotation.ParametersAreNonnullByDefault; + import org.openrdf.model.URI; import org.openrdf.model.Value; import org.openrdf.model.ValueFactory; @@ -36,89 +37,68 @@ import org.openrdf.query.Binding; import org.openrdf.query.BindingSet; import org.openrdf.query.algebra.evaluation.QueryBindingSet; +import com.google.common.base.Joiner; + import mvm.rya.api.domain.RyaType; import mvm.rya.api.resolver.RdfToRyaConversions; import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; /** - * Converts {@link BindingSet}s to Strings and back again. + * Converts {@link BindingSet}s to Strings and back again. The Strings do not + * include the binding names and are ordered with a {@link VariableOrder}. */ -public class BindingSetStringConverter { +@ParametersAreNonnullByDefault +public class BindingSetStringConverter implements BindingSetConverter<String> { - private static final String BINDING_DELIM = ":::"; - private static final String TYPE_DELIM = "<<~>>"; + public static final String BINDING_DELIM = ":::"; + public static final String TYPE_DELIM = "<<~>>"; + public static final String NULL_VALUE_STRING = Character.toString( '\0' ); private static final ValueFactory valueFactory = new ValueFactoryImpl(); - /** - * Converts a {@link BindingSet} to a String. You must provide the order the - * {@link Binding}s will be written to. - * </p> - * The resulting string does not include the binding names from the original - * object, so that must be kept with the resulting String if you want to - * convert it back to a BindingSet later. - * </p> - * - * @param bindingSet - The BindingSet that will be converted. (not null) - * @param varOrder - The order the bindings will appear in the resulting String. (not null) - * @return A {@code String} version of {@code bindingSet} whose binding are - * ordered based on {@code varOrder}. - */ - public static String toString(BindingSet bindingSet, VariableOrder varOrder) { - checkSameVariables(bindingSet, varOrder); - - final StringBuilder bindingSetString = new StringBuilder(); - - Iterator<String> it = varOrder.iterator(); - while(it.hasNext()) { - // Add a value to the binding set. - String varName = it.next(); - final Value value = bindingSet.getBinding(varName).getValue(); - final RyaType ryaValue = RdfToRyaConversions.convertValue(value); - bindingSetString.append( ryaValue.getData() ).append(TYPE_DELIM).append( ryaValue.getDataType() ); - - // If there are more values to add, include a delimiter between them. - if(it.hasNext()) { - bindingSetString.append(BINDING_DELIM); + @Override + public String convert(BindingSet bindingSet, VariableOrder varOrder) { + checkBindingsSubsetOfVarOrder(bindingSet, varOrder); + + // Convert each Binding to a String. + List<String> bindingStrings = new ArrayList<>(); + for(String varName : varOrder) { + if(bindingSet.hasBinding(varName)) { + // Add a value to the binding set. + final Value value = bindingSet.getBinding(varName).getValue(); + final RyaType ryaValue = RdfToRyaConversions.convertValue(value); + String bindingString = ryaValue.getData() + TYPE_DELIM + ryaValue.getDataType(); + bindingStrings.add(bindingString); + } else { + // Add a null value to the binding set. + bindingStrings.add(NULL_VALUE_STRING); } } - - return bindingSetString.toString(); + + // Join the bindings using the binding delim. + return Joiner.on(BINDING_DELIM).join(bindingStrings); } /** * Checks to see if the names of all the {@link Binding}s in the {@link BindingSet} - * match the variable names in the {@link VariableOrder}. - * + * are a subset of the variables names in {@link VariableOrder}. + * * @param bindingSet - The binding set whose Bindings will be inspected. (not null) - * @param varOrder - The names of the bindings that must appear in the BindingSet. (not null) - * @throws IllegalArgumentException Indicates the number of bindings did not match - * the number of variables or that the binding names did not match the names - * of the variables. + * @param varOrder - The names of the bindings that may appear in the BindingSet. (not null) + * @throws IllegalArgumentException Indicates the names of the bindings are + * not a subset of the variable order. */ - private static void checkSameVariables(BindingSet bindingSet, VariableOrder varOrder) throws IllegalArgumentException { + private static void checkBindingsSubsetOfVarOrder(BindingSet bindingSet, VariableOrder varOrder) throws IllegalArgumentException { checkNotNull(bindingSet); checkNotNull(varOrder); Set<String> bindingNames = bindingSet.getBindingNames(); - List<String> varOrderList = varOrder.getVariableOrders(); - checkArgument(bindingNames.size() == varOrderList.size(), "The number of Bindings must match the length of the VariableOrder."); - checkArgument(bindingNames.containsAll(varOrderList), "The names of the Bindings must match the variable names in VariableOrder."); + List<String> varNames = varOrder.getVariableOrders(); + checkArgument(varNames.containsAll(bindingNames), "The BindingSet contains a Binding whose name is not part of the VariableOrder."); } - /** - * Converts the String representation of a {@link BindingSet} as is created - * by {@link #toString(BindingSet, VariableOrder)} back into a BindingSet. - * <p> - * You must provide the Binding names in the order they were written to. - * </p> - * - * @param bindingSetString - The binding set values as a String. (not null) - * @param varOrder - The order the bindings appear in the String version of - * the BindingSet. (not null) - * @return A {@link BindingSet} representation of the String. - */ - public static BindingSet fromString(final String bindingSetString, final VariableOrder varOrder) { + @Override + public BindingSet convert(String bindingSetString, VariableOrder varOrder) { checkNotNull(bindingSetString); checkNotNull(varOrder); @@ -128,9 +108,12 @@ public class BindingSetStringConverter { final QueryBindingSet bindingSet = new QueryBindingSet(); for(int i = 0; i < bindingStrings.length; i++) { - final String name = varOrrderArr[i]; - final Value value = toValue(bindingStrings[i]); - bindingSet.addBinding(name, value); + String bindingString = bindingStrings[i]; + if(!NULL_VALUE_STRING.equals(bindingString)) { + final String name = varOrrderArr[i]; + final Value value = toValue(bindingStrings[i]); + bindingSet.addBinding(name, value); + } } return bindingSet; } http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/PcjTables.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/PcjTables.java b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/PcjTables.java index f87df51..fc940f6 100644 --- a/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/PcjTables.java +++ b/extras/indexing/src/main/java/mvm/rya/indexing/external/tupleSet/PcjTables.java @@ -8,9 +8,9 @@ package mvm.rya.indexing.external.tupleSet; * 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 @@ -35,8 +35,6 @@ import java.util.Set; import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.concurrent.Immutable; -import mvm.rya.api.resolver.RyaTypeResolverException; - import org.apache.accumulo.core.client.AccumuloException; import org.apache.accumulo.core.client.AccumuloSecurityException; import org.apache.accumulo.core.client.BatchWriter; @@ -76,6 +74,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import mvm.rya.api.resolver.RyaTypeResolverException; +import mvm.rya.indexing.external.tupleSet.BindingSetConverter.BindingSetConversionException; + /** * Functions that create and maintain the PCJ tables that are used by Rya. */ @@ -137,6 +138,16 @@ public class PcjTables { } /** + * Constructs an instance of {@link VariableOrdeR{. + * + * @param varOrder - An ordered collection of Binding Set variables. (not null) + */ + public VariableOrder(Collection<String> varOrder) { + checkNotNull(varOrder); + this.variableOrder = ImmutableList.copyOf(varOrder); + } + + /** * Constructs an instance of {@link VariableOrder}. * * @param varOrderString - The String representation of a VariableOrder. (not null) @@ -621,17 +632,18 @@ public class PcjTables { checkNotNull(result); Set<Mutation> mutations = new HashSet<>(); - + AccumuloPcjSerializer converter = new AccumuloPcjSerializer(); + for(final VariableOrder varOrder : varOrders) { try { // Serialize the result to the variable order. - byte[] serializedResult = AccumuloPcjSerializer.serialize(result, varOrder.toArray()); + byte[] serializedResult = converter.convert(result, varOrder); // Row ID = binding set values, Column Family = variable order of the binding set. Mutation addResult = new Mutation(serializedResult); addResult.put(varOrder.toString(), "", ""); mutations.add(addResult); - } catch(RyaTypeResolverException e) { + } catch(BindingSetConversionException e) { throw new PcjException("Could not serialize a result.", e); } } http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/test/java/mvm/rya/indexing/external/PCJOptionalTestIT.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/mvm/rya/indexing/external/PCJOptionalTestIT.java b/extras/indexing/src/test/java/mvm/rya/indexing/external/PCJOptionalTestIT.java new file mode 100644 index 0000000..e3ef741 --- /dev/null +++ b/extras/indexing/src/test/java/mvm/rya/indexing/external/PCJOptionalTestIT.java @@ -0,0 +1,324 @@ +/* + * 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. + */ +package mvm.rya.indexing.external; + +import java.util.ArrayList; +import java.util.List; + +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.indexing.external.PrecompJoinOptimizerIntegrationTest.CountingResultHandler; +import mvm.rya.indexing.external.PrecompJoinOptimizerTest.NodeCollector; +import mvm.rya.indexing.external.tupleSet.ExternalTupleSet; +import mvm.rya.indexing.external.tupleSet.PcjTables.PcjException; +import mvm.rya.indexing.external.tupleSet.PcjTables.PcjVarOrderFactory; +import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet; +import mvm.rya.rdftriplestore.inference.InferenceEngineException; + +import org.apache.accumulo.core.client.AccumuloException; +import org.apache.accumulo.core.client.AccumuloSecurityException; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.TableExistsException; +import org.apache.accumulo.core.client.TableNotFoundException; +import org.apache.accumulo.core.client.mock.MockInstance; +import org.apache.accumulo.core.client.security.tokens.PasswordToken; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openrdf.model.URI; +import org.openrdf.model.impl.LiteralImpl; +import org.openrdf.model.impl.URIImpl; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.RDFS; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryEvaluationException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQuery; +import org.openrdf.query.TupleQueryResultHandlerException; +import org.openrdf.query.algebra.Projection; +import org.openrdf.query.algebra.QueryModelNode; +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.parser.ParsedQuery; +import org.openrdf.query.parser.sparql.SPARQLParser; +import org.openrdf.repository.RepositoryException; +import org.openrdf.repository.sail.SailRepository; +import org.openrdf.repository.sail.SailRepositoryConnection; +import org.openrdf.sail.SailException; + +import com.beust.jcommander.internal.Lists; +import com.google.common.base.Optional; + +public class PCJOptionalTestIT { + + + private SailRepositoryConnection conn, pcjConn; + private SailRepository repo, pcjRepo; + private Connector accCon; + String tablePrefix = "table_"; + URI sub, sub2, obj, obj2, subclass, subclass2, talksTo, sub3, subclass3; + + @Before + public void init() throws RepositoryException, + TupleQueryResultHandlerException, QueryEvaluationException, + MalformedQueryException, AccumuloException, + AccumuloSecurityException, TableExistsException, RyaDAOException, + TableNotFoundException, InferenceEngineException { + + repo = PcjIntegrationTestingUtil.getNonPcjRepo(tablePrefix, "instance"); + conn = repo.getConnection(); + + pcjRepo = PcjIntegrationTestingUtil.getPcjRepo(tablePrefix, "instance"); + pcjConn = pcjRepo.getConnection(); + + sub = new URIImpl("uri:entity"); + subclass = new URIImpl("uri:class"); + obj = new URIImpl("uri:obj"); + talksTo = new URIImpl("uri:talksTo"); + + conn.add(sub, RDF.TYPE, subclass); + conn.add(sub, RDFS.LABEL, new LiteralImpl("label")); + conn.add(sub, talksTo, obj); + + sub2 = new URIImpl("uri:entity2"); + subclass2 = new URIImpl("uri:class2"); + obj2 = new URIImpl("uri:obj2"); + sub3 = new URIImpl("uri:entity3"); + subclass3 = new URIImpl("uri:class3"); + + + conn.add(sub2, RDF.TYPE, subclass2); + conn.add(sub2, RDFS.LABEL, new LiteralImpl("label2")); + conn.add(sub2, talksTo, obj2); + conn.add(sub3, RDF.TYPE, subclass3); + conn.add(sub3, RDFS.LABEL, new LiteralImpl("label3")); + + + accCon = new MockInstance("instance").getConnector("root", + new PasswordToken("")); + + } + + @After + public void close() throws RepositoryException, AccumuloException, + AccumuloSecurityException, TableNotFoundException { + + PcjIntegrationTestingUtil.closeAndShutdown(conn, repo); + PcjIntegrationTestingUtil.closeAndShutdown(pcjConn, pcjRepo); + PcjIntegrationTestingUtil.deleteCoreRyaTables(accCon, tablePrefix); + PcjIntegrationTestingUtil.deleteIndexTables(accCon, 2, tablePrefix); + + } + + + @Test + public void testEvaluateSingeIndexExactMatch() + throws TupleQueryResultHandlerException, QueryEvaluationException, + MalformedQueryException, RepositoryException, AccumuloException, + AccumuloSecurityException, TableExistsException, RyaDAOException, + SailException, TableNotFoundException, PcjException, InferenceEngineException { + + String indexSparqlString = ""// + + "SELECT ?e ?c ?l ?o" // + + "{" // + + " ?e a ?c . "// + + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l "// + + " OPTIONAL{?e <uri:talksTo> ?o } . "// + + "}";// + + PcjIntegrationTestingUtil.createAndPopulatePcj(conn, accCon, tablePrefix + + "INDEX_1", indexSparqlString, new String[] { "e", "c", "l", "o" }, + Optional.<PcjVarOrderFactory> absent()); + String queryString = ""// + + "SELECT ?e ?c ?l ?o " // + + "{" // + + " ?e a ?c . "// + + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "// + + " OPTIONAL {?e <uri:talksTo> ?o } . "// + + "}";// + + CountingResultHandler crh = new CountingResultHandler(); + PcjIntegrationTestingUtil.deleteCoreRyaTables(accCon, tablePrefix); + PcjIntegrationTestingUtil.closeAndShutdown(conn, repo); + TupleQuery tupQuery = pcjConn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); + tupQuery.evaluate(crh); + + Assert.assertEquals(3, crh.getCount()); + + } + + + + @Test + public void testEvaluateSingeIndex() + throws TupleQueryResultHandlerException, QueryEvaluationException, + MalformedQueryException, RepositoryException, AccumuloException, + AccumuloSecurityException, TableExistsException, RyaDAOException, + SailException, TableNotFoundException, PcjException, InferenceEngineException { + + String indexSparqlString = ""// + + "SELECT ?e ?l ?o" // + + "{" // + + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l "// + + " OPTIONAL{?e <uri:talksTo> ?o } . "// + + "}";// + + PcjIntegrationTestingUtil.createAndPopulatePcj(conn, accCon, tablePrefix + + "INDEX_1", indexSparqlString, new String[] { "e", "l", "o" }, + Optional.<PcjVarOrderFactory> absent()); + String queryString = ""// + + "SELECT ?e ?c ?l ?o " // + + "{" // + + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "// + + " OPTIONAL {?e <uri:talksTo> ?o } . "// + + " ?e a ?c . "// + + "}";// + + CountingResultHandler crh = new CountingResultHandler(); + PcjIntegrationTestingUtil.deleteCoreRyaTables(accCon, tablePrefix); + PcjIntegrationTestingUtil.closeAndShutdown(conn, repo); + + repo = PcjIntegrationTestingUtil.getPcjRepo(tablePrefix, "instance"); + conn = repo.getConnection(); + conn.add(sub, RDF.TYPE, subclass); + conn.add(sub2, RDF.TYPE, subclass2); + conn.add(sub3, RDF.TYPE, subclass3); + + + TupleQuery tupQuery = pcjConn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); + tupQuery.evaluate(crh); + + Assert.assertEquals(3, crh.getCount()); + + } + + + + + + + @Test + public void testSimpleOptionalTest1() throws Exception { + + String query = ""// + + "SELECT ?u ?s ?t " // + + "{" // + + " ?s a ?t ."// + + " OPTIONAL{?t <http://www.w3.org/2000/01/rdf-schema#label> ?u } ."// + + " ?u <uri:talksTo> ?s . "// + + "}";// + + final SPARQLParser parser = new SPARQLParser(); + + final ParsedQuery pq1 = parser.parseQuery(query, null); + + final SimpleExternalTupleSet extTup1 = new SimpleExternalTupleSet( + (Projection) pq1.getTupleExpr().clone()); + + final List<ExternalTupleSet> list = new ArrayList<ExternalTupleSet>(); + + list.add(extTup1); + + final List<QueryModelNode> optTupNodes = Lists.newArrayList(); + optTupNodes.add(extTup1); + + final PrecompJoinOptimizer pcj = new PrecompJoinOptimizer(list, true); + final TupleExpr te = pq1.getTupleExpr(); + pcj.optimize(te, null, null); + + final NodeCollector nc = new NodeCollector(); + te.visit(nc); + + final List<QueryModelNode> qNodes = nc.getNodes(); + + Assert.assertEquals(qNodes.size(), optTupNodes.size()); + for (final QueryModelNode node : qNodes) { + Assert.assertTrue(optTupNodes.contains(node)); + } + + } + + + @Test + public void testSimpleOptionalTest2() throws Exception { + + String query = ""// + + "SELECT ?u ?s ?t " // + + "{" // + + " ?s a ?t ."// + + " OPTIONAL{?t <http://www.w3.org/2000/01/rdf-schema#label> ?u } ."// + + " ?u <uri:talksTo> ?s . "// + + " ?s a ?u ."// + + "}";// + + + String pcj = ""// + + "SELECT ?d ?b ?c " // + + "{" // + + " ?b a ?c ."// + + " OPTIONAL{?c <http://www.w3.org/2000/01/rdf-schema#label> ?d } ."// + + " ?d <uri:talksTo> ?b . "// + + "}";// + + + String relabel_pcj = ""// + + "SELECT ?u ?s ?t " // + + "{" // + + " ?s a ?t ."// + + " OPTIONAL{?t <http://www.w3.org/2000/01/rdf-schema#label> ?u } ."// + + " ?u <uri:talksTo> ?s . "// + + "}";// + + + final SPARQLParser parser = new SPARQLParser(); + + final ParsedQuery pq1 = parser.parseQuery(query, null); + final ParsedQuery pq2 = parser.parseQuery(pcj, null); + final ParsedQuery pq3 = parser.parseQuery(relabel_pcj, null); + + final SimpleExternalTupleSet extTup1 = new SimpleExternalTupleSet( + (Projection) pq2.getTupleExpr()); + final SimpleExternalTupleSet extTup2 = new SimpleExternalTupleSet( + (Projection) pq3.getTupleExpr()); + + final List<ExternalTupleSet> list = new ArrayList<ExternalTupleSet>(); + + list.add(extTup1); + + final List<QueryModelNode> optTupNodes = Lists.newArrayList(); + optTupNodes.add(extTup2); + + final PrecompJoinOptimizer opt = new PrecompJoinOptimizer(list, true); + final TupleExpr te = pq1.getTupleExpr(); + opt.optimize(te, null, null); + + final NodeCollector nc = new NodeCollector(); + te.visit(nc); + + final List<QueryModelNode> qNodes = nc.getNodes(); + + Assert.assertEquals(qNodes.size(), optTupNodes.size() + 1); + for (QueryModelNode node : optTupNodes) { + Assert.assertTrue(qNodes.contains(node)); + } + + } + + + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/test/java/mvm/rya/indexing/external/PcjIntegrationTestingUtil.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/mvm/rya/indexing/external/PcjIntegrationTestingUtil.java b/extras/indexing/src/test/java/mvm/rya/indexing/external/PcjIntegrationTestingUtil.java index 42e8b09..1be88e2 100644 --- a/extras/indexing/src/test/java/mvm/rya/indexing/external/PcjIntegrationTestingUtil.java +++ b/extras/indexing/src/test/java/mvm/rya/indexing/external/PcjIntegrationTestingUtil.java @@ -31,6 +31,7 @@ import mvm.rya.api.resolver.RyaTypeResolverException; import mvm.rya.sail.config.RyaSailFactory; import mvm.rya.indexing.accumulo.ConfigUtils; import mvm.rya.indexing.external.tupleSet.AccumuloPcjSerializer; +import mvm.rya.indexing.external.tupleSet.BindingSetConverter.BindingSetConversionException; import mvm.rya.indexing.external.tupleSet.ExternalTupleSet; import mvm.rya.indexing.external.tupleSet.PcjTables; import mvm.rya.indexing.external.tupleSet.PcjTables.PcjException; @@ -70,6 +71,8 @@ import com.google.common.collect.Sets; public class PcjIntegrationTestingUtil { + private static final AccumuloPcjSerializer converter = new AccumuloPcjSerializer(); + public static Set<QueryModelNode> getTupleSets(TupleExpr te) { final ExternalTupleVisitor etv = new ExternalTupleVisitor(); te.visit(etv); @@ -386,20 +389,18 @@ public class PcjIntegrationTestingUtil { for (final VariableOrder varOrder : varOrders) { try { // Serialize the result to the variable order. - byte[] serializedResult = AccumuloPcjSerializer.serialize( - result, varOrder.toArray()); + byte[] serializedResult = converter.convert(result, varOrder); // Row ID = binding set values, Column Family = variable order // of the binding set. Mutation addResult = new Mutation(serializedResult); addResult.put(varOrder.toString(), "", ""); mutations.add(addResult); - } catch (RyaTypeResolverException e) { + } catch (BindingSetConversionException e) { throw new PcjException("Could not serialize a result.", e); } } return mutations; } - } http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/test/java/mvm/rya/indexing/external/PrecompJoinOptimizerTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/mvm/rya/indexing/external/PrecompJoinOptimizerTest.java b/extras/indexing/src/test/java/mvm/rya/indexing/external/PrecompJoinOptimizerTest.java index 6e8c721..9428ae4 100644 --- a/extras/indexing/src/test/java/mvm/rya/indexing/external/PrecompJoinOptimizerTest.java +++ b/extras/indexing/src/test/java/mvm/rya/indexing/external/PrecompJoinOptimizerTest.java @@ -174,6 +174,8 @@ public class PrecompJoinOptimizerTest { } + + @Test public void testSingleIndex2() throws Exception { http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerialzerTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerialzerTest.java b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerialzerTest.java index 2fcacb0..4efbb30 100644 --- a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerialzerTest.java +++ b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/AccumuloPcjSerialzerTest.java @@ -20,99 +20,141 @@ package mvm.rya.indexing.external.tupleSet; */ import mvm.rya.api.resolver.RyaTypeResolverException; +import mvm.rya.indexing.external.tupleSet.BindingSetConverter.BindingSetConversionException; +import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; + +import static org.junit.Assert.assertEquals; import org.junit.Test; import org.openrdf.model.impl.LiteralImpl; import org.openrdf.model.impl.URIImpl; import org.openrdf.query.BindingSet; import org.openrdf.query.algebra.evaluation.QueryBindingSet; +import org.openrdf.query.impl.MapBindingSet; -import com.vividsolutions.jts.util.Assert; - +/** + * Tests the methods of {@link AccumuloPcjSerialzer}. + */ public class AccumuloPcjSerialzerTest { + /** + * The BindingSet has fewer Bindings than there are variables in the variable + * order, but they are all in the variable order. This is the case where + * the missing bindings were optional. + */ + @Test + public void serialize_bindingsSubsetOfVarOrder() throws BindingSetConversionException { + // Setup the Binding Set. + final MapBindingSet originalBindingSet = new MapBindingSet(); + originalBindingSet.addBinding("x", new URIImpl("http://a")); + originalBindingSet.addBinding("y", new URIImpl("http://b")); + + // Setup the variable order. + final VariableOrder varOrder = new VariableOrder("x", "a", "y", "b"); + + // Create the byte[] representation of the BindingSet. + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + byte[] serialized = converter.convert(originalBindingSet, varOrder); + + // Deserialize the byte[] back into the binding set. + BindingSet deserialized = converter.convert(serialized, varOrder); + + // Ensure the deserialized value matches the original. + assertEquals(originalBindingSet, deserialized); + } + + /** + * The BindingSet has a Binding whose name is not in the variable order. + * This is illegal. + */ + @Test(expected = IllegalArgumentException.class) + public void serialize_bindingNotInVariableOrder() throws RyaTypeResolverException, BindingSetConversionException { + // Setup the Binding Set. + final MapBindingSet originalBindingSet = new MapBindingSet(); + originalBindingSet.addBinding("x", new URIImpl("http://a")); + originalBindingSet.addBinding("y", new URIImpl("http://b")); + originalBindingSet.addBinding("z", new URIImpl("http://d")); + + // Setup the variable order. + final VariableOrder varOrder = new VariableOrder("x", "y"); + + // Create the byte[] representation of the BindingSet. This will throw an exception. + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + converter.convert(originalBindingSet, varOrder); + } + @Test - public void basicShortUriBsTest() { + public void basicShortUriBsTest() throws BindingSetConversionException { final QueryBindingSet bs = new QueryBindingSet(); bs.addBinding("X",new URIImpl("http://uri1")); bs.addBinding("Y",new URIImpl("http://uri2")); - final String[] varOrder = new String[]{"X","Y"}; - try { - final byte[] byteVal = AccumuloPcjSerializer.serialize(bs, varOrder); - final BindingSet newBs = AccumuloPcjSerializer.deSerialize(byteVal, varOrder); - Assert.equals(bs, newBs); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); - } + final VariableOrder varOrder = new VariableOrder("X","Y"); + + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + final byte[] byteVal = converter.convert(bs, varOrder); + final BindingSet newBs = converter.convert(byteVal, varOrder); + assertEquals(bs, newBs); } @Test - public void basicLongUriBsTest() { + public void basicLongUriBsTest() throws BindingSetConversionException { final QueryBindingSet bs = new QueryBindingSet(); bs.addBinding("X",new URIImpl("http://uri1")); bs.addBinding("Y",new URIImpl("http://uri2")); bs.addBinding("Z",new URIImpl("http://uri3")); bs.addBinding("A",new URIImpl("http://uri4")); bs.addBinding("B",new URIImpl("http://uri5")); - final String[] varOrder = new String[]{"X","Y","Z","A","B"}; - try { - final byte[] byteVal = AccumuloPcjSerializer.serialize(bs, varOrder); - final BindingSet newBs = AccumuloPcjSerializer.deSerialize(byteVal, varOrder); - Assert.equals(bs, newBs); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); - } + final VariableOrder varOrder = new VariableOrder("X","Y","Z","A","B"); + + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + final byte[] byteVal = converter.convert(bs, varOrder); + final BindingSet newBs = converter.convert(byteVal, varOrder); + assertEquals(bs, newBs); } @Test - public void basicShortStringLiteralBsTest() { + public void basicShortStringLiteralBsTest() throws BindingSetConversionException { final QueryBindingSet bs = new QueryBindingSet(); bs.addBinding("X",new LiteralImpl("literal1")); bs.addBinding("Y",new LiteralImpl("literal2")); - final String[] varOrder = new String[]{"X","Y"}; - try { - final byte[] byteVal = AccumuloPcjSerializer.serialize(bs, varOrder); - final BindingSet newBs = AccumuloPcjSerializer.deSerialize(byteVal, varOrder); - Assert.equals(bs, newBs); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); - } + final VariableOrder varOrder = new VariableOrder("X","Y"); + + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + final byte[] byteVal = converter.convert(bs, varOrder); + final BindingSet newBs = converter.convert(byteVal, varOrder); + assertEquals(bs, newBs); } @Test - public void basicShortMixLiteralBsTest() { + public void basicShortMixLiteralBsTest() throws BindingSetConversionException { final QueryBindingSet bs = new QueryBindingSet(); bs.addBinding("X",new LiteralImpl("literal1")); bs.addBinding("Y",new LiteralImpl("5", new URIImpl("http://www.w3.org/2001/XMLSchema#integer"))); - final String[] varOrder = new String[]{"X","Y"}; - try { - final byte[] byteVal = AccumuloPcjSerializer.serialize(bs, varOrder); - final BindingSet newBs = AccumuloPcjSerializer.deSerialize(byteVal, varOrder); - Assert.equals(bs, newBs); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); - } + final VariableOrder varOrder = new VariableOrder("X","Y"); + + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + final byte[] byteVal = converter.convert(bs, varOrder); + final BindingSet newBs = converter.convert(byteVal, varOrder); + assertEquals(bs, newBs); } @Test - public void basicLongMixLiteralBsTest() { + public void basicLongMixLiteralBsTest() throws BindingSetConversionException { final QueryBindingSet bs = new QueryBindingSet(); bs.addBinding("X",new LiteralImpl("literal1")); bs.addBinding("Y",new LiteralImpl("5", new URIImpl("http://www.w3.org/2001/XMLSchema#integer"))); bs.addBinding("Z",new LiteralImpl("5.0", new URIImpl("http://www.w3.org/2001/XMLSchema#double"))); bs.addBinding("W",new LiteralImpl("1000", new URIImpl("http://www.w3.org/2001/XMLSchema#long"))); - final String[] varOrder = new String[]{"W","X","Y","Z"}; - try { - final byte[] byteVal = AccumuloPcjSerializer.serialize(bs, varOrder); - final BindingSet newBs = AccumuloPcjSerializer.deSerialize(byteVal, varOrder); - Assert.equals(bs, newBs); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); - } + final VariableOrder varOrder = new VariableOrder("W","X","Y","Z"); + + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + final byte[] byteVal = converter.convert(bs, varOrder); + final BindingSet newBs = converter.convert(byteVal, varOrder); + assertEquals(bs, newBs); } @Test - public void basicMixUriLiteralBsTest() { + public void basicMixUriLiteralBsTest() throws BindingSetConversionException { final QueryBindingSet bs = new QueryBindingSet(); bs.addBinding("X",new LiteralImpl("literal1")); bs.addBinding("Y",new LiteralImpl("5", new URIImpl("http://www.w3.org/2001/XMLSchema#integer"))); @@ -121,13 +163,11 @@ public class AccumuloPcjSerialzerTest { bs.addBinding("A",new URIImpl("http://uri1")); bs.addBinding("B",new URIImpl("http://uri2")); bs.addBinding("C",new URIImpl("http://uri3")); - final String[] varOrder = new String[]{"A","W","X","Y","Z","B","C"}; - try { - final byte[] byteVal = AccumuloPcjSerializer.serialize(bs, varOrder); - final BindingSet newBs = AccumuloPcjSerializer.deSerialize(byteVal, varOrder); - Assert.equals(bs, newBs); - } catch (final RyaTypeResolverException e) { - e.printStackTrace(); - } + final VariableOrder varOrder = new VariableOrder("A","W","X","Y","Z","B","C"); + + BindingSetConverter<byte[]> converter = new AccumuloPcjSerializer(); + final byte[] byteVal = converter.convert(bs, varOrder); + final BindingSet newBs = converter.convert(byteVal, varOrder); + assertEquals(bs, newBs); } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverterTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverterTest.java b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverterTest.java index 0a7f399..725e557 100644 --- a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverterTest.java +++ b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/BindingSetStringConverterTest.java @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package mvm.rya.indexing.external.tupleSet; import static org.junit.Assert.assertEquals; @@ -32,6 +31,7 @@ import org.openrdf.model.impl.URIImpl; import org.openrdf.query.BindingSet; import org.openrdf.query.impl.MapBindingSet; +import mvm.rya.indexing.external.tupleSet.BindingSetConverter.BindingSetConversionException; import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; /** @@ -40,7 +40,7 @@ import mvm.rya.indexing.external.tupleSet.PcjTables.VariableOrder; public class BindingSetStringConverterTest { @Test - public void toString_URIs() { + public void toString_URIs() throws BindingSetConversionException { // Setup the binding set that will be converted. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new URIImpl("http://a")); @@ -49,9 +49,10 @@ public class BindingSetStringConverterTest { // Convert it to a String. final VariableOrder varOrder = new VariableOrder("y", "z", "x"); - final String bindingSetString = BindingSetStringConverter.toString(originalBindingSet, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final String bindingSetString = converter.convert(originalBindingSet, varOrder); - // Ensure it converted to the expected result. + // Ensure it converted to the expected result.l final String expected = "http://b<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + "http://c<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + @@ -61,14 +62,15 @@ public class BindingSetStringConverterTest { } @Test - public void toString_Decimal() { + public void toString_Decimal() throws BindingSetConversionException { // Setup the binding set that will be converted. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new DecimalLiteralImpl(new BigDecimal(2.5))); // Convert it to a String. final VariableOrder varOrder = new VariableOrder("x"); - final String bindingSetString = BindingSetStringConverter.toString(originalBindingSet, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final String bindingSetString = converter.convert(originalBindingSet, varOrder); // Ensure it converted to the expected result. final String expected = "2.5<<~>>http://www.w3.org/2001/XMLSchema#decimal"; @@ -76,14 +78,15 @@ public class BindingSetStringConverterTest { } @Test - public void toString_Boolean() { + public void toString_Boolean() throws BindingSetConversionException { // Setup the binding set that will be converted. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new BooleanLiteralImpl(true)); // Convert it to a String. final VariableOrder varOrder = new VariableOrder("x"); - final String bindingSetString = BindingSetStringConverter.toString(originalBindingSet, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final String bindingSetString = converter.convert(originalBindingSet, varOrder); // Ensure it converted to the expected result. final String expected = "true<<~>>http://www.w3.org/2001/XMLSchema#boolean"; @@ -91,64 +94,96 @@ public class BindingSetStringConverterTest { } @Test - public void toString_Integer() { + public void toString_Integer() throws BindingSetConversionException { // Setup the binding set that will be converted. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new IntegerLiteralImpl(BigInteger.valueOf(5))); // Convert it to a String. final VariableOrder varOrder = new VariableOrder("x"); - final String bindingSetString = BindingSetStringConverter.toString(originalBindingSet, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final String bindingSetString = converter.convert(originalBindingSet, varOrder); // Ensure it converted to the expected result. final String expected = "5<<~>>http://www.w3.org/2001/XMLSchema#integer"; assertEquals(expected, bindingSetString); } - @Test(expected = IllegalArgumentException.class) - public void toString_varOrderTooShort() { - // Setup the binding set that will be converted. + /** + * All of the Bindings in the BindingSet exactly match the variable order. + * This is the simplest case and is legal. + */ + @Test + public void toString_bindingsMatchVarOrder() throws BindingSetConversionException { + // Setup the Binding Set. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new URIImpl("http://a")); originalBindingSet.addBinding("y", new URIImpl("http://b")); - // This variable order that is too short. - final VariableOrder varOrder = new VariableOrder("y"); + // Setup the variable order. + final VariableOrder varOrder = new VariableOrder("x", "y"); - // The conversion should throw an exception. - BindingSetStringConverter.toString(originalBindingSet, varOrder); + // Create the String representation of the BindingSet. + BindingSetConverter<String> converter = new BindingSetStringConverter(); + String bindingSetString = converter.convert(originalBindingSet, varOrder); + + // Ensure the expected value was created. + String expected = + "http://a<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + + "http://b<<~>>http://www.w3.org/2001/XMLSchema#anyURI"; + assertEquals(expected, bindingSetString); } - @Test(expected = IllegalArgumentException.class) - public void toString_varOrderTooLong() { - // Setup the binding set that will be converted. + /** + * The BindingSet has fewer Bindings than there are variables in the variable + * order, but they are all in the variable order. This is the case where + * the missing bindings were optional. + */ + @Test + public void toString_bindingsSubsetOfVarOrder() throws BindingSetConversionException { + // Setup the Binding Set. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new URIImpl("http://a")); originalBindingSet.addBinding("y", new URIImpl("http://b")); - // This variable order is too long. - final VariableOrder varOrder = new VariableOrder("x", "y", "z"); + // Setup the variable order. + final VariableOrder varOrder = new VariableOrder("x", "a", "y", "b"); - // The conversion should throw an exception. - BindingSetStringConverter.toString(originalBindingSet, varOrder); + // Create the String representation of the BindingSet. + BindingSetConverter<String> converter = new BindingSetStringConverter(); + String bindingSetString = converter.convert(originalBindingSet, varOrder); + + // Ensure the expected value was created. + String expected = + "http://a<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + + BindingSetStringConverter.NULL_VALUE_STRING + ":::" + + "http://b<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + + BindingSetStringConverter.NULL_VALUE_STRING; + assertEquals(expected, bindingSetString); } + /** + * The BindingSet has a Binding whose name is not in the variable order. + * This is illegal. + */ @Test(expected = IllegalArgumentException.class) - public void toString_varOrderWrongBindingNames() { - // Setup the binding set that will be converted. + public void toString_bindingNotInVariableOrder() throws BindingSetConversionException { + // Setup the Binding Set. final MapBindingSet originalBindingSet = new MapBindingSet(); originalBindingSet.addBinding("x", new URIImpl("http://a")); originalBindingSet.addBinding("y", new URIImpl("http://b")); + originalBindingSet.addBinding("z", new URIImpl("http://d")); - // This variable order has the wrong binding names. - final VariableOrder varOrder = new VariableOrder("x", "a"); + // Setup the variable order. + final VariableOrder varOrder = new VariableOrder("x", "y"); - // The conversion should throw an exception. - BindingSetStringConverter.toString(originalBindingSet, varOrder); + // Create the String representation of the BindingSet. This will throw an exception. + BindingSetConverter<String> converter = new BindingSetStringConverter(); + converter.convert(originalBindingSet, varOrder); } @Test - public void fromString() { + public void fromString() throws BindingSetConversionException { // Setup the String that will be converted. final String bindingSetString = "http://b<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + @@ -157,7 +192,8 @@ public class BindingSetStringConverterTest { // Convert it to a BindingSet final VariableOrder varOrder = new VariableOrder("y", "z", "x"); - final BindingSet bindingSet = BindingSetStringConverter.fromString(bindingSetString, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final BindingSet bindingSet = converter.convert(bindingSetString, varOrder); // Ensure it converted to the expected result. final MapBindingSet expected = new MapBindingSet(); @@ -168,13 +204,40 @@ public class BindingSetStringConverterTest { assertEquals(expected, bindingSet); } + /** + * Ensures that when a binding set is converted from a String back to a + * BindingSet, null values do not get converted into Bindings. + */ + @Test + public void fromString_nullValues() throws BindingSetConversionException { + // Setup the String that will be converted. + final String bindingSetString = + "http://value 1<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + + BindingSetStringConverter.NULL_VALUE_STRING + ":::" + + "http://value 2<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + + BindingSetStringConverter.NULL_VALUE_STRING; + + // Convert it to a BindingSet + VariableOrder varOrder = new VariableOrder("x", "a", "y", "b"); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + BindingSet bindingSet = converter.convert(bindingSetString, varOrder); + + // Ensure it converted to the expected reuslt. + final MapBindingSet expected = new MapBindingSet(); + expected.addBinding("x", new URIImpl("http://value 1")); + expected.addBinding("y", new URIImpl("http://value 2")); + + assertEquals(expected, bindingSet); + } + @Test - public void fromString_Decimal() { + public void fromString_Decimal() throws BindingSetConversionException { // Setup the String that will be converted. final String bindingSetString = "2.5<<~>>http://www.w3.org/2001/XMLSchema#decimal"; // Convert it to a BindingSet - final BindingSet bindingSet = BindingSetStringConverter.fromString(bindingSetString, new VariableOrder("x")); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final BindingSet bindingSet = converter.convert(bindingSetString, new VariableOrder("x")); // Ensure it converted to the expected result. final MapBindingSet expected = new MapBindingSet(); @@ -184,12 +247,13 @@ public class BindingSetStringConverterTest { } @Test - public void fromString_Boolean() { + public void fromString_Boolean() throws BindingSetConversionException { // Setup the String that will be converted. final String bindingSetString = "true<<~>>http://www.w3.org/2001/XMLSchema#boolean"; // Convert it to a BindingSet - final BindingSet bindingSet = BindingSetStringConverter.fromString(bindingSetString, new VariableOrder("x")); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final BindingSet bindingSet = converter.convert(bindingSetString, new VariableOrder("x")); // Ensure it converted to the expected result. final MapBindingSet expected = new MapBindingSet(); @@ -199,12 +263,13 @@ public class BindingSetStringConverterTest { } @Test - public void fromString_Integer() { + public void fromString_Integer() throws BindingSetConversionException { // Setup the String that will be converted. final String bindingSetString = "5<<~>>http://www.w3.org/2001/XMLSchema#integer"; // Convert it to a BindingSet - final BindingSet bindingSet = BindingSetStringConverter.fromString(bindingSetString, new VariableOrder("x")); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + final BindingSet bindingSet = converter.convert(bindingSetString, new VariableOrder("x")); // Ensure it converted to the expected result. final MapBindingSet expected = new MapBindingSet(); @@ -214,7 +279,7 @@ public class BindingSetStringConverterTest { } @Test(expected = IllegalArgumentException.class) - public void fromString_varOrderTooShort() { + public void fromString_varOrderTooShort() throws BindingSetConversionException { // Setup the String that will be converted. final String bindingSetString = "http://a<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + @@ -224,11 +289,12 @@ public class BindingSetStringConverterTest { VariableOrder varOrder = new VariableOrder("x"); // The conversion should throw an exception. - BindingSetStringConverter.fromString(bindingSetString, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + converter.convert(bindingSetString, varOrder); } @Test(expected = IllegalArgumentException.class) - public void fromString_varOrderTooLong() { + public void fromString_varOrderTooLong() throws BindingSetConversionException { // Setup the String that will be converted. final String bindingSetString = "http://a<<~>>http://www.w3.org/2001/XMLSchema#anyURI:::" + @@ -238,6 +304,7 @@ public class BindingSetStringConverterTest { VariableOrder varOrder = new VariableOrder("x", "y", "z"); // The conversion should throw an exception. - BindingSetStringConverter.fromString(bindingSetString, varOrder); + BindingSetConverter<String> converter = new BindingSetStringConverter(); + converter.convert(bindingSetString, varOrder); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/PcjTablesIntegrationTests.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/PcjTablesIntegrationTests.java b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/PcjTablesIntegrationTests.java index e3adc16..bb21d33 100644 --- a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/PcjTablesIntegrationTests.java +++ b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/PcjTablesIntegrationTests.java @@ -33,6 +33,7 @@ import mvm.rya.accumulo.AccumuloRyaDAO; import mvm.rya.api.RdfCloudTripleStoreConfiguration; import mvm.rya.api.resolver.RyaTypeResolverException; import mvm.rya.indexing.accumulo.ConfigUtils; +import mvm.rya.indexing.external.tupleSet.BindingSetConverter.BindingSetConversionException; import mvm.rya.indexing.external.tupleSet.PcjTables.PcjException; import mvm.rya.indexing.external.tupleSet.PcjTables.PcjMetadata; import mvm.rya.indexing.external.tupleSet.PcjTables.PcjTableNameFactory; @@ -83,6 +84,8 @@ import com.google.common.io.Files; public class PcjTablesIntegrationTests { private static final Logger log = Logger.getLogger(PcjTablesIntegrationTests.class); + private static final AccumuloPcjSerializer converter = new AccumuloPcjSerializer(); + protected static final String RYA_TABLE_PREFIX = "demo_"; // Rya data store and connections. @@ -137,7 +140,7 @@ public class PcjTablesIntegrationTests { * The method being tested is {@link PcjTables#addResults(Connector, String, java.util.Collection)} */ @Test - public void addResults() throws PcjException, TableNotFoundException, RyaTypeResolverException { + public void addResults() throws PcjException, TableNotFoundException, BindingSetConversionException { final String sparql = "SELECT ?name ?age " + "{" + @@ -189,7 +192,7 @@ public class PcjTablesIntegrationTests { * The method being tested is: {@link PcjTables#populatePcj(Connector, String, RepositoryConnection, String)} */ @Test - public void populatePcj() throws RepositoryException, PcjException, TableNotFoundException, RyaTypeResolverException { + public void populatePcj() throws RepositoryException, PcjException, TableNotFoundException, BindingSetConversionException { // Load some Triples into Rya. Set<Statement> triples = new HashSet<>(); triples.add( new StatementImpl(new URIImpl("http://Alice"), new URIImpl("http://hasAge"), new NumericLiteralImpl(14, XMLSchema.INTEGER)) ); @@ -257,7 +260,7 @@ public class PcjTablesIntegrationTests { * The method being tested is: {@link PcjTables#createAndPopulatePcj(RepositoryConnection, Connector, String, String, String[], Optional)} */ @Test - public void createAndPopulatePcj() throws RepositoryException, PcjException, TableNotFoundException, RyaTypeResolverException { + public void createAndPopulatePcj() throws RepositoryException, PcjException, TableNotFoundException, BindingSetConversionException { // Load some Triples into Rya. Set<Statement> triples = new HashSet<>(); triples.add( new StatementImpl(new URIImpl("http://Alice"), new URIImpl("http://hasAge"), new NumericLiteralImpl(14, XMLSchema.INTEGER)) ); @@ -322,7 +325,7 @@ public class PcjTablesIntegrationTests { * multimap stores a set of deserialized binding sets that were in the PCJ * table for every variable order that is found in the PCJ metadata. */ - private static Multimap<String, BindingSet> loadPcjResults(Connector accumuloConn, String pcjTableName) throws PcjException, TableNotFoundException, RyaTypeResolverException { + private static Multimap<String, BindingSet> loadPcjResults(Connector accumuloConn, String pcjTableName) throws PcjException, TableNotFoundException, BindingSetConversionException { Multimap<String, BindingSet> fetchedResults = HashMultimap.create(); // Get the variable orders the data was written to. @@ -336,7 +339,7 @@ public class PcjTablesIntegrationTests { for(Entry<Key, Value> entry : scanner) { byte[] serializedResult = entry.getKey().getRow().getBytes(); - BindingSet result = AccumuloPcjSerializer.deSerialize(serializedResult, varOrder.toArray()); + BindingSet result = converter.convert(serializedResult, varOrder); fetchedResults.put(varOrder.toString(), result); } } http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/a24515b0/extras/rya.pcj.fluo/pcj.fluo.api/src/main/java/org/apache/rya/indexing/pcj/fluo/api/CreatePcj.java ---------------------------------------------------------------------- diff --git a/extras/rya.pcj.fluo/pcj.fluo.api/src/main/java/org/apache/rya/indexing/pcj/fluo/api/CreatePcj.java b/extras/rya.pcj.fluo/pcj.fluo.api/src/main/java/org/apache/rya/indexing/pcj/fluo/api/CreatePcj.java index b99d293..12e32b6 100644 --- a/extras/rya.pcj.fluo/pcj.fluo.api/src/main/java/org/apache/rya/indexing/pcj/fluo/api/CreatePcj.java +++ b/extras/rya.pcj.fluo/pcj.fluo.api/src/main/java/org/apache/rya/indexing/pcj/fluo/api/CreatePcj.java @@ -36,10 +36,12 @@ import org.apache.rya.indexing.pcj.fluo.app.query.FluoQueryMetadataDAO; import org.apache.rya.indexing.pcj.fluo.app.query.SparqlFluoQueryBuilder; import org.apache.rya.indexing.pcj.fluo.app.query.SparqlFluoQueryBuilder.NodeIds; import org.apache.rya.indexing.pcj.fluo.app.query.StatementPatternMetadata; +import org.openrdf.query.Binding; import org.openrdf.query.BindingSet; import org.openrdf.query.MalformedQueryException; import org.openrdf.query.QueryEvaluationException; import org.openrdf.query.algebra.StatementPattern; +import org.openrdf.query.impl.MapBindingSet; import org.openrdf.query.parser.ParsedQuery; import org.openrdf.query.parser.sparql.SPARQLParser; import org.openrdf.sail.SailConnection; @@ -48,6 +50,7 @@ import org.openrdf.sail.SailException; import info.aduna.iteration.CloseableIteration; import io.fluo.api.client.FluoClient; import io.fluo.api.types.TypedTransaction; +import mvm.rya.indexing.external.tupleSet.BindingSetStringConverter; import mvm.rya.indexing.external.tupleSet.PcjTables; import mvm.rya.indexing.external.tupleSet.PcjTables.PcjException; import mvm.rya.indexing.external.tupleSet.PcjTables.PcjTableNameFactory; @@ -229,13 +232,21 @@ public class CreatePcj { checkNotNull(spMetadata); checkNotNull(batch); + BindingSetStringConverter converter = new BindingSetStringConverter(); + try(TypedTransaction tx = STRING_TYPED_LAYER.wrap(fluo.newTransaction())) { // Get the node's variable order. final String spNodeId = spMetadata.getNodeId(); - final String[] varOrder = spMetadata.getVariableOrder().toArray(); + final VariableOrder varOrder = spMetadata.getVariableOrder(); for(final BindingSet bindingSet : batch) { - final String bindingSetStr = FluoStringConverter.toBindingSetString(bindingSet, varOrder); + MapBindingSet spBindingSet = new MapBindingSet(); + for(String var : varOrder) { + Binding binding = bindingSet.getBinding(var); + spBindingSet.addBinding(binding); + } + + String bindingSetStr = converter.convert(spBindingSet, varOrder); // Write the binding set entry to Fluo for the statement pattern. tx.mutate().row(spNodeId + NODEID_BS_DELIM + bindingSetStr)
