Пример #1
0
        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);
            }
        }
Пример #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);
            //}
        }