blob: baa63e32fcb26735b013505383c2264b5882371b [file] [log] [blame]
ystxdfd42b32025-06-07 13:26:52 +08001package com.pt.service;
2
3import com.pt.entity.PeerInfoEntity;
22301102ca0fb2f2025-06-09 18:40:42 +08004import com.pt.entity.TorrentMeta;
ystxdfd42b32025-06-07 13:26:52 +08005import com.pt.entity.TorrentStats;
6import com.pt.exception.ResourceNotFoundException;
7import com.pt.repository.PeerInfoRepository;
8import com.pt.repository.TorrentMetaRepository;
9import com.pt.repository.TorrentStatsRepository;
10import org.springframework.beans.factory.annotation.Autowired;
11import org.springframework.stereotype.Service;
12import org.springframework.stereotype.Repository;
13import org.springframework.transaction.annotation.Transactional;
14
15import java.time.LocalDateTime;
16import java.util.List;
22301102ca0fb2f2025-06-09 18:40:42 +080017import java.util.Optional;
ystxdfd42b32025-06-07 13:26:52 +080018
19@Service
20public class TorrentStatsService {
21
22 @Autowired
23 private PeerInfoRepository peerInfoRepository;
24
25 @Autowired
26 private TorrentStatsRepository statsRepository;
27
28 @Autowired
29 private TorrentMetaRepository torrentMetaRepository;
30
31 @Autowired
32 public TorrentStatsService(TorrentStatsRepository statsRepository) {
33 this.statsRepository = statsRepository;
34 }
35
36 /**
37 * 增加种子完成次数
38 *
39 * @param torrentId 种子ID
40 */
41 @Transactional
42 public void incrementCompletedCount(Long torrentId) {
43 // 1. 检查统计记录是否存在
44 if (!statsRepository.findByTorrentId(torrentId).isPresent()) {
45 // 创建新的统计记录
46 TorrentStats newStats = new TorrentStats();
47 newStats.setTorrentId(torrentId);
48 newStats.setCompletedCount(1);
49 newStats.setLastUpdated(LocalDateTime.now());
50 statsRepository.save(newStats);
51 return;
52 }
53
54 // 2. 原子操作增加完成次数
55 statsRepository.incrementCompletedCount(torrentId);
56
57 // 3. 更新最后更新时间
58 statsRepository.updateLastUpdatedToNow(torrentId);
59 }
60 /**
61 * 创建新的统计记录
62 */
63 private TorrentStats createNewStats(Long torrentId) {
64 TorrentStats stats = new TorrentStats();
65 stats.setTorrentId(torrentId);
66 stats.setSeederCount(0);
67 stats.setLeecherCount(0);
68 stats.setCompletedCount(0);
69 return statsRepository.save(stats);
70 }
71
72 // 每次客户端上报状态时调用
73 @Transactional
74 public void updateTorrentStats(String infoHash) {
75 // 1. 获取当前种子的peer信息
76 List<PeerInfoEntity> peers = peerInfoRepository.findByInfoHash(infoHash);
77
78 // 2. 统计各类人数
79 int seeders = 0;
80 int leechers = 0;
81 int completed = 0;
82
83 for (PeerInfoEntity peer : peers) {
84 if ("seeding".equals(peer.getStatus()) && peer.isActive()) {
85 seeders++;
86 } else if ("downloading".equals(peer.getStatus()) && peer.isActive()) {
87 leechers++;
88 }
89
90 if ("completed".equals(peer.getStatus())) {
91 completed++;
92 }
93 }
94
95 // 3. 更新统计记录
22301102ca0fb2f2025-06-09 18:40:42 +080096 Optional<TorrentMeta> optionalMeta = torrentMetaRepository.findByInfoHash(infoHash);
97 if (optionalMeta.isEmpty()) {
98 // 处理找不到 info_hash 的情况
99 throw new IllegalArgumentException("Invalid info_hash: not found in database");
100 }
ystxdfd42b32025-06-07 13:26:52 +0800101
22301102ca0fb2f2025-06-09 18:40:42 +0800102 TorrentMeta meta = optionalMeta.get();
103
104 TorrentStats stats = statsRepository.findByTorrentId(meta.getId())
105 .orElse(new TorrentStats());
106
107 stats.setTorrentId(meta.getId());
ystxdfd42b32025-06-07 13:26:52 +0800108 stats.setSeederCount(seeders);
109 stats.setLeecherCount(leechers);
110 stats.setCompletedCount(completed);
111 stats.setLastUpdated(LocalDateTime.now());
112
113 statsRepository.save(stats);
114 }
115
116 // 获取种子统计信息
117 public TorrentStats getTorrentStats(Long torrentId) {
118 return statsRepository.findByTorrentId(torrentId)
119 .orElseThrow(() -> new ResourceNotFoundException("Stats not found"));
120 }
ystx89bd5442025-06-07 19:35:27 +0800121
122 // 新增方法
123 public List<TorrentStats> getTopSeededTorrents(int limit) {
124 return statsRepository.findTopBySeederCount(limit);
125 }
126
127 public List<TorrentStats> getRecentActiveTorrents(int limit) {
128 return statsRepository.findRecentActiveTorrents(limit);
129 }
130
131 public List<TorrentStats> getBatchStats(List<Long> torrentIds) {
132 return statsRepository.findByTorrentIds(torrentIds);
133 }
ystxdfd42b32025-06-07 13:26:52 +0800134}