This list is closed, nobody may subscribe to it.
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(139) |
Aug
(94) |
Sep
(232) |
Oct
(143) |
Nov
(138) |
Dec
(55) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(127) |
Feb
(90) |
Mar
(101) |
Apr
(74) |
May
(148) |
Jun
(241) |
Jul
(169) |
Aug
(121) |
Sep
(157) |
Oct
(199) |
Nov
(281) |
Dec
(75) |
2012 |
Jan
(107) |
Feb
(122) |
Mar
(184) |
Apr
(73) |
May
(14) |
Jun
(49) |
Jul
(26) |
Aug
(103) |
Sep
(133) |
Oct
(61) |
Nov
(51) |
Dec
(55) |
2013 |
Jan
(59) |
Feb
(72) |
Mar
(99) |
Apr
(62) |
May
(92) |
Jun
(19) |
Jul
(31) |
Aug
(138) |
Sep
(47) |
Oct
(83) |
Nov
(95) |
Dec
(111) |
2014 |
Jan
(125) |
Feb
(60) |
Mar
(119) |
Apr
(136) |
May
(270) |
Jun
(83) |
Jul
(88) |
Aug
(30) |
Sep
(47) |
Oct
(27) |
Nov
(23) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
(4) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <tho...@us...> - 2010-09-20 20:14:36
|
Revision: 3599 http://bigdata.svn.sourceforge.net/bigdata/?rev=3599&view=rev Author: thompsonbry Date: 2010-09-20 20:14:28 +0000 (Mon, 20 Sep 2010) Log Message: ----------- Added a Tee and a DataSetJoin operator for use in named and default graph queries. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BindingSetPipelineOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Union.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/bset/TestCopyBindingSets.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java Added Paths: ----------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Tee.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/notes.txt branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/join/ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/join/DataSetJoin.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/TestAll.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestAll.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestDataSetJoin.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOp.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOp.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -195,7 +195,7 @@ * identifier for the {@link BOp} within the context of its owning * query. */ - String BOP_ID = "bopId"; + String BOP_ID = BOp.class.getName()+".bopId"; /** * The timeout for the operator evaluation (milliseconds). @@ -210,7 +210,7 @@ * be interpreted with respect to the time when the query began to * execute. */ - String TIMEOUT = "timeout"; + String TIMEOUT = BOp.class.getName()+".timeout"; /** * The default timeout for operator evaluation. Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BindingSetPipelineOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BindingSetPipelineOp.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BindingSetPipelineOp.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -48,9 +48,16 @@ /** * The value of the annotation is the {@link BOp.Annotations#BOP_ID} of - * the ancestor in the operator tree which serves as an alternative sink - * for binding sets. + * the ancestor in the operator tree which serves as the default sink + * for binding sets (default is the parent). */ + String SINK_REF = BindingSetPipelineOp.class.getName() + ".sinkRef"; + + /** + * The value of the annotation is the {@link BOp.Annotations#BOP_ID} of + * the ancestor in the operator tree which serves as the alternative + * sink for binding sets (default is no alternative sink). + */ String ALT_SINK_REF = BindingSetPipelineOp.class.getName() + ".altSinkRef"; Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -41,14 +41,13 @@ import com.bigdata.relation.accesspath.IBlockingBuffer; /** - * This operator copies its source to its sink. It is used to feed the first - * join in the pipeline. The operator should have no children but may be - * decorated with annotations as necessary. + * This operator copies its source to its sink. Specializations exist which are + * used to feed the the initial set of intermediate results into a pipeline ( + * {@link StartOp}) and which are used to replicate intermediate results to more + * than one sink ({@link Tee}). * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ - * - * @todo unit tests. */ public class CopyBindingSetOp extends BindingSetPipelineOp { @@ -99,8 +98,10 @@ } public Void call() throws Exception { - final IAsynchronousIterator<IBindingSet[]> source = context.getSource(); + final IAsynchronousIterator<IBindingSet[]> source = context + .getSource(); final IBlockingBuffer<IBindingSet[]> sink = context.getSink(); + final IBlockingBuffer<IBindingSet[]> sink2 = context.getSink2(); try { final BOpStats stats = context.getStats(); while (source.hasNext()) { @@ -108,11 +109,17 @@ stats.chunksIn.increment(); stats.unitsIn.add(chunk.length); sink.add(chunk); + if (sink2 != null) + sink2.add(chunk); } sink.flush(); + if (sink2 != null) + sink2.flush(); return null; } finally { sink.close(); + if (sink2 != null) + sink2.close(); source.close(); } } Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Tee.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Tee.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Tee.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -0,0 +1,118 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Sep 20, 2010 + */ + +package com.bigdata.bop.bset; + +import java.util.Map; + +import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpEvaluationContext; +import com.bigdata.bop.BindingSetPipelineOp; +import com.bigdata.bop.join.PipelineJoin; +import com.bigdata.rdf.rules.TMUtility; +import com.bigdata.relation.RelationFusedView; +import com.bigdata.relation.rule.Slice; + +/** + * TEE(op):[sinkRef=X; altSinkRef=Y] + * <p> + * Pipeline operator copies its source to both sink and altSink. The sink and + * the altSink must both be ancestors of the operator. The sinkRef MAY be + * omitted when one of the targets is the immediate parent of the TEE. + * Evaluation scope: {@link BOpEvaluationContext#ANY}. + * <p> + * <h2>Example - Truth Maintenance</h2> + * <p> + * In truth maintenance we establish a focus store which is brought to a fixed + * point by applying some rules and a transitive closure operator. Once the + * fixed point is reached, the assertions in the focus store are either inserted + * onto the database or (for retraction) removed from database unless a proof + * can be found that an assertion is still entailed. + * <p> + * The {@link Tee} operator can be used in truth maintenance to read on the + * UNION of the focus store and the database - see {@link TMUtility}. This is + * handled as the "union" of two JOINs using a {@link Tee} as follows: + * + * <pre> + * slice := SLICE( join2 )[bopId=3] + * join2 := JOIN( join1, bar.spo(A,loves,B))[bopId=2] + * join1 := JOIN( tee, foo.spo(A,loves,B))[bopId=1; sinkRef=3] + * tee := TEE( ... )[altSinkRef=2], + * </pre> + * + * The {@link Tee} copies its inputs to both the default sink (its parent, which + * is join1) and the alternate sink (join2). join1 routes its outputs around + * join2, sending them directly to their lowest common ancestor. This has the + * effect of creating a union of their outputs at the receiver. In this example, + * a {@link Slice} is used as the target for both of the join operators. Since + * this is a pipeline construction, the joins will be evaluated in parallel as + * intermediate results arrive for those operators. Normally the {@link Tee} + * will be fed by a {@link StartOp} or another {@link PipelineJoin}. + * + * @todo The union of access paths was historically handled by + * {@link RelationFusedView}. That class should be removed once queries + * are rewritten to use the union of joins. + * + * @todo The {@link TMUtility} will have to be updated to use this operator + * rather than specifying multiple source "names" for the relation of the + * predicate. + * + * @todo The FastClosureRuleTask will also need to be updated to use a + * {@link Union} over the joins rather than a {@link RelationFusedView}. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class Tee extends CopyBindingSetOp { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Deep copy constructor. + * @param op + */ + public Tee(final Tee op) { + super(op); + } + + /** + * Shallow copy constructor. + * @param args + * @param annotations + */ + public Tee(BOp[] args, Map<String, Object> annotations) { + + super(args, annotations); + + getRequiredProperty(BindingSetPipelineOp.Annotations.ALT_SINK_REF); + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Tee.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Union.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Union.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/Union.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -31,6 +31,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; +import com.bigdata.bop.BOp; import com.bigdata.bop.BOpContext; import com.bigdata.bop.BindingSetPipelineOp; import com.bigdata.bop.IBindingSet; @@ -40,42 +41,29 @@ import com.bigdata.util.concurrent.Haltable; /** - * The union of two or more {@link BindingSetPipelineOp} operators. + * UNION(ops)[maxParallel(default all)] + * <p> + * Executes each of the operands in the union as a subqueries. Each subquery is + * run as a separate query but is linked to the parent query in which the UNION + * is being evaluated. The subqueries do not receive bindings from the parent + * and may be executed independently. By default, the subqueries are run with + * unlimited parallelism. + * <p> + * UNION is useful when independent queries are evaluated and their outputs are + * merged. Outputs from the UNION operator flow to the parent operator and will + * be mapped across shards or nodes as appropriate for the parent. UNION runs on + * the query controller. In order to avoid routing intermediate results through + * the controller, the {@link BindingSetPipelineOp.Annotations#SINK_REF} of each + * child operand should be overriden to specify the parent of the UNION + * operator. + * <p> + * UNION can not be used when the intermediate results must be routed into the + * subqueries. However, a {@link Tee} pattern may help in such cases. For + * example, a {@link Tee} may be used to create a union of pipeline joins for + * two access paths during truth maintenance. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ - * - * @todo I have some basic questions about the ability to use a UNION of two - * predicates in scale-out. I think that this might be more accurately - * modeled as the UNION of two joins. That is, rather than: - * - * <pre> - * JOIN( ..., - * UNION( foo.spo(A,loves,B), - * bar.spo(A,loves,B) ) - * ) - * </pre> - * - * using - * - * <pre> - * UNION( JOIN( ..., foo.spo(A,loves,B) ), - * JOIN( ..., bar.spo(A,loves,B) ) - * ) - * </pre> - * - * which would be a binding set union rather than an element union. - * - * @todo The union of access paths was historically handled by - * {@link RelationFusedView}. That class should be removed once queries - * are rewritten to use the union of joins. - * - * @todo The {@link TMUtility} will have to be updated to use this operator - * rather than specifying multiple source "names" for the relation of the - * predicate. - * - * @todo The FastClosureRuleTask will also need to be updated to use a - * {@link Union} over the joins rather than a {@link RelationFusedView}. */ public class Union extends BindingSetPipelineOp { @@ -101,35 +89,35 @@ public FutureTask<Void> eval(final BOpContext<IBindingSet> context) { - return new FutureTask<Void>(new UnionTask(this, context)); - +// return new FutureTask<Void>(new UnionTask(this, context)); + throw new UnsupportedOperationException(); } - /** - * Pipeline union impl. - * - * FIXME All this does is copy its inputs to its outputs. Since we only run - * one chunk of input at a time, it seems that the easiest way to implement - * a union is to have the operators in the union just target the same sink. - */ - private static class UnionTask extends Haltable<Void> implements Callable<Void> { - - public UnionTask(// - final Union op,// - final BOpContext<IBindingSet> context - ) { - - if (op == null) - throw new IllegalArgumentException(); - if (context == null) - throw new IllegalArgumentException(); - } - - public Void call() throws Exception { - // TODO Auto-generated method stub - throw new UnsupportedOperationException(); - } - - } +// /** +// * Pipeline union impl. +// * +// * FIXME All this does is copy its inputs to its outputs. Since we only run +// * one chunk of input at a time, it seems that the easiest way to implement +// * a union is to have the operators in the union just target the same sink. +// */ +// private static class UnionTask extends Haltable<Void> implements Callable<Void> { +// +// public UnionTask(// +// final Union op,// +// final BOpContext<IBindingSet> context +// ) { +// +// if (op == null) +// throw new IllegalArgumentException(); +// if (context == null) +// throw new IllegalArgumentException(); +// } +// +// public Void call() throws Exception { +// // TODO Auto-generated method stub +// throw new UnsupportedOperationException(); +// } +// +// } } Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/notes.txt =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/notes.txt (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/notes.txt 2010-09-20 20:14:28 UTC (rev 3599) @@ -0,0 +1,160 @@ +RunningQuery: + + * FIXME Raise this into an annotation that we can tweak from the unit + * tests and then debug the problem. + * + * FIXME Add an annotation or method to mark operators which must be + * evaluated using operator-at-a-time evaluation. SORT is the main + * example here (it must be operator at a time of necessity) but other + * operators may implemented with operator at a time assumptions. This + * might be on PipelineOp and could be trinary {Chunked,Blocked,All}. + +Note: Many of the maxParallel annotations related to thread consumption will go +away with Java7 and async file IO. Other annotations, such as the #of 1M buffers +to allocate to an operator, need to be introduced to handle high volume queries. + +Note: UNION, STEPS, and STAR(transitive closure) are all evaluated on the query +controller. + +--- +UNION(ops)[maxParallel(default all)] + +Executes each of the operands in the union as subqueries. Each subquery is run +as a separate RunningQuery but is linked to the parent query in which the UNION +is being evaluated. The subqueries do not receive bindings from the parent and +may be executed independently. + +--- +STEPS(ops)[maxParallel(default 1)] + +The operands are executed as independent subqueries. Unlike UNION, STEPS does +not copy its source binding sets. + +--- + +STAR(op) [maxItr(default all)] + +Evaluate the operand until its mutation count remains unchanged from one round +to the next. The operand must write on a resource. The fixed point is determined +by examining BOPStats.mutationCount. + +Do with INSERT/REMOVE since all involve mutation. + +--- +DataSetJoin([left,var])[graphs={graphIds}; maxParallel=50] + +SPARQL specific join binds var to each of the given graphIds values for each +source binding set. This join operator is useful when the multiplicity of the +graphIds set is modest (between 2 and ~5000). This differs from a pipeline join +by joining against inline data and by being more specialized (it lacks a pred). +An alternative would be to develop an inline access path and then specify a std +predicate which references the data in its annotation. That could then generalize +to a predicate which references persistent data, query or tx local data, or inline +data. However, the DataSetJoin is still far simpler since it just binds the var +and send out the asBound binding set and does not need to worry about internal +parallelism, alternative sinks, or chunking. + +Note: SPARQL default graph queries require us to apply a +distinct {s,p,o} filter to each default graph access path. For scale-out, that +is a distributed distinct access path filter. A DHT is used when the scale is +moderate. A distributed external merge sort SORT is used when the scale is very +large. + +Special cases exist for: + + - Whenever C is a constant, we are guaranteed that the SPO will be distinct and + do not need to apply a distributed distinct filter. + + - The SPOC access path can be optimized because we know that C is strictly + ascending. We can note the last observed {s,p,o} and skip to the next possible + o in the index (o:=o+1) using an advancer pattern (this could also just scan + until o changes). These are the possibly distinct {s,p,o} triples, which can + then be sent to the DHT unless we have a guarantee that S never crosses a + shard boundary (this is trivially true for standalone can this constraint can + be imposed on scale-out, but can cause problems if some subjects are very + highly referenced). + + - ? + +--- +INSERT(op,pred) : insert elements into an index. +DELETE(op,pred) : remove elements from an index. + +The access path mutation operators construct elements from the source binding +sets and the asBBound predicates. For each element so constructed, they insert/ +remove the corresponding element into/from the access path. These operators +update a mutation counter IFF the access path was modified for the constructed +element. STAR relies on the mutation operator to detect a fixed point. + +The mutation access paths need to use the appropriate concurrency control to +ensure the constraint on the mutable B+Tree is respected. This is either +the UnisolatedReadWriteIndex or the LockManager/ConcurrencyManager. + +The basic mutation operators write on an access path and may be combined using +STEPS in order to update all of the indices associated with a relation. + + - For incremental TM, we also need to construct an element for the just index + from the rule and assert it onto that index. + + - For the lexicon, we also need to write on the full text index. + + - For SIDs mode, we also need to capture the logic to ground the statements by + binding the SIDs. + + - triggers could be integrated here. perhaps events backed by a queue which + could be either restart safe or query local? + +---- +Parallel distributed closure : TBD. Review notes posted on trak. + +---- +done. TEE(op):[sinkRef=X; altSinkRef=Y] + +Pipeline operator copies its source to both sink and altSink. The sink and the +altSink must both be ancestors of the operator. The sinkRef MAY be omitted when +one of the targets is the immediate parent of the TEE. Evaluation scope: ANY. + +TM rules. JOIN of AP UNION is the same as the UNION of JOINs of the APs. This +gets translated into a pattern of routing in the pipeline such that the two JOINs +appear one after the other and the first join has its default sink _overridden_ +to reference the same target as the second join. This has the effect of creating +a union of their outputs at the receiver and the benefit that the JOINs run in +parallel. + +- We MUST also satisfy the requirement that the source binding sets are seen by +both joins. This can be done using an operator which copies its source binding +sets to both its default and alternative sinks. That would be an ANY scope op. + +This is basically an OR "pattern". + +---- +Lexicon joins - + +==== +Features: + + - operator-at-once evaluation. The operator is triggered once its possible + triggers are done. This is just an application of the same utility method + which we use to decide when a query is done. + + - subquery evaluation (linked parent to child). a subquery may be cancelled + by a slice without cancelling the parent. cancelling the parent terminates + all subqueries. whenever a query or subquery is terminated, we need to go + through its operator and query life cycle tear down methods (unit tests). + + - default graph access path using DHT. See DataSetJoin, which has some notes. + + - query and connection local resources: creating, destroying and using resources. + references to query local resources permit reuse of intermediate results across + different. + + CREATE FOO AS TEMP GRAPH ON LOCAL TEMP STORE SPO ONLY SHARED LEXICON + + - "thick" resources which can be sent along with the query or access either by + RMI or copied to the node where the query is running on demand. (This could + be just alternative access path instantiations which are selected by the query + optimizer or defaulted based on the amount of data to be moved to/from the + node if not specified.) + + - The predicate could have fromRevision/toRevision annotations which would be + used for fast computation of the delta between two historical commit points. Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/notes.txt ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/join/DataSetJoin.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/join/DataSetJoin.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/join/DataSetJoin.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -0,0 +1,254 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Sep 20, 2010 + */ + +package com.bigdata.bop.rdf.join; + +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; + +import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpContext; +import com.bigdata.bop.BOpEvaluationContext; +import com.bigdata.bop.BindingSetPipelineOp; +import com.bigdata.bop.Constant; +import com.bigdata.bop.IBindingSet; +import com.bigdata.bop.IVariable; +import com.bigdata.bop.constraint.INConstraint; +import com.bigdata.bop.engine.BOpStats; +import com.bigdata.bop.engine.IChunkAccessor; +import com.bigdata.bop.join.PipelineJoin; +import com.bigdata.rdf.internal.IV; +import com.bigdata.relation.accesspath.IAsynchronousIterator; +import com.bigdata.relation.accesspath.IBlockingBuffer; + +/** + * DataSetJoin(left,var)[graphs={graphIds}; maxParallel=50] + * <p> + * SPARQL specific join binds <i>var</i> to each of the given graphIds values + * for each source binding set. This join operator is useful when the + * multiplicity of the graphs is small to moderate. If there are a very large + * number of graphs, then the operator tree is to cumbersome and you would do + * better off joining against an index (whether temporary or permanent) + * containing the graphs. + * <p> + * The evaluation context is {@link BOpEvaluationContext#ANY}. + * + * @todo An alternative would be to develop an inline access path and then + * specify a standard predicate which references the data in its + * annotation. That could then generalize to a predicate which references + * persistent data, query or tx local data, or inline data. However, the + * DataSetJoin is still far simpler since it just binds the var and send + * out the asBound binding set and does not need to worry about internal + * parallelism, alternative sinks, or chunking. + * + * @todo SPARQL default graph queries require us to apply a distinct {s,p,o} + * filter to each default graph access path. For scale-out, that is a + * distributed distinct access path filter. A DHT is used when the scale + * is moderate. A distributed external merge sort SORT is used when the + * scale is very large. + * <p> + * Special cases exist for: + * <ul> + * + * <li>Whenever C is a constant, we are guaranteed that the SPO will be + * distinct and do not need to apply a distributed distinct filter.</li> + * <li> + * The SPOC access path can be optimized because we know that C is + * strictly ascending. We can note the last observed {s,p,o} and skip to + * the next possible o in the index (o:=o+1) using an advancer pattern + * (this could also just scan until o changes). These are the possibly + * distinct {s,p,o} triples, which can then be sent to the DHT unless we + * have a guarantee that S never crosses a shard boundary (this is + * trivially true for standalone can this constraint can be imposed on + * scale-out, but can cause problems if some subjects are very highly + * referenced).</li> + * <li> + * There will be some cases where we do better by doing a + * {@link PipelineJoin} and filtering using an {@link INConstraint}. + * However, this is probably only true for very small temporary graphs and + * in high volume scale-out joins where a cost analysis shows that it will + * be more efficient to read all the shards with the IN filter.</li> + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class DataSetJoin extends BindingSetPipelineOp { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public interface Annotations extends BindingSetPipelineOp.Annotations { + + /** + * The variable to be bound. + */ + String VAR = DataSetJoin.class.getName() + ".var"; + + /** + * The {@link IV}s to be bound. This is logically a set and SHOULD NOT + * include duplicates. The elements in this array SHOULD be ordered for + * improved efficiency. + */ + String GRAPHS = DataSetJoin.class.getName() + ".graphs"; + + } + + /** + * Deep copy constructor. + * + * @param op + */ + public DataSetJoin(DataSetJoin op) { + super(op); + } + + /** + * Shallow copy constructor. + * @param args + * @param annotations + */ + public DataSetJoin(BOp[] args, Map<String, Object> annotations) { + super(args, annotations); + getVar(); + getGraphs(); + } + + public IVariable<?> getVar() { + return (IVariable<?>)getRequiredProperty(Annotations.VAR); + } + + public IV[] getGraphs() { + return (IV[]) getRequiredProperty(Annotations.GRAPHS); + } + + public FutureTask<Void> eval(final BOpContext<IBindingSet> context) { + + return new FutureTask<Void>(new DataSetJoinTask(this,context)); + + } + + /** + * Copy the source to the sink. + * + * @todo Optimize this. When using an {@link IChunkAccessor} we should be + * able to directly output the same chunk. + */ + static private class DataSetJoinTask implements Callable<Void> { + + private final DataSetJoin op; + + private final BOpContext<IBindingSet> context; + + private final IVariable<?> var; + private final IV[] graphs; + + DataSetJoinTask(final DataSetJoin op, + final BOpContext<IBindingSet> context) { + + this.op = op; + + this.context = context; + + var = op.getVar(); + + graphs = op.getGraphs(); + + } + + /** + * FIXME unit tests. + */ + public Void call() throws Exception { + final IAsynchronousIterator<IBindingSet[]> source = context + .getSource(); + final IBlockingBuffer<IBindingSet[]> sink = context.getSink(); + try { + final BOpStats stats = context.getStats(); + while (source.hasNext()) { + final IBindingSet[] chunk = source.next(); + stats.chunksIn.increment(); + stats.unitsIn.add(chunk.length); + handleChunk_(chunk, sink); + } + sink.flush(); + return null; + } finally { + sink.close(); + source.close(); + } + } + + /** + * Cross product join. For each source binding set and each graph, + * output one binding set in which the variable is bound to that graph. + * + * @param chunk + * A chunk of {@link IBindingSet}s from the source. + * @param sink + * Where to write the data. + * + * @todo Should we choose the nesting order of the loops based on the + * multiplicity of the source chunk size and the #of graphs to be + * bound? That way the inner loop decides the chunk size of the + * output. + * <p> + * Should we always emit an asBound source chunk for a given + * graphId? That will cluster better when the target predicate is + * mapped over CSPO. + */ + private void handleChunk_(final IBindingSet[] chunk, + final IBlockingBuffer<IBindingSet[]> sink) { + + final IBindingSet[] chunkOut = new IBindingSet[chunk.length + * graphs.length]; + + int n = 0; + + for (IBindingSet bset : chunk) { + + for (IV c : graphs) { + + bset = bset.clone(); + + bset.set(var, new Constant<IV>(c)); + + chunkOut[n++] = bset; + + } + + } + + sink.add(chunkOut); + + } + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/rdf/join/DataSetJoin.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -92,6 +92,9 @@ // join operators. suite.addTest(com.bigdata.bop.join.TestAll.suite()); + // Specialized RDF join operators : @todo move to bigdata-rdf. + suite.addTest(com.bigdata.bop.rdf.join.TestAll.suite()); + // aggregation operators. suite.addTest(com.bigdata.bop.solutions.TestAll.suite()); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/bset/TestCopyBindingSets.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/bset/TestCopyBindingSets.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/bset/TestCopyBindingSets.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -176,5 +176,14 @@ assertEquals(1L, stats.chunksOut.get()); } + + /** + * {@link Tee} is just a specialized {@link CopyBindingSetOp} which requires + * that the alternate sink is also specified. Write a unit test of those + * semantics for {@link CopyBindingSetOp}. + */ + public void test_copyToSinkAndAltSink() { + fail("write test"); + } } Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/TestAll.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/TestAll.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/TestAll.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -0,0 +1,70 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.bop.rdf; + + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Aggregates test suites into increasing dependency order. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestAll extends TestCase { + + /** + * + */ + public TestAll() { + + } + + /** + * @param arg0 + */ + public TestAll(String arg0) { + + super(arg0); + + } + + /** + * Returns a test that will run each of the implementation specific test + * suites in turn. + */ + public static Test suite() + { + + final TestSuite suite = new TestSuite("RDF operators"); + + suite.addTest(com.bigdata.bop.rdf.join.TestAll.suite()); + + return suite; + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/TestAll.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestAll.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestAll.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestAll.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -0,0 +1,70 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.bop.rdf.join; + + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Aggregates test suites into increasing dependency order. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestAll extends TestCase { + + /** + * + */ + public TestAll() { + + } + + /** + * @param arg0 + */ + public TestAll(String arg0) { + + super(arg0); + + } + + /** + * Returns a test that will run each of the implementation specific test + * suites in turn. + */ + public static Test suite() + { + + final TestSuite suite = new TestSuite("RDF join operators"); + + suite.addTestSuite(TestDataSetJoin.class); + + return suite; + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestAll.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestDataSetJoin.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestDataSetJoin.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestDataSetJoin.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -0,0 +1,56 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Sep 20, 2010 + */ + +package com.bigdata.bop.rdf.join; + +import junit.framework.TestCase2; + +/** + * Test {@link DataSetJoin} + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestDataSetJoin extends TestCase2 { + + /** + * + */ + public TestDataSetJoin() { + } + + /** + * @param name + */ + public TestDataSetJoin(String name) { + super(name); + } + + public void test_something() { + fail("write tests"); + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/rdf/join/TestDataSetJoin.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java 2010-09-20 19:43:44 UTC (rev 3598) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java 2010-09-20 20:14:28 UTC (rev 3599) @@ -121,6 +121,7 @@ * that go around the sail. */ cxn.flush();//commit(); + cxn.commit();// if (log.isInfoEnabled()) { log.info("\n" + sail.getDatabase().dumpStore()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mrp...@us...> - 2010-09-20 19:43:55
|
Revision: 3598 http://bigdata.svn.sourceforge.net/bigdata/?rev=3598&view=rev Author: mrpersonick Date: 2010-09-20 19:43:44 +0000 (Mon, 20 Sep 2010) Log Message: ----------- adding Sesame to BOp conversion Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/magic/MagicPredicate.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java 2010-09-20 19:40:52 UTC (rev 3597) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java 2010-09-20 19:43:44 UTC (rev 3598) @@ -41,6 +41,7 @@ import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.NV; import com.bigdata.btree.IRangeQuery; +import com.bigdata.journal.ITx; import com.bigdata.relation.IRelation; import com.bigdata.relation.accesspath.IElementFilter; import com.bigdata.relation.rule.ISolutionExpander; @@ -93,7 +94,7 @@ final String relationName) { this(values, relationName, -1/* partitionId */, false/* optional */, - null/* constraint */, null/* expander */); + null/* constraint */, null/* expander */, ITx.READ_COMMITTED); } @@ -116,7 +117,7 @@ public Predicate(final IVariableOrConstant<?>[] values, final String relationName, final int partitionId, final boolean optional, final IElementFilter<E> constraint, - final ISolutionExpander<E> expander) { + final ISolutionExpander<E> expander, final long timestamp) { this(values, NV.asMap(new NV[] {// new NV(Annotations.RELATION_NAME,new String[]{relationName}),// @@ -124,6 +125,7 @@ new NV(Annotations.OPTIONAL,optional),// new NV(Annotations.CONSTRAINT,constraint),// new NV(Annotations.EXPANDER,expander),// + new NV(Annotations.TIMESTAMP, timestamp) })); if (relationName == null) Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java 2010-09-20 19:40:52 UTC (rev 3597) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/Rule2BOpUtility.java 2010-09-20 19:43:44 UTC (rev 3598) @@ -73,10 +73,10 @@ * * @return */ - public static BindingSetPipelineOp convert(final IStep step) { + public static BindingSetPipelineOp convert(final IStep step, final int startId) { if (step instanceof Rule) - return convert((Rule) step); + return convert((Rule) step, startId); else if (step instanceof Program) return convert((Program) step); @@ -91,9 +91,9 @@ * * @return */ - public static BindingSetPipelineOp convert(final Rule rule) { + public static BindingSetPipelineOp convert(final Rule rule, final int startId) { - int bopId = 1; + int bopId = startId; final BindingSetPipelineOp startOp = new StartOp(new BOp[] {}, NV.asMap(new NV[] {// Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/magic/MagicPredicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/magic/MagicPredicate.java 2010-09-20 19:40:52 UTC (rev 3597) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/magic/MagicPredicate.java 2010-09-20 19:43:44 UTC (rev 3598) @@ -30,6 +30,7 @@ import com.bigdata.bop.BOp; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.ap.Predicate; +import com.bigdata.journal.ITx; import com.bigdata.rdf.internal.IV; import com.bigdata.relation.accesspath.IElementFilter; import com.bigdata.relation.rule.ISolutionExpander; @@ -120,7 +121,7 @@ IVariableOrConstant<IV>... terms// ) { - super(terms, relationName[0], partitionId, false, constraint, expander); + super(terms, relationName[0], partitionId, false, constraint, expander, ITx.READ_COMMITTED); } Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java 2010-09-20 19:40:52 UTC (rev 3597) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java 2010-09-20 19:43:44 UTC (rev 3598) @@ -32,6 +32,7 @@ import com.bigdata.bop.IVariable; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.ap.Predicate; +import com.bigdata.journal.ITx; import com.bigdata.rdf.internal.IV; import com.bigdata.relation.accesspath.IElementFilter; import com.bigdata.relation.rule.ISolutionExpander; @@ -51,19 +52,19 @@ */ private static final long serialVersionUID = 1L; - /** - * The arity is 3 unless the context position was given (as either a - * variable or bound to a constant) in which case it is 4. - * - * @todo rather than having a conditional arity, modify the SPOPredicate - * constructor to pass on either args[3] or args[3] depending on - * whether we are using triples or quads. - */ - public final int arity() { - - return get(3/*c*/) == null ? 3 : 4; - - } +// /** +// * The arity is 3 unless the context position was given (as either a +// * variable or bound to a constant) in which case it is 4. +// * +// * @todo rather than having a conditional arity, modify the SPOPredicate +// * constructor to pass on either args[3] or args[3] depending on +// * whether we are using triples or quads. +// */ +// public final int arity() { +// +// return get(3/*c*/) == null ? 3 : 4; +// +// } /** * Required shallow copy constructor. @@ -230,12 +231,12 @@ ) { super( -// (c == null ? new IVariableOrConstant[] { s, p, o } -// : new IVariableOrConstant[] { s, p, o, c }), + (c == null ? new IVariableOrConstant[] { s, p, o } + : new IVariableOrConstant[] { s, p, o, c }), - new IVariableOrConstant[] { s, p, o, c }, +// new IVariableOrConstant[] { s, p, o, c }, - relationName[0], partitionId, optional, constraint, expander); + relationName[0], partitionId, optional, constraint, expander, ITx.READ_COMMITTED); // if (relationName == null) // throw new IllegalArgumentException(); Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl.java 2010-09-20 19:40:52 UTC (rev 3597) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl.java 2010-09-20 19:43:44 UTC (rev 3598) @@ -49,6 +49,7 @@ import org.openrdf.query.algebra.evaluation.iterator.FilterIterator; import org.openrdf.query.algebra.helpers.QueryModelVisitorBase; import com.bigdata.BigdataStatics; +import com.bigdata.bop.BOpContext; import com.bigdata.bop.BindingSetPipelineOp; import com.bigdata.bop.Constant; import com.bigdata.bop.HashBindingSet; @@ -64,7 +65,9 @@ import com.bigdata.bop.constraint.NE; import com.bigdata.bop.constraint.NEConstant; import com.bigdata.bop.constraint.OR; +import com.bigdata.bop.engine.BOpStats; import com.bigdata.bop.engine.LocalChunkMessage; +import com.bigdata.bop.engine.MockRunningQuery; import com.bigdata.bop.engine.QueryEngine; import com.bigdata.bop.engine.Rule2BOpUtility; import com.bigdata.bop.engine.RunningQuery; @@ -94,6 +97,7 @@ import com.bigdata.rdf.store.IRawTripleStore; import com.bigdata.relation.accesspath.IAccessPath; import com.bigdata.relation.accesspath.IAsynchronousIterator; +import com.bigdata.relation.accesspath.IBlockingBuffer; import com.bigdata.relation.accesspath.IBuffer; import com.bigdata.relation.accesspath.IElementFilter; import com.bigdata.relation.accesspath.ThickAsynchronousIterator; @@ -1640,14 +1644,13 @@ final IStep step) throws Exception { - final BindingSetPipelineOp query = Rule2BOpUtility.convert(step); + final int startId = 1; + final BindingSetPipelineOp query = Rule2BOpUtility.convert(step, startId); if (log.isInfoEnabled()) { log.info(query); } - final int startId = query.getProperty(Predicate.Annotations.BOP_ID); - final QueryEngine queryEngine = tripleSource.getSail().getQueryEngine(); final UUID queryId = UUID.randomUUID(); @@ -1655,7 +1658,7 @@ new LocalChunkMessage<IBindingSet>(queryEngine, queryId, startId, -1/* partitionId */, newBindingSetIterator(new HashBindingSet()))); - + final IAsynchronousIterator<IBindingSet[]> it1 = runningQuery.iterator(); Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java 2010-09-20 19:40:52 UTC (rev 3597) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestBOps.java 2010-09-20 19:43:44 UTC (rev 3598) @@ -136,24 +136,28 @@ "select * " + "WHERE { " + " ?s rdf:type ns:Person . " + - " ?s ns:likes ?likes . " + - " ?s rdfs:label ?label . " + + " ?s ns:likes ns:RDF . " + +// " ?s rdfs:label ?label . " + "}"; final TupleQuery tupleQuery = cxn.prepareTupleQuery(QueryLanguage.SPARQL, query); TupleQueryResult result = tupleQuery.evaluate(); + + while (result.hasNext()) { + System.err.println(result.next()); + } Collection<BindingSet> solution = new LinkedList<BindingSet>(); solution.add(createBindingSet(new Binding[] { new BindingImpl("s", mike), - new BindingImpl("likes", rdf), - new BindingImpl("label", l1) +// new BindingImpl("likes", rdf), +// new BindingImpl("label", l1) })); solution.add(createBindingSet(new Binding[] { new BindingImpl("s", bryan), - new BindingImpl("likes", rdf), - new BindingImpl("label", l2) +// new BindingImpl("likes", rdf), +// new BindingImpl("label", l2) })); compare(result, solution); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 19:40:58
|
Revision: 3597 http://bigdata.svn.sourceforge.net/bigdata/?rev=3597&view=rev Author: blevine218 Date: 2010-09-20 19:40:52 +0000 (Mon, 20 Sep 2010) Log Message: ----------- add *Remote tests to include pattern Modified Paths: -------------- branches/maven_scaleout/bigdata-integ/pom.xml Modified: branches/maven_scaleout/bigdata-integ/pom.xml =================================================================== --- branches/maven_scaleout/bigdata-integ/pom.xml 2010-09-20 18:00:40 UTC (rev 3596) +++ branches/maven_scaleout/bigdata-integ/pom.xml 2010-09-20 19:40:52 UTC (rev 3597) @@ -104,7 +104,12 @@ <includes> <include>**/Test*.java</include> <include>**/*Test.java</include> + <include>**/*TestRemote.java</include> + <include>**/Test*Remote.java</include> </includes> + <excludes> + <exclude>**/*Suite.java</exclude> + </excludes> <systemPropertyVariables> <java.security.policy>${java.security.policy}</java.security.policy> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 18:00:46
|
Revision: 3596 http://bigdata.svn.sourceforge.net/bigdata/?rev=3596&view=rev Author: blevine218 Date: 2010-09-20 18:00:40 +0000 (Mon, 20 Sep 2010) Log Message: ----------- remove dependency on federation.name system property and instead use ConfigDeployUtil.getFederationName() Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java Modified: branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java 2010-09-20 17:56:03 UTC (rev 3595) +++ branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java 2010-09-20 18:00:40 UTC (rev 3596) @@ -42,6 +42,7 @@ import com.bigdata.jini.start.config.ServiceConfiguration; import com.bigdata.jini.start.config.TransactionServerConfiguration; import com.bigdata.service.jini.TransactionServer; +import com.bigdata.util.config.ConfigDeployUtil; /** * Some unit tests for {@link ServiceConfiguration} and friends focused on @@ -166,7 +167,7 @@ String groupsOpt = "com.bigdata.transaction.groupsToJoin=" +"new String[]" +openBracket - +quote+ System.getProperty("federation.name","testFed")+quote + +quote+ConfigDeployUtil.getFederationName()+quote +comma +quote+System.getProperty("bigdata.zrootname","testZroot")+quote +closeBracket; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 17:56:09
|
Revision: 3595 http://bigdata.svn.sourceforge.net/bigdata/?rev=3595&view=rev Author: blevine218 Date: 2010-09-20 17:56:03 +0000 (Mon, 20 Sep 2010) Log Message: ----------- removed commented out code Modified Paths: -------------- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java Modified: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java 2010-09-20 17:54:31 UTC (rev 3594) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java 2010-09-20 17:56:03 UTC (rev 3595) @@ -154,7 +154,7 @@ String groupsOpt = "com.bigdata.transaction.groupsToJoin=" +"new String[]" +openBracket - +quote+ /*System.getProperty("federation.name","testFed")*/ ConfigDeployUtil.getFederationName() +quote + +quote+ConfigDeployUtil.getFederationName()+quote +comma +quote+System.getProperty("bigdata.zrootname","testZroot")+quote +closeBracket; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 17:54:38
|
Revision: 3594 http://bigdata.svn.sourceforge.net/bigdata/?rev=3594&view=rev Author: blevine218 Date: 2010-09-20 17:54:31 +0000 (Mon, 20 Sep 2010) Log Message: ----------- check in tests in com.bigdata.jini.start.config package Added Paths: ----------- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/JiniStartConfigSuite.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfigurationRemote.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestZookeeperServerEntry.java Added: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/JiniStartConfigSuite.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/JiniStartConfigSuite.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/JiniStartConfigSuite.java 2010-09-20 17:54:31 UTC (rev 3594) @@ -0,0 +1,33 @@ +/*********************************************************************** + * + * $Id$ + * + * Copyright (c) 2000-2010 Nokia Corporation. + * + * This material, including documentation and any related computer + * programs, is protected by copyright controlled by Nokia Corporation. + * All rights are reserved. Copying, including reproducing, storing, + * adapting or translating, any or all of this material requires the prior + * written consent of Nokia Corporation. This material also contains + * confidential information which may not be disclosed to others without + * the prior written consent of Nokia Corporation. + **********************************************************************/ +package com.bigdata.jini.start.config; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author blevine + * + */ +@RunWith(Suite.class) +...@Su...iteClasses({ + TestServiceConfiguration.class, + TestServiceConfigurationRemote.class, + TestZookeeperServerEntry.class +}) + +public class JiniStartConfigSuite +{ +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java (from rev 3580, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfiguration.java 2010-09-20 17:54:31 UTC (rev 3594) @@ -0,0 +1,176 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 6, 2009 + */ + +package com.bigdata.jini.start.config; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.Test; + +import com.bigdata.DataFinder; +import net.jini.config.Configuration; +import net.jini.config.ConfigurationException; +import net.jini.config.ConfigurationProvider; + +import com.bigdata.jini.start.config.BigdataServiceConfiguration; +import com.bigdata.jini.start.config.IServiceConstraint; +import com.bigdata.jini.start.config.ServiceConfiguration; +import com.bigdata.jini.start.config.TransactionServerConfiguration; +import com.bigdata.service.jini.TransactionServer; +import com.bigdata.util.config.ConfigDeployUtil; + + +/** + * Some unit tests for {@link ServiceConfiguration} and friends focused on + * verifying correct extraction of properties and the correct generation of + * command lines and configuration files. + * <p> + * Note: all of this can be tested directly since we can parse the generated + * configuration files. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + * + * @todo not testing correct generation of command lines + * + * @todo not testing correct generation of configuration files. + */ +public class TestServiceConfiguration { + + protected boolean serviceImplRemote; + + /** + * + */ + public TestServiceConfiguration() { + this.serviceImplRemote = false; + } + + protected TestServiceConfiguration(boolean serviceImplRemote) { + this.serviceImplRemote = serviceImplRemote; + } + + /** + * A configuration file used by some of the unit tests in this package. + */ + private final String configFile = DataFinder.bestURI("testing/data/com/bigdata/jini/start/config/testfed.config").toASCIIString(); + + /** + * + * + * @throws FileNotFoundException + * @throws ConfigurationException + */ + @Test + public void test01() throws FileNotFoundException, ConfigurationException { + + // Note: reads from a URI. + final Configuration config = ConfigurationProvider.getInstance(new String[] { configFile }); + + System.err.println(Arrays.toString((String[])config.getEntry( + ServiceConfiguration.class.getName(), "classpath", + String[].class))); + + File serviceDirFromConfig = + (File)config.getEntry(ServiceConfiguration.class.getName(), "serviceDir", + File.class, new File("serviceDir-NOT-SET")); + + BigdataServiceConfiguration serviceConfig = null; + if(serviceImplRemote) { + serviceConfig = new TransactionServerConfiguration + (TransactionServer.class, config); + Assert.assertEquals(TransactionServer.class.getName(), serviceConfig.className); + Assert.assertArrayEquals(new String[] {"-Xmx1G", "-server"}, serviceConfig.args); + Assert.assertArrayEquals( + new String[] { "com.bigdata.service.jini.TransactionServer.Options.SNAPSHOT_INTERVAL=60000" }, + serviceConfig.options); + } else { + serviceConfig = + new TransactionServerConfiguration + (com.bigdata.transaction.ServiceImpl.class, config); + + Assert.assertEquals(com.bigdata.transaction.ServiceImpl.class.getName(), serviceConfig.className); + + String appHome = System.getProperty("app.home"); + String fSep = System.getProperty("file.separator"); + String logDir = + appHome+fSep+"dist"+fSep+"bigdata"+fSep+"var"+fSep+"log"; + String logFile = + appHome+fSep+"dist"+fSep+"bigdata"+fSep+"var"+fSep+"config" + +fSep+"logging"+fSep+"transaction-logging.properties"; + String configFile = + appHome+fSep+"dist"+fSep+"bigdata"+fSep+"var"+fSep+"config" + +fSep+"jini"+fSep+"transaction.config"; + + String memVal = "-Xmx1G"; + String securityMgr = "-Djava.security.manager="; + String log4jProp = "-Dlog4j.configuration="+logFile; + String log4jPrimProp = "-Dlog4j.primary.configuration="+logFile; + String logDirProp = "-Dbigdata.logDir="+logDir; + String javaUtilProp = "-Djava.util.logging.config.file="+logFile; + String appHomeProp = "-Dapp.home="+appHome; + String configProp = "-Dconfig="+configFile; + String usingProp = "-DusingServiceConfiguration=true"; + + String[] expectedArgsArray = + new String[] { memVal, securityMgr, log4jProp, log4jPrimProp, + javaUtilProp, logDirProp, appHomeProp, + configProp, usingProp }; + + Assert.assertArrayEquals(expectedArgsArray, serviceConfig.args); + + String quote = "\""; + String comma = ","; + String openBracket = "{"; + String closeBracket = "}"; + String snapshotOpt = "com.bigdata.transaction.EmbeddedTransactionService.Options.SNAPSHOT_INTERVAL=60000"; + String groupsOpt = "com.bigdata.transaction.groupsToJoin=" + +"new String[]" + +openBracket + +quote+ /*System.getProperty("federation.name","testFed")*/ ConfigDeployUtil.getFederationName() +quote + +comma + +quote+System.getProperty("bigdata.zrootname","testZroot")+quote + +closeBracket; + String locatorsOpt = "com.bigdata.transaction.locatorsToJoin=" + +"new LookupLocator[]" + +openBracket + +closeBracket; + + String[] expectedOptsArray = new String[] { snapshotOpt, groupsOpt, locatorsOpt }; + + Assert.assertArrayEquals( expectedOptsArray, serviceConfig.options); + } + + Assert.assertEquals(serviceDirFromConfig, serviceConfig.serviceDir); + Assert.assertEquals(1, serviceConfig.serviceCount); + Assert.assertEquals(1, serviceConfig.replicationCount); + Assert.assertArrayEquals(new IServiceConstraint[0], serviceConfig.constraints); + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfigurationRemote.java (from rev 3580, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestServiceConfigurationRemote.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfigurationRemote.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestServiceConfigurationRemote.java 2010-09-20 17:54:31 UTC (rev 3594) @@ -0,0 +1,36 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package com.bigdata.jini.start.config; + +/** + * Uses the purely remote implementation of the service(s) tested + * by this test's smart proxy based super class counterpart. + */ +public class TestServiceConfigurationRemote extends TestServiceConfiguration +{ + public TestServiceConfigurationRemote() { + super(true); + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestZookeeperServerEntry.java (from rev 3580, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/config/TestZookeeperServerEntry.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestZookeeperServerEntry.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/config/TestZookeeperServerEntry.java 2010-09-20 17:54:31 UTC (rev 3594) @@ -0,0 +1,124 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 2, 2009 + */ + +package com.bigdata.jini.start.config; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +import org.junit.Assert; +import org.junit.Test; + +import net.jini.config.ConfigurationException; + +import com.bigdata.util.config.NicUtil; + +/** + * Unit tests for the {@link ZookeeperServerEntry}. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestZookeeperServerEntry { + + /** + * + */ + public TestZookeeperServerEntry() { + } + + + @Test + public void test_correctRejection() { + try { + new ZookeeperServerEntry(0, null); + Assert.fail("Expecting " + IllegalArgumentException.class); + } catch (IllegalArgumentException ex) { + } + } + + /** + * Test {@link ZookeeperServerEntry} parsing. + */ + @Test + public void test001() { + final int expectedId = 0; + final String expectedHostname = "192.168.1.2"; + final int expectedPeerPort = 233; + final int expectedLeaderPort = 1992; + + ZookeeperServerEntry entry = new ZookeeperServerEntry(expectedId, + expectedHostname + ":" + expectedPeerPort + ":" + + expectedLeaderPort); + + Assert.assertEquals(expectedId, entry.id); + Assert.assertEquals(expectedHostname, entry.hostname); + Assert.assertEquals(expectedPeerPort, entry.peerPort); + Assert.assertEquals(expectedLeaderPort, entry.leaderPort); + } + + /** + * Unit test for + * {@link ZookeeperServerConfiguration#getZookeeperServerEntries(String)} + * + * @throws ConfigurationException + * @throws SocketException + * @throws UnknownHostException + */ + @Test + public void test002() throws ConfigurationException, SocketException, UnknownHostException, IOException { + + final String server = NicUtil.getIpAddress("default.nic", "default", true); + + final String[] hosts = new String[] { + "127.0.0.1", + "localhost", + server + }; + + final String servers = "1=127.0.0.1:2888:3888, 2=localhost:2888:3888, 3="+ server + ":2888:3888"; + + final ZookeeperServerEntry[] a = ZookeeperServerConfiguration.getZookeeperServerEntries(servers); + + for (int i = 0; i < a.length; i++) { + final ZookeeperServerEntry entry = a[i]; + + Assert.assertEquals(i + 1, entry.id); + Assert.assertEquals(hosts[i], entry.hostname); + Assert.assertEquals(2888, entry.peerPort); + Assert.assertEquals(3888, entry.leaderPort); + + InetAddress.getByName(entry.hostname); + + Assert.assertTrue(entry.isLocalHost()); + Assert.assertTrue(new HostAllowConstraint(entry.hostname).allow()); + Assert.assertFalse(new HostRejectConstraint(entry.hostname).allow()); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 17:42:52
|
Revision: 3593 http://bigdata.svn.sourceforge.net/bigdata/?rev=3593&view=rev Author: blevine218 Date: 2010-09-20 17:42:45 +0000 (Mon, 20 Sep 2010) Log Message: ----------- set appDotHome correctly Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config 2010-09-20 17:24:17 UTC (rev 3592) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config 2010-09-20 17:42:45 UTC (rev 3593) @@ -118,6 +118,8 @@ */ com.bigdata.jini.start.config.ServiceConfiguration { + private static appDotHome = System.getProperty("app.home", ConfigMath.getAbsolutePath(new File(".")) ); + // Optional command line arguments. //args=new String[]{}; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 17:24:23
|
Revision: 3592 http://bigdata.svn.sourceforge.net/bigdata/?rev=3592&view=rev Author: blevine218 Date: 2010-09-20 17:24:17 +0000 (Mon, 20 Sep 2010) Log Message: ----------- add import of ConfigDeployUtil Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config 2010-09-20 16:53:03 UTC (rev 3591) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config 2010-09-20 17:24:17 UTC (rev 3592) @@ -28,6 +28,7 @@ import com.bigdata.util.config.NicUtil; import com.sun.jini.config.ConfigUtil; +import com.bigdata.util.config.ConfigDeployUtil; bigdata { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 16:53:09
|
Revision: 3591 http://bigdata.svn.sourceforge.net/bigdata/?rev=3591&view=rev Author: blevine218 Date: 2010-09-20 16:53:03 +0000 (Mon, 20 Sep 2010) Log Message: ----------- Removed some debug statements Modified Paths: -------------- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java Modified: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java 2010-09-20 16:46:06 UTC (rev 3590) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java 2010-09-20 16:53:03 UTC (rev 3591) @@ -89,8 +89,7 @@ @Before public void setUp() throws Exception { final String[] args; - - System.out.println("BJL BJL BJL: configFile = " + configFile); + { final String home = System.getenv("JINI_HOME"); @@ -132,7 +131,6 @@ */ @Test public void test_findStartKill() throws Exception { - System.out.println("BJl BJL BJL config = " + config); final JiniCoreServicesConfiguration serviceConfig = new JiniCoreServicesConfiguration(config); final JiniClientConfig clientConfig = new JiniClientConfig(null, config); Modified: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java 2010-09-20 16:46:06 UTC (rev 3590) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java 2010-09-20 16:53:03 UTC (rev 3591) @@ -58,8 +58,9 @@ public class TestServiceConfigurationMonitoring extends AbstractFedZooTestCase { - private final static String testName = "TestServiceConfigurationMonitoring"; + private final static String TEST_NAME = "TestServiceConfigurationMonitoring"; protected boolean serviceImplRemote; + protected String testName = TEST_NAME; /** * @@ -68,8 +69,9 @@ this.serviceImplRemote = false; } - protected TestServiceConfigurationMonitoring (boolean serviceImplRemote) { + protected TestServiceConfigurationMonitoring (boolean serviceImplRemote, String testName) { this.serviceImplRemote = serviceImplRemote; + this.testName = testName; } @Before Modified: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java 2010-09-20 16:46:06 UTC (rev 3590) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java 2010-09-20 16:53:03 UTC (rev 3591) @@ -33,6 +33,6 @@ extends TestServiceConfigurationMonitoring { public TestServiceConfigurationMonitoringRemote() { - super(true); + super(true, "TestServiceConfigurationMonitoringRemote"); } } Modified: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java 2010-09-20 16:46:06 UTC (rev 3590) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java 2010-09-20 16:53:03 UTC (rev 3591) @@ -42,6 +42,8 @@ import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import com.bigdata.io.SerializerUtil; @@ -67,8 +69,11 @@ * @version $Id$ */ public class TestServiceStarter extends AbstractFedZooTestCase { + + private final static String TEST_NAME = "TestServiceStarter"; protected boolean serviceImplRemote; + protected String testName = TEST_NAME; /** * @@ -78,10 +83,22 @@ } - protected TestServiceStarter(boolean serviceImplRemote) { + protected TestServiceStarter(boolean serviceImplRemote, String testName) { this.serviceImplRemote = serviceImplRemote; + this.testName = testName; } + + @Before + public void setUp() throws Exception { + super.setUp(testName); + } + + @After + public void tearDown() throws Exception { + super.tearDown(testName); + } + /** * Unit test verifies that we can start and destroy a service instance using * a {@link BigdataServiceConfiguration}. The test waits until the service Modified: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java 2010-09-20 16:46:06 UTC (rev 3590) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java 2010-09-20 16:53:03 UTC (rev 3591) @@ -31,6 +31,6 @@ */ public class TestServiceStarterRemote extends TestServiceStarter { public TestServiceStarterRemote() { - super(true); + super(true, "TestServiceStarterRemote"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 16:46:15
|
Revision: 3590 http://bigdata.svn.sourceforge.net/bigdata/?rev=3590&view=rev Author: blevine218 Date: 2010-09-20 16:46:06 +0000 (Mon, 20 Sep 2010) Log Message: ----------- set federation name using ConfigDeployUtil.getFederationName() rather than relying directly on the federation.name system property. Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config 2010-09-20 16:39:39 UTC (rev 3589) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/config/testfed.config 2010-09-20 16:46:06 UTC (rev 3590) @@ -31,7 +31,7 @@ bigdata { - fedname = System.getProperty("federation.name","testFed"); + fedname = ConfigDeployUtil.getFederationName(); zrootname = System.getProperty("bigdata.zrootname","testZroot"); // logging configuration (value is a URI!) @@ -130,7 +130,7 @@ "-server", "-ea", "-Dcom.sun.jini.jeri.tcp.useNIO=true", - "-Djava.security.policy="+ConfigMath.getAbsolutePath(new File("policy.all")) + "-Djava.security.policy="+ConfigUtil.concat( new String[] { appDotHome, "${/}testing${/}conf${/}policy.all" } ) }; // Optional classpath components. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-20 16:39:50
|
Revision: 3589 http://bigdata.svn.sourceforge.net/bigdata/?rev=3589&view=rev Author: blevine218 Date: 2010-09-20 16:39:39 +0000 (Mon, 20 Sep 2010) Log Message: ----------- set federation name using ConfigDeployUtil.getFederationName() rather than relying directly on the federation.name system property. Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config 2010-09-20 12:04:22 UTC (rev 3588) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config 2010-09-20 16:39:39 UTC (rev 3589) @@ -28,10 +28,10 @@ import com.bigdata.util.config.NicUtil; import com.sun.jini.config.ConfigUtil; +import com.bigdata.util.config.ConfigDeployUtil; bigdata { - - fedname = System.getProperty("federation.name","testFed"); + static fedname = ConfigDeployUtil.getFederationName(); zrootname = System.getProperty("bigdata.zrootname","testZroot"); // logging configuration (value is a URI!) @@ -87,6 +87,9 @@ */ com.bigdata.jini.start.config.ServiceConfiguration { + private static appDotHome = + System.getProperty("app.home", ConfigMath.getAbsolutePath(new File(".")) ); + // Optional command line arguments. //args=new String[]{}; @@ -100,7 +103,7 @@ "-server", "-ea", "-Dcom.sun.jini.jeri.tcp.useNIO=true", - "-Djava.security.policy="+ConfigUtil.concat( new String[] { appHome, "${/}testing${/}conf${/}policy.all" } ) + "-Djava.security.policy="+ConfigUtil.concat( new String[] { appDotHome, "${/}testing${/}conf${/}policy.all" } ) }; // Optional classpath components. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <res...@us...> - 2010-09-20 12:04:31
|
Revision: 3588 http://bigdata.svn.sourceforge.net/bigdata/?rev=3588&view=rev Author: resendes Date: 2010-09-20 12:04:22 +0000 (Mon, 20 Sep 2010) Log Message: ----------- Branch to handle Ticket #163 tasks: clean-up packages that have had their cyclic dependencies broken. Added Paths: ----------- branches/bbb_cleanup/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2010-09-17 23:28:18
|
Revision: 3587 http://bigdata.svn.sourceforge.net/bigdata/?rev=3587&view=rev Author: thompsonbry Date: 2010-09-17 23:28:12 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Added notes on operator at a time queries, e.g., sort. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java 2010-09-17 19:17:52 UTC (rev 3586) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java 2010-09-17 23:28:12 UTC (rev 3587) @@ -414,10 +414,16 @@ * Note: The partitionId will always be -1 in scale-up. */ final int partitionId = -1; - + /* * FIXME Raise this into an annotation that we can tweak from the unit * tests and then debug the problem. + * + * FIXME Add an annotation or method to mark operators which must be + * evaluated using operator-at-a-time evaluation. SORT is the main + * example here (it must be operator at a time of necessity) but other + * operators may implemented with operator at a time assumptions. This + * might be on PipelineOp and could be trinary {Chunked,Blocked,All}. */ final boolean oneMessagePerChunk = false; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-17 19:18:00
|
Revision: 3586 http://bigdata.svn.sourceforge.net/bigdata/?rev=3586&view=rev Author: blevine218 Date: 2010-09-17 19:17:52 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Check in tests in jini.start package. Not all tests are successful at this point Added Paths: ----------- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/AbstractFedZooTestCase.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/DestroyTransactionService.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/JiniStartSuite.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/MockListener.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationZNodeEnum.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/AbstractFedZooTestCase.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/AbstractFedZooTestCase.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/AbstractFedZooTestCase.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/AbstractFedZooTestCase.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,201 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 7, 2009 + */ + +package com.bigdata.jini.start; + +import java.io.File; +import java.util.List; +import java.util.UUID; + +import com.bigdata.DataFinder; +import net.jini.config.Configuration; +import net.jini.config.ConfigurationProvider; + +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.ZooDefs.Ids; +import org.apache.zookeeper.data.ACL; +import org.junit.Rule; +import org.junit.rules.TestName; + +import com.bigdata.jini.start.config.ZookeeperClientConfig; +import com.bigdata.jini.start.process.ProcessHelper; +import com.bigdata.jini.start.process.ZookeeperProcessHelper; +import com.bigdata.resources.ResourceFileFilter; +import com.bigdata.service.jini.JiniClient; +import com.bigdata.service.jini.JiniFederation; +import com.bigdata.test.util.Assert; + +/** + * Abstract base class for unit tests requiring a running zookeeper and a + * running federation as configured from a test resource. + * <p> + * You MUST specify a security policy, e.g.: + * + * <pre> + * -Djava.security.policy=policy.all + * </pre> + * + * for these tests to run. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class AbstractFedZooTestCase { + + // A configuration file used by some of the unit tests in this package. + protected final String configFile = DataFinder.bestURI("testing/data/com/bigdata/jini/start/testfed.config").toASCIIString(); + + // ACL used for the unit tests. + protected final List<ACL> acl = Ids.OPEN_ACL_UNSAFE; + + protected final MockListener listener = new MockListener(); + + Configuration config; + JiniFederation fed; + + String zrootname = null; + + + public AbstractFedZooTestCase() { + } + + + + public void setUp(String name) throws Exception { + + zrootname = name + "_" + UUID.randomUUID(); + + if (new File(zrootname).exists()) { + // clean out old files. + recursiveDelete(new File(zrootname)); + } + + // a unique zroot in the /test namespace. + final String zroot = "/"+zrootname;//"/test/" + zrootname; + + System.err.println(name + ": setting up zrootname=" + zrootname); + + final String[] args = new String[] { configFile, + // Note: overrides the zroot to be unique. + ZookeeperClientConfig.Options.NAMESPACE + "." + + ZookeeperClientConfig.Options.ZROOT + "=" + "\"" + + zroot + "\"" , +// // Override the federation name. +// "bigdata.fedname=\""+fedname+"\"" + }; + + // apply the federation name to the configuration file. + System.setProperty("bigdata.zrootname", zrootname); + + config = ConfigurationProvider.getInstance(args); + + // if necessary, start zookeeper (a server instance). + ZookeeperProcessHelper.startZookeeper(config, listener); + + /* + * FIXME We need to start a jini lookup service for groups = {fedname} + * for this test to succeed. + */ + + fed = JiniClient.newInstance(args).connect(); + + /* + * Create the federation zroot and config znodes. + */ + final ZooKeeper zookeeper = fed.getZookeeper(); + + // make sure that we have the zroot that we overrode above. + Assert.assertEquals(zroot, fed.getZooConfig().zroot); + + fed.createKeyZNodes(zookeeper); + } + + public void tearDown(String name) throws Exception { + + System.err.println(name + ": tearing down zrootname=" + zrootname); + + // destroy any processes started by this test suite. + for (ProcessHelper t : listener.running) { + t.kill(true/*immediateShutdown*/); + } + + if (fed != null) { + + /* + * @todo if we do this to kill zk then we must ensure that a private + * instance was started on the desired port. That means an override + * for the configuration file and an unused port assigned for the + * client and peers on the zk instance started for this unit test. + */ +// ZooHelper.kill(clientPort); + + fed.shutdownNow(); + } + + if (zrootname != null && new File(zrootname).exists()) { + + /* + * Wait a bit and then try and delete the federation directory + * structure. + */ + + try { + Thread.sleep(250); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + recursiveDelete(new File(zrootname)); + } + } + + /** + * Recursively removes any files and subdirectories and then removes the + * file (or directory) itself. + * <p> + * Note: Files that are not recognized will be logged by the + * {@link ResourceFileFilter}. + * + * @param f + * A file or directory. + */ + private void recursiveDelete(final File f) { + + if (f.isDirectory()) { + final File[] children = f.listFiles(); + + if (children == null) { + // The directory does not exist. + return; + } + + for (int i = 0; i < children.length; i++) { + recursiveDelete(children[i]); + } + } + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/DestroyTransactionService.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/DestroyTransactionService.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/DestroyTransactionService.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/DestroyTransactionService.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,111 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 10, 2009 + */ + +package com.bigdata.jini.start; + +import java.rmi.RemoteException; + +//BTM import com.bigdata.service.IService; +import com.bigdata.service.jini.JiniClient; +import com.bigdata.service.jini.JiniFederation; +import com.bigdata.service.jini.RemoteDestroyAdmin; +import com.bigdata.service.jini.TransactionServer; + +//BTM +import com.bigdata.journal.TransactionService; +import com.sun.jini.admin.DestroyAdmin; +import net.jini.admin.Administrable; + +/** + * Destroys a specific service - the {@link TransactionServer}. This is for use + * in testing the behavior of the {@link ServicesManagerServer} and the behavior + * of the other services in the federation when the {@link TransactionServer} is + * lost. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class DestroyTransactionService { + + /** + * @param args + * Configuration file and optional overrides. + * + * @throws InterruptedException + * @throws RemoteException + */ + public static void main(String[] args) throws InterruptedException, + RemoteException { + + JiniFederation fed = JiniClient.newInstance(args).connect(); + + try { + +//BTM IService service = fed.getTransactionService(); +TransactionService service = fed.getTransactionService(); + + if (service == null) { + + System.err.println("Service not found."); + + } else { +if(service instanceof RemoteDestroyAdmin) { + ((RemoteDestroyAdmin) service).destroy(); + System.err.println("destroyed transaction service [remote implementation]"); +} else if(service instanceof Administrable) { + try { + Object serviceAdmin = ((Administrable)service).getAdmin(); + if(serviceAdmin instanceof DestroyAdmin) { + try { + ((DestroyAdmin)serviceAdmin).destroy(); + System.err.println("destroyed transaction service [smart proxy implementation]"); + } catch(Throwable t) { + System.err.println("ERROR: exception while destroying transaction service ["+t+"]"); + } + } else { + System.err.println("FAILURE: transaction service admin not instance of DestroyAdmin"); + } + } catch(Throwable t) { + System.err.println("ERROR: exception from call to getAdmin while destroying transaction service ["+t+"]"); + } +} else { + System.err.println("FAILURE: transaction service not instance of Administrable"); +} + +//BTM System.err.println("Service destroyed."); + + } + + } finally { + + fed.shutdown(); + + } + + } + +} Added: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/JiniStartSuite.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/JiniStartSuite.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/JiniStartSuite.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * $Id$ + * + * Copyright (c) 2000-2010 Nokia Corporation. + * + * This material, including documentation and any related computer + * programs, is protected by copyright controlled by Nokia Corporation. + * All rights are reserved. Copying, including reproducing, storing, + * adapting or translating, any or all of this material requires the prior + * written consent of Nokia Corporation. This material also contains + * confidential information which may not be disclosed to others without + * the prior written consent of Nokia Corporation. + **********************************************************************/ +package com.bigdata.jini.start; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author blevine + * + */ +@RunWith(Suite.class) +...@Su...iteClasses({ + TestJiniCoreServicesProcessHelper.class, + TestServiceConfigurationMonitoring.class, + TestServiceConfigurationMonitoringRemote.class, + TestServiceConfigurationZNodeEnum.class, + TestServiceStarter.class, + TestServiceStarterRemote.class +}) +public class JiniStartSuite +{ +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/MockListener.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/MockListener.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/MockListener.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/MockListener.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,44 @@ +package com.bigdata.jini.start; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.apache.log4j.Logger; + +import com.bigdata.jini.start.process.ProcessHelper; + +/** + * Mock implementation used by some unit tests. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class MockListener implements IServiceListener { + + protected static final Logger log = Logger.getLogger(MockListener.class); + + protected static final boolean INFO = log.isInfoEnabled(); + + protected static final boolean DEBUG = log.isDebugEnabled(); + + public Queue<ProcessHelper> running = new ConcurrentLinkedQueue<ProcessHelper>(); + + public void add(ProcessHelper service) { + + if (INFO) + log.info("adding: " + service); + + running.add(service); + + } + + public void remove(ProcessHelper service) { + + if (INFO) + log.info("removing: " + service); + + running.remove(service); + + } + +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoring.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,196 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 7, 2009 + */ + +package com.bigdata.jini.start; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeoutException; + +import net.jini.config.ConfigurationException; + +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.ZooKeeper; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +import com.bigdata.io.SerializerUtil; +import com.bigdata.jini.start.config.ServiceConfiguration; +import com.bigdata.jini.start.config.TransactionServerConfiguration; +import com.bigdata.service.jini.TransactionServer; +import com.bigdata.test.util.Assert; + +/** + * Test suite for monitoring state changes for a {@link ServiceConfiguration} + * and creating a new physical service instance. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestServiceConfigurationMonitoring extends AbstractFedZooTestCase { + + + private final static String testName = "TestServiceConfigurationMonitoring"; + protected boolean serviceImplRemote; + + /** + * + */ + public TestServiceConfigurationMonitoring() { + this.serviceImplRemote = false; + } + + protected TestServiceConfigurationMonitoring (boolean serviceImplRemote) { + this.serviceImplRemote = serviceImplRemote; + } + + @Before + public void setUp() throws Exception { + super.setUp(testName); + } + + @After + public void tearDown() throws Exception { + super.tearDown(testName); + } + + /** + * @throws InterruptedException + * @throws KeeperException + * @throws ConfigurationException + * @throws ExecutionException + * @throws TimeoutException + * + * @todo Unit test where the appropriate watchers are established and we + * then create the service configuration znode and let the watchers + * handle the creation of the logical and physical services and their + * znodes. + * + * @todo verify that normal service shutdown does remove the ephemeral znode + * and that service restart re-creates the SAME ephemeral znode (both + * should be true as the znode is created using the assigned service + * UUID rather than SEQUENTIAL so that it can be a restart safe + * zpath). + */ + @Test + public void test_logicalServiceWatcher() throws KeeperException, + InterruptedException, ConfigurationException, ExecutionException, + TimeoutException { + + // the config for that fake zroot. + final String zconfig = fed.getZooConfig().zroot + BigdataZooDefs.ZSLASH + BigdataZooDefs.CONFIG; + + final ZooKeeper zookeeper = fed.getZookeeper(); + + final int numBefore = listener.running.size(); + + // zpath for the service configuration znode. + final String serviceConfigurationZPath = zconfig + BigdataZooDefs.ZSLASH + TransactionServer.class.getName(); + + // create monitor task that will compete for locks and start procsses. + MonitorCreatePhysicalServiceLocksTask task1 = new MonitorCreatePhysicalServiceLocksTask(fed, listener); + + final Future f1 = fed.getExecutorService().submit(task1); + + Assert.assertFalse(f1.isDone()); + + // create monitor task for a specific service config node. + ServiceConfigurationZNodeMonitorTask task = new ServiceConfigurationZNodeMonitorTask( + fed, listener, TransactionServer.class.getName()); + + final Future f = fed.getExecutorService().submit(task); + + Assert.assertFalse(f.isDone()); + + /* + * Create znode for the ServiceConfiguration. + * + * Note: This should trigger the watcher. In turn, then watcher should + * create an instance of the service on our behalf. + */ + System.out.println("Creating zpath [serviceImplRemote="+serviceImplRemote+"]: " +serviceConfigurationZPath); + String zp = null; + if(serviceImplRemote) { + zp = zookeeper.create(serviceConfigurationZPath, SerializerUtil + .serialize(new TransactionServerConfiguration(TransactionServer.class, config)), acl, + CreateMode.PERSISTENT); + } else { + zp = zookeeper.create(serviceConfigurationZPath, SerializerUtil + .serialize(new TransactionServerConfiguration(com.bigdata.transaction.ServiceImpl.class, config)), acl, + CreateMode.PERSISTENT); + } + + System.out.println("Created zpath: " + zp); + + /* + * Verify that a logicalService znode was created for that configuration + * znode. + */ + + // pause a moment. + Thread.sleep(1000/*ms*/); + + System.out.println("logicalServices: " + zookeeper.getChildren(serviceConfigurationZPath, false)); + + Assert.assertEquals(1, zookeeper.getChildren(serviceConfigurationZPath, false).size()); + + /* + * Let things run for few seconds. + * + * This give the task the chance to notice the ServiceConfiguration + * znode (we just created it) and to execute the task that creates the + * new logical service. + */ + + Thread.sleep(10000/*ms*/); + + if (f.isDone()) { + f.get(); + Assert.fail("not expecting task to end by itself."); + } else + f.cancel(true/* mayInterruptIfRunning */); + + if (f1.isDone()) { + f1.get(); + Assert.fail("not expecting task to end by itself."); + } else + f1.cancel(true/* mayInterruptIfRunning */); + + /* + * FIXME verify service is created, discover and query that service and + * verify that it is the instance that we wanted, then shutdown service + * and then verify service restart re-creates the same ephemeral node. + */ + + // verify a process was started. + Assert.assertEquals(numBefore + 1, listener.running.size()); + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationMonitoringRemote.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,38 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package com.bigdata.jini.start; + +/** + * Test suite for monitoring state changes for a {@link ServiceConfiguration} + * and creating a new physical service instance using the purely remote + * service implementation. + */ +public class TestServiceConfigurationMonitoringRemote + extends TestServiceConfigurationMonitoring +{ + public TestServiceConfigurationMonitoringRemote() { + super(true); + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationZNodeEnum.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/TestServiceConfigurationZNodeEnum.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationZNodeEnum.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceConfigurationZNodeEnum.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,122 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 12, 2009 + */ + +package com.bigdata.jini.start; + +import org.junit.Test; + +import com.bigdata.service.jini.TransactionServer; +import com.bigdata.test.util.Assert; + + +/** + * Test suite for {@link ServiceConfigurationZNodeEnum}. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestServiceConfigurationZNodeEnum { + + /** + * + */ + public TestServiceConfigurationZNodeEnum() { + } + + final String serviceConfigZPath = "test-fed/" + BigdataZooDefs.CONFIG + "/" + TransactionServer.class.getName(); + + /** + * <p> + * The behavior can be best interpreted with reference to an example: + * + * <pre> + * test-fed + * locks + * serviceConfigMonitor + * com.bigdata.service.jini.TransactionServer + * lock0000000000 (Ephemeral) + * createPhysicalService + * config + * W com.bigdata.service.jini.TransactionServer {TransactionServiceConfiguration} + * W logicalService0000000000 + * W physicalServices + * W abde9b91-24d5-4dc5-9bbf-41d7e7cac272 (Ephemeral) + * masterElection + * lock0000000000 (Ephemeral) + * </pre> + * + * In this example, the <code>W</code> appears at the start of each + * watched znode for the {@link TransactionServerConfiguration} znode. The + * master election znode can be seen directly below that. + */ + @Test + public void test01() { + + Assert.assertEquals(ServiceConfigurationZNodeEnum.ServiceConfiguration, + ServiceConfigurationZNodeEnum + .getType(serviceConfigZPath, serviceConfigZPath)); + + Assert.assertEquals(ServiceConfigurationZNodeEnum.LogicalService, + ServiceConfigurationZNodeEnum.getType(serviceConfigZPath, + serviceConfigZPath + "/" + + BigdataZooDefs.LOGICAL_SERVICE_PREFIX + + "0000000000")); + + Assert.assertEquals(ServiceConfigurationZNodeEnum.PhysicalServicesContainer, + ServiceConfigurationZNodeEnum.getType(serviceConfigZPath, + serviceConfigZPath + "/" + + BigdataZooDefs.LOGICAL_SERVICE_PREFIX + + "0000000000"+"/" + + BigdataZooDefs.PHYSICAL_SERVICES_CONTAINER)); + + + Assert.assertEquals(ServiceConfigurationZNodeEnum.PhysicalService, + ServiceConfigurationZNodeEnum.getType(serviceConfigZPath, + serviceConfigZPath + "/" + + BigdataZooDefs.LOGICAL_SERVICE_PREFIX + + "0000000000" + "/" + + BigdataZooDefs.PHYSICAL_SERVICES_CONTAINER + + "/" + "abde9b91-24d5-4dc5-9bbf-41d7e7cac272")); + + Assert.assertEquals(ServiceConfigurationZNodeEnum.MasterElection, + ServiceConfigurationZNodeEnum.getType(serviceConfigZPath, + serviceConfigZPath + "/" + + BigdataZooDefs.LOGICAL_SERVICE_PREFIX + + "0000000000" + "/" + + BigdataZooDefs.MASTER_ELECTION + )); + + Assert.assertEquals(ServiceConfigurationZNodeEnum.MasterElectionLock, + ServiceConfigurationZNodeEnum.getType(serviceConfigZPath, + serviceConfigZPath + "/" + + BigdataZooDefs.LOGICAL_SERVICE_PREFIX + + "0000000000" + "/" + + BigdataZooDefs.MASTER_ELECTION + + "/" + "lock0000000000")); + + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/TestServiceStarter.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarter.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,267 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 5, 2009 + */ + +package com.bigdata.jini.start; + +import java.io.IOException; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import net.jini.config.ConfigurationException; +import net.jini.core.lookup.ServiceID; +import net.jini.core.lookup.ServiceItem; +import net.jini.core.lookup.ServiceTemplate; +import net.jini.lease.LeaseRenewalManager; +import net.jini.lookup.ServiceDiscoveryManager; + +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.Stat; +import org.junit.Test; + +import com.bigdata.io.SerializerUtil; +import com.bigdata.jini.start.config.BigdataServiceConfiguration; +import com.bigdata.jini.start.config.ServiceConfiguration; +import com.bigdata.jini.start.config.TransactionServerConfiguration; +import com.bigdata.jini.start.config.ManagedServiceConfiguration.ManagedServiceStarter; +import com.bigdata.jini.start.process.ProcessHelper; +import com.bigdata.jini.util.JiniUtil; +import com.bigdata.service.IService; +import com.bigdata.service.Service; +import com.bigdata.service.jini.RemoteDestroyAdmin; +import com.bigdata.service.jini.TransactionServer; +import com.bigdata.test.util.Assert; +import com.bigdata.zookeeper.ZNodeDeletedWatcher; +import com.bigdata.zookeeper.ZooHelper; + +/** + * Test suite for starting a bigdata service based on a + * {@link ServiceConfiguration} stored in {@link ZooKeeper}. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestServiceStarter extends AbstractFedZooTestCase { + + protected boolean serviceImplRemote; + + /** + * + */ + public TestServiceStarter() { + this.serviceImplRemote = false; + } + + + protected TestServiceStarter(boolean serviceImplRemote) { + this.serviceImplRemote = serviceImplRemote; + } + + /** + * Unit test verifies that we can start and destroy a service instance using + * a {@link BigdataServiceConfiguration}. The test waits until the service + * has been assigned its serviceId by jini and verify that the serviceId is + * recorded in the physicalService znode. + * + * @throws ConfigurationException + * @throws Exception + */ + @Test + public void test_startServer() throws ConfigurationException, Exception { + final ZooKeeper zookeeper = fed.getZookeeper(); + + TransactionServerConfiguration serviceConfig = null; + if(serviceImplRemote) { + serviceConfig = new TransactionServerConfiguration(TransactionServer.class, config); + } else { + serviceConfig = new TransactionServerConfiguration(com.bigdata.transaction.ServiceImpl.class, config); + } + + // znode for serviceConfiguration + final String zserviceConfig = zookeeper.create(fed.getZooConfig().zroot + + BigdataZooDefs.ZSLASH + BigdataZooDefs.CONFIG + + BigdataZooDefs.ZSLASH + + TransactionServer.class.getName(), SerializerUtil + .serialize(serviceConfig), acl, CreateMode.PERSISTENT); + + /* + * znode for a logical service (the logical service is either a + * collection of peers or a service failover chain, depending on the + * type of the service). Logical services are persistent. Each one is + * assigned a unique (sequential) identifier by zookeeper. It is also + * assigned a random UUID. + */ + final String logicalServiceZPath = zookeeper.create(zserviceConfig + + BigdataZooDefs.LOGICAL_SERVICE_PREFIX, SerializerUtil.serialize(UUID + .randomUUID()), acl, CreateMode.PERSISTENT_SEQUENTIAL); + + /* + * Create the znode that is the parent for the physical service + * instances (direct child of the logicalSevice znode). + */ + final String parentZNode = logicalServiceZPath + "/" + BigdataZooDefs.PHYSICAL_SERVICES_CONTAINER; + final ManagedServiceStarter serviceStarter = + (ManagedServiceStarter) serviceConfig.newServiceStarter + (fed, listener, logicalServiceZPath, null/* attributes */); + + zookeeper.create(parentZNode, SerializerUtil.serialize(serviceStarter.serviceUUID), acl, CreateMode.PERSISTENT); + + /* + * Create the znode for the election of the primary physical service for + * this logical service (direct child of the logicalSevice znode). + */ + zookeeper.create(logicalServiceZPath + "/" + BigdataZooDefs.MASTER_ELECTION, new byte[0], acl, CreateMode.PERSISTENT); + + // will be zero unless we started a zookeeper server above. + final int processCountBefore = listener.running.size(); + + // start the service. + final ProcessHelper processHelper = serviceStarter.call(); + + // verify listener was notified of service start. + Assert.assertEquals(processCountBefore + 1, listener.running.size()); + + // verify that the physicalService was registered with zookeeper. + final ServiceItem serviceItem; + IService proxy = null; + Service smartProxy = null; + final String physicalServiceZPath; + { + final List<String> children = zookeeper.getChildren(logicalServiceZPath, false/* watch */); + + System.err.println("physicalServices=" + children); + + // will fail if the znode was not registered. + Assert.assertEquals(2, children.size()); + + /* + * There should be only one child, which is the physical service + * that we created. + * + * Note: You could explicitly build the correct zpath using the + * serviceUUID obtained from the service proxy. + */ + physicalServiceZPath = logicalServiceZPath + "/" + children.get(0); + + // get the serviceUUID from the physicalServiceZNode's data. + final UUID serviceUUID = (UUID) SerializerUtil.deserialize(zookeeper.getData(physicalServiceZPath, false, new Stat())); + + serviceItem = discoverService(serviceUUID); + + // verify that the service item is registered with jini. + Assert.assertNotNull(serviceItem); + + // save reference to the service proxy. + if(serviceItem.service instanceof IService) { + proxy = (IService)serviceItem.service; + } else if(serviceItem.service instanceof Service) { + smartProxy = (Service)serviceItem.service; + } else { + Assert.fail("service not an instance of either Service or IService"); + } + } + + // Verify the service UUID using the proxy + if(proxy == null) { + Assert.assertEquals(JiniUtil.serviceID2UUID(serviceItem.serviceID), smartProxy.getServiceUUID()); + } else { + Assert.assertEquals(JiniUtil.serviceID2UUID(serviceItem.serviceID), proxy.getServiceUUID()); + } + + // Verify the service name using the proxy + // (Note: only do this for the remote case, + // names will be different for smart proxy case) + if(proxy != null) { + Assert.assertEquals(serviceStarter.serviceName, proxy.getServiceName()); + } + + // Tell the service to destroy itself. + if(proxy == null) { + try { + ((com.sun.jini.admin.DestroyAdmin)(((net.jini.admin.Administrable)smartProxy).getAdmin())).destroy(); + } catch(Throwable t) { + System.out.println("TestServiceStarter: SHUTDOWN WARNING ["+t+"]"); + t.printStackTrace(); + } + } else { + ((RemoteDestroyAdmin)proxy).destroy(); + } + + + // wait a bit for the process to die. + processHelper.exitValue(10L, TimeUnit.SECONDS); + + // verify that it has been removed from our listener. + Assert.assertEquals("Expected " + processCountBefore + ", but #running=" + + listener.running.size() + ", processes=" + + listener.running.toString(), processCountBefore, + listener.running.size()); + + ZooHelper.destroyZNodes(zookeeper, parentZNode, 1); + + /* + * Wait until the znode for the physical service has been removed. + * + * Note: An ephemeral znode will be removed once the zookeeper client + * either times out or is explicitly closed. Since we are killing the + * process rather than terminating the service normally we may have to + * raise the timeout before zookeeper will delete the service's znode on + * its behalf. + */ + if (!ZNodeDeletedWatcher.awaitDelete(zookeeper, physicalServiceZPath, 20000, TimeUnit.MILLISECONDS)) { + Assert.fail("znode not removed: zpath=" + physicalServiceZPath); + } + } + + /** + * Looks up the service item in any joined jini registrars but does not wait + * for the service item to become registered. + * + * @param serviceUUID + * + * @return + * + * @throws IOException + */ + protected ServiceItem discoverService(final UUID serviceUUID) throws IOException { + + final ServiceID serviceId = JiniUtil.uuid2ServiceID(serviceUUID); + + ServiceDiscoveryManager serviceDiscoveryManager = null; + + try { + serviceDiscoveryManager = new ServiceDiscoveryManager(fed.getDiscoveryManagement(), new LeaseRenewalManager()); + final ServiceItem item = serviceDiscoveryManager.lookup(new ServiceTemplate(serviceId, null, null), null); + return item; + } finally { + if (serviceDiscoveryManager != null) { + serviceDiscoveryManager.terminate(); + } + } + } +} Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestServiceStarterRemote.java 2010-09-17 19:17:52 UTC (rev 3586) @@ -0,0 +1,36 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package com.bigdata.jini.start; + +/** + * Test suite for starting a purely remote bigdata service + * implementation based on a {@link ServiceConfiguration} stored + * in {@link ZooKeeper}. + */ +public class TestServiceStarterRemote extends TestServiceStarter { + public TestServiceStarterRemote() { + super(true); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2010-09-17 17:55:39
|
Revision: 3585 http://bigdata.svn.sourceforge.net/bigdata/?rev=3585&view=rev Author: thompsonbry Date: 2010-09-17 17:55:31 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Removed unused test class (TestBindingSet). Added javadoc on IConstant to specify why it does not implement Comparable and updated both it and Constant to clear out old references to that interface. More systematic deep and shallow copy constructors for bops. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/AbstractChunkedOrderedIteratorOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpList.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Constant.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IConstant.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/QuoteOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Var.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java Removed Paths: ------------- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestBindingSet.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/AbstractChunkedOrderedIteratorOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/AbstractChunkedOrderedIteratorOp.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/AbstractChunkedOrderedIteratorOp.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -46,12 +46,12 @@ } - /** - * @param args - */ - protected AbstractChunkedOrderedIteratorOp(BOp[] args) { - super(args); - } +// /** +// * @param args +// */ +// protected AbstractChunkedOrderedIteratorOp(BOp[] args) { +// super(args); +// } /** * Required shallow copy constructor. Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -135,6 +135,8 @@ } /** + * Deep copy constructor (required). + * <p> * Each {@link BOp} MUST implement a public copy constructor with the * signature: * @@ -168,18 +170,22 @@ // deep copy the annotations. annotations = deepCopy(op.annotations); } - - /** - * @param args - * The arguments to the operator. - */ - public BOpBase(final BOp[] args) { - - this(args, null/* annotations */); - - } +// /** +// * @param args +// * The arguments to the operator. +// * +// * @deprecated Use the shallow copy constructor. +// */ +// public BOpBase(final BOp[] args) { +// +// this(args, null/* annotations */); +// +// } + /** + * Shallow copy constructor (required). + * * @param args * The arguments to the operator. * @param annotations Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpList.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpList.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpList.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -58,8 +58,8 @@ } - public BOpList(final BOp[] args) { - super(args); - } +// public BOpList(final BOp[] args) { +// super(args); +// } } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Constant.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Constant.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Constant.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -29,8 +29,7 @@ * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ -final public class Constant<E/* extends Comparable<E> */> extends BOpBase - implements IConstant<E> { +final public class Constant<E> extends BOpBase implements IConstant<E> { /** * @@ -73,7 +72,7 @@ public Constant(final E value) { - super(new BOp[]{}); + super(new BOp[] {}, null/* annotations */); if (value == null) throw new IllegalArgumentException(); @@ -130,25 +129,6 @@ return value.hashCode(); } - -// public int compareTo(IVariableOrConstant arg0) { -// -// // order vars before ids -// if(arg0 instanceof Var) return 1; -// -// // @todo ordering only among constants of the same class? -// Constant o = (Constant)arg0; -// -// /* -// * Note: logic avoids possible overflow of [long] by not computing the -// * difference between two longs. -// */ -// -// int ret = id < o.id ? -1 : id > o.id ? 1 : 0; -// -// return ret; -// -// } final public E get() { @@ -167,11 +147,5 @@ throw new UnsupportedOperationException(); } - -// public int compareTo(IConstant<E> o) { -// -// return value.compareTo(o.get()); -// -// } } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IConstant.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IConstant.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IConstant.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -30,12 +30,24 @@ /** * A constant. + * <p> + * Note: {@link IConstant} does not implement {@link Comparable} for two + * reasons: + * <ol> + * <li>{@link Constant}s wrapping different data types are not comparable. Rigid + * schema data models such as SQL do not have this problem since columns have a + * single data type, but schema flexible object models and RDF both have runtime + * determination of the data type.</li> + * <li>The specifics of the ordering to be imposed are generally determined by a + * high level query language (SPARQL, XQUERY, SQL, etc). Thus even if this + * interface was {@link Comparable}, SORT operators generally must provide their + * own ordering semantics.</li> + * </ol> * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ -public interface IConstant<E/* extends Comparable<E>*/> extends - IVariableOrConstant<E> { //, Comparable<IConstant<E>> { +public interface IConstant<E> extends IVariableOrConstant<E> { /** * The hash code of the value that would be returned by Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/QuoteOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/QuoteOp.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/QuoteOp.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -72,7 +72,7 @@ */ public QuoteOp(final BOp op) { - super(new BOp[] { op }); + super(new BOp[] { op }, null/*annotations*/); if (op == null) throw new IllegalArgumentException(); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Var.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Var.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/Var.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -58,7 +58,7 @@ */ private Var(final String name) { - super(new BOp[]{}); + super(new BOp[] {}, null/* annotations */); assert name != null; Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/QueryEngine.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -48,7 +48,6 @@ import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IPredicate; import com.bigdata.bop.bset.Union; -import com.bigdata.bop.fed.FederatedQueryEngine; import com.bigdata.btree.BTree; import com.bigdata.btree.IndexSegment; import com.bigdata.btree.view.FusedView; @@ -757,22 +756,6 @@ * @throws IllegalStateException * if the {@link QueryEngine} has been {@link #shutdown()}. * @throws Exception - * @throws RemoteException - * - * FIXME The test suites need to be modified to create a local - * {@link FederatedQueryEngine} object which fronts for an - * {@link IIndexManager} which is local to the client - not on a - * data service at all. This is necessary in order for the unit - * test (or application code) to directly access the - * RunningQuery reference, which is needed to use get() (to wait - * for the query), iterator() (to drain the query), etc. - * <p> - * This will also give us a place to hang query-local resources - * on the client. - * <p> - * This has to be a {@link FederatedQueryEngine} because it - * needs to talk to a federation. There should be nothing DS - * specific about the {@link FederatedQueryEngine}. */ public RunningQuery eval(final UUID queryId, final BindingSetPipelineOp query, Deleted: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestBindingSet.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestBindingSet.java 2010-09-17 17:50:43 UTC (rev 3584) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestBindingSet.java 2010-09-17 17:55:31 UTC (rev 3585) @@ -1,176 +0,0 @@ -/* - -Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. - -Contact: - SYSTAP, LLC - 4501 Tower Road - Greensboro, NC 27410 - lic...@bi... - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -/* - * Created on Jun 19, 2008 - */ - -package com.bigdata.bop; - -import junit.framework.TestCase2; - -/** - * Unit tests for {@link IBindingSet}s. - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - */ -public class TestBindingSet extends TestCase2 { - - /** - * - */ - public TestBindingSet() { - } - - /** - * @param name - */ - public TestBindingSet(String name) { - super(name); - } - - /** - * Unit test for {@link ArrayBindingSet#copy(IVariable[])} - */ - public void test_copy_abs() { - - IVariable[] vars = new IVariable[] { - Var.var("a"), - Var.var("b"), - Var.var("c"), - Var.var("d"), - Var.var("e") - }; - - IConstant[] vals = new IConstant[] { - new Constant<Integer>(1), - new Constant<Integer>(2), - new Constant<Integer>(3), - new Constant<Integer>(4), - new Constant<Integer>(5) - }; - - ArrayBindingSet bs = new ArrayBindingSet(vars, vals); - - assertTrue(bs.size() == 5); - for (IVariable v : vars) { - assertTrue(bs.isBound(v)); - } - - IVariable[] varsToKeep = new IVariable[] { - Var.var("a"), - Var.var("c"), - Var.var("e") - }; - - ArrayBindingSet bs2 = bs.copy(varsToKeep); - assertTrue(bs2.size() == 3); - for (IVariable v : varsToKeep) { - assertTrue(bs2.isBound(v)); - assertTrue(bs2.get(v).equals(bs.get(v))); - } - assertFalse(bs2.isBound(Var.var("b"))); - assertFalse(bs2.isBound(Var.var("d"))); - - } - - /** - * Unit test for {@link HashBindingSet#copy(IVariable[])} - */ - public void test_copy_hbs() { - - IVariable[] vars = new IVariable[] { - Var.var("a"), - Var.var("b"), - Var.var("c"), - Var.var("d"), - Var.var("e") - }; - - IConstant[] vals = new IConstant[] { - new Constant<Integer>(1), - new Constant<Integer>(2), - new Constant<Integer>(3), - new Constant<Integer>(4), - new Constant<Integer>(5) - }; - - HashBindingSet bs = new HashBindingSet(); - for (int i = 0; i < vars.length; i++) { - bs.set(vars[i], vals[i]); - } - - assertTrue(bs.size() == 5); - for (IVariable v : vars) { - assertTrue(bs.isBound(v)); - } - - IVariable[] varsToKeep = new IVariable[] { - Var.var("a"), - Var.var("c"), - Var.var("e") - }; - - HashBindingSet bs2 = bs.copy(varsToKeep); - assertTrue(bs2.size() == 3); - for (IVariable v : varsToKeep) { - assertTrue(bs2.isBound(v)); - assertTrue(bs2.get(v).equals(bs.get(v))); - } - assertFalse(bs2.isBound(Var.var("b"))); - assertFalse(bs2.isBound(Var.var("d"))); - - } - - /** - * @todo Write unit tests for equals which verify that binding sets are - * equals iff they have the same variables and those variables have - * the same bindings. - */ - public void test_equals() { - fail("write tests"); - } - - /** - * @todo Write unit tests for the hash code which demonstrate that the hash - * code of binding sets with the same bindings on the same variables - * is the same regardless of the order in which those variables - * appear. - */ - public void test_hashCode() { - fail("write tests"); - } - - /** - * @todo Write unit tests for the hash code which demonstrate that the hash - * code of the binding sets is invalidated and recomputed when there - * is a mutation to the binding set. Do this for all - * {@link IBindingSet} implementations. - */ - public void test_hashCode_mutations() { - fail("write tests"); - } - -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sgo...@us...> - 2010-09-17 17:50:50
|
Revision: 3584 http://bigdata.svn.sourceforge.net/bigdata/?rev=3584&view=rev Author: sgossard Date: 2010-09-17 17:50:43 +0000 (Fri, 17 Sep 2010) Log Message: ----------- [maven_scaleout] : Broke all direct dependency cycles with package 'com.bigdata.config' by removing ignored IIndexManager parameter from Configuration.getProperty() calls. Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/btree/IndexMetadata.java branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/config/Configuration.java branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/journal/AbstractJournal.java branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/rdf/rules/RDFJoinNexus.java branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/relation/AbstractResource.java branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/config/TestConfiguration.java Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/btree/IndexMetadata.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/btree/IndexMetadata.java 2010-09-17 15:04:56 UTC (rev 3583) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/btree/IndexMetadata.java 2010-09-17 17:50:43 UTC (rev 3584) @@ -3053,20 +3053,20 @@ } /** - * @see Configuration#getProperty(IIndexManager, Properties, String, String, + * @see Configuration#getProperty(Properties, String, String, * String) */ protected String getProperty(final IIndexManager indexManager, final Properties properties, final String namespace, final String globalName, final String defaultValue) { - return Configuration.getProperty(indexManager, properties, namespace, + return Configuration.getProperty(properties, namespace, globalName, defaultValue); } /** - * @see Configuration#getProperty(IIndexManager, Properties, String, String, + * @see Configuration#getProperty(Properties, String, String, * String, IValidator) */ protected <E> E getProperty(final IIndexManager indexManager, @@ -3074,7 +3074,7 @@ final String globalName, final String defaultValue, IValidator<E> validator) { - return Configuration.getProperty(indexManager, properties, namespace, + return Configuration.getProperty(properties, namespace, globalName, defaultValue, validator); } Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/config/Configuration.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/config/Configuration.java 2010-09-17 15:04:56 UTC (rev 3583) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/config/Configuration.java 2010-09-17 17:50:43 UTC (rev 3584) @@ -28,19 +28,10 @@ package com.bigdata.config; -import java.io.IOException; import java.util.Properties; -import java.util.UUID; import org.apache.log4j.Logger; -import com.bigdata.btree.BTree; -import com.bigdata.btree.IndexMetadata; -import com.bigdata.journal.IIndexManager; -import com.bigdata.relation.RelationSchema; -import com.bigdata.service.DataService; -import com.bigdata.service.IBigdataFederation; -import com.bigdata.service.IDataService; import com.bigdata.util.NV; /** @@ -64,7 +55,7 @@ * <p> * This presumes a fixed syntactic relation between a resource/index and * its container rather than the explicit relation defined by - * {@link RelationSchema#CONTAINER}. + * {@link com.bigdata.relation.RelationSchema#CONTAINER}. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ @@ -99,8 +90,8 @@ * * <li>The default value may be globally overridden using the property name. * For example, you can override the default branching factor for all - * {@link BTree}s by specifying a value for - * {@link IndexMetadata.Options#BTREE_BRANCHING_FACTOR}. In general, the + * {@link com.bigdata.btree.BTree}s by specifying a value for + * {@link com.bigdata.btree.IndexMetadata.Options#BTREE_BRANCHING_FACTOR}. In general, the * name of the property is declared by an interface along with its default * value. </li> * @@ -112,7 +103,7 @@ * <code>com.bigdata.namespace.foo.myIndex.com.bigdata.btree.BTree.branchingFactor</code> ({@value #NAMESPACE} * is the {@link #NAMESPACE} prefix for overrides, <code>foo.myIndex</code> * is the name of the index, and - * {@value IndexMetadata.Options#BTREE_BRANCHING_FACTOR} is the name of the + * com.bigdata.btree.IndexMetadata.Options#BTREE_BRANCHING_FACTOR is the name of the * property that will be overridden for that index). Alternatively you can * override the branching factor for all indices in the "foo" relation by * specifying a value for the property name @@ -123,8 +114,6 @@ * * </ol> * - * @param indexManagerIsIgnored - * The value specified to the ctor (optional). * @param properties * The properties object against which the value of the property * will be resolved. @@ -141,11 +130,11 @@ * * @todo test when namespace is empty (journal uses that) and possibly null. */ - public static String getProperty(final IIndexManager indexManagerIsIgnored, + public static String getProperty( final Properties properties, final String namespace, final String propertyName, final String defaultValue) { - final NV nv = getProperty2(indexManagerIsIgnored, properties, namespace, + final NV nv = getProperty2(properties, namespace, propertyName, defaultValue); if(nv == null) return null; @@ -158,15 +147,13 @@ * Variant returns both the name under which the value was discovered and * the value. * - * @param indexManagerIsIgnored * @param properties * @param namespace * @param globalName * @param defaultValue * @return */ - public static NV getProperty2(final IIndexManager indexManagerIsIgnored, - final Properties properties, final String namespace, + public static NV getProperty2(final Properties properties, final String namespace, final String globalName, final String defaultValue) { // indexManager MAY be null. @@ -263,7 +250,6 @@ * Variant converts to the specified generic type and validates the value. * * @param <E> - * @param indexManager * @param properties * @param namespace * @param globalName @@ -273,7 +259,7 @@ * @return The validated value -or- <code>null</code> if there was no * default. */ - public static <E> E getProperty(final IIndexManager indexManager, + public static <E> E getProperty( final Properties properties, final String namespace, final String globalName, final String defaultValue, final IValidator<E> validator) @@ -282,7 +268,7 @@ if (validator == null) throw new IllegalArgumentException(); - final NV nv = getProperty2(indexManager, properties, namespace, + final NV nv = getProperty2(properties, namespace, globalName, defaultValue); if (nv == null) @@ -315,84 +301,7 @@ // return localName; // // } - - /** - * Resolve the value to a {@link DataService} {@link UUID}. - * - * @param indexManager - * The index manager (optional). - * @param val - * The value is either a {@link UUID} or a service name. - * - * @return The {@link UUID} of the identified service -or- <code>null</code> - * if no service is identified for that value or if the - * <i>indexManager</i> is either not given or not an - * {@link IBigdataFederation}. - * - * @throws IllegalArgumentException - * if the <i>val</i> is <code>null</code>. - */ - static protected UUID resolveDataService(final IIndexManager indexManager, - final String val) { - if (indexManager == null) - return null; - - if (val == null) - throw new IllegalArgumentException(); - - if (!(indexManager instanceof IBigdataFederation)) - return null; - - final IBigdataFederation fed = ((IBigdataFederation) indexManager); - - /* - * Value is a UUID? - */ - try { - - // valid UUID? - return UUID.fromString(val); - - } catch (IllegalArgumentException ex) { - - // Ignore. - - } - - /* - * Value is the name of a data service? - */ - { - - final IDataService dataService = fed.getDataServiceByName(val); - - if (dataService != null) { - - try { - - return dataService.getServiceUUID(); - - } catch (IOException ex) { - - throw new RuntimeException(ex); - - } - - } - - // fall through. - - } - - // can't interpret the value. - - log.warn("Could not resolve: "+val); - - return null; - - } - /** * Return the name that can be used to override the specified property for * the given namespace. Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/journal/AbstractJournal.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/journal/AbstractJournal.java 2010-09-17 15:04:56 UTC (rev 3583) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/journal/AbstractJournal.java 2010-09-17 17:50:43 UTC (rev 3584) @@ -564,13 +564,13 @@ /** * Resolves the property value (static variant for ctor initialization). * - * @see Configuration#getProperty(IIndexManager, Properties, String, String, + * @see Configuration#getProperty(Properties, String, String, * String) */ static protected String getProperty(final Properties properties, final String name, final String defaultValue) { - return Configuration.getProperty(null/* indexManager */, properties, + return Configuration.getProperty(properties, ""/* no namespace */, name, defaultValue); } @@ -578,12 +578,12 @@ /** * Resolves the property value. * - * @see Configuration#getProperty(IIndexManager, Properties, String, String, + * @see Configuration#getProperty(Properties, String, String, * String) */ protected String getProperty(final String name, final String defaultValue) { - return Configuration.getProperty(this, properties, + return Configuration.getProperty(properties, ""/* no namespace */, name, defaultValue); } @@ -597,7 +597,7 @@ protected <E> E getProperty(final String name, final String defaultValue, IValidator<E> validator) { - return Configuration.getProperty(this, properties, + return Configuration.getProperty(properties, ""/* no namespace */, name, defaultValue, validator); } Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/rdf/rules/RDFJoinNexus.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/rdf/rules/RDFJoinNexus.java 2010-09-17 15:04:56 UTC (rev 3583) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/rdf/rules/RDFJoinNexus.java 2010-09-17 17:50:43 UTC (rev 3584) @@ -223,7 +223,7 @@ public String getProperty(final String name, final String defaultValue) { // @todo pass namespace in with the RDFJoinNexusFactory? - return Configuration.getProperty(indexManager, + return Configuration.getProperty( joinNexusFactory.properties, null/* namespace */, name, defaultValue); @@ -233,7 +233,7 @@ final IValidator<T> validator) { // @todo pass namespace in with the RDFJoinNexusFactory? - return Configuration.getProperty(indexManager, + return Configuration.getProperty( joinNexusFactory.properties, null/* namespace */, name, defaultValue, validator); Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/relation/AbstractResource.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/relation/AbstractResource.java 2010-09-17 15:04:56 UTC (rev 3583) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/relation/AbstractResource.java 2010-09-17 17:50:43 UTC (rev 3584) @@ -734,9 +734,7 @@ * Resolve the property value using the {@link IIndexManager}, the * namespace of the resource, and the {@link Properties} instance to be * tested as hidden parameters. - * - * @param globalName - * The global property name. + * * @param defaultValue * The default. * @@ -747,7 +745,7 @@ protected String getProperty(final String localName, final String defaultValue) { - return Configuration.getProperty(indexManager, properties, namespace, + return Configuration.getProperty(properties, namespace, localName, defaultValue); } @@ -764,7 +762,7 @@ protected <T> T getProperty(final String name, final String defaultValue, final IValidator<T> validator) { - return Configuration.getProperty(indexManager, properties, namespace, + return Configuration.getProperty(properties, namespace, name, defaultValue, validator); } Modified: branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/config/TestConfiguration.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/config/TestConfiguration.java 2010-09-17 15:04:56 UTC (rev 3583) +++ branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/config/TestConfiguration.java 2010-09-17 17:50:43 UTC (rev 3584) @@ -32,11 +32,6 @@ import junit.framework.TestCase; -import com.bigdata.btree.IndexMetadata; -import com.bigdata.journal.IIndexManager; -import com.bigdata.rdf.lexicon.LexiconKeyOrder; -import com.bigdata.rdf.lexicon.LexiconRelation; - /** * Unit tests for {@link Configuration}. * @@ -44,6 +39,12 @@ * @version $Id$ */ public class TestConfiguration extends TestCase { + //These constants happen line up with constants further up the bigdata tree, but the Configuration class really doesn't care. -gossard + private static final String NAME_LEXICON_RELATION = "lex"; + private static final String TERM_2_ID = "TERM2ID"; + private static final String ID_2_TERM = "ID2TERM"; + private static final String SCATTER_SPLIT_DATA_SERVICE_COUNT = "com.bigdata.btree.ScatterSplitConfiguration.dataServiceCount"; + private static final String SCATTER_SPLIT_ENABLED = "com.bigdata.btree.ScatterSplitConfiguration.enabled"; public TestConfiguration() { @@ -63,8 +64,6 @@ */ public void testGlobalOverride() { - final IIndexManager indexManager = null; - final Properties properties = new Properties(); final String namespace = "foo.bar"; @@ -76,12 +75,12 @@ final String globalOverride = "boo"; - assertEquals(defaultValue, Configuration.getProperty(indexManager, + assertEquals(defaultValue, Configuration.getProperty( properties, namespace, globalName, defaultValue)); properties.setProperty(globalName, globalOverride); - assertEquals(globalOverride, Configuration.getProperty(indexManager, + assertEquals(globalOverride, Configuration.getProperty( properties, namespace, globalName, defaultValue)); } @@ -92,8 +91,6 @@ */ public void test_exactNamespaceOverride() { - final IIndexManager indexManager = null; - final Properties properties = new Properties(); final String namespace = "foo.baz"; @@ -108,7 +105,7 @@ final String overrideValue = "boo"; - assertEquals(defaultValue, Configuration.getProperty(indexManager, + assertEquals(defaultValue, Configuration.getProperty( properties, namespace, globalName, defaultValue)); final String overrideName = Configuration.getOverrideProperty( @@ -116,7 +113,7 @@ properties.setProperty(overrideName, overrideValue); - assertEquals(overrideValue, Configuration.getProperty(indexManager, + assertEquals(overrideValue, Configuration.getProperty( properties, namespace, globalName, defaultValue)); } @@ -126,8 +123,6 @@ * the namespace ("foo" vs "foo.baz"). */ public void test_prefixNamespaceOverride() { - - final IIndexManager indexManager = null; final Properties properties = new Properties(); @@ -146,12 +141,12 @@ final String overrideValue = "boo"; - assertEquals(defaultValue, Configuration.getProperty(indexManager, + assertEquals(defaultValue, Configuration.getProperty( properties, namespace, globalName, defaultValue)); properties.setProperty(overrideName, overrideValue); - assertEquals(overrideValue, Configuration.getProperty(indexManager, + assertEquals(overrideValue, Configuration.getProperty( properties, namespace, globalName, defaultValue)); } @@ -161,11 +156,11 @@ final String namespace = "U8000"; final String namespace2 = "U100"; - final String propertyName = IndexMetadata.Options.SCATTER_SPLIT_ENABLED; + final String propertyName = SCATTER_SPLIT_ENABLED; final String overrideName = Configuration.getOverrideProperty(namespace - + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName); + + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName); System.err.println(overrideName); @@ -176,31 +171,29 @@ // override this property. p.setProperty(overrideName, "false"); - final IIndexManager indexManager = null; - /* * Verify override used for U8000.lex.TERM2ID (this is the specific case * for the override). */ - assertEquals("false", Configuration.getProperty(indexManager, p, - namespace + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName, defaultValue)); + assertEquals("false", Configuration.getProperty( p, + namespace + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName, defaultValue)); /* * Verify override ignored for U8000.lex.ID2TERM (another index in the * same relation). */ - assertEquals(defaultValue, Configuration.getProperty(indexManager, p, - namespace + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.ID2TERM, propertyName, defaultValue)); + assertEquals(defaultValue, Configuration.getProperty(p, + namespace + "." + NAME_LEXICON_RELATION + "." + + ID_2_TERM, propertyName, defaultValue)); /* * Verify override ignored for U100.lex.TERM2ID (an index in a different * relation). */ - assertEquals(defaultValue, Configuration.getProperty(indexManager, p, - namespace2 + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName, defaultValue)); + assertEquals(defaultValue, Configuration.getProperty(p, + namespace2 + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName, defaultValue)); } @@ -210,12 +203,12 @@ final String namespace1 = "U100"; final String namespace2 = "U50"; - final String propertyName = IndexMetadata.Options.SCATTER_SPLIT_DATA_SERVICE_COUNT; + final String propertyName = SCATTER_SPLIT_DATA_SERVICE_COUNT; // override of a specific index in a specific relation. final String overrideName = Configuration.getOverrideProperty(namespace - + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName); + + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName); // override of all indices in a different relation. final String overrideName2 = Configuration.getOverrideProperty( @@ -243,41 +236,39 @@ // a different override for a different relation. p.setProperty(overrideName2, otherOverride); - final IIndexManager indexManager = null; - /* * Verify override used for U8000.lex.TERM2ID (this is the specific case * for the override). */ - assertEquals("2", Configuration.getProperty(indexManager, p, - namespace + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName, defaultValue)); + assertEquals("2", Configuration.getProperty(p, + namespace + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName, defaultValue)); /* * Verify global override used for a different index in the same * relation. */ - assertEquals(globalOverride, Configuration.getProperty(indexManager, p, - namespace + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.ID2TERM, propertyName, defaultValue)); + assertEquals(globalOverride, Configuration.getProperty(p, + namespace + "." + NAME_LEXICON_RELATION + "." + + ID_2_TERM, propertyName, defaultValue)); /* * Verify global override used for an index in another relation. */ - assertEquals(globalOverride, Configuration.getProperty(indexManager, p, - namespace1 + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName, defaultValue)); + assertEquals(globalOverride, Configuration.getProperty(p, + namespace1 + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName, defaultValue)); /* * Verify other override used for all indices in the namespace2 * relation. */ - assertEquals(otherOverride, Configuration.getProperty(indexManager, p, - namespace2 + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.TERM2ID, propertyName, defaultValue)); - assertEquals(otherOverride, Configuration.getProperty(indexManager, p, - namespace2 + "." + LexiconRelation.NAME_LEXICON_RELATION + "." - + LexiconKeyOrder.ID2TERM, propertyName, defaultValue)); + assertEquals(otherOverride, Configuration.getProperty(p, + namespace2 + "." + NAME_LEXICON_RELATION + "." + + TERM_2_ID, propertyName, defaultValue)); + assertEquals(otherOverride, Configuration.getProperty(p, + namespace2 + "." + NAME_LEXICON_RELATION + "." + + ID_2_TERM, propertyName, defaultValue)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2010-09-17 15:05:04
|
Revision: 3583 http://bigdata.svn.sourceforge.net/bigdata/?rev=3583&view=rev Author: thompsonbry Date: 2010-09-17 15:04:56 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Added BOp.isSharedState() so the query controller will know to invoke SliceOp with the same SliceStats instance each time. This fixes the problems with slice. I have replicated a problem with multiple join invocations first observed in scale-out against a local query engine. I will work to debug that next. Several new unit tests for query. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/PipelineOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/PipelineUtility.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestAll.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestBOpStats.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java Added Paths: ----------- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine_Slice.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/PipelineOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/PipelineOp.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/PipelineOp.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit; import com.bigdata.bop.engine.BOpStats; +import com.bigdata.bop.engine.QueryEngine; import com.bigdata.btree.IRangeQuery; import com.bigdata.relation.accesspath.AccessPath; import com.bigdata.relation.accesspath.BlockingBuffer; @@ -107,9 +108,12 @@ /** * The default for {@link #CHUNK_TIMEOUT}. * - * @todo this is probably much larger than we want. Try 10ms. + * @todo Experiment with values for this. Low values will push chunks + * through quickly. High values will cause chunks to be combined + * and move larger chunks around. [But if we factor BlockingBuffer + * out of the query engine then this will go away]. */ - int DEFAULT_CHUNK_TIMEOUT = 1000; + int DEFAULT_CHUNK_TIMEOUT = 20; /** * If the estimated rangeCount for an {@link AccessPath#iterator()} is @@ -125,9 +129,10 @@ /** * Default for {@link #FULLY_BUFFERED_READ_THRESHOLD}. * - * @todo try something closer to the branching factor, e.g., 100. + * @todo Experiment with this. It should probably be something close to + * the branching factor, e.g., 100. */ - int DEFAULT_FULLY_BUFFERED_READ_THRESHOLD = 1000; + int DEFAULT_FULLY_BUFFERED_READ_THRESHOLD = 100; /** * Flags for the iterator ({@link IRangeQuery#KEYS}, @@ -203,6 +208,24 @@ */ protected static transient final TimeUnit chunkTimeoutUnit = TimeUnit.MILLISECONDS; + /** + * Return <code>true</code> iff {@link #newStats()} must be shared across + * all invocations of {@link #eval(BOpContext)} for this operator for a + * given query (default <code>false</code>). + * <p> + * Note: {@link BOp#getEvaluationContext()} MUST be overridden to return + * {@link BOpEvaluationContext#CONTROLLER} if this method is overridden to + * return <code>true</code>. + * <p> + * When <code>true</code>, the {@link QueryEngine} will impose the necessary + * constraints when the operator is evaluated. + */ + public boolean isSharedState() { + + return false; + + } + public BOpStats newStats() { return new BOpStats(); @@ -227,13 +250,16 @@ * @param chunkOfChunksCapacity * @param chunkCapacity * @param chunkTimeout - * @param chunktimeoutunit + * @param chunkTimeoutUnit * @param stats */ public BlockingBufferWithStats(int chunkOfChunksCapacity, int chunkCapacity, long chunkTimeout, - TimeUnit chunktimeoutunit, final BOpStats stats) { + TimeUnit chunkTimeoutUnit, final BOpStats stats) { + super(chunkOfChunksCapacity, chunkCapacity, chunkTimeout, + chunkTimeoutUnit); + this.stats = stats; } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/bset/CopyBindingSetOp.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -108,8 +108,6 @@ stats.chunksIn.increment(); stats.unitsIn.add(chunk.length); sink.add(chunk); -// stats.chunksOut.increment(); -// stats.unitsOut.add(chunk.length); } sink.flush(); return null; Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -91,12 +91,16 @@ } /** - * Combine the statistics (addition). + * Combine the statistics (addition), but do NOT add to self. * * @param o * Another statistics object. */ public void add(final BOpStats o) { + if (this == o) { + // Do not add to self! + return; + } chunksIn.add(o.chunksIn.get()); unitsIn.add(o.unitsIn.get()); unitsOut.add(o.unitsOut.get()); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/PipelineUtility.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/PipelineUtility.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/PipelineUtility.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -149,6 +149,9 @@ } + if (log.isInfoEnabled()) + log.info("Operator can not be triggered: op=" + op); + return true; } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/RunningQuery.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -55,6 +55,7 @@ import com.bigdata.bop.solutions.SliceOp; import com.bigdata.journal.IIndexManager; import com.bigdata.journal.ITx; +import com.bigdata.relation.accesspath.BlockingBuffer; import com.bigdata.relation.accesspath.IAsynchronousIterator; import com.bigdata.relation.accesspath.IBlockingBuffer; import com.bigdata.service.IBigdataFederation; @@ -135,8 +136,8 @@ /** * The buffer used for the overall output of the query pipeline. * <p> - * Note: In scale out, this only exists on the query controller. In order to - * ensure that the results are transferred to the query controller, the + * Note: This only exists on the query controller. In order to ensure that + * the results are transferred to the query controller in scale-out, the * top-level operator in the query plan must specify * {@link BOpEvaluationContext#CONTROLLER}. For example, {@link SliceOp} * uses this {@link BOpEvaluationContext}. @@ -393,8 +394,8 @@ * <p> * The default implementation supports a standalone database. The generated * chunk is left on the Java heap and handed off synchronously using - * {@link QueryEngine#add(IChunkMessage)}. That method will queue the chunk - * for asynchronous processing. + * {@link QueryEngine#acceptChunk(IChunkMessage)}. That method will queue + * the chunk for asynchronous processing. * * @param sinkId * The identifier of the target operator. @@ -412,9 +413,44 @@ /* * Note: The partitionId will always be -1 in scale-up. */ + final int partitionId = -1; + + /* + * FIXME Raise this into an annotation that we can tweak from the unit + * tests and then debug the problem. + */ + final boolean oneMessagePerChunk = false; + + if (oneMessagePerChunk) { + + final IAsynchronousIterator<IBindingSet[]> itr = sink.iterator(); + + int nchunks = 0; + + while (itr.hasNext()) { + + final IBlockingBuffer<IBindingSet[]> tmp = new BlockingBuffer<IBindingSet[]>( + 1); + + tmp.add(itr.next()); + + tmp.close(); + + final LocalChunkMessage<IBindingSet> chunk = new LocalChunkMessage<IBindingSet>( + clientProxy, queryId, sinkId, partitionId, tmp.iterator()); + + queryEngine.acceptChunk(chunk); + + nchunks++; + + } + + return nchunks; + + } + final LocalChunkMessage<IBindingSet> chunk = new LocalChunkMessage<IBindingSet>( - clientProxy, queryId, sinkId, -1/* partitionId */, sink - .iterator()); + clientProxy, queryId, sinkId, partitionId, sink.iterator()); queryEngine.acceptChunk(chunk); @@ -539,8 +575,10 @@ // update per-operator statistics. final BOpStats tmp = statsMap.putIfAbsent(msg.bopId, msg.taskStats); - if (tmp != null) + if (tmp != null && tmp != msg.taskStats) { + // combine, but do not add to self. tmp.add(msg.taskStats); + } Throwable cause = null; boolean allDone = false; @@ -828,7 +866,25 @@ + bop); } - final BOpStats stats = op.newStats(); + /* + * Setup the BOpStats object. For some operators, e.g., SliceOp, + * this MUST be the same object across all invocations of that + * instance of that operator for this query. This is marked by the + * PipelineOp#isSharedState() method and is handled by a + * putIfAbsent() pattern when that method returns true. + * + * Note: RunState#haltOp() avoids adding a BOpStats object to itself + * since that would cause double counting when the same object is + * used for each invocation of the operator. + */ + final BOpStats stats; + if (((PipelineOp<?>) bop).isSharedState()) { + final BOpStats foo = op.newStats(); + final BOpStats bar = statsMap.putIfAbsent(bopId, foo); + stats = (bar == null ? foo : bar); + } else { + stats = op.newStats(); + } sink = (p == null ? queryBuffer : op.newBuffer(stats)); @@ -853,8 +909,8 @@ int sinkChunksOut = 0; int altSinkChunksOut = 0; try { - clientProxy.startOp(new StartOpMessage(queryId, - bopId, partitionId, serviceId, fanIn)); + clientProxy.startOp(new StartOpMessage(queryId, bopId, + partitionId, serviceId, fanIn)); if (log.isDebugEnabled()) log.debug("Running chunk: " + msg); ft.run(); // run Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -27,7 +27,6 @@ package com.bigdata.bop.solutions; -import java.math.BigInteger; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; @@ -41,7 +40,6 @@ import com.bigdata.bop.BindingSetPipelineOp; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.engine.BOpStats; -import com.bigdata.bop.engine.QueryEngine; import com.bigdata.bop.engine.RunningQuery; import com.bigdata.relation.accesspath.IAsynchronousIterator; import com.bigdata.relation.accesspath.IBlockingBuffer; @@ -67,21 +65,11 @@ * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * - * @todo Unit test with stress test for concurrent {@link SliceOp} invocations - * against a streaming chunk producer. Make sure that the same - * {@link SliceStats} are used for each concurrent invocation of the same - * query. - * - * @todo What is sufficient serialization to make SLICE(ORDER_BY(...)) stable? - * The {@link SortOp} will impose a total ordering and will know how to - * deliver that total ordering to another operator. The {@link SliceOp} - * needs to accept the chunks from the {@link SortOp} in the order in - * which they were sent. This should work as long as we do not reorder the - * chunks for a given operator in the {@link QueryEngine} when they are - * received by the query controller. - * - * @todo If we allow complex operator trees in which "subqueries" can also use a - * slice then either then need to run as their own query with their own + * @todo Slice is not safe for subqueries - the entire query is cancelled when + * the slice is satisfied. + * <p> + * If we allow complex operator trees in which "subqueries" can also use a + * slice then either they need to run as their own query with their own * {@link RunningQuery} state or the API for cancelling a running query as * used here needs to only cancel evaluation of the child operators. * Otherwise we could cancel all operator evaluation for the query, @@ -166,6 +154,20 @@ } /** + * Overridden to return <code>true</code> since the correct decision + * semantics for the slice depend on concurrent invocations for the same + * query having the same {@link SliceStats} object. + * <p> + * {@inheritDoc} + */ + @Override + final public boolean isSharedState() { + + return true; + + } + + /** * Extends {@link BOpStats} to capture the state of the {@link SliceOp}. */ public static class SliceStats extends BOpStats { @@ -184,6 +186,11 @@ @Override public void add(final BOpStats o) { + if (this == o) { + // Do not add to self! + return; + } + super.add(o); if (o instanceof SliceStats) { @@ -201,7 +208,7 @@ @Override protected void toString(final StringBuilder sb) { - sb.append(",nseed=" + nseen); + sb.append(",nseen=" + nseen); sb.append(",naccepted=" + naccepted); @@ -237,14 +244,8 @@ /** #of solutions to accept. */ private final long limit; - private final long last; - -// /** #of solutions visited. */ -// private long nseen; -// -// /** #of solutions accepted. */ -// private long naccepted; -// +// private final long last; + private final SliceStats stats; SliceTask(final SliceOp op, final BOpContext<IBindingSet> context) { @@ -266,9 +267,9 @@ this.stats = (SliceStats) context.getStats(); // this.last = offset + limit; - this.last = BigInteger.valueOf(offset).add( - BigInteger.valueOf(limit)).min( - BigInteger.valueOf(Long.MAX_VALUE)).longValue(); +// this.last = BigInteger.valueOf(offset).add( +// BigInteger.valueOf(limit)).min( +// BigInteger.valueOf(Long.MAX_VALUE)).longValue(); } @@ -282,8 +283,6 @@ final IBlockingBuffer<IBindingSet[]> sink = context.getSink(); -// final BOpStats stats = context.getStats(); - try { /* @@ -326,8 +325,10 @@ sink.flush(); - if (halt) + if (halt) { + log.error("Slice will interrupt query.");// @todo remove. throw new InterruptedException(); + } // cancelQuery(); return null; Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestAll.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestAll.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestAll.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -69,6 +69,9 @@ // test suite for query evaluation (basic JOINs). suite.addTestSuite(TestQueryEngine.class); + // stress test for SliceOp. + suite.addTestSuite(TestQueryEngine_Slice.class); + // test suite for query evaluation (DISTINCT, ORDER BY, GROUP BY). suite.addTestSuite(TestQueryEngine2.class); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestBOpStats.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestBOpStats.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestBOpStats.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -99,5 +99,34 @@ assertEquals("chunksOut", 4L, totals.chunksOut.get()); } + + public void test_addToSelf() { + + final BOpStats stats = new BOpStats(); + + assertEquals("chunksIn", 0L, stats.chunksIn.get()); + assertEquals("unitsIn", 0L, stats.unitsIn.get()); + assertEquals("unitsOut", 0L, stats.unitsOut.get()); + assertEquals("chunksOut", 0L, stats.chunksOut.get()); + + stats.chunksIn.increment(); + stats.unitsIn.increment(); + stats.unitsIn.increment(); + + assertEquals("chunksIn", 1L, stats.chunksIn.get()); + assertEquals("unitsIn", 2L, stats.unitsIn.get()); + assertEquals("unitsOut", 0L, stats.unitsOut.get()); + assertEquals("chunksOut", 0L, stats.chunksOut.get()); + + // add to self. + stats.add(stats); + + // verify no change. + assertEquals("chunksIn", 1L, stats.chunksIn.get()); + assertEquals("unitsIn", 2L, stats.unitsIn.get()); + assertEquals("unitsOut", 0L, stats.unitsOut.get()); + assertEquals("chunksOut", 0L, stats.chunksOut.get()); + + } } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -54,6 +54,7 @@ import com.bigdata.bop.IVariable; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.NV; +import com.bigdata.bop.PipelineOp; import com.bigdata.bop.Var; import com.bigdata.bop.ap.E; import com.bigdata.bop.ap.Predicate; @@ -64,6 +65,7 @@ import com.bigdata.bop.fed.TestFederatedQueryEngine; import com.bigdata.bop.join.PipelineJoin; import com.bigdata.bop.solutions.SliceOp; +import com.bigdata.bop.solutions.SliceOp.SliceStats; import com.bigdata.journal.BufferMode; import com.bigdata.journal.ITx; import com.bigdata.journal.Journal; @@ -90,6 +92,8 @@ * @version $Id$ * * @see TestFederatedQueryEngine + * + * @todo write a unit and stress tests for deadlines. */ public class TestQueryEngine extends TestCase2 { @@ -189,6 +193,35 @@ } /** + * Return an {@link IAsynchronousIterator} that will read a single, chunk + * containing all of the specified {@link IBindingSet}s. + * + * @param bindingSets + * the binding sets. + */ + protected ThickAsynchronousIterator<IBindingSet[]> newBindingSetIterator( + final IBindingSet[] bindingSets) { + + return new ThickAsynchronousIterator<IBindingSet[]>( + new IBindingSet[][] { bindingSets }); + + } + + /** + * Return an {@link IAsynchronousIterator} that will read a single, chunk + * containing all of the specified {@link IBindingSet}s. + * + * @param bindingSetChunks + * the chunks of binding sets. + */ + protected ThickAsynchronousIterator<IBindingSet[]> newBindingSetIterator( + final IBindingSet[][] bindingSetChunks) { + + return new ThickAsynchronousIterator<IBindingSet[]>(bindingSetChunks); + + } + + /** * Starts and stops the {@link QueryEngine}, but does not validate the * semantics of shutdown() versus shutdownNow() since we need to be * evaluating query mixes in order to verify the semantics of those @@ -357,6 +390,187 @@ } /** + * Test the ability run a simple join when multiple binding sets are + * submitted as the initial input. The access path associated with the join + * does not have any constants but the join picks up bindings from the input + * binding sets and uses them to constrain the access path. + */ + public void test_query_join1_multipleChunksIn() throws Exception { + + final Var<?> x = Var.var("x"); + final Var<?> y = Var.var("y"); + + final int startId = 1; + final int joinId = 2; + final int predId = 3; + + /* + * Enforce a constraint on the source such that it hands 3 each source + * chunk to the join operator as a separate chunk + * + * @todo This is not enough to force the query engine to run the join + * operator once per source chunk. Instead, it takes the output of the + * source operator, which is N chunks, and sends them all to a single + * invocation of the join task. To do better than that we have to send + * multiple chunk messages rather than just one. + */ + final int nsources = 3; + final StartOp startOp = new StartOp(new BOp[] {}, NV.asMap(new NV[] {// + new NV(Predicate.Annotations.BOP_ID, startId),// + new NV(PipelineOp.Annotations.CHUNK_CAPACITY, 1),// + new NV(PipelineOp.Annotations.CHUNK_OF_CHUNKS_CAPACITY, nsources),// + })); + + final Predicate<E> predOp = new Predicate<E>(new IVariableOrConstant[] { + x, y }, NV.asMap(new NV[] {// + new NV(Predicate.Annotations.RELATION_NAME, + new String[] { namespace }),// + new NV(Predicate.Annotations.PARTITION_ID, Integer + .valueOf(-1)),// + new NV(Predicate.Annotations.OPTIONAL, Boolean.FALSE),// + new NV(Predicate.Annotations.CONSTRAINT, null),// + new NV(Predicate.Annotations.EXPANDER, null),// + new NV(Predicate.Annotations.BOP_ID, predId),// + new NV(Predicate.Annotations.TIMESTAMP, + ITx.READ_COMMITTED),// + })); + + final PipelineJoin<E> joinOp = new PipelineJoin<E>( + startOp/* left */, predOp/* right */, + // join annotations + NV.asMap(new NV[] { // + new NV(Predicate.Annotations.BOP_ID, joinId),// +// new NV(PipelineOp.Annotations.CHUNK_CAPACITY, 1),// +// new NV(PipelineOp.Annotations.CHUNK_OF_CHUNKS_CAPACITY, 1),// + })// + ); + + final int sliceId = 4; + final SliceOp sliceOp = new SliceOp(new BOp[] { joinOp }, + // slice annotations + NV.asMap(new NV[] {// + new NV(Predicate.Annotations.BOP_ID, sliceId),// + })// + ); + + final BindingSetPipelineOp query = sliceOp; + + /* + * Source binding sets. + * + * Note: We can't bind y in advance for the primary index! + */ + final IBindingSet[] source = new IBindingSet[] {// + new HashBindingSet(new ArrayBindingSet(// + new IVariable[] { x },// + new IConstant[] { new Constant<String>("Paul") }// + )),// + new HashBindingSet(new ArrayBindingSet(// + new IVariable[] { x },// + new IConstant[] { new Constant<String>("Leon") }// + )), + new HashBindingSet(new ArrayBindingSet(// + new IVariable[] { x },// + new IConstant[] { new Constant<String>("Mary") }// + )), + }; + // Put each source binding set into a chunk by itself. + final IBindingSet[][] sources = new IBindingSet[source.length][]; + for (int i = 0; i < sources.length; i++) { + sources[i] = new IBindingSet[] { source[i] }; + } + assertEquals(nsources,source.length); + assertEquals(nsources,sources.length); + +// new E("John", "Mary"),// [0] +// new E("Leon", "Paul"),// [1] +// new E("Mary", "Paul"),// [2] +// new E("Paul", "Leon"),// [3] + + // the expected solution (just one). + final IBindingSet[] expected = new IBindingSet[] {// + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { // + new Constant<String>("Paul"), new Constant<String>("Leon") }// + ),// + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { // + new Constant<String>("Leon"), new Constant<String>("Paul") }// + ), + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { // + new Constant<String>("Mary"), new Constant<String>("Paul") }// + ), + }; + + final UUID queryId = UUID.randomUUID(); + final RunningQuery runningQuery = queryEngine.eval(queryId, query, + new LocalChunkMessage<IBindingSet>(queryEngine, queryId, + startId, -1 /* partitionId */, + newBindingSetIterator(sources))); + + // verify solutions. + assertSameSolutionsAnyOrder(expected, new Dechunkerator<IBindingSet>( + runningQuery.iterator())); + + // Wait until the query is done. + runningQuery.get(); + final Map<Integer, BOpStats> statsMap = runningQuery.getStats(); + { + // validate the stats map. + assertNotNull(statsMap); + assertEquals(3, statsMap.size()); + if (log.isInfoEnabled()) + log.info(statsMap.toString()); + } + + // validate the stats for the start operator. + { + final BOpStats stats = statsMap.get(startId); + assertNotNull(stats); + if (log.isInfoEnabled()) + log.info("start: "+stats.toString()); + + assertEquals(3L, stats.chunksIn.get()); + assertEquals(3L, stats.unitsIn.get()); + assertEquals(3L, stats.unitsOut.get()); + assertEquals(3L, stats.chunksOut.get()); + } + + // validate the stats for the join operator. + { + final BOpStats stats = statsMap.get(joinId); + assertNotNull(stats); + if (log.isInfoEnabled()) + log.info("join : "+stats.toString()); + +// assertEquals(3L, stats.chunksIn.get()); + assertEquals(3L, stats.unitsIn.get()); + assertEquals(3L, stats.unitsOut.get()); +// assertEquals(3L, stats.chunksOut.get()); + } + + // validate the stats for the slice operator. + { + final SliceStats stats = (SliceStats) statsMap.get(sliceId); + assertNotNull(stats); + if (log.isInfoEnabled()) + log.info("slice: "+stats.toString()); + + assertEquals(3L, stats.nseen.get()); + assertEquals(3L, stats.naccepted.get()); +// assertEquals(3L, stats.chunksIn.get()); + assertEquals(3L, stats.unitsIn.get()); + assertEquals(3L, stats.unitsOut.get()); +// assertEquals(3L, stats.chunksOut.get()); + } + + } + + /** * @todo Test the ability close the iterator draining a result set before * the query has finished executing and verify that the query is * correctly terminated [this is difficult to test without having Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine_Slice.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine_Slice.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine_Slice.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -0,0 +1,197 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Sep 17, 2010 + */ + +package com.bigdata.bop.engine; + +import java.util.Properties; +import java.util.Random; +import java.util.UUID; + +import junit.framework.TestCase2; + +import com.bigdata.bop.BOp; +import com.bigdata.bop.EmptyBindingSet; +import com.bigdata.bop.IBindingSet; +import com.bigdata.bop.NV; +import com.bigdata.bop.solutions.SliceOp; +import com.bigdata.bop.solutions.SliceOp.SliceStats; +import com.bigdata.journal.BufferMode; +import com.bigdata.journal.Journal; +import com.bigdata.relation.accesspath.IAsynchronousIterator; +import com.bigdata.relation.accesspath.ThickAsynchronousIterator; + +/** + * Stress test for {@link SliceOp} in which a large number of small chunks are + * fed into the query such that the concurrency constraints of the slice are + * stress tested. {@link SliceOp#isSharedState()} returns <code>true</code> so + * each invocation of the same {@link SliceOp} operator instance should use the + * same {@link SliceStats} object. This test will fail if that is not true. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestQueryEngine_Slice extends TestCase2 { + + /** + * + */ + public TestQueryEngine_Slice() { + } + + /** + * @param name + */ + public TestQueryEngine_Slice(String name) { + super(name); + } + + @Override + public Properties getProperties() { + + final Properties p = new Properties(super.getProperties()); + + p.setProperty(Journal.Options.BUFFER_MODE, BufferMode.Transient + .toString()); + + return p; + + } + + Journal jnl; + QueryEngine queryEngine; + + public void setUp() throws Exception { + + jnl = new Journal(getProperties()); + + queryEngine = new QueryEngine(jnl); + + queryEngine.init(); + + } + + public void tearDown() throws Exception { + + if (queryEngine != null) { + queryEngine.shutdownNow(); + queryEngine = null; + } + + if (jnl != null) { + jnl.destroy(); + jnl = null; + } + + } + + /** + * Return an {@link IAsynchronousIterator} that will read a single, chunk + * containing all of the specified {@link IBindingSet}s. + * + * @param bindingSetChunks + * the chunks of binding sets. + */ + protected ThickAsynchronousIterator<IBindingSet[]> newBindingSetIterator( + final IBindingSet[][] bindingSetChunks) { + + return new ThickAsynchronousIterator<IBindingSet[]>(bindingSetChunks); + + } + + public void test_slice_threadSafe() throws Exception { + + final long timeout = 10000; // ms + + final int ntrials = 10000; + + final int poolSize = 10; + + doSliceTest(500L/* offset */, 1500L/* limit */, timeout, ntrials, + poolSize); + + } + + /** + * + * @param timeout + * @param ntrials + * @param poolSize + * + * @return The #of successful trials. + * + * @throws Exception + */ + protected void doSliceTest(final long offset, final long limit, + final long timeout, final int ntrials, final int poolSize) + throws Exception { + + final IBindingSet[][] chunks = new IBindingSet[ntrials][]; + { + final Random r = new Random(); + final IBindingSet bset = EmptyBindingSet.INSTANCE; + for (int i = 0; i < chunks.length; i++) { + // random non-zero chunk size + chunks[i] = new IBindingSet[r.nextInt(10) + 1]; + for (int j = 0; j < chunks[i].length; j++) { + chunks[i][j] = bset; + } + } + } + final int sliceId = 1; + final SliceOp query = new SliceOp(new BOp[] {}, NV.asMap(new NV[] {// + new NV(SliceOp.Annotations.BOP_ID, sliceId),// + new NV(SliceOp.Annotations.OFFSET, offset),// + new NV(SliceOp.Annotations.LIMIT, limit),// + })); + + final UUID queryId = UUID.randomUUID(); + final RunningQuery q = queryEngine.eval(queryId, query, + new LocalChunkMessage<IBindingSet>(queryEngine, queryId, + sliceId, -1/* partitionId */, + newBindingSetIterator(chunks))); + + // consume solutions. + int nsolutions = 0; + final IAsynchronousIterator<IBindingSet[]> itr = q.iterator(); + while (itr.hasNext()) { + nsolutions += itr.next().length; + } + + // wait for the query to terminate. + q.get(); + + // Verify stats. + final SliceStats stats = (SliceStats) q.getStats().get(sliceId); + System.err.println(getClass().getName() + "." + getName() + " : " + + stats); + assertNotNull(stats); + assertEquals(limit, stats.naccepted.get()); + assertEquals(limit, nsolutions); + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/engine/TestQueryEngine_Slice.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -65,7 +65,6 @@ import com.bigdata.bop.solutions.SliceOp; import com.bigdata.bop.solutions.SortOp; import com.bigdata.btree.keys.KeyBuilder; -import com.bigdata.counters.CAT; import com.bigdata.journal.BufferMode; import com.bigdata.journal.ITx; import com.bigdata.journal.Journal; @@ -106,6 +105,9 @@ * thompsonbry $ * * @todo reuse the stress test from {@link TestQueryEngine}. + * + * @todo there should be a stress test of {@link SliceOp} with a non-zero offset + * in order to verify that it is properly synchronized. */ public class TestFederatedQueryEngine extends AbstractEmbeddedFederationTestCase { @@ -428,7 +430,7 @@ * * @throws Exception */ - public void test_query_startThenSlice() throws Exception { + public void test_query_startThenSlice_noJoins() throws Exception { final int startId = 1; final int sliceId = 4; @@ -508,15 +510,19 @@ } /** - * Test the ability run a simple join. There are three operators. One feeds - * an empty binding set[] into the join, another is the predicate for the - * access path on which the join will read (it probes the index once for - * "Mary" and binds "Paul" and "John" when it does so), and the third is the - * join itself (there are two solutions, which are "value=Paul" and - * value="John"). + * Test the ability run a simple join which is mapped across two index + * partitions. There are three operators. One feeds an empty binding set[] + * into the join, another is the predicate for the access path on which the + * join will read (no variables are bound so it will read everything), and + * the third is the join itself. + * + * @throws Exception */ - public void test_query_join1() throws Exception { + public void test_query_join_2shards_nothingBoundOnAccessPath() throws Exception { + final Var<?> x = Var.var("x") ; + final Var<?> y = Var.var("y") ; + final int startId = 1; final int joinId = 2; final int predId = 3; @@ -526,13 +532,12 @@ new NV(Predicate.Annotations.BOP_ID, startId),// })); + // access path has has no constants and no constraint. final Predicate<E> predOp = new Predicate<E>(new IVariableOrConstant[] { - new Constant<String>("Mary"), Var.var("value") }, NV + x, y}, NV .asMap(new NV[] {// new NV(Predicate.Annotations.RELATION_NAME, new String[] { namespace }),// - new NV(Predicate.Annotations.KEY_ORDER, - R.primaryKeyOrder),// new NV(Predicate.Annotations.PARTITION_ID, Integer .valueOf(-1)),// new NV(Predicate.Annotations.OPTIONAL, Boolean.FALSE),// @@ -541,6 +546,8 @@ new NV(Predicate.Annotations.BOP_ID, predId),// new NV(Predicate.Annotations.TIMESTAMP, ITx.READ_COMMITTED),// + new NV(Predicate.Annotations.KEY_ORDER, + R.primaryKeyOrder),// })); final PipelineJoin<E> joinOp = new PipelineJoin<E>(startOp/* left */, @@ -552,7 +559,7 @@ ); final BindingSetPipelineOp query = new SliceOp(new BOp[] { joinOp }, - // slice annotations + // slice annotations NV.asMap(new NV[] {// new NV(Predicate.Annotations.BOP_ID, sliceId),// })// @@ -560,15 +567,46 @@ // the expected solutions (order is not reliable due to concurrency). final IBindingSet[] expected = new IBindingSet[] {// - new ArrayBindingSet(// - new IVariable[] { Var.var("value") },// - new IConstant[] { new Constant<String>("Paul") }// + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { // + new Constant<String>("John"), + new Constant<String>("Mary") }// ), // - new ArrayBindingSet(// - new IVariable[] { Var.var("value") },// - new IConstant[] { new Constant<String>("John") }// - ) }; + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] {// + new Constant<String>("Leon"), + new Constant<String>("Paul") }// + ), // + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { // + new Constant<String>("Mary"), + new Constant<String>("John") }// + ), // + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] {// + new Constant<String>("Mary"), + new Constant<String>("Paul") }// + ), // + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { // + new Constant<String>("Paul"), + new Constant<String>("Leon") }// + ), // + }; +// // partition0 +// new E("John", "Mary"),// +// new E("Leon", "Paul"),// +// // partition1 +// new E("Mary", "John"),// +// new E("Mary", "Paul"),// +// new E("Paul", "Leon"),// + // run query with empty binding set, so nothing is bound on the join. final UUID queryId = UUID.randomUUID(); final RunningQuery runningQuery = queryEngine.eval(queryId, query, new LocalChunkMessage<IBindingSet>(queryEngine, queryId, @@ -615,8 +653,8 @@ // verify query solution stats details. assertEquals(1L, stats.chunksIn.get()); assertEquals(1L, stats.unitsIn.get()); - assertEquals(2L, stats.unitsOut.get()); - assertEquals(1L, stats.chunksOut.get()); // @todo this depends on which index partitions we read on. + assertEquals(5L, stats.unitsOut.get()); + assertEquals(2L, stats.chunksOut.get()); // since we read on both shards. } // validate the stats for the slice operator. @@ -627,36 +665,21 @@ log.info("slice: "+stats.toString()); // verify query solution stats details. - assertEquals(1L, stats.chunksIn.get()); - assertEquals(2L, stats.unitsIn.get()); - assertEquals(2L, stats.unitsOut.get()); - assertEquals(1L, stats.chunksOut.get()); + assertEquals(2L, stats.chunksIn.get()); // from both shards. + assertEquals(5L, stats.unitsIn.get()); + assertEquals(5L, stats.unitsOut.get()); + assertEquals(2L, stats.chunksOut.get()); } } /** * Test the ability run a simple join which is mapped across two index - * partitions. - * - * FIXME This is failing because the {@link SliceOp} is not remembering its - * state across distinct invocations and is cancelling the query as soon as - * it exhausts its input. In order to have correct decision boundaries, - * slice needs to be invoked either once, concurrently if using {@link CAT} - * s, or in a series of presentations otherwise (single-threaded operator or - * internal locking in the operator implementation on its {@link SliceOp} to - * achieve chunk-wise serialization of processing). - * <p> - * The easiest way to fix this is to have {@link SliceOp} specialize the - * {@link BOpStats}s and carry its state there. That will also make it safe - * for concurrent evaluation within the same query, and we will have to - * write a unit test for that. - * <p> - * I am not yet convinced that the problem with the test failure is double - * invocation of {@link SliceOp}. It could also be that we are not invoking - * it the 2nd time. + * partitions. The join is constrained to filter for only solutions in which + * [y==Paul]. */ - public void test_query_join_withConstraint_readsOn2shards() throws Exception { + public void test_query_join_2shards_nothingBoundOnAccessPath_withConstraint() + throws Exception { final Var<?> x = Var.var("x"); final Var<?> y = Var.var("y"); @@ -671,7 +694,6 @@ })); /* - * * Note: Since the index on which this reads is formed as (column1 + * column2) the probe key will be [null] if it does not bind the first * column. Therefore, in order to have the 2nd column constraint we have @@ -725,7 +747,7 @@ new IConstant[] { new Constant<String>("Mary"), new Constant<String>("Paul") }// ), // - }; + }; // // partition0 // new E("John", "Mary"),// // new E("Leon", "Paul"),// @@ -786,9 +808,9 @@ log.info("join : "+stats.toString()); // verify query solution stats details. - assertEquals(1L, stats.chunksIn.get()); - assertEquals(1L, stats.unitsIn.get()); - assertEquals(5L, stats.unitsOut.get()); + assertEquals(2L, stats.chunksIn.get()); // since we read on two shards. + assertEquals(1L, stats.unitsIn.get()); // a single empty binding set. + assertEquals(5L, stats.unitsOut.get()); // each of the tuples will be read. assertEquals(2L, stats.chunksOut.get()); // since we read on both shards. } @@ -801,27 +823,23 @@ // verify query solution stats details. assertEquals(2L, stats.chunksIn.get()); // from both shards. - assertEquals(5L, stats.unitsIn.get()); - assertEquals(5L, stats.unitsOut.get()); + assertEquals(2L, stats.unitsIn.get()); + assertEquals(2L, stats.unitsOut.get()); assertEquals(2L, stats.chunksOut.get()); } } /** - * Test the ability run a simple join which is mapped across two index - * partitions. There are three operators. One feeds an empty binding set[] - * into the join, another is the predicate for the access path on which the - * join will read (no variables are bound so it will read everything), and - * the third is the join itself. - * - * @throws Exception + * Test the ability run a simple join reading on a single shard. There are + * three operators. One feeds an empty binding set[] into the join, another + * is the predicate for the access path on which the join will read (it + * probes the index once for "Mary" and binds "Paul" and "John" when it does + * so), and the third is the join itself (there are two solutions, which are + * "value=Paul" and value="John"). */ - public void test_query_join1_2shards_nothingBoundOnAccessPath() throws Exception { + public void test_query_join_1shard() throws Exception { - final Var<?> x = Var.var("x") ; - final Var<?> y = Var.var("y") ; - final int startId = 1; final int joinId = 2; final int predId = 3; @@ -831,11 +849,14 @@ new NV(Predicate.Annotations.BOP_ID, startId),// })); + // Note: tuples with "Mary" in the 1st column are on partition1. final Predicate<E> predOp = new Predicate<E>(new IVariableOrConstant[] { - x, y}, NV + new Constant<String>("Mary"), Var.var("value") }, NV .asMap(new NV[] {// new NV(Predicate.Annotations.RELATION_NAME, new String[] { namespace }),// + new NV(Predicate.Annotations.KEY_ORDER, + R.primaryKeyOrder),// new NV(Predicate.Annotations.PARTITION_ID, Integer .valueOf(-1)),// new NV(Predicate.Annotations.OPTIONAL, Boolean.FALSE),// @@ -844,8 +865,6 @@ new NV(Predicate.Annotations.BOP_ID, predId),// new NV(Predicate.Annotations.TIMESTAMP, ITx.READ_COMMITTED),// - new NV(Predicate.Annotations.KEY_ORDER, - R.primaryKeyOrder),// })); final PipelineJoin<E> joinOp = new PipelineJoin<E>(startOp/* left */, @@ -857,7 +876,7 @@ ); final BindingSetPipelineOp query = new SliceOp(new BOp[] { joinOp }, - // slice annotations + // slice annotations NV.asMap(new NV[] {// new NV(Predicate.Annotations.BOP_ID, sliceId),// })// @@ -865,39 +884,14 @@ // the expected solutions (order is not reliable due to concurrency). final IBindingSet[] expected = new IBindingSet[] {// - new ArrayBindingSet(// - new IVariable[] { x, y },// - new IConstant[] { new Constant<String>("John"), - new Constant<String>("Mary") }// + new ArrayBindingSet(// + new IVariable[] { Var.var("value") },// + new IConstant[] { new Constant<String>("Paul") }// ), // - new ArrayBindingSet(// - new IVariable[] { x, y },// - new IConstant[] { new Constant<String>("John"), - new Constant<String>("Paul") }// - ), // - new ArrayBindingSet(// - new IVariable[] { x, y },// - new IConstant[] { new Constant<String>("Mary"), - new Constant<String>("John") }// - ), // - new ArrayBindingSet(// - new IVariable[] { x, y },// - new IConstant[] { new Constant<String>("Mary"), - new Constant<String>("Paul") }// - ), // - new ArrayBindingSet(// - new IVariable[] { x, y },// - new IConstant[] { new Constant<String>("Paul"), - new Constant<String>("Leon") }// - ), // - }; -// // partition0 -// new E("John", "Mary"),// -// new E("Leon", "Paul"),// -// // partition1 -// new E("Mary", "John"),// -// new E("Mary", "Paul"),// -// new E("Paul", "Leon"),// + new ArrayBindingSet(// + new IVariable[] { Var.var("value") },// + new IConstant[] { new Constant<String>("John") }// + ) }; final UUID queryId = UUID.randomUUID(); final RunningQuery runningQuery = queryEngine.eval(queryId, query, @@ -945,8 +939,8 @@ // verify query solution stats details. assertEquals(1L, stats.chunksIn.get()); assertEquals(1L, stats.unitsIn.get()); - assertEquals(5L, stats.unitsOut.get()); - assertEquals(2L, stats.chunksOut.get()); // since we read on both shards. + assertEquals(2L, stats.unitsOut.get()); + assertEquals(1L, stats.chunksOut.get()); // @todo this depends on which index partitions we read on. } // validate the stats for the slice operator. @@ -957,10 +951,10 @@ log.info("slice: "+stats.toString()); // verify query solution stats details. - assertEquals(2L, stats.chunksIn.get()); // from both shards. - assertEquals(5L, stats.unitsIn.get()); - assertEquals(5L, stats.unitsOut.get()); - assertEquals(2L, stats.chunksOut.get()); + assertEquals(1L, stats.chunksIn.get()); + assertEquals(2L, stats.unitsIn.get()); + assertEquals(2L, stats.unitsOut.get()); + assertEquals(1L, stats.chunksOut.get()); } } @@ -988,26 +982,6 @@ } /** - * @todo Test ability to impose a limit/offset slice on a query. - * <p> - * Note: While the logic for visiting only the solutions selected by - * the slice can be tested against a mock object, the integration by - * which a slice halts a query when it is satisfied has to be tested - * against a {@link QueryEngine}. - * <p> - * This must also be tested in scale-out to make sure that the data - * backing the solutions is not discarded before the caller can use - * those data. [This could be handled by materializing binding set - * objects out of a {@link ByteBuffer} rather than using a live decode - * of the data in that {@link ByteBuffer}.] - */ - public void test_query_slice() { - - fail("write test"); - - } - - /** * @todo Test the ability run a query reading on an access path using a * element filter (other than DISTINCT). */ Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java 2010-09-17 14:54:26 UTC (rev 3582) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java 2010-09-17 15:04:56 UTC (rev 3583) @@ -207,7 +207,7 @@ // new IVariable[] { x, y },// // new IConstant[] { new Constant<String>("Leon"), // new Constant<String>("Paul") }// -// ), +// ),ne }; final SliceStats stats = query.newStats(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-17 14:54:33
|
Revision: 3582 http://bigdata.svn.sourceforge.net/bigdata/?rev=3582&view=rev Author: blevine218 Date: 2010-09-17 14:54:26 +0000 (Fri, 17 Sep 2010) Log Message: ----------- TestJiniCoreServicesProcessHelper now runs after path changes to test config files Added Paths: ----------- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java Copied: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java (from rev 3541, branches/maven_scaleout/bigdata-core/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java) =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/jini/start/TestJiniCoreServicesProcessHelper.java 2010-09-17 14:54:26 UTC (rev 3582) @@ -0,0 +1,186 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Jan 11, 2009 + */ + +package com.bigdata.jini.start; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; + +import com.bigdata.DataFinder; +import net.jini.admin.Administrable; +import net.jini.config.Configuration; +import net.jini.config.ConfigurationProvider; +import net.jini.core.lookup.ServiceItem; +import net.jini.core.lookup.ServiceRegistrar; +import net.jini.core.lookup.ServiceTemplate; +import net.jini.discovery.LookupDiscoveryManager; +import net.jini.lookup.ServiceDiscoveryManager; + +import com.bigdata.jini.start.config.JiniCoreServicesConfiguration; +import com.bigdata.jini.start.config.JiniCoreServicesConfiguration.Options; +import com.bigdata.jini.start.process.JiniCoreServicesProcessHelper; +import com.bigdata.jini.util.ConfigMath; +import com.bigdata.service.jini.JiniClientConfig; +import com.bigdata.service.jini.util.JiniServicesHelper; +import com.bigdata.test.util.Assert; + +/** + * Test suite for the {@link JiniCoreServicesProcessHelper} + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestJiniCoreServicesProcessHelper { + + /** + * + */ + public TestJiniCoreServicesProcessHelper() { + + } + + + /** + * The configuration file used the unit tests. + */ + protected final String configFile = DataFinder.bestURI("testing/data/com/bigdata/jini/start/testjini.config").toASCIIString(); + + /** + * The configuration read from that file with any overrides applied. + */ + protected Configuration config; + + protected final MockListener listener = new MockListener(); + + /** + * Reads the {@link #config} from the {@link #configFile}. + * <p> + * Note: You can specify JINI_HOME in your environment in order to override + * the location where jini is installed on your machine. + */ + @Before + public void setUp() throws Exception { + final String[] args; + + System.out.println("BJL BJL BJL: configFile = " + configFile); + { + final String home = System.getenv("JINI_HOME"); + + if (home == null) { + args = new String[] { configFile }; + } else { + + /* + * Overrides the serviceDir to your jini install location. + */ + + args = new String[] { + configFile, + JiniCoreServicesConfiguration.Options.NAMESPACE + "." + + Options.SERVICE_DIR + "=" + + ConfigMath.q(home) }; + + } + + } + + // read the configuration, applying the override if set above. + config = ConfigurationProvider.getInstance(args); + } + + + /** + * @todo this is not really a unit test yet - more of a tool to helper debug + * the behavior when starting and (trying to) kill the jini core + * services. + * <p> + * The main problem with testability is that I have not figured out + * how to kill jini programmatically. One consequence is that this + * "test" will not terminate if it starts a jini instance until you + * close the jini instance in the gui. + * + * @see JiniCoreServicesProcessHelper#startCoreServices(Configuration, + * IServiceListener) + */ + @Test + public void test_findStartKill() throws Exception { + System.out.println("BJl BJL BJL config = " + config); + final JiniCoreServicesConfiguration serviceConfig = new JiniCoreServicesConfiguration(config); + final JiniClientConfig clientConfig = new JiniClientConfig(null, config); + + // make sure jini is not running before we start this test. + Assert.assertFalse("Jini already running: locators=" + + Arrays.toString(clientConfig.locators), JiniServicesHelper + .isJiniRunning(clientConfig.groups, clientConfig.locators, 500, + TimeUnit.MILLISECONDS)); + + boolean serviceStarted = JiniCoreServicesProcessHelper.startCoreServices(config, listener); + String testName = (this.getClass()).getSimpleName(); + + if(serviceStarted) { + // Find and shutdown lookup service started above + ServiceDiscoveryManager sdm = + new ServiceDiscoveryManager + (new LookupDiscoveryManager(clientConfig.groups, + clientConfig.locators, null), + null); + Class[] types = new Class[] { ServiceRegistrar.class }; + ServiceTemplate tmpl = new ServiceTemplate(null, types, null); + ServiceItem regItem = sdm.lookup(tmpl, null, 5L*1000L); + if(regItem == null) { + System.err.println + ("WARNING ["+testName+"]: lookup service started but " + +"could not discover it for shutdown"); + } else { + ServiceRegistrar reg = (ServiceRegistrar)(regItem.service); + List<String> groupsList = Arrays.asList(reg.getGroups()); + System.err.println + ("INFO ["+testName+"]: lookup service started " + +"[groups="+groupsList+"] - shutting it down"); + Object admin = ((Administrable)reg).getAdmin(); + ((com.sun.jini.admin.DestroyAdmin)admin).destroy(); + System.err.println + ("INFO ["+testName+"]: lookup service started and " + +"destroyed - [groups="+groupsList+"]"); + } + } + + // Shutdown the httpd class server + String httpdStopCmd = + (String)config.getEntry("jini", "httpdStopCmd", String.class, + null /*force exception if not in config*/); + System.err.println + ("INFO ["+testName+"]: shutdown class server ["+httpdStopCmd+"]"); + Runtime.getRuntime().exec(httpdStopCmd); + + Assert.assertTrue(serviceStarted); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-17 14:44:31
|
Revision: 3581 http://bigdata.svn.sourceforge.net/bigdata/?rev=3581&view=rev Author: blevine218 Date: 2010-09-17 14:44:23 +0000 (Fri, 17 Sep 2010) Log Message: ----------- changes paths in certain config files Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/main/deploy/var/config/deploy/default-deploy.properties branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/service/jini/util/LookupStarter.java branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/util/config/ConfigDeployUtil.java branches/maven_scaleout/bigdata-core/src/test/deploy/testing/conf/bigdataStandaloneTesting.config branches/maven_scaleout/bigdata-core/src/test/deploy/testing/test.xml Property Changed: ---------------- branches/maven_scaleout/bigdata-core/ Property changes on: branches/maven_scaleout/bigdata-core ___________________________________________________________________ Added: svn:ignore + target .settings .classpath .project Modified: branches/maven_scaleout/bigdata-core/src/main/deploy/var/config/deploy/default-deploy.properties =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/deploy/var/config/deploy/default-deploy.properties 2010-09-17 14:39:31 UTC (rev 3580) +++ branches/maven_scaleout/bigdata-core/src/main/deploy/var/config/deploy/default-deploy.properties 2010-09-17 14:44:23 UTC (rev 3581) @@ -8,7 +8,7 @@ # Federation properties federation.name.description=Name of the federation to discover -federation.name.default=@FED@ +federation.name.default= federation.name.type=string federation.minNodes.description=Minimum number of nodes in the federation Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/service/jini/util/LookupStarter.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/service/jini/util/LookupStarter.java 2010-09-17 14:39:31 UTC (rev 3580) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/service/jini/util/LookupStarter.java 2010-09-17 14:44:23 UTC (rev 3581) @@ -25,6 +25,7 @@ package com.bigdata.service.jini.util; +import com.bigdata.util.config.ConfigDeployUtil; import com.bigdata.util.config.ConfigurationUtil; import com.bigdata.util.config.LogUtil; import com.bigdata.util.config.NicUtil; @@ -75,10 +76,10 @@ private static String defaultGroup = null; static { try { - thisHost = NicUtil.getIpAddress("default.nic", "default", true); - defaultGroup = - System.getProperty("federation.name", - "bigdata.test.group-"+thisHost); + thisHost = NicUtil.getIpAddress("default.nic", "default", false); + //defaultGroup = System.getProperty("federation.name","bigdata.test.group-"+thisHost); + defaultGroup = ConfigDeployUtil.getFederationName(); + } catch (Throwable t) { /* swallow */ } } private static String defaultCodebasePort = "23333"; Modified: branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/util/config/ConfigDeployUtil.java =================================================================== --- branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/util/config/ConfigDeployUtil.java 2010-09-17 14:39:31 UTC (rev 3580) +++ branches/maven_scaleout/bigdata-core/src/main/java/com/bigdata/util/config/ConfigDeployUtil.java 2010-09-17 14:44:23 UTC (rev 3581) @@ -55,6 +55,9 @@ private static final String MIN = ".min"; private static final String DESCRIPTION = ".description"; private static final String TYPE = ".type"; + + private static final String FALLBACK_FEDNAME_FORMAT = "bigdata.test.group-%s"; + private static final String TEMPLATE_TOKEN_PATTERN = "@.*@"; public static String getString(String parameter) throws ConfigurationException @@ -156,12 +159,49 @@ */ public static String[] getGroupsToDiscover() throws ConfigurationException { - String fedNameStr = System.getProperty("federation.name"); - if(fedNameStr == null) { - fedNameStr = getString("federation.name"); - } + String fedNameStr = getFederationName(); return fedNameStr.split(","); } + + /** + * Retrieve the federation name (also used as Jini group name) via this pecking pecking order: + * <ol> + * <li>From the Java system property: <code>federation.name</code></li> + * <li>From the deployment properties file. Note that a value from the deployment + * properties file that has not gone through token replacement is considered + * invalid. In this case, the next value in the pecking order is used.</li> + * <li>Using the fallback convention: <code>bigdata.test.group-<ipaddress></code></li> + * </ol> + * + * @return String the federation name + * + * @throws ConfigurationException + */ + public static String getFederationName() throws ConfigurationException + { + // If we have a system property override, use that. + String fedName = System.getProperty("federation.name"); + + // If not, look in the deploy properties + if(fedName == null) { + fedName = getString("federation.name"); + } + + // If not set in the deploy properties, then use the fallback name of + // "bigdata.test.group-<ipaddress>". This is primarily to support test + // environments and we should never get this far in production. + if (fedName == null || fedName.length() == 0) { + try { + String ipAddress = NicUtil.getIpAddress("default.nic", "default", true); + fedName = String.format(FALLBACK_FEDNAME_FORMAT, ipAddress); + } + catch (Exception e) { + throw new ConfigurationException("Error retrieving IP address while constructing fallback federation name.", e); + } + } + + return fedName; + } /** * Returns an array of <code>LookupLocator</code> instances that can Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/conf/bigdataStandaloneTesting.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/conf/bigdataStandaloneTesting.config 2010-09-17 14:39:31 UTC (rev 3580) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/conf/bigdataStandaloneTesting.config 2010-09-17 14:44:23 UTC (rev 3581) @@ -77,7 +77,8 @@ * MUST use unicast discovery and specify the federation name in * the [groups]. */ - static fedname = System.getProperty("federation.name","testBigdataStandalone"); + //static fedname = System.getProperty("federation.name","testBigdataStandalone"); + static fedname = ConfigDeployUtil.getFederationName(); static zrootname = System.getProperty("bigdata.zrootname","testBigdataStandaloneZroot"); private static appHome = System.getProperty("app.home", ConfigMath.getAbsolutePath(new File(".")) ); Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/test.xml =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/test.xml 2010-09-17 14:39:31 UTC (rev 3580) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/test.xml 2010-09-17 14:44:23 UTC (rev 3581) @@ -32,7 +32,7 @@ <target name="setup" > <exec executable="hostname" outputproperty="this.hostname" /> <property name="test.codebase" value="http://${this.hostname}:${test.codebase.port}/jsk-dl.jar" /> - <property name="federation.name" value="bigdata.test.group-${this.hostname}" /> + <!-- <property name="federation.name" value="bigdata.test.group-${this.hostname}" /> --> </target> <target name="junit" description="starts http class server, lookup service, runs junit tests, stops lookup service, stops http class server." @@ -100,7 +100,9 @@ <sysproperty key="log4j.configuration" value="${log4j.configuration}" /> <sysproperty key="codebase.port" value="${test.codebase.port}" /> <sysproperty key="java.net.preferIPv4Stack" value="${java.net.preferIPv4Stack}" /> + <!-- <sysproperty key="federation.name" value="${federation.name}" /> + --> <sysproperty key="default.nic" value="${default.nic}" /> </java> </target> @@ -120,7 +122,9 @@ <sysproperty key="java.security.policy" value="${java.security.policy}" /> <sysproperty key="log4j.configuration" value="${log4j.configuration}" /> <sysproperty key="java.net.preferIPv4Stack" value="${java.net.preferIPv4Stack}" /> + <!-- <sysproperty key="federation.name" value="${federation.name}" /> + --> <sysproperty key="default.nic" value="${default.nic}" /> <arg value="-stop" /> </java> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-17 14:39:38
|
Revision: 3580 http://bigdata.svn.sourceforge.net/bigdata/?rev=3580&view=rev Author: blevine218 Date: 2010-09-17 14:39:31 +0000 (Fri, 17 Sep 2010) Log Message: ----------- fixed some paths Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testStartJini.config branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testStartJini.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testStartJini.config 2010-09-17 14:27:23 UTC (rev 3579) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testStartJini.config 2010-09-17 14:39:31 UTC (rev 3580) @@ -18,7 +18,7 @@ NicUtil.getIpAddress("default.nic", "default", true); private static codebasePort = "23334"; private static defaultCodebaseRootDir = - ConfigUtil.concat( new String[] { appHome, "${/}bigdata-jini${/}lib${/}jini${/}lib-dl" } ); + ConfigUtil.concat( new String[] { appHome, "${/}lib-dl" } ); private static codebaseRootDir = System.getProperty("bigdata.codebase.rootDir", defaultCodebaseRootDir); private static jskCodebase = @@ -28,13 +28,13 @@ codebaseRootDir, "none" ); private static servicePolicyFile = - ConfigUtil.concat( new String[] { appHome, "${/}src${/}resources${/}config${/}policy.all" } ); + ConfigUtil.concat( new String[] { appHome, "${/}testing${/}conf${/}policy.all" } ); // For starting HTTP codebase class server private static httpdCodebase = ""; private static httpdPolicyFile = servicePolicyFile; private static httpdClasspath = - ConfigUtil.concat( new String[] { appHome, "${/}bigdata-jini${/}lib${/}jini${/}lib${/}classserver.jar" } ); + ConfigUtil.concat( new String[] { appHome, "${/}lib${/}classserver.jar" } ); private static httpdImplName = "com.sun.jini.tool.ClassServer"; private static httpdArgsArray = new String[] { "-port", codebasePort, @@ -56,11 +56,11 @@ ConfigUtil.concat( new String[] { reggieServerCodebase, " ", jskCodebase } ); private static reggieClasspath = - ConfigUtil.concat( new String[] { appHome, "${/}bigdata-jini${/}lib${/}jini${/}lib${/}reggie.jar" } ); + ConfigUtil.concat( new String[] { appHome, "${/}lib${/}reggie.jar" } ); private static reggieImplName = "com.sun.jini.reggie.TransientRegistrarImpl"; private static reggieConfig = - ConfigUtil.concat( new String[] { appHome, "${/}bigdata-jini${/}src${/}test${/}com${/}bigdata${/}jini${/}start${/}testReggie.config" } ); + ConfigUtil.concat( new String[] { appHome, "${/}testing${/}data${/}com${/}bigdata${/}jini${/}start${/}testReggie.config" } ); private static reggieArgs = "com.sun.jini.reggie.initialLookupLocators=new LookupLocator[]{}"; Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config 2010-09-17 14:27:23 UTC (rev 3579) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testfed.config 2010-09-17 14:39:31 UTC (rev 3580) @@ -100,7 +100,7 @@ "-server", "-ea", "-Dcom.sun.jini.jeri.tcp.useNIO=true", - "-Djava.security.policy="+ConfigMath.getAbsolutePath(new File("policy.all")) + "-Djava.security.policy="+ConfigUtil.concat( new String[] { appHome, "${/}testing${/}conf${/}policy.all" } ) }; // Optional classpath components. @@ -205,13 +205,13 @@ private static appDotHome = System.getProperty("app.home", ConfigMath.getAbsolutePath(new File(".")) ); private static policyFile = - ConfigUtil.concat( new String[] { appDotHome, "${/}dist${/}bigdata${/}var${/}config${/}policy${/}policy.all" } ); + ConfigUtil.concat( new String[] { appDotHome, "{/}testing${/}conf${/}policy.all" } ); private static configFile = - ConfigUtil.concat( new String[] { appDotHome, "${/}dist${/}bigdata${/}var${/}config${/}jini${/}transaction.config" } ); + ConfigUtil.concat( new String[] { appDotHome, "${/}var${/}config${/}jini${/}transaction.config" } ); private static logFile = - ConfigUtil.concat( new String[] { appDotHome, "${/}dist${/}bigdata${/}var${/}config${/}logging${/}transaction-logging.properties" } ); + ConfigUtil.concat( new String[] { appDotHome, "${/}var${/}config${/}logging${/}transaction-logging.properties" } ); private static logDir = - ConfigUtil.concat( new String[] { appDotHome, "${/}dist${/}bigdata${/}var${/}log" } ); + ConfigUtil.concat( new String[] { appDotHome, "${/}var${/}log" } ); //overrides for the entries in the config file specified //below in the args entry; which will be added (as part @@ -249,7 +249,8 @@ //rather than /opt/bigdata/var/config/deploy, <appHome>/var/config/deploy, //or (if none of the above exist), <user.dir>/src/java/com/bigdata/util/config - args = new String[]{ + args = + new String[]{ "-Xmx1G", "-Djava.security.manager=", "-Dlog4j.configuration="+logFile, @@ -260,4 +261,6 @@ "-Dconfig="+configFile, "-DusingServiceConfiguration=true" }; + + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ble...@us...> - 2010-09-17 14:27:30
|
Revision: 3579 http://bigdata.svn.sourceforge.net/bigdata/?rev=3579&view=rev Author: blevine218 Date: 2010-09-17 14:27:23 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Fix paths in certain test config files Modified Paths: -------------- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testjini.config Modified: branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testjini.config =================================================================== --- branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testjini.config 2010-09-17 11:22:28 UTC (rev 3578) +++ branches/maven_scaleout/bigdata-core/src/test/deploy/testing/data/com/bigdata/jini/start/testjini.config 2010-09-17 14:27:23 UTC (rev 3579) @@ -51,9 +51,10 @@ */ serviceCount = 1; - private static configFilename = - ConfigUtil.concat( new String[] { bigdata.appHome, - "${/}bigdata-jini${/}src${/}test${/}com${/}bigdata${/}jini${/}start${/}testStartJini.config" } ); + //private static configFilename = testing/data/ + // ConfigUtil.concat( new String[] { bigdata.appHome, + // "${/}bigdata-jini${/}src${/}test${/}com${/}bigdata${/}jini${/}start${/}testStartJini.config" } ); + private static configFilename = DataFinder.bestPath("testing/data/com/bigdata/jini/start/testStartJini.config"); configFile = new File(configFilename); @@ -79,22 +80,22 @@ private static classpathArr = new String[] { ConfigUtil.concat( new String[] { bigdata.appHome, "${/}bin", ":", - bigdata.appHome, "${/}bigdata-test${/}lib${/}bigdata-core.jar", ":", - bigdata.appHome, "${/}bigdata-jini${/}lib${/}jini${/}lib${/}start.jar", ":", - bigdata.appHome, "${/}bigdata-jini${/}lib${/}jini${/}lib${/}jsk-lib.jar", ":", + bigdata.appHome, "${/}lib${/}bigdata-core.jar", ":", + bigdata.appHome, "${/}lib${/}start.jar", ":", + bigdata.appHome, "${/}lib${/}jsk-lib.jar", ":", log4jJar } ) }; private static arg0 = ServiceConfiguration.concat(cpArr, classpathArr); private static policyProp = - ConfigUtil.concat( new String[] { "-Djava.security.policy=", bigdata.appHome, "${/}src${/}resources${/}config${/}policy.all" } ); + ConfigUtil.concat( new String[] { "-Djava.security.policy=", bigdata.appHome, "${/}testing${/}conf${/}policy.all" } ); private static policyArg = new String[] {policyProp}; private static arg1 = ServiceConfiguration.concat(arg0, policyArg); private static log4jProp = ConfigUtil.concat( new String[] { "-Dlog4j.configuration=", bigdata.appHome, - "${/}src${/}resources${/}config${/}standalone${/}log4j.properties" } ); + "${/}var${/}config${/}logging${/}log4j.properties" } ); private static log4jArg = new String[] {log4jProp}; private static arg2 = ServiceConfiguration.concat(arg1, log4jArg); @@ -105,7 +106,7 @@ private static javaHome = System.getProperty("java.home"); private static javaCmd = ConfigUtil.concat( new String[] { javaHome, "${/}", "bin", "${/}", "java" } ); private static classserverJar = - ConfigUtil.concat( new String[] { bigdata.appHome, "${/}bigdata-jini${/}lib${/}jini${/}lib${/}classserver.jar" } ); + ConfigUtil.concat( new String[] { bigdata.appHome, "{/}lib${/}classserver.jar" } ); httpdStopCmd = ConfigUtil.concat( new String[] { javaCmd, " ", "-jar", " ", classserverJar, " ", "-port", " ", httpdPort, " ", "-stop" } ); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dm...@us...> - 2010-09-17 11:22:36
|
Revision: 3578 http://bigdata.svn.sourceforge.net/bigdata/?rev=3578&view=rev Author: dmacgbr Date: 2010-09-17 11:22:28 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Add some unit tests Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ArrayBindingSet.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/HashBindingSet.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/MemorySortOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestMemorySortOp.java Added Paths: ----------- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestArrayBindingSet.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestHashBindingSet.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestIBindingSet.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ArrayBindingSet.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ArrayBindingSet.java 2010-09-17 10:44:01 UTC (rev 3577) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ArrayBindingSet.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -435,10 +435,8 @@ for(int i=0; i<nbound; i++) { -// if (!o.isBound(vars[i])) -// return false; - - if (!vals[i].equals(o.get(vars[i]))) + IConstant<?> o_val = o.get ( vars [ i ] ) ; + if ( null == o_val || !vals[i].equals( o_val )) return false; } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/HashBindingSet.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/HashBindingSet.java 2010-09-17 10:44:01 UTC (rev 3577) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/HashBindingSet.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -283,8 +283,8 @@ // if (!o.isBound(vars[i])) // return false; - - if (!val.equals(o.get(var))) + IConstant<?> o_val = o.get ( var ) ; + if (null == o_val || !val.equals(o_val)) return false; } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/MemorySortOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/MemorySortOp.java 2010-09-17 10:44:01 UTC (rev 3577) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/MemorySortOp.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -88,10 +88,6 @@ // sort. Arrays.sort(all, comparator); - // update counters. - stats.unitsOut.add(all.length); - stats.chunksOut.increment(); - // write output and flush. sink.add(all); sink.flush(); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java 2010-09-17 10:44:01 UTC (rev 3577) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestAll.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -65,7 +65,8 @@ suite.addTestSuite(TestConstant.class); // test binding set impls. - suite.addTestSuite(TestBindingSet.class); + suite.addTestSuite(TestArrayBindingSet.class); + suite.addTestSuite(TestHashBindingSet.class); // unit tests for ctor existence and deep copy semantics suite.addTestSuite(TestDeepCopy.class); Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestArrayBindingSet.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestArrayBindingSet.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestArrayBindingSet.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -0,0 +1,110 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +/* + * Created on Jun 19, 2008 + */ + +package com.bigdata.bop; + + +/** + * Unit tests for {@link ArrayBindingSet}. + * + * Note: + * a) these tests assume that the values held for a given key are not cloned, + * i.e. comparison is done by '==' and not '.equals' + * b) keys with the same 'name' are a unique object. + * + * @author <a href="mailto:dm...@us...">David MacMillan</a> + * @version $Id$ + */ +public class TestArrayBindingSet extends TestIBindingSet +{ + /** + * + */ + public TestArrayBindingSet () {} + + /** + * @param name + */ + public TestArrayBindingSet ( String name ) { super ( name ) ; } + + /** + * Unit test for {@link ArrayBindingSet#ArrayBindingSet(ArrayBindingSet)} + */ + public void testConstructorArrayBindingSet () + { + try { assertTrue ( null != new ArrayBindingSet ( null ) ) ; fail ( "IllegalArgumentException expected, copy from was null" ) ; } + catch ( IllegalArgumentException e ) {} + + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + IVariable<?> vars [] = new IVariable [] { var1, var2 } ; + IConstant<?> vals [] = new IConstant [] { val1, val2 } ; + + assertEqual ( new ArrayBindingSet ( new ArrayBindingSet ( vars, vals ) ), vars, vals ) ; + } + + /** + * Unit test for {@link ArrayBindingSet#ArrayBindingSet(IVariable[],IConstant[])} + */ + public void testConstructorVariablesConstants () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + IVariable<?> vars [] = new IVariable [] { var1, var2 } ; + IConstant<?> vals [] = new IConstant [] { val1, val2 } ; + + try { assertTrue ( null != new ArrayBindingSet ( null, vals ) ) ; fail ( "IllegalArgumentException expected, vars was null" ) ; } + catch ( IllegalArgumentException e ) {} + + try { assertTrue ( null != new ArrayBindingSet ( vars, null ) ) ; fail ( "IllegalArgumentException expected, vals was null" ) ; } + catch ( IllegalArgumentException e ) {} + + try { assertTrue ( null != new ArrayBindingSet ( vars, new IConstant [] { val1 } ) ) ; fail ( "IllegalArgumentException expected, vars and vals were different sizes" ) ; } + catch ( IllegalArgumentException e ) {} + + assertEqual ( new ArrayBindingSet ( vars, vals ), vars, vals ) ; + } + + /** + * Unit test for {@link ArrayBindingSet#ArrayBindingSet(int)} + */ + public void testConstructorInt () + { + try { assertTrue ( null != new ArrayBindingSet ( -1 ) ) ; fail ( "IllegalArgumentException expected, capacity was negative" ) ; } + catch ( IllegalArgumentException e ) {} + + assertEqual ( new ArrayBindingSet ( 2 ), new IVariable [] {}, new IConstant [] {} ) ; + } + + @Override protected IBindingSet newBindingSet ( IVariable<?> vars [], IConstant<?> vals [] ) { return new ArrayBindingSet ( vars, vals ) ; } + @Override protected IBindingSet newBindingSet ( int size ) { return new ArrayBindingSet ( size ) ; } +} \ No newline at end of file Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestHashBindingSet.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestHashBindingSet.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestHashBindingSet.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -0,0 +1,128 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +/* + * Created on Jun 19, 2008 + */ + +package com.bigdata.bop; + + +/** + * Unit tests for {@link HashBindingSet}. + * + * Note: + * a) these tests assume that the values held for a given key are not cloned, + * i.e. comparison is done by '==' and not '.equals' + * b) keys with the same 'name' are a unique object. + * + * @author <a href="mailto:dm...@us...">David MacMillan</a> + * @version $Id$ + */ +public class TestHashBindingSet extends TestIBindingSet +{ + + /** + * + */ + public TestHashBindingSet () {} + + /** + * @param name + */ + public TestHashBindingSet ( String name ) { super ( name ) ; } + + /** + * Unit test for {@link HashBindingSet#HashBindingSet()} + */ + public void testConstructorHashBindingSet () + { + assertTrue ( null != new HashBindingSet () ) ; + } + + /** + * Unit test for {@link HashBindingSet#HashBindingSet(HashBindingSet)} + */ + public void testConstructorHashBindingSetHashBindingSet () + { + // TODO what is our philosophy on argument validation? +// try { assertTrue ( null != new HashBindingSet ( null ) ) ; fail ( "IllegalArgumentException expected, copy from was null" ) ; } +// catch ( IllegalArgumentException e ) {} + + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + IVariable<?> vars [] = new IVariable [] { var1, var2 } ; + IConstant<?> vals [] = new IConstant [] { val1, val2 } ; + + assertEqual ( new HashBindingSet ( new HashBindingSet ( vars, vals ) ), vars, vals ) ; + } + + /** + * Unit test for {@link HashBindingSet#HashBindingSet(IBindingSet)} + */ + public void testConstructorHashBindingSetIBindingSet () + { + // TODO what is our philosophy on argument validation? +// try { assertTrue ( null != new HashBindingSet ( null ) ) ; fail ( "IllegalArgumentException expected, copy from was null" ) ; } +// catch ( IllegalArgumentException e ) {} + + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + IVariable<?> vars [] = new IVariable [] { var1, var2 } ; + IConstant<?> vals [] = new IConstant [] { val1, val2 } ; + + assertEqual ( new HashBindingSet ( new ArrayBindingSet ( vars, vals ) ), vars, vals ) ; + } + + /** + * Unit test for {@link HashBindingSet#HashBindingSet(IVariable[],IConstant[])} + */ + public void testConstructorVariablesConstants () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + IVariable<?> vars [] = new IVariable [] { var1, var2 } ; + IConstant<?> vals [] = new IConstant [] { val1, val2 } ; + + try { assertTrue ( null != new HashBindingSet ( null, vals ) ) ; fail ( "IllegalArgumentException expected, vars was null" ) ; } + catch ( IllegalArgumentException e ) {} + + try { assertTrue ( null != new HashBindingSet ( vars, null ) ) ; fail ( "IllegalArgumentException expected, vals was null" ) ; } + catch ( IllegalArgumentException e ) {} + + try { assertTrue ( null != new HashBindingSet ( vars, new IConstant [] { val1 } ) ) ; fail ( "IllegalArgumentException expected, vars and vals were different sizes" ) ; } + catch ( IllegalArgumentException e ) {} + + assertEqual ( new HashBindingSet ( vars, vals ), vars, vals ) ; + } + + @Override protected IBindingSet newBindingSet ( IVariable<?> vars [], IConstant<?> vals [] ) { return new HashBindingSet ( vars, vals ) ; } + @Override protected IBindingSet newBindingSet ( int size ) { return new HashBindingSet () ; } +} \ No newline at end of file Added: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestIBindingSet.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestIBindingSet.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/TestIBindingSet.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -0,0 +1,327 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +/* + * Created on Jun 19, 2008 + */ + +package com.bigdata.bop; + +import java.util.Iterator; +import java.util.Map; + +import junit.framework.TestCase2; + +/** + * Unit tests for {@link IBindingSet}. + * + * Note: + * a) these tests assume that the values held for a given key are not cloned, + * i.e. comparison is done by '==' and not '.equals' + * b) keys with the same 'name' are a unique object. + * + * @author <a href="mailto:dm...@us...">David MacMillan</a> + * @version $Id$ + */ +public abstract class TestIBindingSet extends TestCase2 { + + /** + * + */ + public TestIBindingSet () {} + + /** + * @param name + */ + public TestIBindingSet ( String name ) { super ( name ) ; } + + /** + * Unit test for {@link IBindingSet#isBound(IVariable)} + */ + public void testIsBound () + { + Var<?> a = Var.var ( "a" ) ; + Var<?> b = Var.var ( "b" ) ; + Var<?> c = Var.var ( "a" ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { a }, new IConstant [] { new Constant<Integer> ( 1 ) } ) ; + + assertTrue ( "bound expected, same variable", bs.isBound ( a ) ) ; + assertFalse ( "not bound expected", bs.isBound ( b ) ) ; + assertTrue ( "bound expected, equivalent variable", bs.isBound ( c ) ) ; + } + + /** + * Unit test for {@link IBindingSet#set(IVariable,IConstant)} + */ + public void testSet () + { + Var<?> var = Var.var ( "a" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs = newBindingSet ( 2 ) ; + + try { bs.set ( null, val1 ) ; fail ( "IllegalArgumentException expected, var was null" ) ; } + catch ( IllegalArgumentException e ) {} + + try { bs.set ( var, null ) ; fail ( "IllegalArgumentException expected, val was null" ) ; } + catch ( IllegalArgumentException e ) {} + + bs.set ( var, val1 ) ; + assertTrue ( val1 == bs.get ( var ) ) ; + + bs.set ( var, val2 ) ; + assertTrue ( val2 == bs.get ( var ) ) ; + } + + /** + * Unit test for {@link IBindingSet#get(IVariable)} + */ + public void testGet () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { var1 }, new IConstant [] { val1 } ) ; + + try { bs.get ( null ) ; fail ( "IllegalArgumentException expected, var was null" ) ; } + catch ( IllegalArgumentException e ) {} + + assertTrue ( val1 == bs.get ( var1 ) ) ; + assertTrue ( null == bs.get ( var2 ) ) ; + } + + /** + * Unit test for {@link IBindingSet#clear(IVariable)} + */ + public void testClear () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + + try { bs.clear ( null ) ; fail ( "IllegalArgumentException expected, var was null" ) ; } + catch ( IllegalArgumentException e ) {} + + bs.clear ( var1 ) ; + assertTrue ( null == bs.get ( var1 ) ) ; + assertTrue ( val2 == bs.get ( var2 ) ) ; + + bs.clear ( var2 ) ; + assertTrue ( null == bs.get ( var2 ) ) ; + assertTrue ( 0 == bs.size () ) ; + } + + /** + * Unit test for {@link IBindingSet#clearAll()} + */ + public void testClearAll () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + + bs.clearAll () ; + assertTrue ( null == bs.get ( var1 ) ) ; + assertTrue ( null == bs.get ( var2 ) ) ; + assertTrue ( 0 == bs.size () ) ; + } + + /** + * Unit test for {@link IBindingSet#size()} + */ + public void testSize () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs = newBindingSet ( 2 ) ; + + assertTrue ( 0 == bs.size () ) ; + + bs.set ( var1, val1 ) ; + bs.set ( var2, val2 ) ; + assertTrue ( 2 == bs.size () ) ; + + bs.clear ( var2 ) ; + assertTrue ( 1 == bs.size () ) ; + } + + /** + * Unit test for {@link IBindingSet#iterator()} + */ + public void testIterator () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + + int n = 0 ; + for ( Iterator<Map.Entry<IVariable,IConstant>> i = bs.iterator (); i.hasNext (); ) + { + Map.Entry<IVariable,IConstant> e = i.next () ; + IVariable<?> var = e.getKey () ; + + if ( var1 == var ) assertTrue ( "wrong value", val1 == e.getValue () ) ; + else if ( var2 == var ) assertTrue ( "wrong value", val2 == e.getValue () ) ; + else fail ( "unexpected variable: " + var ) ; + + try { i.remove () ; fail ( "UnsupportedOperationException expected, iterator remove" ) ; } + catch ( UnsupportedOperationException ex ) {} + n++ ; + } + assertTrue ( "wrong count", 2 == n ) ; + } + + /** + * Unit test for {@link IBindingSet#vars()} + */ + public void testVars () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + + int n = 0 ; + for ( Iterator<IVariable> i = bs.vars (); i.hasNext (); ) + { + IVariable<?> var = i.next () ; + + if ( var1 != var && var2 != var ) + fail ( "unexpected variable: " + var ) ; + + try { i.remove () ; fail ( "UnsupportedOperationException expected, iterator remove" ) ; } + catch ( UnsupportedOperationException e ) {} + n++ ; + } + assertTrue ( "wrong count", 2 == n ) ; + } + + /** + * Unit test for {@link IBindingSet#copy(IVariable[])} + */ + public void testCopy () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Var<?> var3 = Var.var ( "c" ) ; + Var<?> var4 = Var.var ( "d" ) ; + Var<?> var5 = Var.var ( "e" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + Constant<Integer> val3 = new Constant<Integer> ( 3 ) ; + Constant<Integer> val4 = new Constant<Integer> ( 4 ) ; + Constant<Integer> val5 = new Constant<Integer> ( 5 ) ; + + IBindingSet bs = newBindingSet ( new IVariable [] { var1, var2, var3, var4, var5 } + , new IConstant [] { val1, val2, val3, val4, val5 } + ) ; + + IBindingSet bs2 = bs.copy ( new IVariable [] { var1, var3, var5 } ) ; + + assertTrue ( 3 == bs2.size () ) ; + for ( IVariable<?> v : new IVariable [] { var1, var3, var5 } ) + assertTrue ( bs2.get ( v ).equals ( bs.get ( v ) ) ) ; + } + + /** + * Unit test for {@link IBindingSet#equals(Object)} + */ + public void testEquals () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Var<?> var3 = Var.var ( "c" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + Constant<Integer> val3 = new Constant<Integer> ( 3 ) ; + + IBindingSet bs1 = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + IBindingSet bs2 = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + IBindingSet bs3 = newBindingSet ( new IVariable [] { var2, var1 }, new IConstant [] { val2, val1 } ) ; + IBindingSet bs4 = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val3 } ) ; + IBindingSet bs5 = newBindingSet ( new IVariable [] { var1, var3 }, new IConstant [] { val1, val3 } ) ; + IBindingSet bs6 = newBindingSet ( new IVariable [] { var1, var2, var3 }, new IConstant [] { val1, val2, val3 } ) ; + IBindingSet bs7 = newBindingSet ( new IVariable [] { var1 }, new IConstant [] { val1 } ) ; + + assertTrue ( "expected equal: same bindings, same order", bs1.equals ( bs2 ) ) ; + assertTrue ( "expected equal: same bindings, different order", bs1.equals ( bs3 ) ) ; + assertTrue ( "expected not equal: different value", !bs1.equals ( bs4 ) ) ; + assertTrue ( "expected not equal: different variable", !bs1.equals ( bs5 ) ) ; + assertTrue ( "expected not equal: subsetOf ( this, that )", !bs1.equals ( bs6 ) ) ; + assertTrue ( "expected not equal: subsetOf ( that, this )", !bs1.equals ( bs7 ) ) ; + } + + /** + * Unit test for {@link IBindingSet#hashCode()} + */ + public void testHashCode () + { + Var<?> var1 = Var.var ( "a" ) ; + Var<?> var2 = Var.var ( "b" ) ; + Constant<Integer> val1 = new Constant<Integer> ( 1 ) ; + Constant<Integer> val2 = new Constant<Integer> ( 2 ) ; + + IBindingSet bs1 = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + IBindingSet bs2 = newBindingSet ( new IVariable [] { var1, var2 }, new IConstant [] { val1, val2 } ) ; + IBindingSet bs3 = newBindingSet ( new IVariable [] { var2, var1 }, new IConstant [] { val2, val1 } ) ; + IBindingSet bs4 = newBindingSet ( new IVariable [] { var2 }, new IConstant [] { val2 } ) ; + + assertTrue ( "expected equal: same bindings, same order", bs1.hashCode () == bs2.hashCode () ) ; + assertTrue ( "expected equal: same bindings, different order", bs1.hashCode () == bs3.hashCode () ) ; + + // + // After mutation. Not sure that this really proves anything, although in most cases I guess that + // the original value of bs1.hasCode () will not equal the subsequent value or that of bs4.hashCode () + // + bs1.clear ( var1 ) ; + assertTrue ( "expected equal: same bindings after mutation", bs1.hashCode () == bs4.hashCode () ) ; + } + + protected abstract IBindingSet newBindingSet ( IVariable<?> vars [], IConstant<?> vals [] ) ; + protected abstract IBindingSet newBindingSet ( int size ) ; + + protected void assertEqual ( IBindingSet actual, IVariable<?> vars [], IConstant<?> vals [] ) + { + assertTrue ( "wrong size", actual.size () == vars.length ) ; + for ( int i = 0; i < vars.length; i++ ) + assertTrue ( "wrong value", vals [ i ] == actual.get ( vars [ i ] ) ) ; + } +} \ No newline at end of file Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestMemorySortOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestMemorySortOp.java 2010-09-17 10:44:01 UTC (rev 3577) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestMemorySortOp.java 2010-09-17 11:22:28 UTC (rev 3578) @@ -27,11 +27,24 @@ package com.bigdata.bop.solutions; -import com.bigdata.bop.solutions.ISortOrder; -import com.bigdata.bop.solutions.MemorySortOp; - import junit.framework.TestCase2; +import com.bigdata.bop.ArrayBindingSet; +import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpContext; +import com.bigdata.bop.Constant; +import com.bigdata.bop.IBindingSet; +import com.bigdata.bop.IConstant; +import com.bigdata.bop.IVariable; +import com.bigdata.bop.NV; +import com.bigdata.bop.Var; +import com.bigdata.bop.engine.BOpStats; +import com.bigdata.bop.engine.MockRunningQuery; +import com.bigdata.bop.engine.TestQueryEngine; +import com.bigdata.relation.accesspath.IAsynchronousIterator; +import com.bigdata.relation.accesspath.IBlockingBuffer; +import com.bigdata.relation.accesspath.ThickAsynchronousIterator; + /** * Unit tests for the {@link MemorySortOp}. * @@ -43,26 +56,137 @@ /** * */ - public TestMemorySortOp() { - } + public TestMemorySortOp () {} /** * @param name */ - public TestMemorySortOp(String name) { - super(name); + public TestMemorySortOp ( String name ) + { + super ( name ) ; } - /** - * @todo unit tests for the in-memory sort operator. These tests should not - * focus on SPARQL semantics. Instead, just test the ability to impose - * the appropriate {@link ISortOrder}[] on some in-memory binding - * sets. - */ - public void test_something() { + public void testEval () + { + IVariable<?> x = Var.var ( "x" ) ; + IVariable<?> y = Var.var ( "y" ) ; + IConstant<String> a = new Constant<String> ( "a" ) ; + IConstant<String> b = new Constant<String> ( "b" ) ; + IConstant<String> c = new Constant<String> ( "c" ) ; + IConstant<String> d = new Constant<String> ( "d" ) ; + IConstant<String> e = new Constant<String> ( "e" ) ; - fail("write tests"); + ISortOrder<?> sors [] = new ISortOrder [] { new SortOrder ( x, true ), new SortOrder ( y, false ) } ; + + SortOp query = new MemorySortOp ( new BOp [] {} + , NV.asMap ( new NV [] { new NV ( MemorySortOp.Annotations.BOP_ID, 1 ) + , new NV ( MemorySortOp.Annotations.COMPARATOR, new StringComparatorOp ( sors ) ) + } + ) + ) ; + + // + // the test data + // + IBindingSet data [] = new IBindingSet [] + { + new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { a, a } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { a, e } ) + , new ArrayBindingSet ( new IVariable<?> [] { x }, new IConstant [] { c } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { d, a } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { d, b } ) + , new ArrayBindingSet ( new IVariable<?> [] {}, new IConstant [] {} ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { a, c } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { b, d } ) + , new ArrayBindingSet ( new IVariable<?> [] { y }, new IConstant [] { a } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { b, b } ) + } ; + + // + // the expected solutions + // + IBindingSet expected [] = new IBindingSet [] + { + new ArrayBindingSet ( new IVariable<?> [] { y }, new IConstant [] { a } ) + , new ArrayBindingSet ( new IVariable<?> [] {}, new IConstant [] {} ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { a, e } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { a, c } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { a, a } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { b, d } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { b, b } ) + , new ArrayBindingSet ( new IVariable<?> [] { x }, new IConstant [] { c } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { d, b } ) + , new ArrayBindingSet ( new IVariable<?> [] { x, y }, new IConstant [] { d, a } ) + } ; + + BOpStats stats = query.newStats () ; + + IAsynchronousIterator<IBindingSet[]> source = new ThickAsynchronousIterator<IBindingSet[]> ( new IBindingSet [][] { data } ) ; + + IBlockingBuffer<IBindingSet[]> sink = query.newBuffer ( stats ) ; + + BOpContext<IBindingSet> context = new BOpContext<IBindingSet> ( new MockRunningQuery ( null/* fed */ + , null/* indexManager */ + ) + , -1/* partitionId */ + , stats + , source + , sink + , null/* sink2 */ + ) ; + + query.eval ( context ).run () ; + + TestQueryEngine.assertSameSolutions ( expected, sink.iterator () ) ; + + assertEquals ( 1, stats.chunksIn.get () ) ; + assertEquals ( 10, stats.unitsIn.get () ) ; + assertEquals ( 10, stats.unitsOut.get () ) ; + assertEquals ( 1, stats.chunksOut.get () ) ; + } + + /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + @SuppressWarnings("serial") + private class StringComparatorOp extends ComparatorOp + { + public StringComparatorOp ( ISortOrder<?> sors [] ) + { + super ( new BOp [] {}, NV.asMap ( new NV [] { new NV ( ComparatorOp.Annotations.ORDER, sors ) } ) ) ; + _sors = sors ; + } + + public int compare ( IBindingSet o1, IBindingSet o2 ) + { + for ( ISortOrder<?> sor : _sors ) + { + int ret = compare ( sor, o1, o2 ) ; + if ( 0 != ret ) + return ret ; + } + return 0 ; + } + + private int compare ( ISortOrder<?> sor, IBindingSet lhs, IBindingSet rhs ) + { + int compare = 0 ; + + IConstant<?> lhsv = lhs.get ( sor.getVariable () ) ; + IConstant<?> rhsv = rhs.get ( sor.getVariable () ) ; + + if ( null == lhsv && null == rhsv ) + return 0 ; + else if ( null == lhsv ) + compare = -1 ; + else if ( null == rhsv ) + compare = 1 ; + else + compare = lhsv.toString ().compareTo ( rhsv.toString () ) ; + + return compare * ( sor.isAscending () ? 1 : -1 ) ; + } + private ISortOrder<?> [] _sors = null ; } - -} +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2010-09-17 10:44:08
|
Revision: 3577 http://bigdata.svn.sourceforge.net/bigdata/?rev=3577&view=rev Author: thompsonbry Date: 2010-09-17 10:44:01 +0000 (Fri, 17 Sep 2010) Log Message: ----------- fixed SliceOp and added a concurrent stress test. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java 2010-09-17 10:19:27 UTC (rev 3576) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java 2010-09-17 10:44:01 UTC (rev 3577) @@ -27,6 +27,7 @@ package com.bigdata.bop.solutions; +import java.math.BigInteger; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; @@ -40,6 +41,7 @@ import com.bigdata.bop.BindingSetPipelineOp; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.engine.BOpStats; +import com.bigdata.bop.engine.QueryEngine; import com.bigdata.bop.engine.RunningQuery; import com.bigdata.relation.accesspath.IAsynchronousIterator; import com.bigdata.relation.accesspath.IBlockingBuffer; @@ -65,20 +67,18 @@ * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * - * @todo unit test with stress test for concurrent {@link SliceOp} invocations - * against a streaming chunk producer. + * @todo Unit test with stress test for concurrent {@link SliceOp} invocations + * against a streaming chunk producer. Make sure that the same + * {@link SliceStats} are used for each concurrent invocation of the same + * query. * - * @todo If this operator is invoked for each chunk output by a query onto the - * pipeline then it will over produce unless (A) it is given the same - * {@link BOpStats} each time; and (B) it is not invoked for two chunks - * concurrently. - * <p> - * A safer way to impose the slice constraint is by wrapping the query - * buffer on the query controller. Once the slice is satisfied, it can - * just cancel the query. The only drawback of this approach is that the - * wrapping a buffer is not really the same as applying a {@link BOp} to - * the pipeline so it falls outside of the standard operator evaluation - * logic. + * @todo What is sufficient serialization to make SLICE(ORDER_BY(...)) stable? + * The {@link SortOp} will impose a total ordering and will know how to + * deliver that total ordering to another operator. The {@link SliceOp} + * needs to accept the chunks from the {@link SortOp} in the order in + * which they were sent. This should work as long as we do not reorder the + * chunks for a given operator in the {@link QueryEngine} when they are + * received by the query controller. * * @todo If we allow complex operator trees in which "subqueries" can also use a * slice then either then need to run as their own query with their own @@ -175,8 +175,10 @@ */ private static final long serialVersionUID = 1L; + /** #of solutions visited. */ public final AtomicLong nseen = new AtomicLong(); + /** #of solutions accepted. */ public final AtomicLong naccepted = new AtomicLong(); @Override @@ -235,6 +237,8 @@ /** #of solutions to accept. */ private final long limit; + private final long last; + // /** #of solutions visited. */ // private long nseen; // @@ -261,6 +265,11 @@ this.stats = (SliceStats) context.getStats(); +// this.last = offset + limit; + this.last = BigInteger.valueOf(offset).add( + BigInteger.valueOf(limit)).min( + BigInteger.valueOf(Long.MAX_VALUE)).longValue(); + } public Void call() throws Exception { @@ -277,96 +286,175 @@ try { - // buffer forms chunks which get flushed onto the sink. + /* + * buffer forms chunks which get flushed onto the sink. + * + * @todo if we have visibility into the #of source chunks, then + * do not buffer more than min(#source,#needed). + */ final UnsynchronizedArrayBuffer<IBindingSet> out = new UnsynchronizedArrayBuffer<IBindingSet>( sink, op.getChunkCapacity()); boolean halt = false; - while (source.hasNext()) { + while (source.hasNext() && !halt) { + final IBindingSet[] chunk = source.next(); + /* - * @todo batch each chunk through a lock for better - * concurrency (avoids CAS contention). + * Batch each chunk through a lock for better concurrency + * (avoids CAS contention). + * + * Note: This is safe because the source chunk is already + * materialized and the sink will not block (that is part of + * the bop evaluation contract). */ - final IBindingSet[] chunk = source.next(); - - stats.chunksIn.increment(); - - for (int i = 0; i < chunk.length; i++) { - - stats.unitsIn.increment(); - - if (stats.nseen.incrementAndGet() <= offset) { - // skip solution. - if(log.isTraceEnabled()) - log.trace(toString()); - continue; - } - - final IBindingSet bset = chunk[i]; + synchronized (stats) { - if (out.add2(bset)) { - // chunk was output. -// stats.chunksOut.increment(); - } + if (handleChunk(out, chunk)) { - if(log.isTraceEnabled()) - log.trace(toString() + ":" + bset); + halt = true; -// stats.unitsOut.increment(); - - if (stats.naccepted.incrementAndGet() >= limit) { - if (!out.isEmpty()) { - out.flush(); -// stats.chunksOut.increment(); - } - halt = true; - break; } } - + } - out.flush(); + if (!out.isEmpty()) + out.flush(); + sink.flush(); -// stats.chunksOut.increment(); if (halt) throw new InterruptedException(); -// cancelQuery(); - + // cancelQuery(); + return null; - + } finally { - + sink.close(); - + } } -// /** -// * Cancel the query evaluation. This is invoked when the slice has been -// * satisfied. At that point we want to halt not only the {@link SliceOp} -// * but also the entire query since it does not need to produce any more -// * results. -// */ -// private void cancelQuery() { -// -// context.halt(); -// -// } + /** + * <p> + * Apply the slice semantics to a chunk of binding sets. + * </p> + * <h2>example</h2> + * <p> + * offset=2, limit=3, last=3+2=5. The number line represents the + * observed binding sets. The first binding set is at index ZERO (0). + * The initial conditions are: nseen(S)=0 and naccepted(A)=0. S is + * placed beneath each observation and paired with the value of A for + * that observation. The offset is satisfied when S=2 and observation + * ONE (1) is the first observation accepted. The limit is satisfied + * when A=3, which occurs at observation FOUR (4) which is also + * S=last=5. The observation on which the limit is satisfied is accepted + * and the slice halts as no more observations should be made. {2,3,4} + * are accepted. + * </p> + * + * <pre> + * 0 1 2 3 4 5 6 7 8 9 + * S=1, A=0 + * </pre> + * + * <pre> + * 0 1 2 3 4 5 6 7 8 9 + * S=2, A=0 + * </pre> + * + * <pre> + * 0 1 2 3 4 5 6 7 8 9 + * S=3, A=1 {2} + * </pre> + * + * <pre> + * 0 1 2 3 4 5 6 7 8 9 + * S=4, A=2 {2,3} + * </pre> + * + * <pre> + * 0 1 2 3 4 5 6 7 8 9 + * S=5, A=3 {2,3,4} + * </pre> + * <p> + * Note: The caller MUST be synchronized on the <em>shared</em> + * {@link SliceStats} in order for the decision process to be thread + * safe. + * + * @param chunk + * The chunk of binding sets. + * + * @return <code>true</code> if the slice is satisfied and the query + * should halt. + */ + private boolean handleChunk( + final UnsynchronizedArrayBuffer<IBindingSet> out, + final IBindingSet[] chunk) { + stats.chunksIn.increment(); + + for (int i = 0; i < chunk.length; i++) { + + if (stats.naccepted.get() >= limit) + return true; // nothing more will be accepted. + + stats.unitsIn.increment(); + + final long S = stats.nseen.incrementAndGet(); + + if (S <= offset) + continue; // skip solution. + + final long A = stats.naccepted.get(); + + if (A < limit) { + + final IBindingSet bset = chunk[i]; + + out.add(bset); + + stats.naccepted.incrementAndGet(); + + if (log.isTraceEnabled()) + log.trace(toString() + ":" + bset); + + } + + } // next bindingSet + + return false; + + } + + // /** + // * Cancel the query evaluation. This is invoked when the slice has + // been + // * satisfied. At that point we want to halt not only the {@link + // SliceOp} + // * but also the entire query since it does not need to produce any + // more + // * results. + // */ + // private void cancelQuery() { + // + // context.halt(); + // + // } + public String toString() { return getClass().getName() + "{offset=" + offset + ",limit=" + limit + ",nseen=" + stats.nseen + ",naccepted=" + stats.naccepted + "}"; - + } - + } /** @@ -374,9 +462,9 @@ */ @Override public BOpEvaluationContext getEvaluationContext() { - + return BOpEvaluationContext.CONTROLLER; - + } } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java 2010-09-17 10:19:27 UTC (rev 3576) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/solutions/TestSliceOp.java 2010-09-17 10:44:01 UTC (rev 3577) @@ -28,8 +28,16 @@ package com.bigdata.bop.solutions; import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import junit.framework.TestCase2; @@ -37,6 +45,7 @@ import com.bigdata.bop.BOp; import com.bigdata.bop.BOpContext; import com.bigdata.bop.Constant; +import com.bigdata.bop.EmptyBindingSet; import com.bigdata.bop.HashBindingSet; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IConstant; @@ -44,8 +53,11 @@ import com.bigdata.bop.NV; import com.bigdata.bop.Var; import com.bigdata.bop.engine.BOpStats; +import com.bigdata.bop.engine.IRunningQuery; import com.bigdata.bop.engine.MockRunningQuery; import com.bigdata.bop.engine.TestQueryEngine; +import com.bigdata.bop.solutions.SliceOp.SliceStats; +import com.bigdata.relation.accesspath.BlockingBuffer; import com.bigdata.relation.accesspath.IAsynchronousIterator; import com.bigdata.relation.accesspath.IBlockingBuffer; import com.bigdata.relation.accesspath.ThickAsynchronousIterator; @@ -142,6 +154,113 @@ * @throws ExecutionException * @throws InterruptedException */ + public void test_slice_offset2_limit3() throws InterruptedException, + ExecutionException { + + final Var<?> x = Var.var("x"); + final Var<?> y = Var.var("y"); + + final int bopId = 1; + + final long offset = 2L; + final long limit = 3L; + + final SliceOp query = new SliceOp(new BOp[]{}, + NV.asMap(new NV[]{// + new NV(SliceOp.Annotations.BOP_ID, bopId),// + new NV(SliceOp.Annotations.OFFSET, offset),// + new NV(SliceOp.Annotations.LIMIT, limit),// + })); + + assertEquals("offset", offset, query.getOffset()); + + assertEquals("limit", limit, query.getLimit()); + + // the expected solutions + final IBindingSet[] expected = new IBindingSet[] {// +// new ArrayBindingSet(// +// new IVariable[] { x, y },// +// new IConstant[] { new Constant<String>("John"), +// new Constant<String>("Mary"), }// +// ), +// new ArrayBindingSet(// +// new IVariable[] { x, y },// +// new IConstant[] { new Constant<String>("Mary"), +// new Constant<String>("Paul"), }// +// ), + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { new Constant<String>("Mary"), + new Constant<String>("Jane") }// + ), + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { new Constant<String>("Paul"), + new Constant<String>("Leon") }// + ), + new ArrayBindingSet(// + new IVariable[] { x, y },// + new IConstant[] { new Constant<String>("Paul"), + new Constant<String>("John") }// + ), +// new ArrayBindingSet(// +// new IVariable[] { x, y },// +// new IConstant[] { new Constant<String>("Leon"), +// new Constant<String>("Paul") }// +// ), + }; + + final SliceStats stats = query.newStats(); + + final IAsynchronousIterator<IBindingSet[]> source = new ThickAsynchronousIterator<IBindingSet[]>( + new IBindingSet[][] { data.toArray(new IBindingSet[0]) }); + + final IBlockingBuffer<IBindingSet[]> sink = query.newBuffer(stats); + + final BOpContext<IBindingSet> context = new BOpContext<IBindingSet>( + new MockRunningQuery(null/* fed */, null/* indexManager */ + ), -1/* partitionId */, stats, + source, sink, null/* sink2 */); + + // get task. + final FutureTask<Void> ft = query.eval(context); + + ft.run(); + + TestQueryEngine.assertSameSolutions(expected, sink.iterator()); + + assertTrue(ft.isDone()); + assertFalse(ft.isCancelled()); + try { + ft.get(); // verify nothing thrown. + fail("Expecting inner cause : " + InterruptedException.class); + } catch (Throwable t) { + if (InnerCause.isInnerCause(t, InterruptedException.class)) { + if (log.isInfoEnabled()) + log.info("Ignoring expected exception: " + t, t); + } else { + fail("Expecting inner cause : " + InterruptedException.class); + } + } + + // check the slice stats first. + assertEquals(limit, stats.naccepted.get()); + assertEquals(offset+limit, stats.nseen.get()); + + // then the general purpose bop stats (less critical). + assertEquals(1L, stats.chunksIn.get()); + assertEquals(offset+limit, stats.unitsIn.get()); + assertEquals(limit, stats.unitsOut.get()); + assertEquals(1L, stats.chunksOut.get()); + + } + + /** + * Unit test for correct visitation for a variety of offset/limit values. + * + * @throws ExecutionException + * @throws InterruptedException + */ public void test_slice_offset1_limit3() throws InterruptedException, ExecutionException { @@ -149,17 +268,20 @@ final Var<?> y = Var.var("y"); final int bopId = 1; + + final long offset = 1; + final long limit = 3; final SliceOp query = new SliceOp(new BOp[]{}, NV.asMap(new NV[]{// new NV(SliceOp.Annotations.BOP_ID, bopId),// - new NV(SliceOp.Annotations.OFFSET, 1L),// - new NV(SliceOp.Annotations.LIMIT, 3L),// + new NV(SliceOp.Annotations.OFFSET, offset),// + new NV(SliceOp.Annotations.LIMIT, limit),// })); - assertEquals("offset", 1L, query.getOffset()); + assertEquals("offset", offset, query.getOffset()); - assertEquals("limit", 3L, query.getLimit()); + assertEquals("limit", limit, query.getLimit()); // the expected solutions final IBindingSet[] expected = new IBindingSet[] {// @@ -179,7 +301,7 @@ new Constant<String>("Leon") }// ), }; - final BOpStats stats = query.newStats(); + final SliceStats stats = query.newStats(); final IAsynchronousIterator<IBindingSet[]> source = new ThickAsynchronousIterator<IBindingSet[]>( new IBindingSet[][] { data.toArray(new IBindingSet[0]) }); @@ -212,6 +334,9 @@ } } + assertEquals(limit, stats.naccepted.get()); + assertEquals(offset+limit, stats.nseen.get()); + assertEquals(1L, stats.chunksIn.get()); assertEquals(4L, stats.unitsIn.get()); assertEquals(3L, stats.unitsOut.get()); @@ -222,9 +347,6 @@ public void test_slice_offset0_limitAll() throws InterruptedException, ExecutionException { - final Var<?> x = Var.var("x"); - final Var<?> y = Var.var("y"); - final int bopId = 1; final SliceOp query = new SliceOp(new BOp[] {}, NV.asMap(new NV[] {// @@ -240,7 +362,7 @@ // the expected solutions final IBindingSet[] expected = data.toArray(new IBindingSet[0]); - final BOpStats stats = query.newStats(); + final SliceStats stats = query.newStats(); final IAsynchronousIterator<IBindingSet[]> source = new ThickAsynchronousIterator<IBindingSet[]>( new IBindingSet[][] { data.toArray(new IBindingSet[0]) }); @@ -266,6 +388,8 @@ assertEquals(6L, stats.unitsIn.get()); assertEquals(6L, stats.unitsOut.get()); assertEquals(1L, stats.chunksOut.get()); + assertEquals(6L, stats.nseen.get()); + assertEquals(6L, stats.naccepted.get()); } @@ -342,4 +466,146 @@ } + public void test_slice_threadSafe() throws Exception { + + final long timeout = 10000; // ms + + final int ntrials = 10000; + + final int poolSize = 10; + + doStressTest(500L/* offset */, 1500L/* limit */, timeout, ntrials, + poolSize); + + } + + /** + * + * @param timeout + * @param ntrials + * @param poolSize + * + * @return The #of successful trials. + * + * @throws Exception + */ + protected int doStressTest(final long offset, final long limit, + final long timeout, final int ntrials, final int poolSize) + throws Exception { + + final IBindingSet[][] chunks = new IBindingSet[ntrials][]; + { + final Random r = new Random(); + final IBindingSet bset = EmptyBindingSet.INSTANCE; + for (int i = 0; i < chunks.length; i++) { + // random non-zero chunk size + chunks[i] = new IBindingSet[r.nextInt(10) + 1]; + for (int j = 0; j < chunks[i].length; j++) { + chunks[i][j] = bset; + } + } + } + final int bopId = 1; + final SliceOp query = new SliceOp(new BOp[] {}, NV.asMap(new NV[] {// + new NV(SliceOp.Annotations.BOP_ID, bopId),// + new NV(SliceOp.Annotations.OFFSET, offset),// + new NV(SliceOp.Annotations.LIMIT, limit),// + })); + + final SliceStats stats = query.newStats(); + + final IRunningQuery q = new MockRunningQuery(null/* fed */, null/* indexManager */); + + // start time in nanos. + final long begin = System.nanoTime(); + + // timeout in nanos. + final long nanos = TimeUnit.MILLISECONDS.toNanos(timeout); + + final ThreadPoolExecutor service = (ThreadPoolExecutor) Executors + .newFixedThreadPool(poolSize); + + try { + + service.prestartAllCoreThreads(); + + final List<FutureTask<Void>> futures = new LinkedList<FutureTask<Void>>(); + + for (int i = 0; i < ntrials; i++) { + + final IBindingSet[] chunk = chunks[i]; + + final IAsynchronousIterator<IBindingSet[]> source = new ThickAsynchronousIterator<IBindingSet[]>( + new IBindingSet[][] { chunk }); + + final BOpContext<IBindingSet> context = new BOpContext<IBindingSet>( + q, -1/* partitionId */, stats, source, + new BlockingBuffer<IBindingSet[]>(chunk.length), null/* sink2 */); + + final FutureTask<Void> ft = query.eval(context); + + futures.add(ft); + + service.execute(ft); + + } + + int nerror = 0; + int ncancel = 0; + int ntimeout = 0; + int nsuccess = 0; + int ninterrupt = 0; + for (FutureTask<Void> ft : futures) { + // remaining nanoseconds. + final long remaining = nanos - (System.nanoTime() - begin); + if (remaining <= 0) + ft.cancel(true/* mayInterruptIfRunning */); + try { + ft.get(remaining, TimeUnit.NANOSECONDS); + nsuccess++; + } catch (CancellationException ex) { + ncancel++; + } catch (TimeoutException ex) { + ntimeout++; + } catch (ExecutionException ex) { + if (InnerCause.isInnerCause(ex, InterruptedException.class)) { + ninterrupt++; + } else { + log.error(ex, ex); + nerror++; + } + } + } + + final long nseen = stats.nseen.get(); + + final long naccepted = stats.naccepted.get(); + + final long nexpected = limit; + + final String msg = "offset=" + offset + ", limit=" + limit + + ", nseen=" + nseen + ",naccepted=" + naccepted + + ", nexpected=" + nexpected + ", nerror=" + nerror + + ", ncancel=" + ncancel + ", ntimeout=" + ntimeout + + ", ninterrupt=" + ninterrupt + ", nsuccess=" + nsuccess; + + System.err.println(getClass().getName() + "." + getName() + " : " + + msg); + + if (nerror > 0) + fail(msg); + + if (nexpected != naccepted) + fail(msg); + + return nsuccess; + + } finally { + + service.shutdownNow(); + + } + + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2010-09-17 10:19:33
|
Revision: 3576 http://bigdata.svn.sourceforge.net/bigdata/?rev=3576&view=rev Author: martyncutcher Date: 2010-09-17 10:19:27 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Implement BufferedWrites and Allocation locality enhancements Modified Paths: -------------- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/WriteCache.java branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/FixedAllocator.java branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWWriteCacheService.java branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWORMWriteCacheService.java branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWriteCache.java Added Paths: ----------- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/BufferedWrite.java Added: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/BufferedWrite.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/BufferedWrite.java (rev 0) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/BufferedWrite.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -0,0 +1,108 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2010. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package com.bigdata.io.writecache; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +import com.bigdata.io.DirectBufferPool; +import com.bigdata.io.FileChannelUtility; +import com.bigdata.io.IReopenChannel; +import com.bigdata.rwstore.RWStore; + +/** + * The BufferedWrite merges/elides sorted scattered writes to minimise + * IO requests and maximise IO rates. + * + * @author Martyn Cutcher + * + */ +public class BufferedWrite { + final RWStore m_store; + final ByteBuffer m_data; + long m_startAddr = -1; + long m_endAddr = 0; + + long m_dataBytes = 0; + long m_dataWrites = 0; + long m_fileWrites = 0; + + public BufferedWrite(final RWStore store) throws InterruptedException { + m_store = store; + m_data = DirectBufferPool.INSTANCE.acquire(); + } + + public void write(final long offset, final ByteBuffer data, final IReopenChannel<FileChannel> opener) throws IOException { + m_dataWrites++; + + int data_len = data.remaining(); + int slot_len = m_store.getSlotSize(data_len); + + if (slot_len > m_data.remaining()) { + flush(opener); + } + + if (m_startAddr == -1) { + m_startAddr = m_endAddr = offset; + } else if (m_endAddr != offset) { + // if this is NOT a contiguous write then flush existing content + flush(opener); + m_startAddr = m_endAddr = offset; + } + m_data.put(data); + m_endAddr += slot_len; + long pos = m_endAddr - m_startAddr; + m_data.position((int) pos); + } + + public void flush(final IReopenChannel<FileChannel> opener) throws IOException { + m_dataBytes += m_data.position(); + + m_data.flip(); + FileChannelUtility.writeAll(opener, m_data, m_startAddr); + m_fileWrites++; + + m_data.position(0); + m_data.limit(m_data.capacity()); + + m_startAddr = -1; + m_endAddr = 0; + } + + public String getStats(StringBuffer buf, boolean reset) { + String ret = "BufferedWrites, data: " + m_dataWrites + ", file: " + m_fileWrites + ", bytes: " + m_dataBytes; + + if (buf != null) { + buf.append(ret + "\n"); + } + + if (reset) { + m_dataBytes = m_fileWrites = m_dataWrites = 0; + } + + return ret; + } +} Property changes on: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/BufferedWrite.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Date Revision Author HeadURL Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/WriteCache.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/WriteCache.java 2010-09-16 21:09:42 UTC (rev 3575) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/io/writecache/WriteCache.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -1579,6 +1579,12 @@ * for the RW mode. Look into putting a thread pool to work on the scattered * writes. This could be part of a refactor to apply a thread pool to IOs * and related to prefetch and {@link Memoizer} behaviors. + * + * FIXME To maximize IO rates we should attempt to elide/merge contiguous + * writes. To do this can double-buffer in writeOnChannel. This also + * provides an opportunity to write the full slot size of the RWStore that + * may have advantages, particularly for an SSD, since it may avoid a + * pre-write read to populate the write sector. */ public static class FileChannelScatteredWriteCache extends WriteCache { @@ -1587,6 +1593,7 @@ */ private final IReopenChannel<FileChannel> opener; + private final BufferedWrite m_bufferedWrite; /** * @param baseOffset * An offset @@ -1596,7 +1603,8 @@ * @throws InterruptedException */ public FileChannelScatteredWriteCache(final ByteBuffer buf, final boolean useChecksum, - final boolean isHighlyAvailable, final boolean bufferHasData, final IReopenChannel<FileChannel> opener) + final boolean isHighlyAvailable, final boolean bufferHasData, final IReopenChannel<FileChannel> opener, + final BufferedWrite bufferedWrite) throws InterruptedException { super(buf, true/* scatteredWrites */, useChecksum, isHighlyAvailable, bufferHasData); @@ -1605,6 +1613,8 @@ throw new IllegalArgumentException(); this.opener = opener; + + m_bufferedWrite = bufferedWrite; } @@ -1646,13 +1656,23 @@ view.position(pos); final long offset = entry.getKey(); // offset in file to update - - nwrites += FileChannelUtility.writeAll(opener, view, offset); + if (m_bufferedWrite == null) { + nwrites += FileChannelUtility.writeAll(opener, view, offset); + } else { + m_bufferedWrite.write(offset, view, opener); + } // if (log.isInfoEnabled()) // log.info("writing to: " + offset); registerWriteStatus(offset, md.recordLength, 'W'); } + if (m_bufferedWrite != null) { + m_bufferedWrite.flush(opener); + + if (log.isTraceEnabled()) + log.trace(m_bufferedWrite.getStats(null, true)); + } + final WriteCacheCounters counters = this.counters.get(); counters.nwrite += nwrites; counters.bytesWritten += nbytes; Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/FixedAllocator.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/FixedAllocator.java 2010-09-16 21:09:42 UTC (rev 3575) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/FixedAllocator.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -117,6 +117,7 @@ if (hasFree()) { m_freeList.add(this); + m_freeWaiting = false; } } @@ -190,6 +191,7 @@ // added back if ((m_freeTransients == m_freeBits) && (m_freeTransients != 0)) { m_freeList.add(this); + m_freeWaiting = false; } m_freeTransients = 0; @@ -325,9 +327,7 @@ public String getStats(final AtomicLong counter) { - final StringBuilder sb = new StringBuilder("Block size : " + m_size - + " start : " + getStartAddr() + " free : " + m_freeBits - + "\r\n"); + final StringBuilder sb = new StringBuilder(getSummaryStats()); final Iterator<AllocBlock> iter = m_allocBlocks.iterator(); while (iter.hasNext()) { @@ -336,12 +336,20 @@ break; } sb.append(block.getStats(null) + "\r\n"); - counter.addAndGet(block.getAllocBits() * m_size); + if (counter != null) + counter.addAndGet(block.getAllocBits() * m_size); } return sb.toString(); } + public String getSummaryStats() { + + return"Block size : " + m_size + + " start : " + getStartAddr() + " free : " + m_freeBits + + "\r\n"; + } + public boolean verify(int addr) { if (addr >= m_startAddr && addr < m_endAddr) { @@ -372,6 +380,8 @@ return false; } + private boolean m_freeWaiting = true; + public boolean free(final int addr, final int size) { if (addr < 0) { final int offset = ((-addr) & RWStore.OFFSET_BITS_MASK) - 3; // bit adjust @@ -382,8 +392,14 @@ if (((AllocBlock) m_allocBlocks.get(block)) .freeBit(offset % nbits)) { // bit adjust - if (m_freeBits++ == 0) { + + // Only add back to the free list if at least 3000 bits avail + if (m_freeBits++ == 0 && false) { + m_freeWaiting = false; m_freeList.add(this); + } else if (m_freeWaiting && m_freeBits == 3000) { + m_freeWaiting = false; + m_freeList.add(this); } } else { m_freeTransients++; @@ -445,6 +461,13 @@ if (log.isTraceEnabled()) log.trace("Remove from free list"); m_freeList.remove(this); + m_freeWaiting = true; + + // Should have been first on list, now check for first + if (m_freeList.size() > 0) { + FixedAllocator nxt = (FixedAllocator) m_freeList.get(0); + System.out.println("Freelist head: " + nxt.getSummaryStats()); + } } addr += (count * 32 * m_bitSize); Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2010-09-16 21:09:42 UTC (rev 3575) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -50,6 +50,7 @@ import com.bigdata.io.FileChannelUtility; import com.bigdata.io.IReopenChannel; +import com.bigdata.io.writecache.BufferedWrite; import com.bigdata.io.writecache.WriteCache; import com.bigdata.journal.AbstractJournal; import com.bigdata.journal.CommitRecordIndex; @@ -327,6 +328,8 @@ private ReopenFileChannel m_reopener = null; + BufferedWrite m_bufferedWrite; + class WriteCacheImpl extends WriteCache.FileChannelScatteredWriteCache { public WriteCacheImpl(final ByteBuffer buf, final boolean useChecksum, @@ -335,7 +338,7 @@ throws InterruptedException { super(buf, useChecksum, m_quorum!=null&&m_quorum - .isHighlyAvailable(), bufferHasData, opener); + .isHighlyAvailable(), bufferHasData, opener, m_bufferedWrite); } @@ -379,6 +382,7 @@ * @param fileMetadataView * @param readOnly * @param quorum + * @throws InterruptedException */ public RWStore(final FileMetadataView fileMetadataView, final boolean readOnly, @@ -412,6 +416,12 @@ } catch (IOException e1) { throw new RuntimeException(e1); } + + try { + m_bufferedWrite = new BufferedWrite(this); + } catch (InterruptedException e1) { + m_bufferedWrite = null; + } int buffers = m_fmv.getFileMetadata().writeCacheBufferCount; log.warn("RWStore using writeCacheService with buffers: " + buffers); @@ -2122,6 +2132,7 @@ str.append("Allocation: " + stats[i].m_blockSize); str.append(", slots: " + stats[i].m_filledSlots + "/" + stats[i].m_reservedSlots); str.append(", storage: " + filled + "/" + reserved); + str.append(", usage: " + (filled * 100 / reserved) + "%"); str.append("\n"); } str.append("Total - file: " + convertAddr(m_fileSize) + ", slots: " + tfilledSlots + "/" + treservedSlots + ", storage: " + tfilled + "/" + treserved + "\n"); @@ -2942,4 +2953,17 @@ return ret; } + + + public int getSlotSize(int data_len) { + int i = 0; + + int ret = m_minFixedAlloc; + while (data_len > ret) { + i++; + ret = 64 * m_allocSizes[i]; + } + + return ret; + } } Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWWriteCacheService.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWWriteCacheService.java 2010-09-16 21:09:42 UTC (rev 3575) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWWriteCacheService.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -32,6 +32,7 @@ import org.apache.log4j.Logger; import com.bigdata.io.IReopenChannel; +import com.bigdata.io.writecache.BufferedWrite; import com.bigdata.io.writecache.WriteCache; import com.bigdata.io.writecache.WriteCacheService; import com.bigdata.io.writecache.WriteCache.FileChannelScatteredWriteCache; @@ -53,7 +54,6 @@ super(nbuffers, true/* useChecksum */, fileExtent, opener, quorum); - } /** @@ -72,7 +72,7 @@ return new FileChannelScatteredWriteCache(buf, true/* useChecksum */, highlyAvailable, bufferHasData, - (IReopenChannel<FileChannel>) opener); + (IReopenChannel<FileChannel>) opener, null); } Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWORMWriteCacheService.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWORMWriteCacheService.java 2010-09-16 21:09:42 UTC (rev 3575) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWORMWriteCacheService.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -1780,7 +1780,7 @@ case RW: return new FileChannelScatteredWriteCache(buf, useChecksum, isHighlyAvailable, bufferHasData, - (IReopenChannel<FileChannel>) opener); + (IReopenChannel<FileChannel>) opener, null); default: throw new UnsupportedOperationException(); } Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWriteCache.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWriteCache.java 2010-09-16 21:09:42 UTC (rev 3575) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/io/writecache/TestWriteCache.java 2010-09-17 10:19:27 UTC (rev 3576) @@ -528,7 +528,7 @@ // ctor correct rejection tests: opener is null. try { new WriteCache.FileChannelScatteredWriteCache(buf, - useChecksum, isHighlyAvailable, bufferHasData, null/* opener */); + useChecksum, isHighlyAvailable, bufferHasData, null/* opener */, null); fail("Expected: " + IllegalArgumentException.class); } catch (IllegalArgumentException ex) { if (log.isInfoEnabled()) @@ -537,7 +537,7 @@ // allocate write cache using our buffer. final WriteCache writeCache = new WriteCache.FileChannelScatteredWriteCache( - buf, useChecksum, isHighlyAvailable, bufferHasData, opener); + buf, useChecksum, isHighlyAvailable, bufferHasData, opener, null); // verify the write cache self-reported capacity. assertEquals(DirectBufferPool.INSTANCE.getBufferCapacity() @@ -869,9 +869,9 @@ ByteBuffer data2 = getRandomData(20 * 1024); int chk2 = ChecksumUtility.threadChk.get().checksum(data2, 0/* offset */, data2.limit()); WriteCache cache1 = new WriteCache.FileChannelScatteredWriteCache(buf, true, true, - false, opener); + false, opener, null); WriteCache cache2 = new WriteCache.FileChannelScatteredWriteCache(buf2, true, true, - false, opener); + false, opener, null); // write first data buffer cache1.write(addr1, data1, chk1); @@ -976,7 +976,7 @@ // allocate write cache using our buffer. final WriteCache writeCache = new WriteCache.FileChannelScatteredWriteCache( - buf, useChecksum, isHighlyAvailable, bufferHasData, opener); + buf, useChecksum, isHighlyAvailable, bufferHasData, opener, null); /* * First write 500 records into the cache and confirm they can all be read okay This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tho...@us...> - 2010-09-16 21:09:48
|
Revision: 3575 http://bigdata.svn.sourceforge.net/bigdata/?rev=3575&view=rev Author: thompsonbry Date: 2010-09-16 21:09:42 +0000 (Thu, 16 Sep 2010) Log Message: ----------- Modified SliceOp to be thread safe. It may be a CAS hotspot, but that can be addressed by batching each chunk through a lock. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java 2010-09-16 20:29:51 UTC (rev 3574) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/engine/BOpStats.java 2010-09-16 21:09:42 UTC (rev 3575) @@ -63,12 +63,6 @@ // */ // private final long startTime; -// /** -// * The index partition for which these statistics were collected or -1 -// * if the statistics are aggregated across index partitions. -// */ -// public final int partitionId; - /** * #of chunks in. */ @@ -116,7 +110,7 @@ sb.append(",unitsIn=" + unitsIn.estimate_get()); sb.append(",chunksOut=" + chunksOut.estimate_get()); sb.append(",unitsOut=" + unitsOut.estimate_get()); - toString(sb); + toString(sb); // extension hook sb.append("}"); return sb.toString(); } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java 2010-09-16 20:29:51 UTC (rev 3574) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/solutions/SliceOp.java 2010-09-16 21:09:42 UTC (rev 3575) @@ -30,6 +30,7 @@ import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; +import java.util.concurrent.atomic.AtomicLong; import org.apache.log4j.Logger; @@ -55,11 +56,18 @@ * <p> * Note: When running on an {@link IBigdataFederation}, this operator must be * imposed on the query controller so it can count the solutions as they flow - * through. + * through - see {@link #getEvaluationContext()}. + * <p> + * Note: {@link SliceOp} is safe for concurrent invocations for the same query. + * Multiple chunks may flow through multiple invocations of the operator so long + * as they use the same {@link BOpStats} object. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * + * @todo unit test with stress test for concurrent {@link SliceOp} invocations + * against a streaming chunk producer. + * * @todo If this operator is invoked for each chunk output by a query onto the * pipeline then it will over produce unless (A) it is given the same * {@link BOpStats} each time; and (B) it is not invoked for two chunks @@ -156,7 +164,55 @@ return getProperty(Annotations.LIMIT, Annotations.DEFAULT_LIMIT); } + + /** + * Extends {@link BOpStats} to capture the state of the {@link SliceOp}. + */ + public static class SliceStats extends BOpStats { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public final AtomicLong nseen = new AtomicLong(); + + public final AtomicLong naccepted = new AtomicLong(); + + @Override + public void add(final BOpStats o) { + + super.add(o); + + if (o instanceof SliceStats) { + + final SliceStats t = (SliceStats) o; + + nseen.addAndGet(t.nseen.get()); + + naccepted.addAndGet(t.naccepted.get()); + + } + + } + + @Override + protected void toString(final StringBuilder sb) { + + sb.append(",nseed=" + nseen); + + sb.append(",naccepted=" + naccepted); + + } + + } + public SliceStats newStats() { + + return new SliceStats(); + + } + public FutureTask<Void> eval(final BOpContext<IBindingSet> context) { return new FutureTask<Void>(new SliceTask(this, context)); @@ -179,12 +235,14 @@ /** #of solutions to accept. */ private final long limit; - /** #of solutions visited. */ - private long nseen; - - /** #of solutions accepted. */ - private long naccepted; - +// /** #of solutions visited. */ +// private long nseen; +// +// /** #of solutions accepted. */ +// private long naccepted; +// + private final SliceStats stats; + SliceTask(final SliceOp op, final BOpContext<IBindingSet> context) { this.op = op; @@ -201,6 +259,8 @@ if (limit <= 0) throw new IllegalArgumentException(Annotations.LIMIT); + this.stats = (SliceStats) context.getStats(); + } public Void call() throws Exception { @@ -211,14 +271,9 @@ final IAsynchronousIterator<IBindingSet[]> source = context .getSource(); - /* - * @todo This needs to be wrapping to automatically update the #of - * chunks actually output in order to have correct reporting. Review - * all of the other operators for this same issue. - */ final IBlockingBuffer<IBindingSet[]> sink = context.getSink(); - final BOpStats stats = context.getStats(); +// final BOpStats stats = context.getStats(); try { @@ -230,17 +285,20 @@ while (source.hasNext()) { + /* + * @todo batch each chunk through a lock for better + * concurrency (avoids CAS contention). + */ final IBindingSet[] chunk = source.next(); - + stats.chunksIn.increment(); for (int i = 0; i < chunk.length; i++) { stats.unitsIn.increment(); - if (nseen < offset) { + if (stats.nseen.incrementAndGet() <= offset) { // skip solution. - nseen++; if(log.isTraceEnabled()) log.trace(toString()); continue; @@ -258,9 +316,7 @@ // stats.unitsOut.increment(); - naccepted++; - nseen++; - if (naccepted >= limit) { + if (stats.naccepted.incrementAndGet() >= limit) { if (!out.isEmpty()) { out.flush(); // stats.chunksOut.increment(); @@ -306,8 +362,8 @@ public String toString() { return getClass().getName() + "{offset=" + offset + ",limit=" - + limit + ",nseen=" + nseen + ",naccepted=" + naccepted - + "}"; + + limit + ",nseen=" + stats.nseen + ",naccepted=" + + stats.naccepted + "}"; } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java 2010-09-16 20:29:51 UTC (rev 3574) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestFederatedQueryEngine.java 2010-09-16 21:09:42 UTC (rev 3575) @@ -643,7 +643,9 @@ * state across distinct invocations and is cancelling the query as soon as * it exhausts its input. In order to have correct decision boundaries, * slice needs to be invoked either once, concurrently if using {@link CAT} - * s, or in a series of presentations otherwise. + * s, or in a series of presentations otherwise (single-threaded operator or + * internal locking in the operator implementation on its {@link SliceOp} to + * achieve chunk-wise serialization of processing). * <p> * The easiest way to fix this is to have {@link SliceOp} specialize the * {@link BOpStats}s and carry its state there. That will also make it safe This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |