浏览代码

Misc changes suggested by readability review

Should have no functional changes
Raul Silvera 8 年前
父节点
当前提交
9714e5d100
共有 4 个文件被更改,包括 109 次插入166 次删除
  1. 1
    1
      profile/encode.go
  2. 101
    159
      profile/legacy_profile.go
  3. 1
    1
      profile/profile.go
  4. 6
    5
      profile/proto.go

+ 1
- 1
profile/encode.go 查看文件

@@ -197,7 +197,7 @@ var profileDecoder = []decoder{
197 197
 		if err != nil {
198 198
 			return err
199 199
 		}
200
-		if *&m.(*Profile).stringTable[0] != "" {
200
+		if m.(*Profile).stringTable[0] != "" {
201 201
 			return errors.New("string_table[0] must be ''")
202 202
 		}
203 203
 		return nil

+ 101
- 159
profile/legacy_profile.go 查看文件

@@ -29,8 +29,8 @@ import (
29 29
 )
30 30
 
31 31
 var (
32
-	countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\n\z`)
33
-	countRE      = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`)
32
+	countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\z`)
33
+	countRE      = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\z`)
34 34
 
35 35
 	heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`)
36 36
 	heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`)
@@ -59,22 +59,14 @@ func isSpaceOrComment(line string) bool {
59 59
 // parseGoCount parses a Go count profile (e.g., threadcreate or
60 60
 // goroutine) and returns a new Profile.
61 61
 func parseGoCount(b []byte) (*Profile, error) {
62
-	r := bytes.NewBuffer(b)
63
-
64
-	var line string
65
-	var err error
66
-	for {
67
-		// Skip past comments and empty lines seeking a real header.
68
-		line, err = r.ReadString('\n')
69
-		if err != nil {
70
-			return nil, err
71
-		}
72
-		if !isSpaceOrComment(line) {
73
-			break
74
-		}
62
+	s := bufio.NewScanner(bytes.NewBuffer(b))
63
+	// Skip comments at the beginning of the file.
64
+	for s.Scan() && isSpaceOrComment(s.Text()) {
75 65
 	}
76
-
77
-	m := countStartRE.FindStringSubmatch(line)
66
+	if err := s.Err(); err != nil {
67
+		return nil, err
68
+	}
69
+	m := countStartRE.FindStringSubmatch(s.Text())
78 70
 	if m == nil {
79 71
 		return nil, errUnrecognized
80 72
 	}
@@ -85,14 +77,8 @@ func parseGoCount(b []byte) (*Profile, error) {
85 77
 		SampleType: []*ValueType{{Type: profileType, Unit: "count"}},
86 78
 	}
87 79
 	locations := make(map[uint64]*Location)
88
-	for {
89
-		line, err = r.ReadString('\n')
90
-		if err != nil {
91
-			if err == io.EOF {
92
-				break
93
-			}
94
-			return nil, err
95
-		}
80
+	for s.Scan() {
81
+		line := s.Text()
96 82
 		if isSpaceOrComment(line) {
97 83
 			continue
98 84
 		}
@@ -131,8 +117,11 @@ func parseGoCount(b []byte) (*Profile, error) {
131 117
 			Value:    []int64{n},
132 118
 		})
133 119
 	}
120
+	if err := s.Err(); err != nil {
121
+		return nil, err
122
+	}
134 123
 
135
-	if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil {
124
+	if err := parseAdditionalSections(s, p); err != nil {
136 125
 		return nil, err
137 126
 	}
138 127
 	return p, nil
@@ -455,26 +444,25 @@ func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust boo
455 444
 // parseHeap parses a heapz legacy or a growthz profile and
456 445
 // returns a newly populated Profile.
457 446
 func parseHeap(b []byte) (p *Profile, err error) {
458
-	r := bytes.NewBuffer(b)
459
-	l, err := r.ReadString('\n')
460
-	if err != nil {
461
-		return nil, errUnrecognized
447
+	s := bufio.NewScanner(bytes.NewBuffer(b))
448
+	if !s.Scan() {
449
+		return nil, s.Err()
462 450
 	}
463
-
464 451
 	p = &Profile{}
465 452
 
466 453
 	sampling := ""
467 454
 	hasAlloc := false
468 455
 
456
+	line := s.Text()
469 457
 	p.PeriodType = &ValueType{Type: "space", Unit: "bytes"}
470
-	if header := heapHeaderRE.FindStringSubmatch(l); header != nil {
471
-		sampling, p.Period, hasAlloc, err = parseHeapHeader(l)
458
+	if header := heapHeaderRE.FindStringSubmatch(line); header != nil {
459
+		sampling, p.Period, hasAlloc, err = parseHeapHeader(line)
472 460
 		if err != nil {
473 461
 			return nil, err
474 462
 		}
475
-	} else if header = growthHeaderRE.FindStringSubmatch(l); header != nil {
463
+	} else if header = growthHeaderRE.FindStringSubmatch(line); header != nil {
476 464
 		p.Period = 1
477
-	} else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil {
465
+	} else if header = fragmentationHeaderRE.FindStringSubmatch(line); header != nil {
478 466
 		p.Period = 1
479 467
 	} else {
480 468
 		return nil, errUnrecognized
@@ -497,28 +485,18 @@ func parseHeap(b []byte) (p *Profile, err error) {
497 485
 	}
498 486
 
499 487
 	locs := make(map[uint64]*Location)
500
-	for {
501
-		l, err = r.ReadString('\n')
502
-		if err != nil {
503
-			if err != io.EOF {
504
-				return nil, err
505
-			}
488
+	for s.Scan() {
489
+		line := strings.TrimSpace(s.Text())
506 490
 
507
-			if l == "" {
508
-				break
509
-			}
510
-		}
511
-
512
-		if isSpaceOrComment(l) {
491
+		if isSpaceOrComment(line) {
513 492
 			continue
514 493
 		}
515
-		l = strings.TrimSpace(l)
516 494
 
517
-		if sectionTrigger(l) != unrecognizedSection {
495
+		if sectionTrigger(line) != unrecognizedSection {
518 496
 			break
519 497
 		}
520 498
 
521
-		value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling, hasAlloc)
499
+		value, blocksize, addrs, err := parseHeapSample(line, p.Period, sampling, hasAlloc)
522 500
 		if err != nil {
523 501
 			return nil, err
524 502
 		}
@@ -545,8 +523,10 @@ func parseHeap(b []byte) (p *Profile, err error) {
545 523
 			NumLabel: map[string][]int64{"bytes": {blocksize}},
546 524
 		})
547 525
 	}
548
-
549
-	if err = parseAdditionalSections(l, r, p); err != nil {
526
+	if err := s.Err(); err != nil {
527
+		return nil, err
528
+	}
529
+	if err := parseAdditionalSections(s, p); err != nil {
550 530
 		return nil, err
551 531
 	}
552 532
 	return p, nil
@@ -678,13 +658,13 @@ func scaleHeapSample(count, size, rate int64) (int64, int64) {
678 658
 // parseContention parses a contentionz profile and returns a newly
679 659
 // populated Profile.
680 660
 func parseContention(b []byte) (p *Profile, err error) {
681
-	r := bytes.NewBuffer(b)
682
-	l, err := r.ReadString('\n')
683
-	if err != nil {
684
-		return nil, errUnrecognized
661
+	s := bufio.NewScanner(bytes.NewBuffer(b))
662
+	if !s.Scan() {
663
+		return nil, s.Err()
685 664
 	}
665
+	line := s.Text()
686 666
 
687
-	if !strings.HasPrefix(l, "--- contention") {
667
+	if !strings.HasPrefix(line, "--- contention") {
688 668
 		return nil, errUnrecognized
689 669
 	}
690 670
 
@@ -700,27 +680,18 @@ func parseContention(b []byte) (p *Profile, err error) {
700 680
 	var cpuHz int64
701 681
 	// Parse text of the form "attribute = value" before the samples.
702 682
 	const delimiter = "="
703
-	for {
704
-		l, err = r.ReadString('\n')
705
-		if err != nil {
706
-			if err != io.EOF {
707
-				return nil, err
708
-			}
709
-
710
-			if l == "" {
711
-				break
712
-			}
713
-		}
683
+	for s.Scan() {
684
+		line := s.Text()
714 685
 
715
-		if l = strings.TrimSpace(l); l == "" {
686
+		if line = strings.TrimSpace(line); line == "" {
716 687
 			continue
717 688
 		}
718 689
 
719
-		if strings.HasPrefix(l, "---") {
690
+		if strings.HasPrefix(line, "---") {
720 691
 			break
721 692
 		}
722 693
 
723
-		attr := strings.SplitN(l, delimiter, 2)
694
+		attr := strings.SplitN(line, delimiter, 2)
724 695
 		if len(attr) != 2 {
725 696
 			break
726 697
 		}
@@ -752,13 +723,17 @@ func parseContention(b []byte) (p *Profile, err error) {
752 723
 			return nil, errUnrecognized
753 724
 		}
754 725
 	}
726
+	if err := s.Err(); err != nil {
727
+		return nil, err
728
+	}
755 729
 
756 730
 	locs := make(map[uint64]*Location)
757 731
 	for {
758
-		if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") {
732
+		line := strings.TrimSpace(s.Text())
733
+		if strings.HasPrefix(line, "---") {
759 734
 			break
760 735
 		}
761
-		value, addrs, err := parseContentionSample(l, p.Period, cpuHz)
736
+		value, addrs, err := parseContentionSample(line, p.Period, cpuHz)
762 737
 		if err != nil {
763 738
 			return nil, err
764 739
 		}
@@ -782,17 +757,15 @@ func parseContention(b []byte) (p *Profile, err error) {
782 757
 			Location: sloc,
783 758
 		})
784 759
 
785
-		if l, err = r.ReadString('\n'); err != nil {
786
-			if err != io.EOF {
787
-				return nil, err
788
-			}
789
-			if l == "" {
790
-				break
791
-			}
760
+		if !s.Scan() {
761
+			break
792 762
 		}
793 763
 	}
764
+	if err := s.Err(); err != nil {
765
+		return nil, err
766
+	}
794 767
 
795
-	if err = parseAdditionalSections(l, r, p); err != nil {
768
+	if err = parseAdditionalSections(s, p); err != nil {
796 769
 		return nil, err
797 770
 	}
798 771
 
@@ -835,35 +808,16 @@ func parseContentionSample(line string, period, cpuHz int64) (value []int64, add
835 808
 
836 809
 // parseThread parses a Threadz profile and returns a new Profile.
837 810
 func parseThread(b []byte) (*Profile, error) {
838
-	r := bytes.NewBuffer(b)
839
-
840
-	var line string
841
-	var err error
842
-	for {
843
-		// Skip past comments and empty lines seeking a real header.
844
-		line, err = r.ReadString('\n')
845
-		if err != nil {
846
-			return nil, err
847
-		}
848
-		if !isSpaceOrComment(line) {
849
-			break
850
-		}
811
+	s := bufio.NewScanner(bytes.NewBuffer(b))
812
+	// Skip past comments and empty lines seeking a real header.
813
+	for s.Scan() && isSpaceOrComment(s.Text()) {
851 814
 	}
852 815
 
816
+	line := s.Text()
853 817
 	if m := threadzStartRE.FindStringSubmatch(line); m != nil {
854 818
 		// Advance over initial comments until first stack trace.
855
-		for {
856
-			line, err = r.ReadString('\n')
857
-			if err != nil {
858
-				if err != io.EOF {
859
-					return nil, err
860
-				}
861
-
862
-				if line == "" {
863
-					break
864
-				}
865
-			}
866
-			if sectionTrigger(line) != unrecognizedSection || line[0] == '-' {
819
+		for s.Scan() {
820
+			if line = s.Text(); sectionTrigger(line) != unrecognizedSection || strings.HasPrefix(line, "-") {
867 821
 				break
868 822
 			}
869 823
 		}
@@ -889,7 +843,8 @@ func parseThread(b []byte) (*Profile, error) {
889 843
 		}
890 844
 
891 845
 		var addrs []uint64
892
-		line, addrs, err = parseThreadSample(r)
846
+		var err error
847
+		line, addrs, err = parseThreadSample(s)
893 848
 		if err != nil {
894 849
 			return nil, errUnrecognized
895 850
 		}
@@ -927,7 +882,7 @@ func parseThread(b []byte) (*Profile, error) {
927 882
 		})
928 883
 	}
929 884
 
930
-	if err = parseAdditionalSections(line, r, p); err != nil {
885
+	if err := parseAdditionalSections(s, p); err != nil {
931 886
 		return nil, err
932 887
 	}
933 888
 
@@ -938,58 +893,43 @@ func parseThread(b []byte) (*Profile, error) {
938 893
 // parseThreadSample parses a symbolized or unsymbolized stack trace.
939 894
 // Returns the first line after the traceback, the sample (or nil if
940 895
 // it hits a 'same-as-previous' marker) and an error.
941
-func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) {
942
-	var l string
896
+func parseThreadSample(s *bufio.Scanner) (nextl string, addrs []uint64, err error) {
897
+	var line string
943 898
 	sameAsPrevious := false
944
-	for {
945
-		if l, err = b.ReadString('\n'); err != nil {
946
-			if err != io.EOF {
947
-				return "", nil, err
948
-			}
949
-			if l == "" {
950
-				break
951
-			}
952
-		}
953
-		if l = strings.TrimSpace(l); l == "" {
899
+	for s.Scan() {
900
+		line = strings.TrimSpace(s.Text())
901
+		if line == "" {
954 902
 			continue
955 903
 		}
956 904
 
957
-		if strings.HasPrefix(l, "---") {
905
+		if strings.HasPrefix(line, "---") {
958 906
 			break
959 907
 		}
960
-		if strings.Contains(l, "same as previous thread") {
908
+		if strings.Contains(line, "same as previous thread") {
961 909
 			sameAsPrevious = true
962 910
 			continue
963 911
 		}
964 912
 
965
-		addrs = append(addrs, parseHexAddresses(l)...)
913
+		addrs = append(addrs, parseHexAddresses(line)...)
914
+	}
915
+	if s.Err() != nil {
916
+		return "", nil, s.Err()
966 917
 	}
967
-
968 918
 	if sameAsPrevious {
969
-		return l, nil, nil
919
+		return line, nil, nil
970 920
 	}
971
-	return l, addrs, nil
921
+	return line, addrs, nil
972 922
 }
973 923
 
974 924
 // parseAdditionalSections parses any additional sections in the
975 925
 // profile, ignoring any unrecognized sections.
976
-func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) error {
977
-	for {
978
-		if sectionTrigger(l) == memoryMapSection {
979
-			break
980
-		}
981
-		// Ignore any unrecognized sections.
982
-		var err error
983
-		if l, err = b.ReadString('\n'); err != nil {
984
-			if err != io.EOF {
985
-				return err
986
-			}
987
-			if l == "" {
988
-				break
989
-			}
990
-		}
926
+func parseAdditionalSections(s *bufio.Scanner, p *Profile) error {
927
+	for sectionTrigger(s.Text()) != memoryMapSection && s.Scan() {
991 928
 	}
992
-	return p.ParseMemoryMap(b)
929
+	if err := s.Err(); err != nil {
930
+		return err
931
+	}
932
+	return p.parseMemoryMapFromScanner(s)
993 933
 }
994 934
 
995 935
 // ParseProcMaps parses a memory map in the format of /proc/self/maps.
@@ -997,36 +937,31 @@ func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) error {
997 937
 // associate locations to the corresponding mapping based on their
998 938
 // address.
999 939
 func ParseProcMaps(rd io.Reader) ([]*Mapping, error) {
1000
-	var mapping []*Mapping
940
+	s := bufio.NewScanner(rd)
941
+	return parseProcMapsFromScanner(s)
942
+}
1001 943
 
1002
-	b := bufio.NewReader(rd)
944
+func parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) {
945
+	var mapping []*Mapping
1003 946
 
1004 947
 	var attrs []string
1005 948
 	var r *strings.Replacer
1006 949
 	const delimiter = "="
1007
-	for {
1008
-		l, err := b.ReadString('\n')
1009
-		if err != nil {
1010
-			if err != io.EOF {
1011
-				return nil, err
1012
-			}
1013
-			if l == "" {
1014
-				break
1015
-			}
1016
-		}
1017
-		if l = strings.TrimSpace(l); l == "" {
950
+	for s.Scan() {
951
+		line := strings.TrimSpace(s.Text())
952
+		if line == "" {
1018 953
 			continue
1019 954
 		}
1020 955
 
1021 956
 		if r != nil {
1022
-			l = r.Replace(l)
957
+			line = r.Replace(line)
1023 958
 		}
1024
-		m, err := parseMappingEntry(l)
959
+		m, err := parseMappingEntry(line)
1025 960
 		if err != nil {
1026 961
 			if err == errUnrecognized {
1027 962
 				// Recognize assignments of the form: attr=value, and replace
1028 963
 				// $attr with value on subsequent mappings.
1029
-				if attr := strings.SplitN(l, delimiter, 2); len(attr) == 2 {
964
+				if attr := strings.SplitN(line, delimiter, 2); len(attr) == 2 {
1030 965
 					attrs = append(attrs, "$"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]))
1031 966
 					r = strings.NewReplacer(attrs...)
1032 967
 				}
@@ -1040,6 +975,9 @@ func ParseProcMaps(rd io.Reader) ([]*Mapping, error) {
1040 975
 		}
1041 976
 		mapping = append(mapping, m)
1042 977
 	}
978
+	if err := s.Err(); err != nil {
979
+		return nil, err
980
+	}
1043 981
 	return mapping, nil
1044 982
 }
1045 983
 
@@ -1047,7 +985,11 @@ func ParseProcMaps(rd io.Reader) ([]*Mapping, error) {
1047 985
 // /proc/self/maps, and overrides the mappings in the current profile.
1048 986
 // It renumbers the samples and locations in the profile correspondingly.
1049 987
 func (p *Profile) ParseMemoryMap(rd io.Reader) error {
1050
-	mapping, err := ParseProcMaps(rd)
988
+	return p.parseMemoryMapFromScanner(bufio.NewScanner(rd))
989
+}
990
+
991
+func (p *Profile) parseMemoryMapFromScanner(s *bufio.Scanner) error {
992
+	mapping, err := parseProcMapsFromScanner(s)
1051 993
 	if err != nil {
1052 994
 		return err
1053 995
 	}

+ 1
- 1
profile/profile.go 查看文件

@@ -240,7 +240,7 @@ func (p *Profile) massageMappings() {
240 240
 		if len(libRx.FindStringSubmatch(file)) > 0 {
241 241
 			continue
242 242
 		}
243
-		if strings.HasPrefix(file, "[") {
243
+		if file[0] == '[' {
244 244
 			continue
245 245
 		}
246 246
 		// Swap what we guess is main to position 0.

+ 6
- 5
profile/proto.go 查看文件

@@ -13,6 +13,8 @@
13 13
 // limitations under the License.
14 14
 
15 15
 // This file is a simple protocol buffer encoder and decoder.
16
+// The format is described at
17
+// https://developers.google.com/protocol-buffers/docs/encoding
16 18
 //
17 19
 // A protocol message must implement the message interface:
18 20
 //   decoder() []decoder
@@ -34,8 +36,8 @@ package profile
34 36
 import "errors"
35 37
 
36 38
 type buffer struct {
37
-	field int
38
-	typ   int
39
+	field int // field tag
40
+	typ   int // proto wire type code for field
39 41
 	u64   uint64
40 42
 	data  []byte
41 43
 	tmp   [16]byte
@@ -190,9 +192,8 @@ func le32(p []byte) uint32 {
190 192
 }
191 193
 
192 194
 func decodeVarint(data []byte) (uint64, []byte, error) {
193
-	var i int
194 195
 	var u uint64
195
-	for i = 0; ; i++ {
196
+	for i := 0; ; i++ {
196 197
 		if i >= 10 || i >= len(data) {
197 198
 			return 0, nil, errors.New("bad varint")
198 199
 		}
@@ -242,7 +243,7 @@ func decodeField(b *buffer, data []byte) ([]byte, error) {
242 243
 		b.u64 = uint64(le32(data[:4]))
243 244
 		data = data[4:]
244 245
 	default:
245
-		return nil, errors.New("unknown type: " + string(b.typ))
246
+		return nil, errors.New("unknown wire type: " + string(b.typ))
246 247
 	}
247 248
 
248 249
 	return data, nil