Example #1
0
        private void Remove(BackgroundDownloadItem item)
        {
            lock (this.ThisLock)
            {
                if (item.State != BackgroundDownloadState.Completed)
                {
                    if (item.Seed.Key != null)
                    {
                        _cacheManager.Unlock(item.Seed.Key);
                    }

                    foreach (var index in item.Indexes)
                    {
                        foreach (var group in index.Groups)
                        {
                            foreach (var key in group.Keys)
                            {
                                _cacheManager.Unlock(key);
                            }
                        }
                    }
                }

                this.UncheckState(item.Index);

                _settings.BackgroundDownloadItems.Remove(item);
            }
        }
        private void Download(Seed seed, BackgroundItemType type, object value)
        {
            if (seed == null) return;

            lock (this.ThisLock)
            {
                if (_settings.BackgroundDownloadItems.Any(n => n.Seed == seed)) return;

                if (seed.Rank == 0)
                {
                    BackgroundDownloadItem item = new BackgroundDownloadItem();

                    item.Rank = 0;
                    item.Seed = seed;
                    item.State = BackgroundDownloadState.Completed;
                    item.Type = type;

                    if (item.Type == BackgroundItemType.Link)
                    {
                        item.Value = new Link();
                    }
                    else if (item.Type == BackgroundItemType.Store)
                    {
                        item.Value = new Store();
                    }
                    else
                    {
                        throw new FormatException();
                    }

                    _settings.BackgroundDownloadItems.Add(item);
                }
                else
                {
                    if (seed.Key == null) return;

                    BackgroundDownloadItem item = new BackgroundDownloadItem();

                    item.Rank = 1;
                    item.Seed = seed;
                    item.State = BackgroundDownloadState.Downloading;
                    item.Type = type;
                    item.Value = value;

                    if (item.Seed.Key != null)
                    {
                        _cacheManager.Lock(item.Seed.Key);
                    }

                    _settings.BackgroundDownloadItems.Add(item);
                }
            }
        }
        private void Remove(BackgroundDownloadItem item)
        {
            lock (this.ThisLock)
            {
                if (item.State != BackgroundDownloadState.Completed)
                {
                    if (item.Seed.Key != null)
                    {
                        _cacheManager.Unlock(item.Seed.Key);
                    }

                    foreach (var index in item.Indexes)
                    {
                        foreach (var group in index.Groups)
                        {
                            foreach (var key in group.Keys)
                            {
                                _cacheManager.Unlock(key);
                            }
                        }
                    }
                }

                this.UncheckState(item.Index);

                _settings.BackgroundDownloadItems.Remove(item);
            }
        }
Example #4
0
        private void DecodeManagerThread()
        {
            for (; ;)
            {
                Thread.Sleep(1000 * 3);
                if (this.State == ManagerState.Stop)
                {
                    return;
                }

                BackgroundDownloadItem item = null;

                try
                {
                    lock (this.ThisLock)
                    {
                        if (_settings.BackgroundDownloadItems.Count > 0)
                        {
                            item = _settings.BackgroundDownloadItems
                                   .Where(n => n.State == BackgroundDownloadState.Decoding)
                                   .OrderBy(n => (n.Rank != n.Seed.Rank) ? 0 : 1)
                                   .FirstOrDefault();
                        }
                    }
                }
                catch (Exception)
                {
                    return;
                }

                if (item == null)
                {
                    continue;
                }

                try
                {
                    if (item.Rank == 1)
                    {
                        if (!_cacheManager.Contains(item.Seed.Key))
                        {
                            item.State = BackgroundDownloadState.Downloading;
                        }
                        else
                        {
                            item.State = BackgroundDownloadState.Decoding;

                            if (item.Rank < item.Seed.Rank)
                            {
                                string fileName  = null;
                                bool   largeFlag = false;

                                try
                                {
                                    using (FileStream stream = BackgroundDownloadManager.GetUniqueFileStream(Path.Combine(_workDirectory, "index")))
                                        using (ProgressStream decodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) =>
                                        {
                                            isStop = (this.State == ManagerState.Stop || !_settings.BackgroundDownloadItems.Contains(item));

                                            if (!isStop && (stream.Length > item.Seed.Length))
                                            {
                                                isStop = true;
                                                largeFlag = true;
                                            }
                                        }, 1024 * 1024, true))
                                        {
                                            fileName = stream.Name;

                                            _cacheManager.Decoding(decodingProgressStream, item.Seed.CompressionAlgorithm, item.Seed.CryptoAlgorithm, item.Seed.CryptoKey,
                                                                   new KeyCollection()
                                            {
                                                item.Seed.Key
                                            });
                                        }
                                }
                                catch (StopIoException)
                                {
                                    if (File.Exists(fileName))
                                    {
                                        File.Delete(fileName);
                                    }

                                    if (largeFlag)
                                    {
                                        throw new Exception();
                                    }

                                    continue;
                                }
                                catch (Exception)
                                {
                                    if (File.Exists(fileName))
                                    {
                                        File.Delete(fileName);
                                    }

                                    throw;
                                }

                                Index index;

                                using (FileStream stream = new FileStream(fileName, FileMode.Open))
                                {
                                    index = Index.Import(stream, _bufferManager);
                                }

                                File.Delete(fileName);

                                lock (this.ThisLock)
                                {
                                    this.UncheckState(item.Index);

                                    item.Index = index;

                                    this.CheckState(item.Index);

                                    foreach (var group in item.Index.Groups)
                                    {
                                        foreach (var key in group.Keys)
                                        {
                                            _cacheManager.Lock(key);
                                        }
                                    }

                                    item.Indexes.Add(index);

                                    item.Rank++;

                                    item.State = BackgroundDownloadState.Downloading;
                                }
                            }
                            else
                            {
                                bool   largeFlag = false;
                                object value     = null;

                                try
                                {
                                    using (Stream stream = new BufferStream(_bufferManager))
                                        using (ProgressStream decodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) =>
                                        {
                                            isStop = (this.State == ManagerState.Stop || !_settings.BackgroundDownloadItems.Contains(item));

                                            if (!isStop && (stream.Length > item.Seed.Length))
                                            {
                                                isStop = true;
                                                largeFlag = true;
                                            }
                                        }, 1024 * 1024, true))
                                        {
                                            _cacheManager.Decoding(decodingProgressStream, item.Seed.CompressionAlgorithm, item.Seed.CryptoAlgorithm, item.Seed.CryptoKey,
                                                                   new KeyCollection()
                                            {
                                                item.Seed.Key
                                            });

                                            if (stream.Length != item.Seed.Length)
                                            {
                                                throw new Exception();
                                            }

                                            stream.Seek(0, SeekOrigin.Begin);

                                            if (item.Type == BackgroundItemType.Link)
                                            {
                                                value = Link.Import(stream, _bufferManager);
                                            }
                                            else if (item.Type == BackgroundItemType.Store)
                                            {
                                                value = Store.Import(stream, _bufferManager);
                                            }
                                        }
                                }
                                catch (StopIoException)
                                {
                                    if (largeFlag)
                                    {
                                        throw new Exception();
                                    }

                                    continue;
                                }
                                catch (Exception)
                                {
                                    throw;
                                }

                                lock (this.ThisLock)
                                {
                                    item.Value = value;

                                    if (item.Seed.Key != null)
                                    {
                                        _cacheManager.Unlock(item.Seed.Key);
                                    }

                                    foreach (var index in item.Indexes)
                                    {
                                        foreach (var group in index.Groups)
                                        {
                                            foreach (var key in group.Keys)
                                            {
                                                _cacheManager.Unlock(key);
                                            }
                                        }
                                    }

                                    item.Indexes.Clear();

                                    item.State = BackgroundDownloadState.Completed;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (!item.Index.Groups.All(n => _existManager.GetCount(n) >= n.InformationLength))
                        {
                            item.State = BackgroundDownloadState.Downloading;
                        }
                        else
                        {
                            List <Key> keys = new List <Key>();

                            try
                            {
                                foreach (var group in item.Index.Groups.ToArray())
                                {
                                    keys.AddRange(_cacheManager.ParityDecoding(group, (object state2) =>
                                    {
                                        return(this.State == ManagerState.Stop || !_settings.BackgroundDownloadItems.Contains(item));
                                    }));
                                }
                            }
                            catch (StopException)
                            {
                                continue;
                            }

                            item.State = BackgroundDownloadState.Decoding;

                            if (item.Rank < item.Seed.Rank)
                            {
                                string fileName  = null;
                                bool   largeFlag = false;

                                try
                                {
                                    using (FileStream stream = BackgroundDownloadManager.GetUniqueFileStream(Path.Combine(_workDirectory, "index")))
                                        using (ProgressStream decodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) =>
                                        {
                                            isStop = (this.State == ManagerState.Stop || !_settings.BackgroundDownloadItems.Contains(item));

                                            if (!isStop && (stream.Length > item.Seed.Length))
                                            {
                                                isStop = true;
                                                largeFlag = true;
                                            }
                                        }, 1024 * 1024, true))
                                        {
                                            fileName = stream.Name;

                                            _cacheManager.Decoding(decodingProgressStream, item.Index.CompressionAlgorithm, item.Index.CryptoAlgorithm, item.Index.CryptoKey,
                                                                   new KeyCollection(keys));
                                        }
                                }
                                catch (StopIoException)
                                {
                                    if (File.Exists(fileName))
                                    {
                                        File.Delete(fileName);
                                    }

                                    if (largeFlag)
                                    {
                                        throw new Exception();
                                    }

                                    continue;
                                }
                                catch (Exception)
                                {
                                    if (File.Exists(fileName))
                                    {
                                        File.Delete(fileName);
                                    }

                                    throw;
                                }

                                Index index;

                                using (FileStream stream = new FileStream(fileName, FileMode.Open))
                                {
                                    index = Index.Import(stream, _bufferManager);
                                }

                                File.Delete(fileName);

                                lock (this.ThisLock)
                                {
                                    this.UncheckState(item.Index);

                                    item.Index = index;

                                    this.CheckState(item.Index);

                                    foreach (var group in item.Index.Groups)
                                    {
                                        foreach (var key in group.Keys)
                                        {
                                            _cacheManager.Lock(key);
                                        }
                                    }

                                    item.Indexes.Add(index);

                                    item.Rank++;

                                    item.State = BackgroundDownloadState.Downloading;
                                }
                            }
                            else
                            {
                                item.State = BackgroundDownloadState.Decoding;

                                bool   largeFlag = false;
                                object value     = null;

                                try
                                {
                                    using (Stream stream = new BufferStream(_bufferManager))
                                        using (ProgressStream decodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) =>
                                        {
                                            isStop = (this.State == ManagerState.Stop || !_settings.BackgroundDownloadItems.Contains(item));

                                            if (!isStop && (stream.Length > item.Seed.Length))
                                            {
                                                isStop = true;
                                                largeFlag = true;
                                            }
                                        }, 1024 * 1024, true))
                                        {
                                            _cacheManager.Decoding(decodingProgressStream, item.Index.CompressionAlgorithm, item.Index.CryptoAlgorithm, item.Index.CryptoKey,
                                                                   new KeyCollection(keys));

                                            if (stream.Length != item.Seed.Length)
                                            {
                                                throw new Exception();
                                            }

                                            stream.Seek(0, SeekOrigin.Begin);

                                            if (item.Type == BackgroundItemType.Link)
                                            {
                                                value = Link.Import(stream, _bufferManager);
                                            }
                                            else if (item.Type == BackgroundItemType.Store)
                                            {
                                                value = Store.Import(stream, _bufferManager);
                                            }
                                        }
                                }
                                catch (StopIoException)
                                {
                                    if (largeFlag)
                                    {
                                        throw new Exception();
                                    }

                                    continue;
                                }
                                catch (Exception)
                                {
                                    throw;
                                }

                                lock (this.ThisLock)
                                {
                                    item.Value = value;

                                    if (item.Seed.Key != null)
                                    {
                                        _cacheManager.Unlock(item.Seed.Key);
                                    }

                                    foreach (var index in item.Indexes)
                                    {
                                        foreach (var group in index.Groups)
                                        {
                                            foreach (var key in group.Keys)
                                            {
                                                _cacheManager.Unlock(key);
                                            }
                                        }
                                    }

                                    item.Indexes.Clear();

                                    item.State = BackgroundDownloadState.Completed;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    if (_cacheManager.Contains(item.Seed.Key))
                    {
                        ArraySegment <byte> buffer = new ArraySegment <byte>();

                        try
                        {
                            buffer = _cacheManager[item.Seed.Key];
                        }
                        catch (Exception)
                        {
                        }
                        finally
                        {
                            if (buffer.Array != null)
                            {
                                _bufferManager.ReturnBuffer(buffer.Array);
                            }
                        }
                    }

                    foreach (var index in item.Indexes)
                    {
                        foreach (var group in index.Groups)
                        {
                            foreach (var key in group.Keys)
                            {
                                if (this.State == ManagerState.Stop)
                                {
                                    return;
                                }

                                if (!_cacheManager.Contains(key))
                                {
                                    continue;
                                }

                                ArraySegment <byte> buffer = new ArraySegment <byte>();

                                try
                                {
                                    buffer = _cacheManager[key];
                                }
                                catch (Exception)
                                {
                                }
                                finally
                                {
                                    if (buffer.Array != null)
                                    {
                                        _bufferManager.ReturnBuffer(buffer.Array);
                                    }
                                }
                            }
                        }
                    }

                    item.State = BackgroundDownloadState.Error;

                    Log.Error(e);
                }
            }
        }
Example #5
0
        private void DownloadManagerThread()
        {
            Random random = new Random();
            int    round  = 0;

            for (; ;)
            {
                Thread.Sleep(1000 * 3);
                if (this.State == ManagerState.Stop)
                {
                    return;
                }

                BackgroundDownloadItem item = null;

                try
                {
                    lock (this.ThisLock)
                    {
                        if (_settings.BackgroundDownloadItems.Count > 0)
                        {
                            {
                                var items = _settings.BackgroundDownloadItems
                                            .Where(n => n.State == BackgroundDownloadState.Downloading)
                                            .Where(x =>
                                {
                                    if (x.Rank == 1)
                                    {
                                        return(0 == (!_cacheManager.Contains(x.Seed.Key) ? 1 : 0));
                                    }
                                    else
                                    {
                                        return(0 == (x.Index.Groups.Sum(n => n.InformationLength) - x.Index.Groups.Sum(n => Math.Min(n.InformationLength, _existManager.GetCount(n)))));
                                    }
                                })
                                            .ToList();

                                item = items.FirstOrDefault();
                            }

                            if (item == null)
                            {
                                var items = _settings.BackgroundDownloadItems
                                            .Where(n => n.State == BackgroundDownloadState.Downloading)
                                            .ToList();

                                if (items.Count > 0)
                                {
                                    round = (round >= items.Count) ? 0 : round;
                                    item  = items[round++];
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    return;
                }

                if (item == null)
                {
                    continue;
                }

                try
                {
                    if (item.Rank == 1)
                    {
                        if (!_cacheManager.Contains(item.Seed.Key))
                        {
                            item.State = BackgroundDownloadState.Downloading;

                            _connectionsManager.Download(item.Seed.Key);
                        }
                        else
                        {
                            item.State = BackgroundDownloadState.Decoding;
                        }
                    }
                    else
                    {
                        if (!item.Index.Groups.All(n => _existManager.GetCount(n) >= n.InformationLength))
                        {
                            item.State = BackgroundDownloadState.Downloading;

                            int limitCount = 256;

                            foreach (var group in item.Index.Groups.ToArray().Randomize())
                            {
                                if (_existManager.GetCount(group) >= group.InformationLength)
                                {
                                    continue;
                                }

                                foreach (var key in _existManager.GetKeys(group, false))
                                {
                                    if (_connectionsManager.IsDownloadWaiting(key))
                                    {
                                        limitCount--;

                                        if (limitCount <= 0)
                                        {
                                            goto End;
                                        }
                                    }
                                }
                            }

                            List <Key> keyList = new List <Key>();

                            foreach (var group in item.Index.Groups.ToArray())
                            {
                                if (_existManager.GetCount(group) >= group.InformationLength)
                                {
                                    continue;
                                }

                                int        downloadCount = 0;
                                List <Key> tempKeys      = new List <Key>();

                                foreach (var key in _existManager.GetKeys(group, false))
                                {
                                    if (_connectionsManager.IsDownloadWaiting(key))
                                    {
                                        downloadCount++;
                                    }
                                    else
                                    {
                                        tempKeys.Add(key);
                                    }
                                }

                                int length = Math.Max(group.InformationLength, 32) - downloadCount;
                                if (length <= 0)
                                {
                                    continue;
                                }

                                random.Shuffle(tempKeys);
                                foreach (var key in tempKeys.Take(length))
                                {
                                    _connectionsManager.Download(key);

                                    limitCount--;
                                }

                                if (limitCount <= 0)
                                {
                                    goto End;
                                }
                            }

                            End :;
                        }
                        else
                        {
                            item.State = BackgroundDownloadState.Decoding;
                        }
                    }
                }
                catch (Exception e)
                {
                    item.State = BackgroundDownloadState.Error;

                    Log.Error(e);

                    this.Remove(item);
                }
            }
        }
Example #6
0
        private void Download(Seed seed, BackgroundItemType type, object value)
        {
            if (seed == null)
            {
                return;
            }

            lock (this.ThisLock)
            {
                if (_settings.BackgroundDownloadItems.Any(n => n.Seed == seed))
                {
                    return;
                }

                if (seed.Rank == 0)
                {
                    BackgroundDownloadItem item = new BackgroundDownloadItem();

                    item.Rank  = 0;
                    item.Seed  = seed;
                    item.State = BackgroundDownloadState.Completed;
                    item.Type  = type;

                    if (item.Type == BackgroundItemType.Link)
                    {
                        item.Value = new Link();
                    }
                    else if (item.Type == BackgroundItemType.Store)
                    {
                        item.Value = new Store();
                    }
                    else
                    {
                        throw new FormatException();
                    }

                    _settings.BackgroundDownloadItems.Add(item);
                }
                else
                {
                    if (seed.Key == null)
                    {
                        return;
                    }

                    BackgroundDownloadItem item = new BackgroundDownloadItem();

                    item.Rank  = 1;
                    item.Seed  = seed;
                    item.State = BackgroundDownloadState.Downloading;
                    item.Type  = type;
                    item.Value = value;

                    if (item.Seed.Key != null)
                    {
                        _cacheManager.Lock(item.Seed.Key);
                    }

                    _settings.BackgroundDownloadItems.Add(item);
                }
            }
        }