// ParseStats parses a Stats from an input io.Reader, using the format
// found in /proc/fs/xfs/stat.
556766
func ParseStats(r io.Reader) (*Stats, error) {
	const (
		// Fields parsed into stats structures.
		fieldExtentAlloc = "extent_alloc"
		fieldAbt         = "abt"
		fieldBlkMap      = "blk_map"
		fieldBmbt        = "bmbt"
		fieldDir         = "dir"
		fieldTrans       = "trans"
		fieldIg          = "ig"
		fieldLog         = "log"
		fieldRw          = "rw"
		fieldAttr        = "attr"
		fieldIcluster    = "icluster"
		fieldVnodes      = "vnodes"
		fieldBuf         = "buf"
		fieldXpc         = "xpc"

		// Unimplemented at this time due to lack of documentation.
		// fieldPushAil = "push_ail"
		// fieldXstrat  = "xstrat"
		// fieldAbtb2   = "abtb2"
		// fieldAbtc2   = "abtc2"
		// fieldBmbt2   = "bmbt2"
		// fieldIbt2    = "ibt2"
		// fieldFibt2   = "fibt2"
		// fieldQm      = "qm"
		// fieldDebug   = "debug"
	)

	var xfss Stats

	s := bufio.NewScanner(r)
	for s.Scan() {
		// Expect at least a string label and a single integer value, ex:
		//   - abt 0
		//   - rw 1 2
		ss := strings.Fields(string(s.Bytes()))
		if len(ss) < 2 {
			continue
		}
		label := ss[0]

		// Extended precision counters are uint64 values.
		if label == fieldXpc {
			us, err := util.ParseUint64s(ss[1:])
			if err != nil {
				return nil, err
			}

			xfss.ExtendedPrecision, err = extendedPrecisionStats(us)
			if err != nil {
				return nil, err
			}

			continue
		}

		// All other counters are uint32 values.
		us, err := util.ParseUint32s(ss[1:])
		if err != nil {
			return nil, err
		}

		switch label {
		case fieldExtentAlloc:
			xfss.ExtentAllocation, err = extentAllocationStats(us)
		case fieldAbt:
			xfss.AllocationBTree, err = btreeStats(us)
		case fieldBlkMap:
			xfss.BlockMapping, err = blockMappingStats(us)
		case fieldBmbt:
			xfss.BlockMapBTree, err = btreeStats(us)
		case fieldDir:
			xfss.DirectoryOperation, err = directoryOperationStats(us)
		case fieldTrans:
			xfss.Transaction, err = transactionStats(us)
		case fieldIg:
			xfss.InodeOperation, err = inodeOperationStats(us)
		case fieldLog:
			xfss.LogOperation, err = logOperationStats(us)
		case fieldRw:
			xfss.ReadWrite, err = readWriteStats(us)
		case fieldAttr:
			xfss.AttributeOperation, err = attributeOperationStats(us)
		case fieldIcluster:
			xfss.InodeClustering, err = inodeClusteringStats(us)
		case fieldVnodes:
			xfss.Vnode, err = vnodeStats(us)
		case fieldBuf:
			xfss.Buffer, err = bufferStats(us)
		}
		if err != nil {
			return nil, err
		}
	}

	return &xfss, s.Err()
}
1351598
func (fs DummyFS) Stat(name string) (os.FileInfo, error) {
	return nil, fs.err
}
733985
func (c *Client) Stats() ClientStats {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	return c.stats
}
490894
func (h *fs) Stat(path string) (os.FileInfo, error) {
	fi, err := os.Stat(path)
	if runtime.GOOS == "windows" && err == nil {
		fi = h.enrichFileInfo(path, fi)
	}
	return fi, err
}
1001999
func (cs *Stats) GetStatistics() StatsEntry {
	cs.mutex.Lock()
	defer cs.mutex.Unlock()
	return cs.StatsEntry
}
1296580
func (sf64 *SliceFloat64) BuildStats() (SliceFloat64Stats, error) {
	stats := NewSliceFloat64Stats()
	stats.Len = sf64.Len()
	max, err := sf64.Max()
	if err != nil {
		return stats, err
	}
	stats.Max = max
	min, err := sf64.Min()
	if err != nil {
		return stats, err
	}
	stats.Min = min
	mean, err := sf64.Mean()
	if err != nil {
		return stats, err
	}
	stats.Mean = mean
	median, err := sf64.Median()
	if err != nil {
		return stats, err
	}
	stats.Median = median
	sum, err := sf64.Sum()
	if err != nil {
		return stats, err
	}
	stats.Sum = sum
	sf64.Stats = stats
	return stats, nil
}
895383
func readWriteStats(us []uint32) (ReadWriteStats, error) {
	if l := len(us); l != 2 {
		return ReadWriteStats{}, fmt.Errorf("incorrect number of values for XFS read write stats: %d", l)
	}

	return ReadWriteStats{
		Read:  us[0],
		Write: us[1],
	}, nil
}
14238
func (p *Partition) readStatsFile() error {
	p.stats = NewMeasurementCardinalityStats()

	f, err := os.Open(p.StatsPath())
	if os.IsNotExist(err) {
		p.statsSize = 0
		return nil
	} else if err != nil {
		return err
	}
	defer f.Close()

	n, err := p.stats.ReadFrom(bufio.NewReader(f))
	if err != nil {
		return err
	}
	p.statsSize = n

	return nil
}
307077
func GetStats() (stats Stats, err error) {
	var memInfo memoryStatusEx
	memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
	if mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))); mem == 0 {
		err = syscall.GetLastError()
	} else {
		stats.TotalRAM = memInfo.ullTotalPhys
	}

	return stats, err
}
184897
func (fs *FileSet) Stats() MeasurementCardinalityStats {
	stats := make(MeasurementCardinalityStats)
	mitr := fs.MeasurementIterator()
	if mitr == nil {
		return stats
	}

	for {
		// Iterate over each measurement and set cardinality.
		mm := mitr.Next()
		if mm == nil {
			return stats
		}

		// Obtain all series for measurement.
		sitr := fs.MeasurementSeriesIDIterator(mm.Name())
		if sitr == nil {
			continue
		}

		// All iterators should be series id set iterators except legacy 1.x data.
		// Skip if it does not conform as aggregation would be too slow.
		ssitr, ok := sitr.(tsdb.SeriesIDSetIterator)
		if !ok {
			continue
		}

		// Set cardinality for the given measurement.
		stats[string(mm.Name())] = int(ssitr.SeriesIDSet().Cardinality())
	}
}
1029956
func ReadProcDiskstats(procfs string) ([]Diskstats, error) {
	file, err := os.Open(path.Join(procfs, procDiskstatsPath))
	if err != nil {
		return nil, err
	}
	defer file.Close()

	diskstats := []Diskstats{}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		d := &Diskstats{}
		d.IoStatsCount, err = fmt.Sscanf(scanner.Text(), procDiskstatsFormat,
			&d.MajorNumber,
			&d.MinorNumber,
			&d.DeviceName,
			&d.ReadIOs,
			&d.ReadMerges,
			&d.ReadSectors,
			&d.ReadTicks,
			&d.WriteIOs,
			&d.WriteMerges,
			&d.WriteSectors,
			&d.WriteTicks,
			&d.IOsInProgress,
			&d.IOsTotalTicks,
			&d.WeightedIOTicks,
			&d.DiscardIOs,
			&d.DiscardMerges,
			&d.DiscardSectors,
			&d.DiscardTicks,
		)
		// The io.EOF error can be safely ignored because it just means we read fewer than
		// the full 18 fields.
		if err != nil && err != io.EOF {
			return diskstats, err
		}
		if d.IoStatsCount == 14 || d.IoStatsCount == 18 {
			diskstats = append(diskstats, *d)
		}
	}
	return diskstats, scanner.Err()
}
1011182
func ReadDiskStats(stats *DiskStats) error {
	// Open the process disk IO counter file
	inf, err := os.Open(fmt.Sprintf("/proc/%d/io", os.Getpid()))
	if err != nil {
		return err
	}
	defer inf.Close()
	in := bufio.NewReader(inf)

	// Iterate over the IO counter, and extract what we need
	for {
		// Read the next line and split to key and value
		line, err := in.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				return nil
			}
			return err
		}
		parts := strings.Split(line, ":")
		if len(parts) != 2 {
			continue
		}
		key := strings.TrimSpace(parts[0])
		value, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64)
		if err != nil {
			return err
		}

		// Update the counter based on the key
		switch key {
		case "syscr":
			stats.ReadCount = value
		case "syscw":
			stats.WriteCount = value
		case "rchar":
			stats.ReadBytes = value
		case "wchar":
			stats.WriteBytes = value
		}
	}
}
760019
func InterfaceToStats(read time.Time, v interface{}) *Stats {
	return &Stats{
		HCSStats: v.(*hcsshim.Statistics),
		Read:     read,
	}
}
615557
func ConnectStats(stats adapter.StatsAPI) (*StatsConnection, error) {
	c := newStatsConnection(stats)

	if err := c.connectClient(); err != nil {
		return nil, err
	}

	return c, nil
}
724269
func ReadStats(sysfs string) ([]*Stats, error) {
	matches, err := filepath.Glob(path.Join(sysfs, "fs/bcache/*-*"))
	if err != nil {
		return nil, err
	}

	stats := make([]*Stats, 0, len(matches))
	for _, uuidPath := range matches {
		// "*-*" in glob above indicates the name of the bcache.
		name := filepath.Base(uuidPath)

		// stats
		s, err := GetStats(uuidPath)
		if err != nil {
			return nil, err
		}

		s.Name = name
		stats = append(stats, s)
	}

	return stats, nil
}
212065
func ParseAST(r io.Reader) ([]AST, error) {
	lexer := iniLexer{}
	tokens, err := lexer.Tokenize(r)
	if err != nil {
		return []AST{}, err
	}

	return parse(tokens)
}
666456
func (fs FS) NewStat() (Stat, error) {
	// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt

	f, err := os.Open(fs.Path("stat"))
	if err != nil {
		return Stat{}, err
	}
	defer f.Close()

	stat := Stat{}

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		parts := strings.Fields(scanner.Text())
		// require at least <key> <value>
		if len(parts) < 2 {
			continue
		}
		switch {
		case parts[0] == "btime":
			if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
				return Stat{}, fmt.Errorf("couldn't parse %s (btime): %s", parts[1], err)
			}
		case parts[0] == "intr":
			if stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
				return Stat{}, fmt.Errorf("couldn't parse %s (intr): %s", parts[1], err)
			}
			numberedIRQs := parts[2:]
			stat.IRQ = make([]uint64, len(numberedIRQs))
			for i, count := range numberedIRQs {
				if stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil {
					return Stat{}, fmt.Errorf("couldn't parse %s (intr%d): %s", count, i, err)
				}
			}
		case parts[0] == "ctxt":
			if stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
				return Stat{}, fmt.Errorf("couldn't parse %s (ctxt): %s", parts[1], err)
			}
		case parts[0] == "processes":
			if stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
				return Stat{}, fmt.Errorf("couldn't parse %s (processes): %s", parts[1], err)
			}
		case parts[0] == "procs_running":
			if stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
				return Stat{}, fmt.Errorf("couldn't parse %s (procs_running): %s", parts[1], err)
			}
		case parts[0] == "procs_blocked":
			if stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
				return Stat{}, fmt.Errorf("couldn't parse %s (procs_blocked): %s", parts[1], err)
			}
		case parts[0] == "softirq":
			softIRQStats, total, err := parseSoftIRQStat(line)
			if err != nil {
				return Stat{}, err
			}
			stat.SoftIRQTotal = total
			stat.SoftIRQ = softIRQStats
		case strings.HasPrefix(parts[0], "cpu"):
			cpuStat, cpuID, err := parseCPUStat(line)
			if err != nil {
				return Stat{}, err
			}
			if cpuID == -1 {
				stat.CPUTotal = cpuStat
			} else {
				for int64(len(stat.CPU)) <= cpuID {
					stat.CPU = append(stat.CPU, CPUStat{})
				}
				stat.CPU[cpuID] = cpuStat
			}
		}
	}

	if err := scanner.Err(); err != nil {
		return Stat{}, fmt.Errorf("couldn't parse %s: %s", f.Name(), err)
	}

	return stat, nil
}