aboutsummaryrefslogblamecommitdiff
path: root/xmpp/gateway/storage.go
blob: fcc381b46e571be4489d9ba950b460078c7e81f1 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                             
 











































































                                                                                                                  
package gateway

import (
	"io/ioutil"
	"os"
	"sort"
	"sync"

	log "github.com/sirupsen/logrus"
)

// StorageQuota is a value from config parsed to bytes number
var StorageQuota uint64

// CachedStorageSize estimates the storage size between full rescans
var CachedStorageSize uint64
var StorageLock = sync.Mutex{}

// MeasureStorageSize replaces the estimated storage size with relevant data from the filesystem
func MeasureStorageSize(path string) {
	dents, err := ioutil.ReadDir(path)
	if err != nil {
		return
	}

	var total uint64
	for _, fi := range dents {
		if !fi.IsDir() {
			total += uint64(fi.Size())
		}
	}

	if total != CachedStorageSize {
		if CachedStorageSize > 0 {
			log.Warnf("Correcting cached storage size: was %v, actually %v", CachedStorageSize, total)
		}
		CachedStorageSize = total
	}
}

// CleanOldFiles purges the oldest files in a directory that exceed the limit
func CleanOldFiles(path string, limit uint64) {
	dents, err := ioutil.ReadDir(path)
	if err != nil {
		return
	}

	var total uint64
	for _, fi := range dents {
		if !fi.IsDir() {
			total += uint64(fi.Size())
		}
	}

	// sort by time
	sort.Slice(dents, func(i int, j int) bool {
		return dents[i].ModTime().Before(dents[j].ModTime())
	})

	// purge
	if total > limit {
		toPurge := total - limit

		var purgedAmount uint64
		var purgedCount uint64

		for _, fi := range dents {
			if !fi.IsDir() {
				err = os.Remove(path + string(os.PathSeparator) + fi.Name())
				if err != nil {
					log.Errorf("Couldn't remove %v: %v", fi.Name(), err)
					continue
				}

				purgedAmount += uint64(fi.Size())
				purgedCount += 1
				if purgedAmount >= toPurge {
					break
				}
			}
		}

		log.Infof("Cleaned %v bytes of %v old files", purgedAmount, purgedCount)
		if CachedStorageSize > purgedAmount {
			CachedStorageSize -= purgedAmount
		} else {
			CachedStorageSize = 0
		}
	}
}