Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(660)

Side by Side Diff: common/dirwalk/tests/tools/walkdir/walkers_phash.go

Issue 2054763004: luci-go/common/dirwalk: Code for walking a directory tree efficiently Base URL: https://github.com/luci/luci-go@master
Patch Set: Fixes. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package main
6
7 import (
8 "flag"
9 "fmt"
10 "io"
11 "runtime"
12
13 "github.com/dustin/go-humanize"
14 "github.com/luci/luci-go/common/isolated"
15 )
16
17 var maxworkers = flag.Int("maxworkers", 100, "Maximum number of workers to use." )
18
19 type ToHash struct {
20 filename string
21 hasdata bool
22 data []byte
23 }
24
25 // ParallelHashWalker implements Walker. It generates a hash for the contents
26 // of each found file using multiple threads.
27 type ParallelHashWalker struct {
28 BaseWalker
29 obuf io.Writer
30 workers int
31 queue *chan ToHash
32 finished chan bool
33 }
34
35 func ParallelHashWalkerWorker(name int, obuf io.Writer, queue <-chan ToHash, fin ished chan<- bool) {
36 fmt.Fprintf(obuf, "Starting hash worker %d\n", name)
37
38 var filecount uint64 = 0
M-A Ruel 2016/09/23 01:48:17 =0 not needed
39 var bytecount uint64 = 0
40 for tohash := range queue {
41 filecount += 1
M-A Ruel 2016/09/23 01:48:17 ++
42
43 var digest isolated.HexDigest
44 if tohash.hasdata {
45 bytecount += uint64(len(tohash.data))
46 digest = isolated.HashBytes(tohash.data)
47 } else {
48 d, _ := isolated.HashFile(tohash.filename)
49 bytecount += uint64(d.Size)
50 digest = isolated.HexDigest(d.Digest)
51 }
52 fmt.Fprintf(obuf, "%s: %v\n", tohash.filename, digest)
53 }
54 fmt.Fprintf(obuf, "Finished hash worker %d (hashed %d files, %s)\n", nam e, filecount, humanize.Bytes(bytecount))
55 finished <- true
56 }
57
58 func CreateParallelHashWalker(obuf io.Writer) *ParallelHashWalker {
59 var max int = *maxworkers
60
61 maxProcs := runtime.GOMAXPROCS(0)
62 if maxProcs < max {
63 max = maxProcs
64 }
65
66 numCPU := runtime.NumCPU()
67 if numCPU < maxProcs {
68 max = numCPU
69 }
70
71 if max < *maxworkers {
72 // FIXME: Warn
73 }
74
75 h := ParallelHashWalker{obuf: obuf, workers: max, finished: make(chan bo ol)}
76 return &h
77 }
78
79 func (h *ParallelHashWalker) Init() {
80 if h.queue == nil {
81 q := make(chan ToHash, h.workers)
82 h.queue = &q
83 for i := 0; i < h.workers; i++ {
84 go ParallelHashWalkerWorker(i, h.obuf, *h.queue, h.finis hed)
85 }
86 }
87 }
88
89 func (h *ParallelHashWalker) SmallFile(filename string, alldata []byte) {
90 h.BaseWalker.SmallFile(filename, alldata)
91 h.Init()
92 *h.queue <- ToHash{filename: filename, hasdata: true, data: alldata}
93 }
94
95 func (h *ParallelHashWalker) LargeFile(filename string) {
96 h.BaseWalker.LargeFile(filename)
97 h.Init()
98 *h.queue <- ToHash{filename: filename, hasdata: false}
99 }
100
101 func (h *ParallelHashWalker) Finished() {
102 h.Init()
103 close(*h.queue)
104 for i := 0; i < h.workers; i++ {
105 <-h.finished
106 }
107 fmt.Fprintln(h.obuf, "All workers finished.")
108 h.queue = nil
109 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698