blob: 95967843d4462cacdd3adeace909d4863a81eb3a [file] [log] [blame]
package com.pt.service;
import com.pt.entity.PeerInfoEntity;
import com.pt.entity.TorrentStats;
import com.pt.exception.ResourceNotFoundException;
import com.pt.repository.PeerInfoRepository;
import com.pt.repository.TorrentMetaRepository;
import com.pt.repository.TorrentStatsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class TorrentStatsService {
@Autowired
private PeerInfoRepository peerInfoRepository;
@Autowired
private TorrentStatsRepository statsRepository;
@Autowired
private TorrentMetaRepository torrentMetaRepository;
@Autowired
public TorrentStatsService(TorrentStatsRepository statsRepository) {
this.statsRepository = statsRepository;
}
/**
* 增加种子完成次数
*
* @param torrentId 种子ID
*/
@Transactional
public void incrementCompletedCount(Long torrentId) {
// 1. 检查统计记录是否存在
if (!statsRepository.findByTorrentId(torrentId).isPresent()) {
// 创建新的统计记录
TorrentStats newStats = new TorrentStats();
newStats.setTorrentId(torrentId);
newStats.setCompletedCount(1);
newStats.setLastUpdated(LocalDateTime.now());
statsRepository.save(newStats);
return;
}
// 2. 原子操作增加完成次数
statsRepository.incrementCompletedCount(torrentId);
// 3. 更新最后更新时间
statsRepository.updateLastUpdatedToNow(torrentId);
}
/**
* 创建新的统计记录
*/
private TorrentStats createNewStats(Long torrentId) {
TorrentStats stats = new TorrentStats();
stats.setTorrentId(torrentId);
stats.setSeederCount(0);
stats.setLeecherCount(0);
stats.setCompletedCount(0);
return statsRepository.save(stats);
}
// 每次客户端上报状态时调用
@Transactional
public void updateTorrentStats(String infoHash) {
// 1. 获取当前种子的peer信息
List<PeerInfoEntity> peers = peerInfoRepository.findByInfoHash(infoHash);
// 2. 统计各类人数
int seeders = 0;
int leechers = 0;
int completed = 0;
for (PeerInfoEntity peer : peers) {
if ("seeding".equals(peer.getStatus()) && peer.isActive()) {
seeders++;
} else if ("downloading".equals(peer.getStatus()) && peer.isActive()) {
leechers++;
}
if ("completed".equals(peer.getStatus())) {
completed++;
}
}
// 3. 更新统计记录
TorrentStats stats = statsRepository.findByTorrentId(
torrentMetaRepository.findByInfoHash(infoHash).getId()
).orElse(new TorrentStats());
stats.setTorrentId(torrentMetaRepository.findByInfoHash(infoHash).getId());
stats.setSeederCount(seeders);
stats.setLeecherCount(leechers);
stats.setCompletedCount(completed);
stats.setLastUpdated(LocalDateTime.now());
statsRepository.save(stats);
}
// 获取种子统计信息
public TorrentStats getTorrentStats(Long torrentId) {
return statsRepository.findByTorrentId(torrentId)
.orElseThrow(() -> new ResourceNotFoundException("Stats not found"));
}
// 新增方法
public List<TorrentStats> getTopSeededTorrents(int limit) {
return statsRepository.findTopBySeederCount(limit);
}
public List<TorrentStats> getRecentActiveTorrents(int limit) {
return statsRepository.findRecentActiveTorrents(limit);
}
public List<TorrentStats> getBatchStats(List<Long> torrentIds) {
return statsRepository.findByTorrentIds(torrentIds);
}
}