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

Side by Side Diff: common/dirwalk/tests/tools/gendir/generate.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: Major rewrite of the code. Created 4 years, 1 month 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 "fmt"
9 "io"
10 "log"
11 "math/rand"
12 "os"
13 "path"
14
15 "github.com/dustin/go-humanize"
16 )
17
18 const (
19 blockSize uint64 = 1 * 1024 * 1024 // 1 Megabyte
20 )
21
22 func writeFile(fileName string, fileContent io.Reader, fileSize uint64) {
23 f, err := os.Create(fileName)
24 if err != nil {
25 log.Fatal(err)
26 }
27 defer f.Close()
28
29 var written uint64
30 for written < fileSize {
mcgreevy_g 2017/06/27 03:29:17 I'm pretty sure that you can achieve this by just
31 content := make([]byte, min(fileSize-written, blockSize))
32
33 // Generate a block of content
34 read, err := fileContent.Read(content)
35 if err != nil {
36 log.Fatal(err)
37 }
38
39 // Write the block of content
40 write, err := f.Write(content[0:read])
41 if err != nil {
42 log.Fatal(err)
43 }
44
45 written += uint64(write)
46 }
47 }
48
49 const (
50 fileNameMinSize uint64 = 4
51 fileNameMaxSize uint64 = 20
52 )
53
54 type fileType int
55
56 const (
57 fileTypeBinaryRandom fileType = iota // Truly random binary data (tota lly uncompressible)
58 fileTypeTextRandom // Truly random text data (mostly uncompressible)
59 fileTypeBinaryRepeated // Repeated binary data (compress ible)
60 fileTypeTextRepeated // Repeated text data (very compr essible)
61 fileTypeTextLorem // Lorem Ipsum txt data (very com pressible)
62
63 fileTypeMax
64 )
65
66 var fileTypeName = []string{
67 "Random Binary",
68 "Random Text",
69 "Repeated Binary",
70 "Repeated Text",
71 "Lorem Text",
72 }
73
74 func (f fileType) String() string {
75 return fileTypeName[int(f)]
76 }
77
78 // Generate num files between (min, max) size
79 func generateFiles(r *rand.Rand, dir string, num uint64, fileSizeMin uint64, fil eSizeMax uint64) {
80 for i := uint64(0); i < num; i++ {
81 var fileName string
82 var filePath string
83 for true {
mcgreevy_g 2017/06/27 03:29:17 This can be expressed as: for { Note: this patte
84 fileName = fileNameRandom(r, randBetween(r, fileNameMinS ize, fileNameMaxSize))
85 filePath = path.Join(dir, fileName)
86 if _, err := os.Stat(filePath); os.IsNotExist(err) {
87 break
88 }
89 }
90 fileSize := randBetween(r, fileSizeMin, fileSizeMax)
91 filetype := fileType(r.Intn(int(fileTypeMax)))
92
93 var fileContent io.Reader
94 switch filetype {
95 case fileTypeBinaryRandom:
96 fileContent = RandomBinaryGenerator(r)
97 case fileTypeTextRandom:
98 fileContent = RandomTextGenerator(r)
99 case fileTypeBinaryRepeated:
100 fileContent = RepeatedBinaryGenerator(r)
101 case fileTypeTextRepeated:
102 fileContent = RepeatedTextGenerator(r)
103 case fileTypeTextLorem:
104 fileContent = LoremTextGenerator()
105 }
106
107 if num < 1000 {
108 fmt.Printf("File: %-40s %-20s (%s)\n", fileName, filetyp e.String(), humanize.Bytes(fileSize))
109 }
110 writeFile(filePath, fileContent, fileSize)
111 }
112 }
113
114 // Generate num directories
115 func generateDirs(r *rand.Rand, dir string, num uint64) []string {
116 var result []string
117
118 for i := uint64(0); i < num; i++ {
119 var dirname string
120 var dirpath string
121 for true {
122 dirname = fileNameRandom(r, randBetween(r, fileNameMinSi ze, fileNameMaxSize))
123 dirpath = path.Join(dir, dirname)
124 if _, err := os.Stat(dirpath); os.IsNotExist(err) {
125 break
126 }
127 }
128
129 if err := os.MkdirAll(dirpath, 0755); err != nil {
130 log.Fatal(err)
131 }
132 result = append(result, dirpath)
133 }
134 return result
135 }
136
137 type fileSettings struct {
138 MinNumber uint64
139 MaxNumber uint64
140 MinSize uint64
141 MaxSize uint64
142 }
143
144 type dirSettings struct {
145 Number []uint64
146 MinFileDepth uint64
147 }
148
149 type treeSettings struct {
150 Files []fileSettings
151 Dir dirSettings
152 }
153
154 func generateTreeInternal(r *rand.Rand, dir string, depth uint64, settings *tree Settings) {
155 fmt.Printf("%04d:%s -->\n", depth, dir)
156 // Generate the files in this directory
157 if depth >= settings.Dir.MinFileDepth {
158 for _, files := range settings.Files {
159 numfiles := randBetween(r, files.MinNumber, files.MaxNum ber)
160 fmt.Printf("%04d:%s: Generating %d files (between %s and %s)\n", depth, dir, numfiles, humanize.Bytes(files.MinSize), humanize.Bytes(fil es.MaxSize))
161 generateFiles(r, dir, numfiles, files.MinSize, files.Max Size)
162 }
163 }
164
165 // Generate another depth of directories
166 if depth < uint64(len(settings.Dir.Number)) {
167 numdirs := settings.Dir.Number[depth]
168 fmt.Printf("%04d:%s: Generating %d directories\n", depth, dir, n umdirs)
169 for _, childpath := range generateDirs(r, dir, numdirs) {
170 generateTreeInternal(r, childpath, depth+1, settings)
171 }
172 }
173 fmt.Printf("%04d:%s <--\n", depth, dir)
174 }
175
176 func generateTree(r *rand.Rand, rootdir string, settings *treeSettings) {
177 generateTreeInternal(r, rootdir, 0, settings)
178 return
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698