@@ -49,7 +49,7 @@ import (
49
49
"errors"
50
50
"fmt"
51
51
"internal/profile"
52
- "io/ioutil "
52
+ "io"
53
53
"os"
54
54
"sort"
55
55
"strconv"
@@ -145,51 +145,52 @@ type Profile struct {
145
145
146
146
var wantHdr = "GO PREPROFILE V1\n "
147
147
148
- func isPreProfileFile (filename string ) (bool , error ) {
149
- content , err := ioutil .ReadFile (filename )
150
- if err != nil {
151
- return false , err
148
+ func isPreProfileFile (r * bufio.Reader ) (bool , error ) {
149
+ hdr , err := r .Peek (len (wantHdr ))
150
+ if err == io .EOF {
151
+ // Empty file.
152
+ return false , nil
153
+ } else if err != nil {
154
+ return false , fmt .Errorf ("error reading profile header: %w" , err )
152
155
}
153
156
154
- /* check the header */
155
- fileContent := string (content )
156
- if strings .HasPrefix (fileContent , wantHdr ) {
157
- return true , nil
158
- }
159
- return false , nil
157
+ return string (hdr ) == wantHdr , nil
160
158
}
161
159
162
160
// New generates a profile-graph from the profile or pre-processed profile.
163
161
func New (profileFile string ) (* Profile , error ) {
164
- var profile * Profile
165
- var err error
166
- isPreProf , err := isPreProfileFile (profileFile )
162
+ f , err := os .Open (profileFile )
167
163
if err != nil {
168
164
return nil , fmt .Errorf ("error opening profile: %w" , err )
169
165
}
170
- if ! isPreProf {
171
- profile , err = processProto (profileFile )
172
- if err != nil {
173
- return nil , fmt .Errorf ("error processing pprof PGO profile: %w" , err )
174
- }
175
- } else {
176
- profile , err = processPreprof (profileFile )
166
+ defer f .Close ()
167
+
168
+ r := bufio .NewReader (f )
169
+
170
+ isPreProf , err := isPreProfileFile (r )
171
+ if err != nil {
172
+ return nil , fmt .Errorf ("error processing profile header: %w" , err )
173
+ }
174
+
175
+ if isPreProf {
176
+ profile , err := processPreprof (r )
177
177
if err != nil {
178
178
return nil , fmt .Errorf ("error processing preprocessed PGO profile: %w" , err )
179
179
}
180
+ return profile , nil
181
+ }
182
+
183
+ profile , err := processProto (r )
184
+ if err != nil {
185
+ return nil , fmt .Errorf ("error processing pprof PGO profile: %w" , err )
180
186
}
181
187
return profile , nil
182
188
183
189
}
184
190
185
191
// processProto generates a profile-graph from the profile.
186
- func processProto (profileFile string ) (* Profile , error ) {
187
- f , err := os .Open (profileFile )
188
- if err != nil {
189
- return nil , fmt .Errorf ("error opening profile: %w" , err )
190
- }
191
- defer f .Close ()
192
- p , err := profile .Parse (f )
192
+ func processProto (r io.Reader ) (* Profile , error ) {
193
+ p , err := profile .Parse (r )
193
194
if errors .Is (err , profile .ErrNoData ) {
194
195
// Treat a completely empty file the same as a profile with no
195
196
// samples: nothing to do.
@@ -242,8 +243,8 @@ func processProto(profileFile string) (*Profile, error) {
242
243
}
243
244
244
245
// processPreprof generates a profile-graph from the pre-procesed profile.
245
- func processPreprof (preprofileFile string ) (* Profile , error ) {
246
- namedEdgeMap , totalWeight , err := createNamedEdgeMapFromPreprocess (preprofileFile )
246
+ func processPreprof (r io. Reader ) (* Profile , error ) {
247
+ namedEdgeMap , totalWeight , err := createNamedEdgeMapFromPreprocess (r )
247
248
if err != nil {
248
249
return nil , err
249
250
}
@@ -297,14 +298,8 @@ func postProcessNamedEdgeMap(weight map[NamedCallEdge]int64, weightVal int64) (e
297
298
298
299
// restore NodeMap information from a preprocessed profile.
299
300
// The reader can refer to the format of preprocessed profile in cmd/preprofile/main.go.
300
- func createNamedEdgeMapFromPreprocess (preprofileFile string ) (edgeMap NamedEdgeMap , totalWeight int64 , err error ) {
301
- readFile , err := os .Open (preprofileFile )
302
- if err != nil {
303
- return NamedEdgeMap {}, 0 , fmt .Errorf ("error opening preprocessed profile: %w" , err )
304
- }
305
- defer readFile .Close ()
306
-
307
- fileScanner := bufio .NewScanner (readFile )
301
+ func createNamedEdgeMapFromPreprocess (r io.Reader ) (edgeMap NamedEdgeMap , totalWeight int64 , err error ) {
302
+ fileScanner := bufio .NewScanner (r )
308
303
fileScanner .Split (bufio .ScanLines )
309
304
weight := make (map [NamedCallEdge ]int64 )
310
305
0 commit comments