rustdoc: Implement a parallel fold

This commit is contained in:
Brian Anderson 2012-02-20 22:08:24 -08:00
parent 7599d2dd51
commit d4f57620ae
3 changed files with 92 additions and 27 deletions

View File

@ -11,6 +11,8 @@ export default_seq_fold_res;
export default_seq_fold_iface;
export default_seq_fold_impl;
export default_seq_fold_type;
export default_par_fold;
export default_par_fold_mod;
enum fold<T> = t<T>;
@ -86,6 +88,22 @@ fn default_seq_fold<T:copy>(ctxt: T) -> fold<T> {
)
}
fn default_par_fold<T:send>(ctxt: T) -> fold<T> {
mk_fold(
ctxt,
{|f, d| default_seq_fold_crate(f, d)},
{|f, d| default_seq_fold_item(f, d)},
{|f, d| default_par_fold_mod(f, d)},
{|f, d| default_seq_fold_fn(f, d)},
{|f, d| default_seq_fold_const(f, d)},
{|f, d| default_seq_fold_enum(f, d)},
{|f, d| default_seq_fold_res(f, d)},
{|f, d| default_seq_fold_iface(f, d)},
{|f, d| default_seq_fold_impl(f, d)},
{|f, d| default_seq_fold_type(f, d)}
)
}
fn default_seq_fold_crate<T>(
fold: fold<T>,
doc: doc::cratedoc
@ -109,37 +127,54 @@ fn default_seq_fold_mod<T>(
{
item: fold.fold_item(fold, doc.item),
items: ~vec::map(*doc.items) {|itemtag|
alt itemtag {
doc::modtag(moddoc) {
doc::modtag(fold.fold_mod(fold, moddoc))
}
doc::fntag(fndoc) {
doc::fntag(fold.fold_fn(fold, fndoc))
}
doc::consttag(constdoc) {
doc::consttag(fold.fold_const(fold, constdoc))
}
doc::enumtag(enumdoc) {
doc::enumtag(fold.fold_enum(fold, enumdoc))
}
doc::restag(resdoc) {
doc::restag(fold.fold_res(fold, resdoc))
}
doc::ifacetag(ifacedoc) {
doc::ifacetag(fold.fold_iface(fold, ifacedoc))
}
doc::impltag(impldoc) {
doc::impltag(fold.fold_impl(fold, impldoc))
}
doc::tytag(tydoc) {
doc::tytag(fold.fold_type(fold, tydoc))
}
}
fold_itemtag(fold, itemtag)
}
with doc
}
}
fn default_par_fold_mod<T:send>(
fold: fold<T>,
doc: doc::moddoc
) -> doc::moddoc {
{
item: fold.fold_item(fold, doc.item),
items: ~util::parmap(*doc.items) {|itemtag|
fold_itemtag(fold, itemtag)
}
with doc
}
}
fn fold_itemtag<T>(fold: fold<T>, doc: doc::itemtag) -> doc::itemtag {
alt doc {
doc::modtag(moddoc) {
doc::modtag(fold.fold_mod(fold, moddoc))
}
doc::fntag(fndoc) {
doc::fntag(fold.fold_fn(fold, fndoc))
}
doc::consttag(constdoc) {
doc::consttag(fold.fold_const(fold, constdoc))
}
doc::enumtag(enumdoc) {
doc::enumtag(fold.fold_enum(fold, enumdoc))
}
doc::restag(resdoc) {
doc::restag(fold.fold_res(fold, resdoc))
}
doc::ifacetag(ifacedoc) {
doc::ifacetag(fold.fold_iface(fold, ifacedoc))
}
doc::impltag(impldoc) {
doc::impltag(fold.fold_impl(fold, impldoc))
}
doc::tytag(tydoc) {
doc::tytag(fold.fold_type(fold, tydoc))
}
}
}
fn default_seq_fold_fn<T>(
fold: fold<T>,
doc: doc::fndoc
@ -238,4 +273,14 @@ fn default_fold_should_produce_same_enums() {
let fld = default_seq_fold(());
let folded = fld.fold_crate(fld, doc);
assert doc == folded;
}
}
#[test]
fn default_parallel_fold_should_produce_same_doc() {
let source = "mod a { fn b() { } mod c { fn d() { } } }";
let ast = parse::from_str(source);
let doc = extract::extract(ast, "");
let fld = default_par_fold(());
let folded = fld.fold_crate(fld, doc);
assert doc == folded;
}

View File

@ -34,3 +34,4 @@ mod sort_pass;
mod sort_item_name_pass;
mod sort_item_type_pass;
mod reexport_pass;
mod util;

19
src/rustdoc/util.rs Normal file
View File

@ -0,0 +1,19 @@
export parmap;
fn parmap<T:send, U:send>(v: [T], f: fn~(T) -> U) -> [U] {
let futures = vec::map(v) {|elt|
future::spawn {||
f(elt)
}
};
vec::map(futures) {|future|
future::get(future)
}
}
#[test]
fn test_parallel_map() {
let i = [1, 2, 3, 4];
let j = parmap(i) {|e| e + 1 };
assert j == [2, 3, 4, 5];
}