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 }