mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/fs: optimize MustGetFreeSpace performance by caching the results for up to 2 seconds
This commit is contained in:
parent
fa103875a0
commit
3d0a0b3785
3 changed files with 33 additions and 31 deletions
31
lib/fs/fs.go
31
lib/fs/fs.go
|
@ -6,8 +6,10 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/filestream"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||
"golang.org/x/sys/unix"
|
||||
|
@ -296,6 +298,35 @@ func CreateFlockFile(dir string) (*os.File, error) {
|
|||
|
||||
// MustGetFreeSpace returns free space for the given directory path.
|
||||
func MustGetFreeSpace(path string) uint64 {
|
||||
// Try obtaining cached value at first.
|
||||
freeSpaceMapLock.Lock()
|
||||
defer freeSpaceMapLock.Unlock()
|
||||
|
||||
e, ok := freeSpaceMap[path]
|
||||
if ok && fasttime.UnixTimestamp()-e.updateTime < 2 {
|
||||
// Fast path - the entry is fresh.
|
||||
return e.freeSpace
|
||||
}
|
||||
|
||||
// Slow path.
|
||||
// Determine the amount of free space at path.
|
||||
e.freeSpace = mustGetFreeSpace(path)
|
||||
e.updateTime = fasttime.UnixTimestamp()
|
||||
freeSpaceMap[path] = e
|
||||
return e.freeSpace
|
||||
}
|
||||
|
||||
var (
|
||||
freeSpaceMap = make(map[string]freeSpaceEntry)
|
||||
freeSpaceMapLock sync.Mutex
|
||||
)
|
||||
|
||||
type freeSpaceEntry struct {
|
||||
updateTime uint64
|
||||
freeSpace uint64
|
||||
}
|
||||
|
||||
func mustGetFreeSpace(path string) uint64 {
|
||||
d, err := os.Open(path)
|
||||
if err != nil {
|
||||
logger.Panicf("FATAL: cannot determine free disk space on %q: %s", path, err)
|
||||
|
|
|
@ -927,7 +927,7 @@ func (pt *partition) partsMerger(mergerFunc func(isFinal bool) error) error {
|
|||
}
|
||||
|
||||
func maxRowsByPath(path string) uint64 {
|
||||
freeSpace := mustGetFreeDiskSpace(path)
|
||||
freeSpace := fs.MustGetFreeSpace(path)
|
||||
|
||||
// Calculate the maximum number of rows in the output merge part
|
||||
// by dividing the freeSpace by the number of concurrent
|
||||
|
@ -942,35 +942,6 @@ func maxRowsByPath(path string) uint64 {
|
|||
return maxRows
|
||||
}
|
||||
|
||||
func mustGetFreeDiskSpace(path string) uint64 {
|
||||
// Try obtaining the cache value at first.
|
||||
freeSpaceMapLock.Lock()
|
||||
defer freeSpaceMapLock.Unlock()
|
||||
|
||||
e, ok := freeSpaceMap[path]
|
||||
if ok && fasttime.UnixTimestamp()-e.updateTime < 2 {
|
||||
// Fast path - the entry is fresh.
|
||||
return e.freeSpace
|
||||
}
|
||||
|
||||
// Slow path.
|
||||
// Determine the amount of free space on bigPartsPath.
|
||||
e.freeSpace = fs.MustGetFreeSpace(path)
|
||||
e.updateTime = fasttime.UnixTimestamp()
|
||||
freeSpaceMap[path] = e
|
||||
return e.freeSpace
|
||||
}
|
||||
|
||||
var (
|
||||
freeSpaceMap = make(map[string]freeSpaceEntry)
|
||||
freeSpaceMapLock sync.Mutex
|
||||
)
|
||||
|
||||
type freeSpaceEntry struct {
|
||||
updateTime uint64
|
||||
freeSpace uint64
|
||||
}
|
||||
|
||||
func (pt *partition) mergeBigParts(isFinal bool) error {
|
||||
bigMergeConcurrencyLimitCh <- struct{}{}
|
||||
defer func() {
|
||||
|
|
Loading…
Reference in a new issue