<commit_before>package swarm

import (
	"bytes"
	"errors"
	"github.com/zeebo/bencode"
	"net"
	"time"
	"github.com/majestrate/XD/lib/bittorrent"
	"github.com/majestrate/XD/lib/bittorrent/extensions"
	"github.com/majestrate/XD/lib/common"
	"github.com/majestrate/XD/lib/dht"
	"github.com/majestrate/XD/lib/log"
	"github.com/majestrate/XD/lib/metainfo"
	"github.com/majestrate/XD/lib/network"
	"github.com/majestrate/XD/lib/stats"
	"github.com/majestrate/XD/lib/storage"
	"github.com/majestrate/XD/lib/sync"
	"github.com/majestrate/XD/lib/tracker"
	"github.com/majestrate/XD/lib/util"
)

// max peers peer swarm default
const DefaultMaxSwarmPeers = 50

// rate name for upload
const RateUpload = "upload"

// rate name for download
const RateDownload = "download"

var defaultRates = []string{RateDownload, RateUpload}

// single torrent tracked in a swarm
type Torrent struct {
	TID              int64
	addr             net.Addr
	Completed        func()
	Started          func()
	Stopped          func()
	RemoveSelf       func()
	netacces         sync.Mutex
	suspended        bool
	Network          func() network.Network
	Trackers         map[string]tracker.Announcer
	announcers       map[string]*torrentAnnounce
	announceMtx      sync.Mutex
	announceTicker   *time.Ticker
	id               common.PeerID
	st               storage.Torrent
	obconns          map[string]*PeerConn
	ibconns          map[string]*PeerConn
	connMtx          sync.Mutex
	pt               *pieceTracker
	defaultOpts      extensions.Message
	closing          bool
	started          bool
	MaxRequests      int
	MaxPeers         uint
	pexState         PEXSwarmState
	xdht             *dht.XDHT
	statsTracker     *stats.Tracker
	tx               uint64
	rx               uint64
	seeding          bool
	metaInfo         []byte
	pendingInfoBF    *bittorrent.Bitfield
	requestingInfoBF *bittorrent.Bitfield
	puttingMetaInfo  bool
	addedAt          time.Time
	peersPool        sync.Pool
	lastPEX          time.Time
	pexInterval      time.Duration
}

func (t *Torrent) ShouldAcceptNewPeer() bool {
	return !t.closing
}

func (t *Torrent) getNextPeer() *PeerConn {
	p := t.peersPool.Get()
	return p.(*PeerConn)
}

func (t *Torrent) DownloadDir() string {
	return t.st.DownloadDir()
}

func (t *Torrent) AddedAt() time.Time {
	return t.addedAt
}

func (t *Torrent) Ready() bool {
	return t.st.MetaInfo() != nil
}

// implements io.Closer<commit_msg>fix previous commit<commit_after>package swarm

import (
	"bytes"
	"errors"
	"github.com/zeebo/bencode"
	"net"
	"time"
	"github.com/majestrate/XD/lib/bittorrent"
	"github.com/majestrate/XD/lib/bittorrent/extensions"
	"github.com/majestrate/XD/lib/common"
	"github.com/majestrate/XD/lib/dht"
	"github.com/majestrate/XD/lib/log"
	"github.com/majestrate/XD/lib/metainfo"
	"github.com/majestrate/XD/lib/network"
	"github.com/majestrate/XD/lib/stats"
	"github.com/majestrate/XD/lib/storage"
	"github.com/majestrate/XD/lib/sync"
	"github.com/majestrate/XD/lib/tracker"
	"github.com/majestrate/XD/lib/util"
)

// max peers peer swarm default
const DefaultMaxSwarmPeers = 50

// rate name for upload
const RateUpload = "upload"

// rate name for download
const RateDownload = "download"

var defaultRates = []string{RateDownload, RateUpload}

// single torrent tracked in a swarm
type Torrent struct {
	TID              int64
	addr             net.Addr
	Completed        func()
	Started          func()
	Stopped          func()
	RemoveSelf       func()
	netacces         sync.Mutex
	suspended        bool
	Network          func() network.Network
	Trackers         map[string]tracker.Announcer
	announcers       map[string]*torrentAnnounce
	announceMtx      sync.Mutex
	announceTicker   *time.Ticker
	id               common.PeerID
	st               storage.Torrent
	obconns          map[string]*PeerConn
	ibconns          map[string]*PeerConn
	connMtx          sync.Mutex
	pt               *pieceTracker
	defaultOpts      extensions.Message
	closing          bool
	started          bool
	MaxRequests      int
	MaxPeers         uint
	pexState         PEXSwarmState
	xdht             *dht.XDHT
	statsTracker     *stats.Tracker
	tx               uint64
	rx               uint64
	seeding          bool
	metaInfo         []byte
	pendingInfoBF    *bittorrent.Bitfield
	requestingInfoBF *bittorrent.Bitfield
	puttingMetaInfo  bool
	addedAt          time.Time
	peersPool        sync.Pool
	lastPEX          time.Time
	pexInterval      time.Duration
}

func (t *Torrent) ShouldAcceptNewPeer() bool {
	state := t.GetStatus().State
	return state == Downloading || state == Seeding
}

func (t *Torrent) getNextPeer() *PeerConn {
	p := t.peersPool.Get()
	return p.(*PeerConn)
}

func (t *Torrent) DownloadDir() string {
	return t.st.DownloadDir()
}

func (t *Torrent) AddedAt() time.Time {
	return t.addedAt
}

func (t *Torrent) Ready() bool {
	return t.st.MetaInfo() != nil
}

// implements io.Closer
{'fraction_non_alphanumeric': 0.09852820932134096, 'fraction_numerical': 0.003270645952575634, 'mean_word_length': 2.5559593023255816, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 13, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4204709', 'n_tokens_mistral': 1753, 'n_tokens_neox': 1705, 'n_words': 350}