ryochack
8/7/2013 - 1:30 PM

finder_waitgroup.go

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sync"
)

var wg sync.WaitGroup

// Expand filelist from path.
func expand(path string, ch chan<- string) {
	list, err := ioutil.ReadDir(path)
	if err != nil {
		fmt.Fprintf(os.Stderr, "expand error[%s]: %v\n", path, err)
	}
	for _, finfo := range list {
		fullpath := path + string(os.PathSeparator) + finfo.Name()
		ch <- fullpath
		if finfo.IsDir() {
			wg.Add(1)
			go expand(fullpath, ch)
		}
	}
	wg.Done()
}

// Reduce expand data.
func reduce(chIn <-chan string, chOut chan<- string) {
	/* do something */
	for msg := range chIn {
		chOut <- msg
	}
}

func search(path string) <-chan string {
	chExpand := make(chan string)
	chReduce := make(chan string)
	go func() {
		wg.Add(1)
		expand(path, chExpand)
		wg.Wait()
		close(chExpand)
	}()
	go func() {
		reduce(chExpand, chReduce)
		close(chReduce)
	}()
	return chReduce
}

func main() {
	if (len(os.Args) < 2) {
		fmt.Fprintln(os.Stderr, "Require path")
		os.Exit(1)
	}

	cpus := runtime.NumCPU()
	runtime.GOMAXPROCS(cpus)

	path := os.Args[1]
	ch := search(path)

	for msg := range ch {
		fmt.Println(msg)
	}

	fmt.Println("exit")
}