Skip to content

Commit 6d34c22

Browse files
committed
Implement new setting OneCacheForAll
Implement storage.cleanPieces which is used when option OneCacheForAll is enabled. It cleans pieces in caches starting with least recently modified
1 parent 2d49f3c commit 6d34c22

2 files changed

Lines changed: 62 additions & 2 deletions

File tree

server/torr/storage/torrstor/cache.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func (c *Cache) GetState() *state.CacheState {
184184
return cState
185185
}
186186

187-
func (c *Cache) cleanPieces() {
187+
func (c *Cache) doCleanPieces() {
188188
if c.isRemove || c.isClosed {
189189
return
190190
}
@@ -211,6 +211,14 @@ func (c *Cache) cleanPieces() {
211211
}
212212
}
213213

214+
func (c *Cache) cleanPieces() {
215+
if settings.BTsets.OneCacheForAll {
216+
c.storage.cleanPieces()
217+
} else {
218+
c.doCleanPieces()
219+
}
220+
}
221+
214222
func (c *Cache) getRemPieces() []*Piece {
215223
piecesRemove := make([]*Piece, 0)
216224
fill := int64(0)

server/torr/storage/torrstor/storage.go

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package torrstor
22

33
import (
44
"sync"
5-
5+
"slices"
6+
"os"
7+
"path/filepath"
68
"server/torr/storage"
9+
"server/settings"
710

811
"github.com/anacrolix/torrent/metainfo"
912
ts "github.com/anacrolix/torrent/storage"
@@ -70,3 +73,52 @@ func (s *Storage) GetCache(hash metainfo.Hash) *Cache {
7073
}
7174
return nil
7275
}
76+
77+
func (s *Storage) cleanPieces() {
78+
s.mu.Lock()
79+
defer s.mu.Unlock()
80+
var filled int64 = 0
81+
for _, ch := range s.caches {
82+
filled += ch.filled
83+
}
84+
overfill := filled - s.capacity
85+
if overfill < 0 {
86+
return
87+
}
88+
sortCachesByModifiedDate := func(a, b *Cache) int {
89+
aname := filepath.Join(settings.BTsets.TorrentsSavePath, a.hash.HexString())
90+
bname := filepath.Join(settings.BTsets.TorrentsSavePath, b.hash.HexString())
91+
ainfo, err := os.Stat(aname)
92+
if err != nil {
93+
return -1
94+
}
95+
binfo, err := os.Stat(bname)
96+
if err != nil {
97+
return 1
98+
}
99+
return ainfo.ModTime().Compare(binfo.ModTime())
100+
}
101+
nonempty := slices.Values(slices.Collect(func(yield func(*Cache) bool) {
102+
for _, c := range s.caches {
103+
if c.filled > 0 {
104+
if !yield(c) {
105+
return
106+
}
107+
}
108+
}
109+
}))
110+
// fill sortedcaches with refs to non-empty caches sorted by respective
111+
// folder modified date in descending order (older first)
112+
sortedcaches := slices.SortedFunc(nonempty, sortCachesByModifiedDate)
113+
for _, c := range sortedcaches {
114+
_cap := c.capacity
115+
c.capacity = max(c.filled - overfill, 0)
116+
overfill -= c.filled
117+
c.doCleanPieces()
118+
overfill += c.filled
119+
c.capacity = _cap
120+
if overfill <= 0 {
121+
return
122+
}
123+
}
124+
}

0 commit comments

Comments
 (0)