libct/cg/fscommon: rename/facelift GetCgroupParamKeyValue

1. This is the only function in the package with Get prefix
   that does not read a file (but parses a string). Rename
   accordingly, and convert the callers.

	GetCgroupParamKeyValue -> ParseKeyValue

2. Use strings.Split rather than strings.Fields. Split by a space
   is 2x faster, plus we can limit the splitting. The downside is
   we have to strip a newline in one of the callers.

3. Improve the doc and the code flow.

4. Fix a test case with invalid data (spaces at BOL).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2021-02-19 02:10:51 -08:00
parent 1880d2fc05
commit 494f900e91
7 changed files with 22 additions and 21 deletions
+1 -1
View File
@@ -97,7 +97,7 @@ func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
sc := bufio.NewScanner(f)
for sc.Scan() {
t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
t, v, err := fscommon.ParseKeyValue(sc.Text())
if err != nil {
return err
}
+1 -1
View File
@@ -112,7 +112,7 @@ func TestCpuStats(t *testing.T) {
throttledTime = uint64(18446744073709551615)
)
cpuStatContent := fmt.Sprintf("nr_periods %d\n nr_throttled %d\n throttled_time %d\n",
cpuStatContent := fmt.Sprintf("nr_periods %d\nnr_throttled %d\nthrottled_time %d\n",
nrPeriods, nrThrottled, throttledTime)
helper.writeFileContents(map[string]string{
"cpu.stat": cpuStatContent,
+1 -1
View File
@@ -188,7 +188,7 @@ func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
sc := bufio.NewScanner(statsFile)
for sc.Scan() {
t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
t, v, err := fscommon.ParseKeyValue(sc.Text())
if err != nil {
return fmt.Errorf("failed to parse memory.stat (%q) - %v", sc.Text(), err)
}
+1 -1
View File
@@ -57,7 +57,7 @@ func statCpu(dirPath string, stats *cgroups.Stats) error {
sc := bufio.NewScanner(f)
for sc.Scan() {
t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
t, v, err := fscommon.ParseKeyValue(sc.Text())
if err != nil {
return err
}
+2 -1
View File
@@ -4,6 +4,7 @@ package fs2
import (
"strconv"
"strings"
"github.com/pkg/errors"
@@ -48,7 +49,7 @@ func statHugeTlb(dirPath string, stats *cgroups.Stats) error {
if err != nil {
return errors.Wrap(err, "failed to read stats")
}
_, value, err = fscommon.GetCgroupParamKeyValue(contents)
_, value, err = fscommon.ParseKeyValue(strings.TrimSuffix(contents, "\n"))
if err != nil {
return errors.Wrap(err, "failed to parse "+fileName)
}
+1 -1
View File
@@ -82,7 +82,7 @@ func statMemory(dirPath string, stats *cgroups.Stats) error {
sc := bufio.NewScanner(statsFile)
for sc.Scan() {
t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
t, v, err := fscommon.ParseKeyValue(sc.Text())
if err != nil {
return errors.Wrapf(err, "failed to parse memory.stat (%q)", sc.Text())
}
+15 -15
View File
@@ -35,22 +35,22 @@ func ParseUint(s string, base, bitSize int) (uint64, error) {
return value, nil
}
// GetCgroupParamKeyValue parses a space-separated "name value" kind of cgroup
// parameter and returns its components. For example, "io_service_bytes 1234"
// will return as "io_service_bytes", 1234.
func GetCgroupParamKeyValue(t string) (string, uint64, error) {
parts := strings.Fields(t)
switch len(parts) {
case 2:
value, err := ParseUint(parts[1], 10, 64)
if err != nil {
return "", 0, fmt.Errorf("unable to convert to uint64: %v", err)
}
return parts[0], value, nil
default:
return "", 0, ErrNotValidFormat
// ParseKeyValue parses a space-separated "name value" kind of cgroup
// parameter and returns its key as a string, and its value as uint64
// (ParseUint is used to convert the value). For example,
// "io_service_bytes 1234" will be returned as "io_service_bytes", 1234.
func ParseKeyValue(t string) (string, uint64, error) {
parts := strings.SplitN(t, " ", 3)
if len(parts) != 2 {
return "", 0, fmt.Errorf("line %q is not in key value format", t)
}
value, err := ParseUint(parts[1], 10, 64)
if err != nil {
return "", 0, fmt.Errorf("unable to convert to uint64: %v", err)
}
return parts[0], value, nil
}
// GetCgroupParamUint reads a single uint64 value from the specified cgroup file.