go-wise / pmap.go

/* Parallel map implementation */
package main

import (
	"fmt"
	"os"
)

// Map function type, for simplicity we're using float64 -> float64
type MapFn func(float64) (float64, os.Error)

// Computation result.
type result struct {
	index int
	result float64
	error os.Error
}

// Parallel map.
func pmap(fn MapFn, items []float64) (out []float64, err os.Error) {
	ch := make(chan *result, len(items))
	for i, v := range items  {
		// We pass i, v as parameters to avoid skope errors (otherwise they'll
		// be the same for every goroutine)
		go func(i int, v float64) {
			r, e := fn(v)
			ch <- &result{i, r, e}
		}(i, v)
	}

	out = make([]float64, len(items))
	for _, _ = range items  {
		if res := <-ch; res.error != nil {
			return out, res.error
		} else {
			out[res.index] = res.result
		}
	}

	return out, nil
}

// Example
func inverse(i float64) (float64, os.Error) {
	if (i == 0.) {
		return 0, os.NewError("can't invert 0.0")
	}
	return 1/i, nil
}

func main() {
	// Should work out fine
	if out, err := pmap(inverse, []float64{1., 2., 3., 4., 5.}); err != nil {
		fmt.Println("error:", err)
	} else {
		fmt.Println(out)
	}

	// Will return error (division by 0)
	if out, err := pmap(inverse, []float64{0., 1., 2., 3., 4.}); err != nil {
		fmt.Println("error:", err)
	} else {
		fmt.Println(out)
	}
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.