private void DownloadManagerDownloadAdding(object sender, CancelDownloadEventArgs e) { if (e.DownloadItem.SaveTargets == null) { return; } var fi = new FileInfo(e.DownloadItem.SaveTargets[0]); var drive1 = Path.GetPathRoot(e.DownloadItem.SaveTargets[0]); // here we should check for free space, if (!string.IsNullOrEmpty(drive1) && FileHelper.GetFreeSpace(fi.DirectoryName) < e.DownloadItem.Magnet.Size) { throw new NoFreeSpaceException(drive1); } if (string.IsNullOrEmpty(drive1)) { return; } // lets check for file size restriction var driveInfo1 = new DriveInfo(drive1); var fileSystem1 = driveInfo1.DriveFormat; if (fileSystem1 == "FAT32") { // maximum file size is 4 Gb if (e.DownloadItem.Magnet.Size > 4L * 1024 * 1024 * 1024) { throw new FileTooBigException(4L * 1024 * 1024 * 1024, e.DownloadItem.Magnet.Size); } } if (fileSystem1 == "NTFS") { // maximum file size is 16 Tb - 64 Kb if (e.DownloadItem.Magnet.Size > 16L * 1024 * 1024 * 1024 * 1024 - 64 * 1024) { throw new FileTooBigException(16L * 1024 * 1024 * 1024 * 1024 - 64 * 1024, e.DownloadItem.Magnet.Size); } } if (Settings.InstantAllocate) { var path = e.DownloadItem.SaveTargets[0]; var dirInfo = new DirectoryInfo(Path.GetDirectoryName(path)); if (!dirInfo.Exists) { dirInfo.Create(); } FileHelper.AllocateFile(path, e.DownloadItem.Magnet.Size); } }
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); //} }