change disk cache

This commit is contained in:
YouROK
2021-05-17 11:54:56 +03:00
parent 5664ede2da
commit 70b71dc279
4 changed files with 85 additions and 61 deletions

View File

@@ -3,6 +3,7 @@ package torr
import (
"io"
"os"
"path/filepath"
"sort"
"time"
@@ -126,6 +127,20 @@ func RemTorrent(hashHex string) {
hash := metainfo.NewHashFromHex(hashHex)
bts.RemoveTorrent(hash)
RemTorrentDB(hash)
if sets.BTsets.UseDisk &&
hashHex != "" &&
hashHex != "/" &&
sets.BTsets.TorrentsSavePath != "" &&
sets.BTsets.TorrentsSavePath != "/" {
name := filepath.Join(sets.BTsets.TorrentsSavePath, hashHex)
err := os.RemoveAll(name)
if err != nil {
log.TLogln("Error remove cache:", err)
} else {
log.TLogln("Remove cache from disk:", hashHex)
}
}
}
func ListTorrent() []*Torrent {

View File

@@ -1,11 +1,11 @@
package torrstor
import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strconv"
"sync"
"time"
@@ -39,9 +39,6 @@ type Cache struct {
isRemove bool
muRemove sync.Mutex
torrent *torrent.Torrent
info *metainfo.Info
file *os.File
}
const FileRangeNotDelete = 5 * 1024 * 1024
@@ -60,7 +57,6 @@ func NewCache(capacity int64, storage *Storage) *Cache {
func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) {
log.TLogln("Create cache for:", info.Name, hash.HexString())
c.info = info
if c.capacity == 0 {
c.capacity = info.PieceLength * 4
}
@@ -71,11 +67,9 @@ func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) {
if settings.BTsets.UseDisk {
name := filepath.Join(settings.BTsets.TorrentsSavePath, hash.HexString())
ff, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, 0666)
err := os.MkdirAll(name, 0777)
if err != nil {
log.TLogln("Error open file:", err)
} else {
c.file = ff
log.TLogln("Error create dir:", err)
}
}
@@ -84,7 +78,18 @@ func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) {
}
if settings.BTsets.UseDisk {
c.loadInfo()
name := filepath.Join(settings.BTsets.TorrentsSavePath, hash.HexString())
fs, err := ioutil.ReadDir(name)
if err == nil {
for _, f := range fs {
id, err := strconv.Atoi(f.Name())
if err == nil {
c.pieces[id].Size = f.Size()
c.pieces[id].Complete = f.Size() == c.pieceLength
c.pieces[id].Accessed = f.ModTime().Unix()
}
}
}
}
}
@@ -108,10 +113,6 @@ func (c *Cache) Close() error {
c.readers = nil
c.muReaders.Unlock()
if c.file != nil {
c.file.Close()
}
utils.FreeOSMemGC()
return nil
}
@@ -268,7 +269,24 @@ func (c *Cache) isIdInFileBE(ranges []Range, id int) bool {
return false
}
func (c *Cache) loadPieces() {
// run only in cache on disk
func (c *Cache) LoadPiecesOnDisk() {
if c.torrent == nil {
return
}
if c.isRemove {
return
}
c.muRemove.Lock()
if c.isRemove {
c.muRemove.Unlock()
return
}
c.isRemove = true
defer func() { c.isRemove = false }()
c.muRemove.Unlock()
ranges := make([]Range, 0)
c.muReaders.Lock()
for r, _ := range c.readers {
@@ -291,29 +309,25 @@ func (c *Cache) loadPieces() {
pc++
}
}
if len(c.readers) == 0 {
limit := 5
pc := 0
end := c.pieceCount
for pc <= end {
if !c.pieces[pc].Complete {
break
}
func (c *Cache) loadInfo() {
name := c.file.Name() + ".info"
buf, err := ioutil.ReadFile(name)
if err == nil {
var pieces map[int]*Piece
err := json.Unmarshal(buf, &pieces)
if err == nil {
for id, p := range pieces {
c.pieces[id].Size = p.Size
c.pieces[id].Complete = p.Complete
c.pieces[id].Accessed = p.Accessed
pc++
}
for pc <= end && limit > 0 {
if !c.pieces[pc].Complete {
if c.torrent.PieceState(pc).Priority == torrent.PiecePriorityNone {
c.torrent.Piece(pc).SetPriority(torrent.PiecePriorityNormal)
}
limit--
}
pc++
}
func (c *Cache) saveInfo() {
buf, err := json.Marshal(c.pieces)
if err == nil {
name := c.file.Name() + ".info"
ioutil.WriteFile(name, buf, 0666)
}
}

View File

@@ -1,38 +1,41 @@
package torrstor
import (
"io"
"os"
"path/filepath"
"strconv"
"sync"
"time"
"server/log"
"server/settings"
)
type DiskPiece struct {
piece *Piece
file *os.File
mu sync.RWMutex
}
func NewDiskPiece(p *Piece) *DiskPiece {
return &DiskPiece{piece: p}
name := filepath.Join(settings.BTsets.TorrentsSavePath, p.cache.hash.HexString(), strconv.Itoa(p.Id))
ff, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
log.TLogln("Error open file:", err)
return nil
}
return &DiskPiece{piece: p, file: ff}
}
func (p *DiskPiece) WriteAt(b []byte, off int64) (n int, err error) {
p.mu.Lock()
defer p.mu.Unlock()
id := int64(p.piece.Id)
pl := p.piece.cache.pieceLength
poff := id * pl
off += poff
n, err = p.file.WriteAt(b, off)
n = 0
off, err = p.piece.cache.file.Seek(off, io.SeekStart)
if err == nil {
n, err = p.piece.cache.file.Write(b)
}
go p.piece.cache.loadPieces()
p.piece.cache.saveInfo()
go p.piece.cache.LoadPiecesOnDisk()
p.piece.Size += int64(n)
p.piece.Accessed = time.Now().Unix()
@@ -43,21 +46,12 @@ func (p *DiskPiece) ReadAt(b []byte, off int64) (n int, err error) {
p.mu.Lock()
defer p.mu.Unlock()
id := int64(p.piece.Id)
pl := p.piece.cache.pieceLength
poff := id * pl
off += poff
n = 0
off, err = p.piece.cache.file.Seek(off, io.SeekStart)
if err == nil {
n, err = p.piece.cache.file.Read(b)
}
n, err = p.file.ReadAt(b, off)
p.piece.Accessed = time.Now().Unix()
return n, nil
}
func (p *DiskPiece) Release() {
p.file.Close()
}

View File

@@ -109,6 +109,7 @@ func (t *Torrent) WaitInfo() bool {
case <-t.Torrent.GotInfo():
t.cache = t.bt.storage.GetCache(t.Hash())
t.cache.SetTorrent(t.Torrent)
go t.cache.LoadPiecesOnDisk()
return true
case <-t.closed:
return false