mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
refactor
This commit is contained in:
@@ -14,53 +14,43 @@ type buffer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BufferPool struct {
|
type BufferPool struct {
|
||||||
buffs map[int]*buffer
|
buffs map[int]*buffer
|
||||||
frees int
|
bufferLength int64
|
||||||
size int64
|
bufferCount int
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufferPool(bufferLength int64, capacity int64) *BufferPool {
|
func NewBufferPool(bufferLength int64) *BufferPool {
|
||||||
bp := new(BufferPool)
|
bp := new(BufferPool)
|
||||||
buffsSize := int(capacity/bufferLength) + 3
|
bp.bufferLength = bufferLength
|
||||||
bp.frees = buffsSize
|
bp.buffs = make(map[int]*buffer)
|
||||||
bp.size = bufferLength
|
|
||||||
return bp
|
return bp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BufferPool) mkBuffs() {
|
|
||||||
if b.buffs != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.buffs = make(map[int]*buffer, b.frees)
|
|
||||||
fmt.Println("Create", b.frees, "buffers")
|
|
||||||
for i := 0; i < b.frees; i++ {
|
|
||||||
buf := buffer{
|
|
||||||
-1,
|
|
||||||
make([]byte, b.size),
|
|
||||||
false,
|
|
||||||
}
|
|
||||||
b.buffs[i] = &buf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BufferPool) GetBuffer(p *Piece) (buff []byte, index int) {
|
func (b *BufferPool) GetBuffer(p *Piece) (buff []byte, index int) {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
b.mkBuffs()
|
|
||||||
for id, buf := range b.buffs {
|
for id, buf := range b.buffs {
|
||||||
if !buf.used {
|
if !buf.used {
|
||||||
|
fmt.Println("Get buffer:", id)
|
||||||
buf.used = true
|
buf.used = true
|
||||||
buf.pieceId = p.Id
|
buf.pieceId = p.Id
|
||||||
buff = buf.buf
|
buff = buf.buf
|
||||||
index = id
|
index = id
|
||||||
b.frees--
|
|
||||||
//fmt.Printf("Get buffer: %v %v %v %p\n", id, p.Id, b.frees, buff)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("Create slow buffer")
|
|
||||||
return make([]byte, b.size), -1
|
fmt.Println("Create buffer:", b.bufferCount)
|
||||||
|
buf := new(buffer)
|
||||||
|
buf.buf = make([]byte, b.bufferLength)
|
||||||
|
buf.used = true
|
||||||
|
buf.pieceId = p.Id
|
||||||
|
b.buffs[b.bufferCount] = buf
|
||||||
|
index = b.bufferCount
|
||||||
|
buff = buf.buf
|
||||||
|
b.bufferCount++
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BufferPool) ReleaseBuffer(index int) {
|
func (b *BufferPool) ReleaseBuffer(index int) {
|
||||||
@@ -70,23 +60,18 @@ func (b *BufferPool) ReleaseBuffer(index int) {
|
|||||||
}
|
}
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
b.mkBuffs()
|
|
||||||
if buff, ok := b.buffs[index]; ok {
|
if buff, ok := b.buffs[index]; ok {
|
||||||
|
fmt.Println("Release buffer:", index)
|
||||||
buff.used = false
|
buff.used = false
|
||||||
buff.pieceId = -1
|
buff.pieceId = -1
|
||||||
b.frees++
|
|
||||||
//fmt.Println("Release buffer:", index, b.frees)
|
|
||||||
} else {
|
} else {
|
||||||
utils.FreeOSMem()
|
utils.FreeOSMem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BufferPool) Used() map[int]struct{} {
|
func (b *BufferPool) Used() map[int]struct{} {
|
||||||
if len(b.buffs) == 0 {
|
b.mu.Lock()
|
||||||
b.mu.Lock()
|
defer b.mu.Unlock()
|
||||||
b.mkBuffs()
|
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
|
||||||
used := make(map[int]struct{})
|
used := make(map[int]struct{})
|
||||||
for _, b := range b.buffs {
|
for _, b := range b.buffs {
|
||||||
if b.used {
|
if b.used {
|
||||||
@@ -97,5 +82,13 @@ func (b *BufferPool) Used() map[int]struct{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BufferPool) Len() int {
|
func (b *BufferPool) Len() int {
|
||||||
return b.frees
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
count := 0
|
||||||
|
for _, b := range b.buffs {
|
||||||
|
if b.used {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import (
|
|||||||
type Cache struct {
|
type Cache struct {
|
||||||
storage.TorrentImpl
|
storage.TorrentImpl
|
||||||
|
|
||||||
s *Storage
|
|
||||||
|
|
||||||
capacity int64
|
capacity int64
|
||||||
filled int64
|
filled int64
|
||||||
hash metainfo.Hash
|
hash metainfo.Hash
|
||||||
@@ -33,14 +31,14 @@ type Cache struct {
|
|||||||
bufferPull *BufferPool
|
bufferPull *BufferPool
|
||||||
|
|
||||||
prcLoaded int
|
prcLoaded int
|
||||||
|
position int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCache(capacity int64, storage *Storage) *Cache {
|
func NewCache(capacity int64) *Cache {
|
||||||
ret := &Cache{
|
ret := &Cache{
|
||||||
capacity: capacity,
|
capacity: capacity,
|
||||||
filled: 0,
|
filled: 0,
|
||||||
pieces: make(map[int]*Piece),
|
pieces: make(map[int]*Piece),
|
||||||
s: storage,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
@@ -57,7 +55,7 @@ func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) {
|
|||||||
c.pieceCount = info.NumPieces()
|
c.pieceCount = info.NumPieces()
|
||||||
c.piecesBuff = int(c.capacity / c.pieceLength)
|
c.piecesBuff = int(c.capacity / c.pieceLength)
|
||||||
c.hash = hash
|
c.hash = hash
|
||||||
c.bufferPull = NewBufferPool(c.pieceLength, c.capacity)
|
c.bufferPull = NewBufferPool(c.pieceLength)
|
||||||
|
|
||||||
for i := 0; i < c.pieceCount; i++ {
|
for i := 0; i < c.pieceCount; i++ {
|
||||||
c.pieces[i] = &Piece{
|
c.pieces[i] = &Piece{
|
||||||
@@ -81,9 +79,6 @@ func (c *Cache) Piece(m metainfo.Piece) storage.PieceImpl {
|
|||||||
func (c *Cache) Close() error {
|
func (c *Cache) Close() error {
|
||||||
c.isRemove = false
|
c.isRemove = false
|
||||||
fmt.Println("Close cache for:", c.hash)
|
fmt.Println("Close cache for:", c.hash)
|
||||||
if _, ok := c.s.caches[c.hash]; ok {
|
|
||||||
delete(c.s.caches, c.hash)
|
|
||||||
}
|
|
||||||
c.pieces = nil
|
c.pieces = nil
|
||||||
c.bufferPull = nil
|
c.bufferPull = nil
|
||||||
utils.FreeOSMemGC()
|
utils.FreeOSMemGC()
|
||||||
@@ -114,6 +109,11 @@ func (c *Cache) GetState() state.CacheState {
|
|||||||
return cState
|
return cState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cache) setPos(pos int) {
|
||||||
|
c.position = (c.position + pos) / 2
|
||||||
|
//fmt.Println("Read:", c.position)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Cache) cleanPieces() {
|
func (c *Cache) cleanPieces() {
|
||||||
if c.isRemove {
|
if c.isRemove {
|
||||||
return
|
return
|
||||||
@@ -150,10 +150,15 @@ func (c *Cache) getRemPieces() []*Piece {
|
|||||||
fill := int64(0)
|
fill := int64(0)
|
||||||
loading := 0
|
loading := 0
|
||||||
used := c.bufferPull.Used()
|
used := c.bufferPull.Used()
|
||||||
|
|
||||||
|
fpices := c.piecesBuff - int(utils.GetReadahead()/c.pieceLength)
|
||||||
|
low := c.position - fpices + 1
|
||||||
|
high := c.position + c.piecesBuff - fpices + 3
|
||||||
|
|
||||||
for u := range used {
|
for u := range used {
|
||||||
v := c.pieces[u]
|
v := c.pieces[u]
|
||||||
if v.Size > 0 {
|
if v.Size > 0 {
|
||||||
if v.Id > 0 {
|
if v.Id > 0 && (v.Id < low || v.Id > high) {
|
||||||
pieces = append(pieces, v)
|
pieces = append(pieces, v)
|
||||||
}
|
}
|
||||||
fill += v.Size
|
fill += v.Size
|
||||||
@@ -164,7 +169,7 @@ func (c *Cache) getRemPieces() []*Piece {
|
|||||||
}
|
}
|
||||||
c.filled = fill
|
c.filled = fill
|
||||||
sort.Slice(pieces, func(i, j int) bool {
|
sort.Slice(pieces, func(i, j int) bool {
|
||||||
return pieces[i].accessed.Before(pieces[j].accessed)
|
return pieces[i].accessed < pieces[j].accessed
|
||||||
})
|
})
|
||||||
|
|
||||||
c.prcLoaded = prc(c.piecesBuff-loading, c.piecesBuff)
|
c.prcLoaded = prc(c.piecesBuff-loading, c.piecesBuff)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type Piece struct {
|
|||||||
|
|
||||||
complete bool
|
complete bool
|
||||||
readed bool
|
readed bool
|
||||||
accessed time.Time
|
accessed int64
|
||||||
buffer []byte
|
buffer []byte
|
||||||
bufIndex int
|
bufIndex int
|
||||||
|
|
||||||
@@ -42,14 +42,13 @@ func (p *Piece) WriteAt(b []byte, off int64) (n int, err error) {
|
|||||||
}
|
}
|
||||||
n = copy(p.buffer[off:], b[:])
|
n = copy(p.buffer[off:], b[:])
|
||||||
p.Size += int64(n)
|
p.Size += int64(n)
|
||||||
p.accessed = time.Now()
|
p.accessed = time.Now().Unix() + 2000
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piece) ReadAt(b []byte, off int64) (n int, err error) {
|
func (p *Piece) ReadAt(b []byte, off int64) (n int, err error) {
|
||||||
p.mu.RLock()
|
p.mu.RLock()
|
||||||
defer p.mu.RUnlock()
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
size := len(b)
|
size := len(b)
|
||||||
if size+int(off) > len(p.buffer) {
|
if size+int(off) > len(p.buffer) {
|
||||||
size = len(p.buffer) - int(off)
|
size = len(p.buffer) - int(off)
|
||||||
@@ -61,13 +60,19 @@ func (p *Piece) ReadAt(b []byte, off int64) (n int, err error) {
|
|||||||
return 0, io.ErrUnexpectedEOF
|
return 0, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
n = copy(b, p.buffer[int(off) : int(off)+size][:])
|
n = copy(b, p.buffer[int(off) : int(off)+size][:])
|
||||||
p.accessed = time.Now()
|
|
||||||
if int(off)+size >= len(p.buffer) {
|
if int(off)+size >= len(p.buffer) {
|
||||||
p.readed = true
|
p.readed = true
|
||||||
}
|
}
|
||||||
if int64(len(b))+off >= p.Size {
|
if int64(len(b))+off >= p.Size {
|
||||||
go p.cache.cleanPieces()
|
go p.cache.cleanPieces()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.complete {
|
||||||
|
p.accessed = time.Now().Unix()
|
||||||
|
p.cache.setPos(p.Id)
|
||||||
|
}
|
||||||
|
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,12 +86,13 @@ func (p *Piece) MarkComplete() error {
|
|||||||
|
|
||||||
func (p *Piece) MarkNotComplete() error {
|
func (p *Piece) MarkNotComplete() error {
|
||||||
p.complete = false
|
p.complete = false
|
||||||
|
p.accessed = 0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piece) Completion() storage.Completion {
|
func (p *Piece) Completion() storage.Completion {
|
||||||
return storage.Completion{
|
return storage.Completion{
|
||||||
Complete: p.complete && len(p.buffer) > 0,
|
Complete: p.complete,
|
||||||
Ok: true,
|
Ok: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func NewStorage(capacity int64) storage.Storage {
|
|||||||
func (s *Storage) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (storage2.TorrentImpl, error) {
|
func (s *Storage) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (storage2.TorrentImpl, error) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
ch := NewCache(s.capacity, s)
|
ch := NewCache(s.capacity)
|
||||||
ch.Init(info, infoHash)
|
ch.Init(info, infoHash)
|
||||||
s.caches[infoHash] = ch
|
s.caches[infoHash] = ch
|
||||||
return ch, nil
|
return ch, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user