github.com/TeaOSLab/EdgeNode@v1.3.8/internal/caches/open_file_pool.go (about)

     1  // Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
     2  
     3  package caches
     4  
     5  import (
     6  	"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
     7  	"github.com/TeaOSLab/EdgeNode/internal/utils/linkedlist"
     8  )
     9  
    10  type OpenFilePool struct {
    11  	c        chan *OpenFile
    12  	linkItem *linkedlist.Item[*OpenFilePool]
    13  	filename string
    14  	version  int64
    15  	isClosed bool
    16  	usedSize int64
    17  }
    18  
    19  func NewOpenFilePool(filename string) *OpenFilePool {
    20  	var pool = &OpenFilePool{
    21  		filename: filename,
    22  		c:        make(chan *OpenFile, 1024),
    23  		version:  fasttime.Now().UnixMilli(),
    24  	}
    25  	pool.linkItem = linkedlist.NewItem[*OpenFilePool](pool)
    26  	return pool
    27  }
    28  
    29  func (this *OpenFilePool) Filename() string {
    30  	return this.filename
    31  }
    32  
    33  func (this *OpenFilePool) Get() (resultFile *OpenFile, consumed bool, consumedSize int64) {
    34  	// 如果已经关闭,直接返回
    35  	if this.isClosed {
    36  		return nil, false, 0
    37  	}
    38  
    39  	select {
    40  	case file := <-this.c:
    41  		if file != nil {
    42  			this.usedSize -= file.size
    43  
    44  			err := file.SeekStart()
    45  			if err != nil {
    46  				_ = file.Close()
    47  				return nil, true, file.size
    48  			}
    49  			file.version = this.version
    50  
    51  			return file, true, file.size
    52  		}
    53  		return nil, false, 0
    54  	default:
    55  		return nil, false, 0
    56  	}
    57  }
    58  
    59  func (this *OpenFilePool) Put(file *OpenFile) bool {
    60  	// 如果已关闭,则不接受新的文件
    61  	if this.isClosed {
    62  		_ = file.Close()
    63  		return false
    64  	}
    65  
    66  	// 检查文件版本号
    67  	if this.version > 0 && file.version > 0 && file.version != this.version {
    68  		_ = file.Close()
    69  		return false
    70  	}
    71  
    72  	// 加入Pool
    73  	select {
    74  	case this.c <- file:
    75  		this.usedSize += file.size
    76  		return true
    77  	default:
    78  		// 多余的直接关闭
    79  		_ = file.Close()
    80  		return false
    81  	}
    82  }
    83  
    84  func (this *OpenFilePool) Len() int {
    85  	return len(this.c)
    86  }
    87  
    88  func (this *OpenFilePool) TotalSize() int64 {
    89  	return this.usedSize
    90  }
    91  
    92  func (this *OpenFilePool) SetClosing() {
    93  	this.isClosed = true
    94  }
    95  
    96  func (this *OpenFilePool) Close() {
    97  	this.isClosed = true
    98  	for {
    99  		select {
   100  		case file := <-this.c:
   101  			_ = file.Close()
   102  		default:
   103  			return
   104  		}
   105  	}
   106  }