mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			99 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
						|
 | 
						|
package caches
 | 
						|
 | 
						|
import (
 | 
						|
	teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
						|
	"github.com/TeaOSLab/EdgeNode/internal/goman"
 | 
						|
	"sync/atomic"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	minOpenFilesValue int32 = 2
 | 
						|
	maxOpenFilesValue int32 = 65535
 | 
						|
 | 
						|
	modeSlow int32 = 1
 | 
						|
	modeFast int32 = 2
 | 
						|
)
 | 
						|
 | 
						|
// MaxOpenFiles max open files manager
 | 
						|
type MaxOpenFiles struct {
 | 
						|
	step         int32
 | 
						|
	maxOpenFiles int32
 | 
						|
	ptr          *int32
 | 
						|
	ticker       *time.Ticker
 | 
						|
	mode         int32
 | 
						|
 | 
						|
	lastOpens    int32
 | 
						|
	currentOpens int32
 | 
						|
}
 | 
						|
 | 
						|
func NewMaxOpenFiles(step int32) *MaxOpenFiles {
 | 
						|
	if step <= 0 {
 | 
						|
		step = 2
 | 
						|
	}
 | 
						|
	var f = &MaxOpenFiles{
 | 
						|
		step:         step,
 | 
						|
		maxOpenFiles: 2,
 | 
						|
	}
 | 
						|
	if teaconst.DiskIsFast {
 | 
						|
		f.maxOpenFiles = 32
 | 
						|
	}
 | 
						|
	f.ptr = &f.maxOpenFiles
 | 
						|
	f.ticker = time.NewTicker(1 * time.Second)
 | 
						|
	f.init()
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
func (this *MaxOpenFiles) init() {
 | 
						|
	goman.New(func() {
 | 
						|
		for range this.ticker.C {
 | 
						|
			var mod = atomic.LoadInt32(&this.mode)
 | 
						|
			switch mod {
 | 
						|
			case modeSlow:
 | 
						|
				// we decrease more quickly, with more steps
 | 
						|
				if atomic.AddInt32(this.ptr, -this.step*2) <= 0 {
 | 
						|
					atomic.StoreInt32(this.ptr, minOpenFilesValue)
 | 
						|
				}
 | 
						|
			case modeFast:
 | 
						|
				// we increase only when file opens increases
 | 
						|
				var currentOpens = atomic.LoadInt32(&this.currentOpens)
 | 
						|
				if currentOpens > this.lastOpens {
 | 
						|
					if atomic.AddInt32(this.ptr, this.step) >= maxOpenFilesValue {
 | 
						|
						atomic.StoreInt32(this.ptr, maxOpenFilesValue)
 | 
						|
					}
 | 
						|
				}
 | 
						|
				this.lastOpens = currentOpens
 | 
						|
				atomic.StoreInt32(&this.currentOpens, 0)
 | 
						|
			}
 | 
						|
 | 
						|
			// reset mode
 | 
						|
			atomic.StoreInt32(&this.mode, 0)
 | 
						|
		}
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func (this *MaxOpenFiles) Fast() {
 | 
						|
	if atomic.LoadInt32(&this.mode) == 0 {
 | 
						|
		this.mode = modeFast
 | 
						|
	}
 | 
						|
	atomic.AddInt32(&this.currentOpens, 1)
 | 
						|
}
 | 
						|
 | 
						|
func (this *MaxOpenFiles) Slow() {
 | 
						|
	atomic.StoreInt32(&this.mode, modeSlow)
 | 
						|
}
 | 
						|
 | 
						|
func (this *MaxOpenFiles) Max() int32 {
 | 
						|
	if atomic.LoadInt32(&this.mode) == modeSlow {
 | 
						|
		return 0
 | 
						|
	}
 | 
						|
 | 
						|
	var v = atomic.LoadInt32(this.ptr)
 | 
						|
	if v <= minOpenFilesValue {
 | 
						|
		return minOpenFilesValue
 | 
						|
	}
 | 
						|
	return v
 | 
						|
}
 |