Merge lp:~zorba-coders/zorba/dataguide into lp:zorba
Status: | Rejected |
---|---|
Rejected by: | Matthias Brantner on 2013-09-19 |
Proposed branch: | lp:~zorba-coders/zorba/dataguide |
Merge into: | lp:zorba |
Diff against target: |
6599 lines (+2320/-394) 162 files modified
src/annotations/annotations.cpp (+9/-0) src/annotations/annotations.h (+4/-1) src/common/shared_types.h (+3/-0) src/compiler/codegen/plan_visitor.cpp (+16/-1) src/compiler/expression/CMakeLists.txt (+2/-1) src/compiler/expression/expr_base.cpp (+109/-0) src/compiler/expression/expr_base.h (+12/-0) src/compiler/expression/expr_clone.cpp (+3/-0) src/compiler/expression/expr_type.cpp (+4/-0) src/compiler/expression/json_dataguide.cpp (+349/-0) src/compiler/expression/json_dataguide.h (+153/-0) src/compiler/expression/var_expr.cpp (+1/-0) src/compiler/rewriter/framework/default_optimizer.cpp (+10/-1) src/compiler/rewriter/rules/nodeid_rules.cpp (+289/-0) src/compiler/rewriter/rules/rule_base.h (+2/-1) src/compiler/rewriter/rules/ruleset.h (+25/-0) src/functions/function.cpp (+24/-0) src/functions/function.h (+4/-2) src/functions/pregenerated/func_accessors.h (+3/-10) src/functions/pregenerated/func_any_uri.h (+0/-1) src/functions/pregenerated/func_base64.h (+0/-2) src/functions/pregenerated/func_booleans.h (+0/-3) src/functions/pregenerated/func_collections.h (+12/-34) src/functions/pregenerated/func_context.h (+0/-8) src/functions/pregenerated/func_datetime.h (+0/-9) src/functions/pregenerated/func_documents.h (+0/-5) src/functions/pregenerated/func_durations_dates_times.h (+0/-21) src/functions/pregenerated/func_errors_and_diagnostics.h (+0/-2) src/functions/pregenerated/func_fetch.h (+0/-3) src/functions/pregenerated/func_fn_hof_functions.h (+7/-7) src/functions/pregenerated/func_fnput.h (+0/-1) src/functions/pregenerated/func_ft_module.h (+0/-15) src/functions/pregenerated/func_ic_ddl.h (+0/-3) src/functions/pregenerated/func_index_func.h (+0/-1) src/functions/pregenerated/func_item.h (+0/-1) src/functions/pregenerated/func_json.h (+0/-2) src/functions/pregenerated/func_jsoniq_functions.h (+4/-23) src/functions/pregenerated/func_maps.h (+0/-10) src/functions/pregenerated/func_maths.h (+0/-26) src/functions/pregenerated/func_node_position.h (+0/-24) src/functions/pregenerated/func_nodes.h (+5/-20) src/functions/pregenerated/func_numerics.h (+3/-8) src/functions/pregenerated/func_other_diagnostics.h (+0/-2) src/functions/pregenerated/func_parse_fragment.h (+1/-3) src/functions/pregenerated/func_parsing_and_serializing.h (+3/-2) src/functions/pregenerated/func_qnames.h (+0/-8) src/functions/pregenerated/func_random.h (+0/-3) src/functions/pregenerated/func_reference.h (+0/-4) src/functions/pregenerated/func_schema.h (+0/-3) src/functions/pregenerated/func_sctx.h (+0/-25) src/functions/pregenerated/func_sequences.h (+5/-32) src/functions/pregenerated/func_strings.h (+2/-30) src/functions/pregenerated/func_uris.h (+0/-3) src/functions/pregenerated/func_xqdoc.h (+0/-2) src/runtime/collections/collections_impl.cpp (+5/-4) src/runtime/collections/pregenerated/collections.cpp (+1/-0) src/runtime/collections/pregenerated/collections.h (+5/-1) src/runtime/json/json_loader.cpp (+3/-2) src/runtime/json/json_loader.h (+5/-2) src/runtime/json/jsoniq_functions_impl.cpp (+1/-1) src/runtime/json/pregenerated/jsoniq_functions.cpp (+1/-0) src/runtime/json/pregenerated/jsoniq_functions.h (+5/-1) src/runtime/spec/codegen-h.xq (+12/-2) src/runtime/spec/collections/collections.xml (+15/-3) src/runtime/spec/json/jsoniq_functions.xml (+10/-0) src/runtime/spec/parsing_and_serializing/parsing_and_serializing.xml (+1/-0) src/store/api/store.h (+3/-1) src/store/naive/json_items.cpp (+13/-2) src/store/naive/store.cpp (+2/-1) src/store/naive/store.h (+1/-1) src/system/globalenv.cpp (+2/-2) src/system/zorba_properties.h (+12/-2) src/system/zorba_properties.txt (+1/-0) test/driver/specification.h (+15/-2) test/driver/testdriver.cpp (+23/-4) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-01.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-02.xml.res (+3/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-03.xml.res (+3/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-04.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-05.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-06.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-07.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-08.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-09.xml.res (+3/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-10.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-11.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-12.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-13.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-14.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-15.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-16.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-17.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-18.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-19.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-20.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-21.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-22.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-23.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-24.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-25.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-26.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-27.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-28.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/jsoniq/dataguide/dataguide-29.xml.res (+2/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-01.jq (+19/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-01.spec (+2/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-02.jq (+29/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-02.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-03.jq (+38/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-03.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-04.jq (+22/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-04.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-05.jq (+25/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-05.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-06.jq (+26/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-06.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-07.jq (+27/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-07.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-08.jq (+27/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-08.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-09.jq (+33/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-09.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-10.jq (+27/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-10.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-11.jq (+25/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-11.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-12.jq (+28/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-12.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-13.jq (+29/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-13.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-14.jq (+29/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-14.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-15.jq (+29/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-15.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-16.jq (+31/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-16.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-17.jq (+31/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-17.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-18.jq (+32/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-18.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-19.jq (+32/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-19.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-20.jq (+38/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-20.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-21.jq (+33/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-21.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-22.jq (+38/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-22.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-23.jq (+39/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-23.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-24.jq (+32/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-24.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-25.jq (+20/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-25.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-26.jq (+20/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-26.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-27.jq (+22/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-27.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-28.jq (+22/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-28.spec (+1/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-29.jq (+228/-0) test/rbkt/Queries/zorba/jsoniq/dataguide/dataguide-29.spec (+1/-0) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/dataguide |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthias Brantner | 2013-07-17 | Needs Fixing on 2013-07-17 | |
Nicolae Brinza | Approve on 2013-07-17 | ||
Markos Zaharioudakis | 2013-07-17 | Pending | |
Review via email:
|
Commit message
Dataguide implementation.
Description of the change
Dataguide implementation.
Zorba Build Bot (zorba-buildbot) wrote : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "TestZorbaUbuntu" failed.
794 tests failed (8369 total tests run).
Check test results at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "TestZorbaUbuntu" failed.
794 tests failed (8369 total tests run).
Check test results at http://
- 11482. By Nicolae Brinza on 2013-07-04
-
Dataguide work in progress.
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "TestZorbaUbuntu" failed.
794 tests failed (8373 total tests run).
Check test results at http://
- 11483. By Nicolae Brinza on 2013-07-04
-
Merged with Zorba trunk
- 11484. By Nicolae Brinza on 2013-07-04
-
Disabled dataguide for testing
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "TestZorbaUbuntu" failed.
26 tests failed (8373 total tests run).
Check test results at http://
- 11485. By Nicolae Brinza on 2013-07-05
-
Re-enabled the dataguide
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
- 11486. By Nicolae Brinza on 2013-07-08
-
Dataguide fixes for the remote queue; cleanup; documentation;
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Voting criteria failed for the following merge proposals:
https:/
Votes: {'Pending': 1}
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "CommitZorba" failed.
Check console output at http://
- 11487. By Nicolae Brinza on 2013-07-08
-
Dataguide cleanup
- I find the name dataguide misleading because it's a guide on the query and not on the data. Maybe QueryPruneGuide would be more meaningful
- Can the user also use the zann_explores_json annotation?
- Why is the dataguide parameter on the Store's getCollection() function? Shouldn't it be on the function that returns the iterator? The problem is that a Collection object within the simplestore exists only once per collection. What's the semantics if multiple queries access the collection (possibly in parallel)?
- Did you measure the performance impact of the optimizer on some larger queries?
Nicolae Brinza (nbrinza) wrote : | # |
> - I find the name dataguide misleading because it's a guide on the query and
> not on the data. Maybe QueryPruneGuide would be more meaningful
The query itself is not pruned, the data is. I think "dataguide" is the established term -- see for example this paper: http://
> - Can the user also use the zann_explores_json annotation?
Yes, the users can use it as well. But does it make sense for them to use it? If they have an external function -- it is automatically handled as if it has the annotation. For a UDF it doesn't really make any sense to add it.
> - Why is the dataguide parameter on the Store's getCollection() function?
> Shouldn't it be on the function that returns the iterator? The problem is that
> a Collection object within the simplestore exists only once per collection.
> What's the semantics if multiple queries access the collection (possibly in
> parallel)?
It very much depends on how the collections are handled. Currently for Zorba collections it doesn't make sense to have any dataguides at all, because they're in-memory collections. I have not taken a look at the Sausalito code and have not seen how e.g. the MongoDB "collections" are managed. getCollection() seemed the most logical place where it should be passed, but the dataguide parameter could be easily propagated to any Store class, including the function that returns the iterator.
Currently each and every db:collection() call has its own dataguide, even if they might refer to the same collection. If the collection manager currently "caches" or reuses the collection iterators, then it might make sense to forbid that so that the dataguide for each individual db:collection call could be used.
Or alternatively, an "union" on the dataguides that refer to the same collection could be performed. But I think it is not always possible to determine if that is the case.
I think this could be investigated and decided upon when implementing the Dataguide push-down into MongoDB or when I would take a better look at the Sausalito's collection manager code.
> - Did you measure the performance impact of the optimizer on some larger
> queries?
The expression tree is traversed in its entirety once and only once, visiting each node, so the performance should not be very different from any other dataflow computation, e.g. ignores sorts/order/etc. If there are no "sources", i.e. db:collection() or jn:parse() calls, then the dataguide computation just propagates NULLs, doing no calculations and almost no memory allocations (at most one dataguide_cb allocation per fo_exprs and several others). If there are "sources" in the tree -- there will be some union operations being performed for some of the nodes.
I will check if any of our larger queries have longer compilation times, but because none of them have db:collection() or jn:parse() calls, I do not expect any differences.
It would make sense to have a specially constructed query that would do a stress-test of the dataguide code -- e.g. a db:collection(
> > - I find the name dataguide misleading because it's a guide on the query and
> > not on the data. Maybe QueryPruneGuide would be more meaningful
>
> The query itself is not pruned, the data is. I think "dataguide" is the
> established term -- see for example this paper:
> http://
"DataGuides serve as dynamic schemas, generated from the database." What we generate is a schema from the query.
> > - Why is the dataguide parameter on the Store's getCollection() function?
> > Shouldn't it be on the function that returns the iterator? The problem is
> that
> > a Collection object within the simplestore exists only once per collection.
> > What's the semantics if multiple queries access the collection (possibly in
> > parallel)?
>
> It very much depends on how the collections are handled. Currently for Zorba
> collections it doesn't make sense to have any dataguides at all, because
> they're in-memory collections. I have not taken a look at the Sausalito code
> and have not seen how e.g. the MongoDB "collections" are managed.
> getCollection() seemed the most logical place where it should be passed, but
> the dataguide parameter could be easily propagated to any Store class,
> including the function that returns the iterator.
>
> Currently each and every db:collection() call has its own dataguide, even if
> they might refer to the same collection. If the collection manager currently
> "caches" or reuses the collection iterators, then it might make sense to
> forbid that so that the dataguide for each individual db:collection call could
> be used.
>
> Or alternatively, an "union" on the dataguides that refer to the same
> collection could be performed. But I think it is not always possible to
> determine if that is the case.
>
> I think this could be investigated and decided upon when implementing the
> Dataguide push-down into MongoDB or when I would take a better look at the
> Sausalito's collection manager code.
I think we will run into a problem. 28msec has only one buffer that is accessed by all db:collection() calls in a query. Hence, the information needs to be the union.
Nicolae Brinza (nbrinza) wrote : | # |
> "DataGuides serve as dynamic schemas, generated from the database." What we generate is a
> schema from the query.
Still, it is a data schema, not a query schema. The one in the paper would be a Database DataGuide and ours would be Query DataGuide. I would agree to change it to QueryDataguide but I don't think there would be any confusions if it was simply called Dataguide.
> I think we will run into a problem. 28msec has only one buffer that is
> accessed by all db:collection() calls in a query. Hence, the information
> needs to be the union.
If there is no way of removing that limitation then we can overcome this by doing an union on all db:collection() dataguides and this will ensure correctness. But it would be a pity to loose the individually computed dataguides for each separate call. Still, if the name of fields of different collections are mostly disjoint sets, then we won't loose much of the improvement.
Again I suggest leaving this until I start implementing the push-down of projection info into the db:collection() calls. It has no impact on jn:parse() -- these dataguides can still be computed and kept individually for each call even if we do an union on db:collection() calls.
--
Nicolae Brinza (nbrinza) wrote : | # |
I've done some additional testing, and these are the results:
For the xray query, the largest that we have in the testsuite, compilation time with --compile-only is pretty much the same with and without the dataguide computaiton, at around ~0.08 sec.
With a specially constructed query that looks like this: (see dataguide-29.jq test)
let $col := dml:collection()
let $col2 := ($col.cat1, $col.cat2, ... , $col.cat10)
return $col2.category.
the compilation time goes from ~0.7s without the dataguide to ~10s with the dataguide enabled, so it is significant. But this is a worst-case scenario. The resulting dataguide is an object 2000-levels deep.
The compilation can be improved significantly by:
- keeping track of the "leaves" nodes in the dataguide tree
- rewriting a bit the dataguide structure to store the trees incrementally instead of cloning them
- adding a depth cutoff
What do you think?
- 11488. By Nicolae Brinza on 2013-07-23
-
Added a stress-test for the dataguide computation
- 11489. By Nicolae Brinza on 2013-07-23
-
Merged with Zorba trunk
- 11490. By Nicolae Brinza on 2013-07-23
-
Fixed the build
- 11491. By Markos Zaharioudakis on 2013-07-30
-
cosmetic
- 11492. By Markos Zaharioudakis on 2013-07-30
-
merge from trunk
Superseded by use-dataguide merge proposal.
Unmerged revisions
- 11492. By Markos Zaharioudakis on 2013-07-30
-
merge from trunk
- 11491. By Markos Zaharioudakis on 2013-07-30
-
cosmetic
- 11490. By Nicolae Brinza on 2013-07-23
-
Fixed the build
- 11489. By Nicolae Brinza on 2013-07-23
-
Merged with Zorba trunk
- 11488. By Nicolae Brinza on 2013-07-23
-
Added a stress-test for the dataguide computation
- 11487. By Nicolae Brinza on 2013-07-08
-
Dataguide cleanup
- 11486. By Nicolae Brinza on 2013-07-08
-
Dataguide fixes for the remote queue; cleanup; documentation;
- 11485. By Nicolae Brinza on 2013-07-05
-
Re-enabled the dataguide
- 11484. By Nicolae Brinza on 2013-07-04
-
Disabled dataguide for testing
- 11483. By Nicolae Brinza on 2013-07-04
-
Merged with Zorba trunk
Validation queue starting for the following merge proposals: /code.launchpad .net/~zorba- coders/ zorba/dataguide /+merge/ 173026
https:/
Progress dashboard at http:// jenkins. lambda. nu/view/ ValidationQueue