func (stats *Stats) AccountDirect(op FuseOp) {
	opStats := stats.getPerFuseOpStats(op)
	atomic.AddUint64(&opStats.Direct, 1)
}
AccountDirect increases the direct counter for the given FuseOp by 1.

Operations that count towards direct are those FUSE operations received by sourcachefs that
were served locally (because the file system was explicitly configured as such).
package stats
import (
	"sync/atomic"
)
type OsOp int
const (
	CloseOsOp    OsOp = iota
	LstatOsOp    OsOp = iota
	MkdirOsOp    OsOp = iota
	OpenOsOp     OsOp = iota
	ReadOsOp     OsOp = iota
	ReaddirOsOp  OsOp = iota
	ReadlinkOsOp OsOp = iota
	RemoveOsOp   OsOp = iota
	RenameOsOp   OsOp = iota
)
var allOsOps = []OsOp{CloseOsOp, LstatOsOp, MkdirOsOp, OpenOsOp, ReadOsOp, ReaddirOsOp, ReadlinkOsOp, RemoveOsOp, RenameOsOp}
type OpDomain int
const (
	LocalDomain OpDomain = iota
	RemoteDomain OpDomain = iota
)
var allDomains = []OpDomain{LocalDomain, RemoteDomain}
type PerOsOpStats struct {
	LocalCount  uint64
	RemoteCount uint64
}
type FuseOp int
const (
	AttrFuseOp     FuseOp = iota
	LookupFuseOp   FuseOp = iota
	OpenFuseOp     FuseOp = iota
	ReadFuseOp     FuseOp = iota
	ReaddirFuseOp  FuseOp = iota
	ReadlinkFuseOp FuseOp = iota
)
var allFuseOps = []FuseOp{AttrFuseOp, LookupFuseOp, OpenFuseOp, ReadFuseOp, ReaddirFuseOp, ReadlinkFuseOp}
type PerFuseOpStats struct {
	CacheHits   uint64
	CacheMisses uint64
	Direct      uint64
}
type OsStatsUpdater interface {
	AccountOsOp(OpDomain, OsOp)
	AccountReadBytes(OpDomain, int)
}
type FuseStatsUpdater interface {
	AccountCacheHit(FuseOp)
	AccountCacheMiss(FuseOp)
	AccountDirect(FuseOp)
}
type Clearer interface {
	Clear()
}
type Updater interface {
	OsStatsUpdater
	FuseStatsUpdater
	Clearer
}
type Retriever interface {
	GetOsOpStats() map[OsOp]PerOsOpStats
	GetReadStats() map[OpDomain]Bytes
	GetFuseOpStats() map[FuseOp]PerFuseOpStats
}
type Bytes uint64
type Stats struct {
	osOpStats   map[OsOp]*PerOsOpStats
	readStats   map[OpDomain]*Bytes
	fuseOpStats map[FuseOp]*PerFuseOpStats
}
var _ FuseStatsUpdater = (*Stats)(nil)
var _ OsStatsUpdater = (*Stats)(nil)
var _ Clearer = (*Stats)(nil)
var _ Retriever = (*Stats)(nil)
var _ Updater = (*Stats)(nil)
func NewStats() *Stats {
	osOpStats := make(map[OsOp]*PerOsOpStats)
	for _, op := range allOsOps {
		osOpStats[op] = &PerOsOpStats{}
	}
	readStats := make(map[OpDomain]*Bytes)
	for _, domain := range allDomains {
		readStats[domain] = new(Bytes)
	}
	fuseOpStats := make(map[FuseOp]*PerFuseOpStats)
	for _, op := range allFuseOps {
		fuseOpStats[op] = &PerFuseOpStats{}
	}
	return &Stats{
		osOpStats:   osOpStats,
		readStats:   readStats,
		fuseOpStats: fuseOpStats,
	}
}
func (stats *Stats) Clear() {
	for _, op := range allOsOps {
		opStats := stats.osOpStats[op]
		atomic.StoreUint64(&opStats.LocalCount, 0)
		atomic.StoreUint64(&opStats.RemoteCount, 0)
	}
	for _, domain := range allDomains {
		atomic.StoreUint64((*uint64)(stats.readStats[domain]), 0)
	}
	for _, op := range allFuseOps {
		opStats := stats.fuseOpStats[op]
		atomic.StoreUint64(&opStats.CacheHits, 0)
		atomic.StoreUint64(&opStats.CacheMisses, 0)
		atomic.StoreUint64(&opStats.Direct, 0)
	}
}
func (stats *Stats) getPerOsOpStats(op OsOp) *PerOsOpStats {
	opStats, ok := stats.osOpStats[op]
	if !ok {
		panic("OS operation not previously registered in map")
	}
	return opStats
}
func (stats *Stats) getPerFuseOpStats(op FuseOp) *PerFuseOpStats {
	opStats, ok := stats.fuseOpStats[op]
	if !ok {
		panic("Fuse operation not previously registered in map")
	}
	return opStats
}
func (stats *Stats) AccountOsOp(domain OpDomain, op OsOp) {
	opStats := stats.getPerOsOpStats(op)
	switch domain {
	case LocalDomain:
		atomic.AddUint64(&opStats.LocalCount, 1)
	case RemoteDomain:
		atomic.AddUint64(&opStats.RemoteCount, 1)
	default:
		panic("Unknown domain")
	}
}
func (stats *Stats) AccountReadBytes(domain OpDomain, bytes int) {
	count, ok := stats.readStats[domain]
	if !ok {
		panic("Unknown domain")
	}
	atomic.AddUint64((*uint64)(count), uint64(bytes))
}
func (stats *Stats) AccountCacheHit(op FuseOp) {
	opStats := stats.getPerFuseOpStats(op)
	atomic.AddUint64(&opStats.CacheHits, 1)
}
func (stats *Stats) AccountCacheMiss(op FuseOp) {
	opStats := stats.getPerFuseOpStats(op)
	atomic.AddUint64(&opStats.CacheMisses, 1)
}