void HttpUploadItem_HttpSegmentNeeded(object sender, UploadItemSegmentEventArgs e) { var segment = FindSegment(e.Magnet.TTH, e.Position, e.Length); if (segment == null) { return; } var buffer = new byte[e.Length]; var pt = PerfTimer.StartNew(); if (ReadCacheSegment(e.Magnet.TTH, e.Position, e.Length, buffer, 0)) { CacheUseSpeed.Update(e.Length); CacheReadAverage.Update((int)pt.ElapsedMilliseconds); Interlocked.Add(ref _uploadedFromCache, e.Length); } }
void HttpUploadItem_HttpSegmentDownloaded(object sender, UploadItemSegmentEventArgs e) { CachedItem item; lock (_syncRoot) { _items.TryGetValue(e.Magnet.TTH, out item); } if (item == null) { if (DisabledTime.ShouldStop()) { return; } StatItem statItem; if (!_engine.StatisticsManager.TryGetValue(e.Magnet.TTH, out statItem)) { return; // no statistics on the item, ignore } if (statItem.CacheEffectivity < CacheGap) { return; // the eff is too low, ignore } lock (_syncRoot) { if (!_items.TryGetValue(e.Magnet.TTH, out item)) { // find current cached items rate var list = new List <KeyValuePair <CachedItem, StatItem> >(); foreach (var cachedItem in _items.Values) { StatItem si; if (_engine.StatisticsManager.TryGetValue(cachedItem.Magnet.TTH, out si)) { list.Add(new KeyValuePair <CachedItem, StatItem>(cachedItem, si)); } else { list.Add(new KeyValuePair <CachedItem, StatItem>(cachedItem, new StatItem { Magnet = e.Magnet })); } } // check for free point var point = _points.FirstOrDefault(p => p.FreeSpace > e.Magnet.Size); if (point == null) { // sort them by the cache efficency ascending list = list.OrderBy(i => i.Value.CacheEffectivity).ToList(); foreach (var cachePoint in _points) { // check if the item has higher rate than one in the cache with gap var possibleFreeSize = list.Where( i => i.Key.Created + TimeSpan.FromMinutes(30) < DateTime.Now && i.Key.CachePath.StartsWith(cachePoint.SystemPath) && i.Value.CacheEffectivity * RemoveThresold < statItem.CacheEffectivity) .Select(i => i.Value.Magnet.Size) .DefaultIfEmpty(0) .Sum(); if (possibleFreeSize + cachePoint.FreeSpace < statItem.Magnet.Size) { continue; // not enough space could be freed for this item } Logger.Info("Need more room for {0} {1} eff: {2:0.0}", statItem.Magnet.FileName, statItem.Magnet.TTH, statItem.CacheEffectivity); for (int i = 0; i < list.Count; i++) { if (list[i].Key.Created + TimeSpan.FromMinutes(30) > DateTime.Now) { continue; } if (!list[i].Key.CachePath.StartsWith(cachePoint.SystemPath)) { continue; } if (list[i].Value.CacheEffectivity * RemoveThresold >= statItem.CacheEffectivity) { break; // break because of sorted list } Logger.Info("Remove less important item from cache {0} {1} {2} eff: {3:0.0} < {4:0.0}", list[i].Key.Magnet.FileName, Utils.FormatBytes(list[i].Key.Magnet.Size), list[i].Key.Magnet.TTH, list[i].Value.CacheEffectivity, statItem.CacheEffectivity); try { RemoveItemFromCache(list[i].Key); } catch (Exception x) { Logger.Error("Can't delete cache file {0}", list[i].Key.Magnet); } if (cachePoint.FreeSpace > e.Magnet.Size) { point = cachePoint; break; } } if (point != null) { break; } } if (point == null) { return; } } item = new CachedItem(e.Magnet, (int)e.Length) { CachePath = Path.Combine(point.SystemPath, e.Magnet.TTH) }; if (LazyCacheDownload) { Exception ex; if (!FileHelper.AllocateFile(item.CachePath, e.Magnet.Size, out ex)) { Logger.Error("Cannot allocate file {0} {1} {2}", item.CachePath, Utils.FormatBytes(e.Magnet.Size), ex?.Message ?? ""); return; } } else { lock (_downloadQueue) { if (_downloadQueue.Count > 5) { return; } Logger.Info("Requesting download {0} to {1}", item.Magnet.FileName, item.CachePath); _downloadQueue.Enqueue(Tuple.Create(e.UploadItem.SystemPath, item)); if (!_downloadThreadAlive) { _downloadThreadAlive = true; new ThreadStart(DownloadCacheFiles).BeginInvoke(null, null); } } } AddItemToCache(item, point); } } } //if (LazyCacheDownload) //{ // using (new PerfLimit("Cache flush")) // using (var fs = new FileStream(item.CachePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite,1024 * 64)) // { // fs.Position = e.Position; // using (var ms = new MemoryStream(e.Buffer, 0, e.Length, false)) // { // ms.CopyTo(fs); // } // } // lock (_syncRoot) // { // item.CachedSegments.Set(DownloadItem.GetSegmentIndex(e.Position, item.SegmentLength), true); // if (item.CachedSegments.FirstFalse() == -1) // item.Complete = true; // } // WriteBitfieldFile(item); //} }