mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
119 lines
2.0 KiB
Go
119 lines
2.0 KiB
Go
package memcacheV2
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"sync"
|
|
"time"
|
|
|
|
"server/torr/storage/state"
|
|
|
|
"github.com/anacrolix/torrent/storage"
|
|
)
|
|
|
|
type Piece struct {
|
|
storage.PieceImpl
|
|
|
|
Id int
|
|
Hash string
|
|
Length int64
|
|
Size int64
|
|
|
|
complete bool
|
|
accessed int64
|
|
buffer []byte
|
|
bufIndex int
|
|
|
|
mu sync.RWMutex
|
|
cache *Cache
|
|
}
|
|
|
|
func (p *Piece) WriteAt(b []byte, off int64) (n int, err error) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
|
|
if p.buffer == nil {
|
|
go p.cache.cleanPieces()
|
|
p.buffer, p.bufIndex = p.cache.bufferPull.GetBuffer(p)
|
|
if p.buffer == nil {
|
|
return 0, errors.New("Can't get buffer write")
|
|
}
|
|
}
|
|
n = copy(p.buffer[off:], b[:])
|
|
p.Size += int64(n)
|
|
p.accessed = time.Now().Unix() + 2000
|
|
return
|
|
}
|
|
|
|
func (p *Piece) ReadAt(b []byte, off int64) (n int, err error) {
|
|
p.mu.RLock()
|
|
defer p.mu.RUnlock()
|
|
size := len(b)
|
|
if size+int(off) > len(p.buffer) {
|
|
size = len(p.buffer) - int(off)
|
|
if size < 0 {
|
|
size = 0
|
|
}
|
|
}
|
|
if len(p.buffer) < int(off) || len(p.buffer) < int(off)+size {
|
|
return 0, io.ErrUnexpectedEOF
|
|
}
|
|
n = copy(b, p.buffer[int(off) : int(off)+size][:])
|
|
|
|
if int64(len(b))+off >= p.Size {
|
|
go p.cache.cleanPieces()
|
|
time.Sleep(time.Millisecond * 2000)
|
|
}
|
|
|
|
if p.complete {
|
|
p.accessed = time.Now().Unix()
|
|
p.cache.SetPos(p.Id)
|
|
}
|
|
|
|
return n, nil
|
|
}
|
|
|
|
func (p *Piece) MarkComplete() error {
|
|
if len(p.buffer) == 0 {
|
|
return errors.New("piece is not complete")
|
|
}
|
|
p.complete = true
|
|
return nil
|
|
}
|
|
|
|
func (p *Piece) MarkNotComplete() error {
|
|
p.complete = false
|
|
p.accessed = 0
|
|
return nil
|
|
}
|
|
|
|
func (p *Piece) Completion() storage.Completion {
|
|
return storage.Completion{
|
|
Complete: p.complete,
|
|
Ok: true,
|
|
}
|
|
}
|
|
|
|
func (p *Piece) Release() {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
if p.buffer != nil {
|
|
p.buffer = nil
|
|
p.cache.bufferPull.ReleaseBuffer(p.bufIndex)
|
|
p.bufIndex = -1
|
|
}
|
|
p.Size = 0
|
|
p.complete = false
|
|
}
|
|
|
|
func (p *Piece) Stat() state.ItemState {
|
|
itm := state.ItemState{
|
|
Id: p.Id,
|
|
Hash: p.Hash,
|
|
Accessed: p.accessed,
|
|
Completed: p.complete,
|
|
BufferSize: p.Size,
|
|
}
|
|
return itm
|
|
}
|