예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            //}
        }