private void Update()
        {
            this.NotifyPropertyChanged(nameof(this.Name));

            {
                var tempList = new List<SignatureTreeViewModel>();

                foreach (var item in _value.Children)
                {
                    tempList.Add(new SignatureTreeViewModel(this, item));
                }

                tempList.Sort((x, y) =>
                {
                    int c = x.Value.LinkItem.Signature.CompareTo(y.Value.LinkItem.Signature);
                    if (c != 0) return c;

                    return x.GetHashCode().CompareTo(y.GetHashCode());
                });

                _children.Clear();
                _children.AddRange(tempList);
            }
        }
Пример #2
0
        /// <summary>
        /// Region growing to encode the source image data.
        /// </summary>
        /// <param name="locationPool"></param>
        /// <param name="maximumDistance"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static HashSet<Region> Process(LocationPool locationPool, double maximumDistance, RegionType type)
        {
            HashSet<Region> result = new HashSet<Region>();
            List<Location> todoList = new List<Location>();
            //let's process pixels into regions
            Region region = null;

            HashSet<Location> alreadyChecked = new HashSet<Location>();

            while (!locationPool.Empty())
            {
                alreadyChecked.Clear();
                Location seed = locationPool.RandomLocation();
                //Console.WriteLine("Have seed " + seed);
                if (type == RegionType.MonoRegion)
                {
                    region = new MonoRegion();
                }
                else if (type == RegionType.MultiColorRegion)
                {
                    MultiColorRegion multiColorRegion = new MultiColorRegion(maximumDistance);
                    region = multiColorRegion;
                }

                region.Add(seed);
                region.Origin = seed.Point;
                seed.Region = region;
                locationPool.SetMarked(seed);
                alreadyChecked.Add(seed);

                AddNeighbors(seed, todoList, alreadyChecked);
                todoList.Sort((x, y) => (int)(SxzColor.GetColorDistance(seed.Color, x.Color) - SxzColor.GetColorDistance(seed.Color, y.Color)));

                int sortCounter = 0;

                //inner loop
                while (todoList.Count != 0)
                {
                    //Console.WriteLine("Unmarked total " + locationPool.Unmarked.Count + " and todolist total " + todoList.Count);
                    seed = todoList[0];
                    todoList.RemoveAt(0);
                    sortCounter++;

                    if (seed.Marked)
                    {
                        throw new Exception("Location already marked!");
                    }

                    if (!region.IsValid(seed))
                    {
                        //we can process non-adjacent pixels by adding neighbors here and sorting before returning but limit the distance from an already
                        //validated location
                        continue;
                    }

                    //Console.WriteLine("Parsed pixel " + seed);
                    //we have a winner!
                    region.Add(seed);
                    locationPool.SetMarked(seed);

                    AddNeighbors(seed, todoList, alreadyChecked);
                    //if (todoList.Count < 1000)
                    if (todoList.Count < 1000 || sortCounter > 1000)
                    {
                        //let's limit the number to be sorted for performance sake
                        todoList.Sort((x1, y1) => (int)(SxzColor.GetColorDistance(seed.Color, x1.Color) - SxzColor.GetColorDistance(seed.Color, y1.Color)));
                        sortCounter = 0;
                    }
                }

                result.Add(region);
            }

            return result;
        }
Пример #3
0
        private void SetupUILanguage()
        {
            string selected = null;
            List<string> list = new List<string>();
            string configuredLangId = OMLSettings.UILanguage;

            foreach (var availableCulture in I18n.AvailableCultures)
            {
                string name = availableCulture.TextInfo.ToTitleCase(availableCulture.NativeName);
                if (string.CompareOrdinal(availableCulture.Name, configuredLangId) == 0)
                {
                    selected = name;
                }
                list.Add(name);
            }

            list.Sort((a, b) => string.Compare(a, b, true, Thread.CurrentThread.CurrentCulture));

            list.Insert(0, "Use system language");
            if (string.IsNullOrEmpty(selected)) selected = list[0];

            _uiLanguage.Options = list;
            _uiLanguage.Chosen = selected;
        }
Пример #4
0
        public bool? Monitor(params object[] data)
        {
            // TODO: move partially up
            byte backgroundCycles = Config.BackgroundCycles;
            doBackgroundPremeasure = backgroundCycles != 0;

            Graph.MeasureGraph g;
            switch (pState) {
                case ProgramStates.Ready:
                    if (SomePointsUsed) {
                        //Order is important here!!!! Underlying data update before both matrix formation and measure mode init.
                        g = Graph.MeasureGraph.Instance;
                        g.ResetForMonitor();
                        //var peaks = g.PreciseData.GetUsed();
                        //already filtered in ResetForMonitor()
                        var peaks = g.PreciseData;

            #warning matrix is formed too early
                        // TODO: move matrix formation to manual operator actions
                        // TODO: parallelize matrix formation, flag on completion
                        // TODO: duplicates
                        peaksForMatrix = peaks.GetWithId();
                        if (peaksForMatrix.Count > 0) {
                            // To comply with other processing order (and saved information)
                            peaksForMatrix.Sort(PreciseEditorData.ComparePreciseEditorDataByPeakValue);
                            matrix = new Matrix(Config.LoadLibrary(peaksForMatrix));
                            // What do with empty matrix?
                            if (matrix != null)
                                matrix.Init();
                            else {
                                OnLog("Error in peak data format or duplicate substance.");
                                return null;
                            }
                        } else
                            matrix = null;

                        // TODO: feed measure mode with start shift value (really?)
                        short? startShiftValue = 0;
                        {
                            var co = g.CommonOptions;
                            var temp = new MeasureMode.Precise.Monitor(Config.MIN_STEP, Config.MAX_STEP,
                                // TODO: getWithId()
                                peaks,
                                co.befTimeReal, co.iTimeReal, co.eTimeReal,
                                co.ForwardTimeEqualsBeforeTime ? co.befTimeReal : co.fTimeReal, co.bTimeReal,
                                (p, peak) => g.updateGraphDuringPreciseMeasure(p, peak, Counts),
                                g.updateGraphAfterPreciseMeasure,
                                Config.Iterations, Config.TimeLimit,
                                // TODO: move extra data into checker
                                Config.CheckerPeak, Config.CheckerPeak == null ? null : startShiftValue, Config.AllowedShift);
                            temp.SaveResults += (s, e) => {
                                Config.autoSaveMonitorSpectrumFile(LabelNumber);
                                if (LabelNumber.HasValue)
                                    LabelNumber = null;
                            };
                            temp.Finalize += (s, e) => Config.finalizeMonitorFile();
                            // how to unsubscribe?
                            //realizer.MeasureSend += (s, e) => temp.NextMeasure(e.Value);

                            CurrentMeasureMode = temp;
                        }

                        if (doBackgroundPremeasure) {
                            initMeasure(ProgramStates.WaitBackgroundMeasure);
                            background = new FixedSizeQueue<List<long>>(backgroundCycles);
                            // or maybe Enumerator realization: one item, always recounting (accumulate values)..
                            g.GraphDataModified += NewBackgroundMeasureReady;
                        } else {
                            initMeasure(ProgramStates.Measure);
                            g.GraphDataModified += NewMonitorMeasureReady;
                        }
                        return true;
                    } else {
                        OnLog("No points for monitor mode measure.");
                        return null;
                    }
                case ProgramStates.BackgroundMeasureReady:
                    // set background end label
                    LabelNumber = 0;

                    g = Graph.MeasureGraph.Instance;
                    g.GraphDataModified -= NewBackgroundMeasureReady;

                    backgroundResult = background.Aggregate(Summarize);
                    for (int i = 0; i < backgroundResult.Count; ++i) {
                        // TODO: check integral operation behaviour here
                        backgroundResult[i] /= backgroundCycles;
                    }

                    setProgramStateWithoutUndo(ProgramStates.Measure);
                    g.GraphDataModified += NewMonitorMeasureReady;
                    return false;
                case ProgramStates.Measure:
                    // set label
                    LabelNumber = (int)data[0];
                    return false;
                default:
                    // wrong state, strange!
                    return null;
            }
        }
Пример #5
0
        private void ConnectionsManagerThread()
        {
            Stopwatch connectionCheckStopwatch = new Stopwatch();
            connectionCheckStopwatch.Start();

            Stopwatch refreshStopwatch = new Stopwatch();

            Stopwatch pushBlockDiffusionStopwatch = new Stopwatch();
            pushBlockDiffusionStopwatch.Start();
            Stopwatch pushBlockUploadStopwatch = new Stopwatch();
            pushBlockUploadStopwatch.Start();
            Stopwatch pushBlockDownloadStopwatch = new Stopwatch();
            pushBlockDownloadStopwatch.Start();

            Stopwatch pushMetadataUploadStopwatch = new Stopwatch();
            pushMetadataUploadStopwatch.Start();
            Stopwatch pushMetadataDownloadStopwatch = new Stopwatch();
            pushMetadataDownloadStopwatch.Start();

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

                var connectionCount = 0;

                lock (this.ThisLock)
                {
                    connectionCount = _connectionManagers.Count;
                }

                if (connectionCount > ((this.ConnectionCountLimit / 3) * 1)
                    && connectionCheckStopwatch.Elapsed.TotalMinutes >= 5)
                {
                    connectionCheckStopwatch.Restart();

                    var nodeSortItems = new List<NodeSortItem>();

                    lock (this.ThisLock)
                    {
                        foreach (var connectionManager in _connectionManagers)
                        {
                            nodeSortItems.Add(new NodeSortItem()
                            {
                                Node = connectionManager.Node,
                                Priority = _messagesManager[connectionManager.Node].Priority,
                                LastPullTime = _messagesManager[connectionManager.Node].LastPullTime,
                            });
                        }
                    }

                    nodeSortItems.Sort((x, y) =>
                    {
                        int c = x.Priority.CompareTo(y.Priority);
                        if (c != 0) return c;

                        return x.LastPullTime.CompareTo(y.LastPullTime);
                    });

                    foreach (var node in nodeSortItems.Select(n => n.Node).Take(1))
                    {
                        ConnectionManager connectionManager = null;

                        lock (this.ThisLock)
                        {
                            connectionManager = _connectionManagers.FirstOrDefault(n => n.Node == node);
                        }

                        if (connectionManager != null)
                        {
                            try
                            {
                                lock (this.ThisLock)
                                {
                                    this.RemoveNode(connectionManager.Node);
                                }

                                connectionManager.PushCancel();

                                Debug.WriteLine("ConnectionManager: Push Cancel");
                            }
                            catch (Exception)
                            {

                            }

                            this.RemoveConnectionManager(connectionManager);
                        }
                    }
                }

                if (!refreshStopwatch.IsRunning || refreshStopwatch.Elapsed.TotalSeconds >= 30)
                {
                    refreshStopwatch.Restart();

                    // トラストにより必要なMetadataを選択し、不要なMetadataを削除する。
                    ThreadPool.QueueUserWorkItem((object wstate) =>
                    {
                        if (_refreshThreadRunning) return;
                        _refreshThreadRunning = true;

                        try
                        {
                            var lockSignatures = this.OnLockSignaturesEvent();
                            if (lockSignatures == null) return;

                            var lockWikis = this.OnLockWikisEvent();
                            if (lockWikis == null) return;

                            var lockChats = this.OnLockChatsEvent();
                            if (lockChats == null) return;

                            // Broadcast
                            {
                                // Signature
                                {
                                    var removeSignatures = new HashSet<string>();
                                    removeSignatures.UnionWith(_settings.MetadataManager.GetBroadcastSignatures());
                                    removeSignatures.ExceptWith(lockSignatures);

                                    var sortList = removeSignatures
                                        .OrderBy(n =>
                                        {
                                            DateTime t;
                                            _broadcastSignatureLastAccessTimes.TryGetValue(n, out t);

                                            return t;
                                        }).ToList();

                                    _settings.MetadataManager.RemoveBroadcastSignatures(sortList.Take(sortList.Count - 1024));

                                    var liveSignatures = new HashSet<string>(_settings.MetadataManager.GetBroadcastSignatures());

                                    foreach (var signature in _broadcastSignatureLastAccessTimes.Keys.ToArray())
                                    {
                                        if (liveSignatures.Contains(signature)) continue;

                                        _broadcastSignatureLastAccessTimes.Remove(signature);
                                    }
                                }
                            }

                            // Unicast
                            {
                                // Signature
                                {
                                    var removeSignatures = new HashSet<string>();
                                    removeSignatures.UnionWith(_settings.MetadataManager.GetUnicastSignatures());
                                    removeSignatures.ExceptWith(lockSignatures);

                                    var sortList = removeSignatures
                                        .OrderBy(n =>
                                        {
                                            DateTime t;
                                            _unicastSignatureLastAccessTimes.TryGetValue(n, out t);

                                            return t;
                                        }).ToList();

                                    _settings.MetadataManager.RemoveUnicastSignatures(sortList.Take(sortList.Count - 1024));

                                    var liveSignatures = new HashSet<string>(_settings.MetadataManager.GetUnicastSignatures());

                                    foreach (var signature in _unicastSignatureLastAccessTimes.Keys.ToArray())
                                    {
                                        if (liveSignatures.Contains(signature)) continue;

                                        _unicastSignatureLastAccessTimes.Remove(signature);
                                    }
                                }
                            }

                            // Multicast
                            {
                                // Wiki
                                {
                                    var removeWikis = new HashSet<Wiki>();
                                    removeWikis.UnionWith(_settings.MetadataManager.GetMulticastWikis());
                                    removeWikis.ExceptWith(lockWikis);

                                    var sortList = removeWikis
                                        .OrderBy(n =>
                                        {
                                            DateTime t;
                                            _multicastWikiLastAccessTimes.TryGetValue(n, out t);

                                            return t;
                                        }).ToList();

                                    _settings.MetadataManager.RemoveMulticastWikis(sortList.Take(sortList.Count - 1024));

                                    var liveWikis = new HashSet<Wiki>(_settings.MetadataManager.GetMulticastWikis());

                                    foreach (var tag in _multicastWikiLastAccessTimes.Keys.ToArray())
                                    {
                                        if (liveWikis.Contains(tag)) continue;

                                        _multicastWikiLastAccessTimes.Remove(tag);
                                    }
                                }

                                // Chat
                                {
                                    var removeChats = new HashSet<Chat>();
                                    removeChats.UnionWith(_settings.MetadataManager.GetMulticastChats());
                                    removeChats.ExceptWith(lockChats);

                                    var sortList = removeChats
                                        .OrderBy(n =>
                                        {
                                            DateTime t;
                                            _multicastChatLastAccessTimes.TryGetValue(n, out t);

                                            return t;
                                        }).ToList();

                                    _settings.MetadataManager.RemoveMulticastChats(sortList.Take(sortList.Count - 1024));

                                    var liveChats = new HashSet<Chat>(_settings.MetadataManager.GetMulticastChats());

                                    foreach (var tag in _multicastChatLastAccessTimes.Keys.ToArray())
                                    {
                                        if (liveChats.Contains(tag)) continue;

                                        _multicastChatLastAccessTimes.Remove(tag);
                                    }
                                }
                            }

                            // Unicast
                            {
                                var trustSignature = new HashSet<string>(lockSignatures);

                                {
                                    var now = DateTime.UtcNow;

                                    var removeSignatureMessageMetadatas = new HashSet<SignatureMessageMetadata>();

                                    foreach (var targetSignature in _settings.MetadataManager.GetUnicastSignatures())
                                    {
                                        // SignatureMessage
                                        {
                                            var trustMetadatas = new Dictionary<string, List<SignatureMessageMetadata>>();
                                            var untrustMetadatas = new Dictionary<string, List<SignatureMessageMetadata>>();

                                            foreach (var metadata in _settings.MetadataManager.GetSignatureMessageMetadatas(targetSignature))
                                            {
                                                var signature = metadata.Certificate.ToString();

                                                if (trustSignature.Contains(signature))
                                                {
                                                    List<SignatureMessageMetadata> list;

                                                    if (!trustMetadatas.TryGetValue(signature, out list))
                                                    {
                                                        list = new List<SignatureMessageMetadata>();
                                                        trustMetadatas[signature] = list;
                                                    }

                                                    list.Add(metadata);
                                                }
                                                else
                                                {
                                                    List<SignatureMessageMetadata> list;

                                                    if (!untrustMetadatas.TryGetValue(signature, out list))
                                                    {
                                                        list = new List<SignatureMessageMetadata>();
                                                        untrustMetadatas[signature] = list;
                                                    }

                                                    list.Add(metadata);
                                                }
                                            }

                                            removeSignatureMessageMetadatas.UnionWith(untrustMetadatas.Randomize().Skip(256).SelectMany(n => n.Value));

                                            foreach (var list in CollectionUtilities.Unite(trustMetadatas.Values, untrustMetadatas.Values))
                                            {
                                                if (list.Count <= 32) continue;

                                                list.Sort((x, y) => x.CreationTime.CompareTo(y.CreationTime));
                                                removeSignatureMessageMetadatas.UnionWith(list.Take(list.Count - 32));
                                            }
                                        }
                                    }

                                    foreach (var metadata in removeSignatureMessageMetadatas)
                                    {
                                        _settings.MetadataManager.RemoveMetadata(metadata);
                                    }
                                }
                            }

                            // Multicast
                            {
                                var trustSignature = new HashSet<string>(lockSignatures);

                                {
                                    var now = DateTime.UtcNow;

                                    var removeWikiDocumentMetadatas = new HashSet<WikiDocumentMetadata>();

                                    foreach (var wiki in _settings.MetadataManager.GetMulticastWikis())
                                    {
                                        // WikiDocument
                                        {
                                            var trustMetadatas = new Dictionary<string, List<WikiDocumentMetadata>>();
                                            var untrustMetadatas = new Dictionary<string, List<WikiDocumentMetadata>>();

                                            foreach (var metadata in _settings.MetadataManager.GetWikiDocumentMetadatas(wiki))
                                            {
                                                var signature = metadata.Certificate.ToString();

                                                if (trustSignature.Contains(signature))
                                                {
                                                    List<WikiDocumentMetadata> list;

                                                    if (!trustMetadatas.TryGetValue(signature, out list))
                                                    {
                                                        list = new List<WikiDocumentMetadata>();
                                                        trustMetadatas[signature] = list;
                                                    }

                                                    list.Add(metadata);
                                                }
                                                else
                                                {
                                                    List<WikiDocumentMetadata> list;

                                                    if (!untrustMetadatas.TryGetValue(signature, out list))
                                                    {
                                                        list = new List<WikiDocumentMetadata>();
                                                        untrustMetadatas[signature] = list;
                                                    }

                                                    list.Add(metadata);
                                                }
                                            }

                                            removeWikiDocumentMetadatas.UnionWith(untrustMetadatas.Randomize().Skip(256).SelectMany(n => n.Value));

                                            foreach (var list in CollectionUtilities.Unite(trustMetadatas.Values, untrustMetadatas.Values))
                                            {
                                                if (list.Count <= 32) continue;

                                                list.Sort((x, y) => x.CreationTime.CompareTo(y.CreationTime));
                                                removeWikiDocumentMetadatas.UnionWith(list.Take(list.Count - 32));
                                            }
                                        }
                                    }

                                    foreach (var metadata in removeWikiDocumentMetadatas)
                                    {
                                        _settings.MetadataManager.RemoveMetadata(metadata);
                                    }
                                }

                                {
                                    var now = DateTime.UtcNow;

                                    var removeChatMessageMetadatas = new HashSet<ChatMessageMetadata>();

                                    foreach (var chat in _settings.MetadataManager.GetMulticastChats())
                                    {
                                        // ChatMessage
                                        {
                                            var trustMetadatas = new Dictionary<string, List<ChatMessageMetadata>>();
                                            var untrustMetadatas = new Dictionary<string, List<ChatMessageMetadata>>();

                                            foreach (var metadata in _settings.MetadataManager.GetChatMessageMetadatas(chat))
                                            {
                                                var signature = metadata.Certificate.ToString();

                                                if (trustSignature.Contains(signature))
                                                {
                                                    List<ChatMessageMetadata> list;

                                                    if (!trustMetadatas.TryGetValue(signature, out list))
                                                    {
                                                        list = new List<ChatMessageMetadata>();
                                                        trustMetadatas[signature] = list;
                                                    }

                                                    list.Add(metadata);
                                                }
                                                else
                                                {
                                                    List<ChatMessageMetadata> list;

                                                    if (!untrustMetadatas.TryGetValue(signature, out list))
                                                    {
                                                        list = new List<ChatMessageMetadata>();
                                                        untrustMetadatas[signature] = list;
                                                    }

                                                    list.Add(metadata);
                                                }
                                            }

                                            removeChatMessageMetadatas.UnionWith(untrustMetadatas.Randomize().Skip(256).SelectMany(n => n.Value));

                                            foreach (var list in CollectionUtilities.Unite(trustMetadatas.Values, untrustMetadatas.Values))
                                            {
                                                if (list.Count <= 32) continue;

                                                list.Sort((x, y) => x.CreationTime.CompareTo(y.CreationTime));
                                                removeChatMessageMetadatas.UnionWith(list.Take(list.Count - 32));
                                            }
                                        }
                                    }

                                    foreach (var metadata in removeChatMessageMetadatas)
                                    {
                                        _settings.MetadataManager.RemoveMetadata(metadata);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                        finally
                        {
                            _refreshThreadRunning = false;
                        }
                    });
                }

                // 拡散アップロード
                if (connectionCount > _diffusionConnectionCountLowerLimit
                    && pushBlockDiffusionStopwatch.Elapsed.TotalSeconds >= 60)
                {
                    pushBlockDiffusionStopwatch.Restart();

                    // 拡散アップロードするブロック数を10000以下に抑える。
                    lock (this.ThisLock)
                    {
                        lock (_settings.DiffusionBlocksRequest.ThisLock)
                        {
                            if (_settings.DiffusionBlocksRequest.Count > 10000)
                            {
                                foreach (var key in _settings.DiffusionBlocksRequest.ToArray().Randomize()
                                    .Take(_settings.DiffusionBlocksRequest.Count - 10000).ToList())
                                {
                                    _settings.DiffusionBlocksRequest.Remove(key);
                                }
                            }
                        }
                    }

                    // 存在しないブロックのKeyをRemoveする。
                    lock (this.ThisLock)
                    {
                        lock (_settings.DiffusionBlocksRequest.ThisLock)
                        {
                            foreach (var key in _cacheManager.ExceptFrom(_settings.DiffusionBlocksRequest.ToArray()).ToArray())
                            {
                                _settings.DiffusionBlocksRequest.Remove(key);
                            }
                        }

                        lock (_settings.UploadBlocksRequest.ThisLock)
                        {
                            foreach (var key in _cacheManager.ExceptFrom(_settings.UploadBlocksRequest.ToArray()).ToArray())
                            {
                                _settings.UploadBlocksRequest.Remove(key);
                            }
                        }
                    }

                    var baseNode = this.BaseNode;

                    var otherNodes = new List<Node>();

                    lock (this.ThisLock)
                    {
                        otherNodes.AddRange(_connectionManagers.Select(n => n.Node));
                    }

                    var messageManagers = new Dictionary<Node, MessageManager>();

                    foreach (var node in otherNodes)
                    {
                        messageManagers[node] = _messagesManager[node];
                    }

                    var diffusionBlocksList = new List<Key>();

                    {
                        {
                            var array = _settings.UploadBlocksRequest.ToArray();
                            _random.Shuffle(array);

                            int count = 256;

                            for (int i = 0; i < count && i < array.Length; i++)
                            {
                                diffusionBlocksList.Add(array[i]);
                            }
                        }

                        {
                            var array = _settings.DiffusionBlocksRequest.ToArray();
                            _random.Shuffle(array);

                            int count = 256;

                            for (int i = 0; i < count && i < array.Length; i++)
                            {
                                diffusionBlocksList.Add(array[i]);
                            }
                        }
                    }

                    _random.Shuffle(diffusionBlocksList);

                    {
                        var diffusionBlocksDictionary = new Dictionary<Node, HashSet<Key>>();

                        foreach (var key in diffusionBlocksList)
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                // 自分より距離が遠いノードにもアップロードを試みる。
                                foreach (var node in Kademlia<Node>.Search(key.Hash, otherNodes, 3))
                                {
                                    requestNodes.Add(node);
                                }

                                if (requestNodes.Any(n => _messagesManager[n].StockBlocks.Contains(key)))
                                {
                                    _settings.UploadBlocksRequest.Remove(key);
                                    _settings.DiffusionBlocksRequest.Remove(key);

                                    continue;
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<Key> collection;

                                    if (!diffusionBlocksDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<Key>();
                                        diffusionBlocksDictionary[requestNodes[i]] = collection;
                                    }

                                    collection.Add(key);
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        lock (_diffusionBlocksDictionary.ThisLock)
                        {
                            _diffusionBlocksDictionary.Clear();

                            foreach (var pair in diffusionBlocksDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _diffusionBlocksDictionary.Add(node, new Queue<Key>(targets.Randomize()));
                            }
                        }
                    }
                }

                // アップロード
                if (connectionCount >= _uploadingConnectionCountLowerLimit
                    && pushBlockUploadStopwatch.Elapsed.TotalSeconds >= 10)
                {
                    pushBlockUploadStopwatch.Restart();

                    var baseNode = this.BaseNode;

                    var otherNodes = new List<Node>();

                    lock (this.ThisLock)
                    {
                        otherNodes.AddRange(_connectionManagers.Select(n => n.Node));
                    }

                    var messageManagers = new Dictionary<Node, MessageManager>();

                    foreach (var node in otherNodes)
                    {
                        messageManagers[node] = _messagesManager[node];
                    }

                    {
                        var uploadBlocksDictionary = new Dictionary<Node, List<Key>>();

                        foreach (var pair in messageManagers)
                        {
                            var node = pair.Key;
                            var messageManager = pair.Value;

                            uploadBlocksDictionary.Add(node, _cacheManager.IntersectFrom(messageManager.PullBlocksRequest.ToArray().Randomize()).Take(128).ToList());
                        }

                        lock (_uploadBlocksDictionary.ThisLock)
                        {
                            _uploadBlocksDictionary.Clear();

                            foreach (var pair in uploadBlocksDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _uploadBlocksDictionary.Add(node, new Queue<Key>(targets.Randomize()));
                            }
                        }
                    }
                }

                // ダウンロード
                if (connectionCount >= _downloadingConnectionCountLowerLimit
                    && pushBlockDownloadStopwatch.Elapsed.TotalSeconds >= 60)
                {
                    pushBlockDownloadStopwatch.Restart();

                    var baseNode = this.BaseNode;

                    var otherNodes = new List<Node>();

                    lock (this.ThisLock)
                    {
                        otherNodes.AddRange(_connectionManagers.Select(n => n.Node));
                    }

                    var messageManagers = new Dictionary<Node, MessageManager>();

                    foreach (var node in otherNodes)
                    {
                        messageManagers[node] = _messagesManager[node];
                    }

                    var pushBlocksLinkList = new List<Key>();
                    var pushBlocksRequestList = new List<Key>();

                    {
                        {
                            var array = _cacheManager.ToArray();
                            _random.Shuffle(array);

                            int count = _maxBlockLinkCount;

                            for (int i = 0; count > 0 && i < array.Length; i++)
                            {
                                if (!messageManagers.Values.Any(n => n.PushBlocksLink.Contains(array[i])))
                                {
                                    pushBlocksLinkList.Add(array[i]);

                                    count--;
                                }
                            }
                        }

                        foreach (var pair in messageManagers)
                        {
                            var node = pair.Key;
                            var messageManager = pair.Value;

                            {
                                var array = messageManager.PullBlocksLink.ToArray();
                                _random.Shuffle(array);

                                int count = (int)(_maxBlockLinkCount * ((double)12 / otherNodes.Count));

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushBlocksLink.Contains(array[i])))
                                    {
                                        pushBlocksLinkList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }
                        }

                        {
                            var array = _cacheManager.ExceptFrom(_downloadBlocks.ToArray()).ToArray();
                            _random.Shuffle(array);

                            int count = _maxBlockRequestCount;

                            for (int i = 0; count > 0 && i < array.Length; i++)
                            {
                                if (!messageManagers.Values.Any(n => n.PushBlocksRequest.Contains(array[i])))
                                {
                                    pushBlocksRequestList.Add(array[i]);

                                    count--;
                                }
                            }
                        }

                        foreach (var pair in messageManagers)
                        {
                            var node = pair.Key;
                            var messageManager = pair.Value;

                            {
                                var array = _cacheManager.ExceptFrom(messageManager.PullBlocksRequest.ToArray()).ToArray();
                                _random.Shuffle(array);

                                int count = (int)(_maxBlockRequestCount * ((double)12 / otherNodes.Count));

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushBlocksRequest.Contains(array[i])))
                                    {
                                        pushBlocksRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }
                        }
                    }

                    _random.Shuffle(pushBlocksLinkList);
                    _random.Shuffle(pushBlocksRequestList);

                    {
                        var pushBlocksLinkDictionary = new Dictionary<Node, HashSet<Key>>();

                        foreach (var key in pushBlocksLinkList)
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(key.Hash, baseNode.Id, otherNodes, 1))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<Key> collection;

                                    if (!pushBlocksLinkDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<Key>();
                                        pushBlocksLinkDictionary[requestNodes[i]] = collection;
                                    }

                                    if (collection.Count < _maxBlockLinkCount)
                                    {
                                        collection.Add(key);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        lock (_pushBlocksLinkDictionary.ThisLock)
                        {
                            _pushBlocksLinkDictionary.Clear();

                            foreach (var pair in pushBlocksLinkDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _pushBlocksLinkDictionary.Add(node, new List<Key>(targets.Randomize()));
                            }
                        }
                    }

                    {
                        var pushBlocksRequestDictionary = new Dictionary<Node, HashSet<Key>>();

                        foreach (var key in pushBlocksRequestList)
                        {
                            try
                            {
                                List<Node> requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(key.Hash, baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                foreach (var pair in messageManagers)
                                {
                                    var node = pair.Key;
                                    var messageManager = pair.Value;

                                    if (messageManager.PullBlocksLink.Contains(key))
                                    {
                                        requestNodes.Add(node);
                                    }
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<Key> collection;

                                    if (!pushBlocksRequestDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<Key>();
                                        pushBlocksRequestDictionary[requestNodes[i]] = collection;
                                    }

                                    if (collection.Count < _maxBlockRequestCount)
                                    {
                                        collection.Add(key);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        lock (_pushBlocksRequestDictionary.ThisLock)
                        {
                            _pushBlocksRequestDictionary.Clear();

                            foreach (var pair in pushBlocksRequestDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _pushBlocksRequestDictionary.Add(node, new List<Key>(targets.Randomize()));
                            }
                        }
                    }
                }

                // Metadataのアップロード
                if (connectionCount >= _uploadingConnectionCountLowerLimit
                    && pushMetadataUploadStopwatch.Elapsed.TotalMinutes >= 3)
                {
                    pushMetadataUploadStopwatch.Restart();

                    var baseNode = this.BaseNode;

                    var otherNodes = new List<Node>();

                    lock (this.ThisLock)
                    {
                        otherNodes.AddRange(_connectionManagers.Select(n => n.Node));
                    }

                    var messageManagers = new Dictionary<Node, MessageManager>();

                    foreach (var node in otherNodes)
                    {
                        messageManagers[node] = _messagesManager[node];
                    }

                    // Broadcast
                    foreach (var signature in _settings.MetadataManager.GetBroadcastSignatures())
                    {
                        try
                        {
                            var requestNodes = new List<Node>();

                            foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), baseNode.Id, otherNodes, 2))
                            {
                                requestNodes.Add(node);
                            }

                            for (int i = 0; i < requestNodes.Count; i++)
                            {
                                messageManagers[requestNodes[i]].PullBroadcastSignaturesRequest.Add(signature);
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                    }

                    // Unicast
                    foreach (var signature in _settings.MetadataManager.GetUnicastSignatures())
                    {
                        try
                        {
                            var requestNodes = new List<Node>();

                            foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), baseNode.Id, otherNodes, 2))
                            {
                                requestNodes.Add(node);
                            }

                            for (int i = 0; i < requestNodes.Count; i++)
                            {
                                messageManagers[requestNodes[i]].PullUnicastSignaturesRequest.Add(signature);
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                    }

                    // Multicast
                    {
                        foreach (var tag in _settings.MetadataManager.GetMulticastWikis())
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(tag.Id, baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    messageManagers[requestNodes[i]].PullMulticastWikisRequest.Add(tag);
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        foreach (var tag in _settings.MetadataManager.GetMulticastChats())
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(tag.Id, baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    messageManagers[requestNodes[i]].PullMulticastChatsRequest.Add(tag);
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }
                    }
                }

                // Metadataのダウンロード
                if (connectionCount >= _downloadingConnectionCountLowerLimit
                    && pushMetadataDownloadStopwatch.Elapsed.TotalSeconds >= 60)
                {
                    pushMetadataDownloadStopwatch.Restart();

                    var baseNode = this.BaseNode;

                    var otherNodes = new List<Node>();

                    lock (this.ThisLock)
                    {
                        otherNodes.AddRange(_connectionManagers.Select(n => n.Node));
                    }

                    var messageManagers = new Dictionary<Node, MessageManager>();

                    foreach (var node in otherNodes)
                    {
                        messageManagers[node] = _messagesManager[node];
                    }

                    var pushBroadcastSignaturesRequestList = new List<string>();
                    var pushUnicastSignaturesRequestList = new List<string>();
                    var pushMulticastWikisRequestList = new List<Wiki>();
                    var pushMulticastChatsRequestList = new List<Chat>();

                    // Broadcast
                    {
                        {
                            var array = _pushBroadcastSignaturesRequestList.ToArray();
                            _random.Shuffle(array);

                            int count = _maxMetadataRequestCount;

                            for (int i = 0; count > 0 && i < array.Length; i++)
                            {
                                if (!messageManagers.Values.Any(n => n.PushBroadcastSignaturesRequest.Contains(array[i])))
                                {
                                    pushBroadcastSignaturesRequestList.Add(array[i]);

                                    count--;
                                }
                            }
                        }

                        foreach (var pair in messageManagers)
                        {
                            var node = pair.Key;
                            var messageManager = pair.Value;

                            {
                                var array = messageManager.PullBroadcastSignaturesRequest.ToArray();
                                _random.Shuffle(array);

                                int count = _maxMetadataRequestCount;

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushBroadcastSignaturesRequest.Contains(array[i])))
                                    {
                                        pushBroadcastSignaturesRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }
                        }
                    }

                    // Unicast
                    {
                        {
                            var array = _pushUnicastSignaturesRequestList.ToArray();
                            _random.Shuffle(array);

                            int count = _maxMetadataRequestCount;

                            for (int i = 0; count > 0 && i < array.Length; i++)
                            {
                                if (!messageManagers.Values.Any(n => n.PushUnicastSignaturesRequest.Contains(array[i])))
                                {
                                    pushUnicastSignaturesRequestList.Add(array[i]);

                                    count--;
                                }
                            }
                        }

                        foreach (var pair in messageManagers)
                        {
                            var node = pair.Key;
                            var messageManager = pair.Value;

                            {
                                var array = messageManager.PullUnicastSignaturesRequest.ToArray();
                                _random.Shuffle(array);

                                int count = _maxMetadataRequestCount;

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushUnicastSignaturesRequest.Contains(array[i])))
                                    {
                                        pushUnicastSignaturesRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }
                        }
                    }

                    // Multicast
                    {
                        {
                            {
                                var array = _pushMulticastWikisRequestList.ToArray();
                                _random.Shuffle(array);

                                int count = _maxMetadataRequestCount;

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushMulticastWikisRequest.Contains(array[i])))
                                    {
                                        pushMulticastWikisRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }

                            {
                                var array = _pushMulticastChatsRequestList.ToArray();
                                _random.Shuffle(array);

                                int count = _maxMetadataRequestCount;

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushMulticastChatsRequest.Contains(array[i])))
                                    {
                                        pushMulticastChatsRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }
                        }

                        foreach (var pair in messageManagers)
                        {
                            var node = pair.Key;
                            var messageManager = pair.Value;

                            {
                                var array = messageManager.PullMulticastWikisRequest.ToArray();
                                _random.Shuffle(array);

                                int count = _maxMetadataRequestCount;

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushMulticastWikisRequest.Contains(array[i])))
                                    {
                                        pushMulticastWikisRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }

                            {
                                var array = messageManager.PullMulticastChatsRequest.ToArray();
                                _random.Shuffle(array);

                                int count = _maxMetadataRequestCount;

                                for (int i = 0; count > 0 && i < array.Length; i++)
                                {
                                    if (!messageManagers.Values.Any(n => n.PushMulticastChatsRequest.Contains(array[i])))
                                    {
                                        pushMulticastChatsRequestList.Add(array[i]);

                                        count--;
                                    }
                                }
                            }
                        }
                    }

                    _random.Shuffle(pushBroadcastSignaturesRequestList);
                    _random.Shuffle(pushUnicastSignaturesRequestList);
                    _random.Shuffle(pushMulticastWikisRequestList);
                    _random.Shuffle(pushMulticastChatsRequestList);

                    // Broadcast
                    {
                        var pushBroadcastSignaturesRequestDictionary = new Dictionary<Node, HashSet<string>>();

                        foreach (var signature in pushBroadcastSignaturesRequestList)
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<string> collection;

                                    if (!pushBroadcastSignaturesRequestDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<string>();
                                        pushBroadcastSignaturesRequestDictionary[requestNodes[i]] = collection;
                                    }

                                    if (collection.Count < _maxMetadataRequestCount)
                                    {
                                        collection.Add(signature);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        lock (_pushBroadcastSignaturesRequestDictionary.ThisLock)
                        {
                            _pushBroadcastSignaturesRequestDictionary.Clear();

                            foreach (var pair in pushBroadcastSignaturesRequestDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _pushBroadcastSignaturesRequestDictionary.Add(node, new List<string>(targets.Randomize()));
                            }
                        }
                    }

                    // Unicast
                    {
                        var pushUnicastSignaturesRequestDictionary = new Dictionary<Node, HashSet<string>>();

                        foreach (var signature in pushUnicastSignaturesRequestList)
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<string> collection;

                                    if (!pushUnicastSignaturesRequestDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<string>();
                                        pushUnicastSignaturesRequestDictionary[requestNodes[i]] = collection;
                                    }

                                    if (collection.Count < _maxMetadataRequestCount)
                                    {
                                        collection.Add(signature);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        lock (_pushUnicastSignaturesRequestDictionary.ThisLock)
                        {
                            _pushUnicastSignaturesRequestDictionary.Clear();

                            foreach (var pair in pushUnicastSignaturesRequestDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _pushUnicastSignaturesRequestDictionary.Add(node, new List<string>(targets.Randomize()));
                            }
                        }
                    }

                    // Multicast
                    {
                        var pushMulticastWikisRequestDictionary = new Dictionary<Node, HashSet<Wiki>>();
                        var pushMulticastChatsRequestDictionary = new Dictionary<Node, HashSet<Chat>>();

                        foreach (var tag in pushMulticastWikisRequestList)
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(tag.Id, baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<Wiki> collection;

                                    if (!pushMulticastWikisRequestDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<Wiki>();
                                        pushMulticastWikisRequestDictionary[requestNodes[i]] = collection;
                                    }

                                    if (collection.Count < _maxMetadataRequestCount)
                                    {
                                        collection.Add(tag);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        foreach (var tag in pushMulticastChatsRequestList)
                        {
                            try
                            {
                                var requestNodes = new List<Node>();

                                foreach (var node in Kademlia<Node>.Search(tag.Id, baseNode.Id, otherNodes, 2))
                                {
                                    requestNodes.Add(node);
                                }

                                for (int i = 0; i < requestNodes.Count; i++)
                                {
                                    HashSet<Chat> collection;

                                    if (!pushMulticastChatsRequestDictionary.TryGetValue(requestNodes[i], out collection))
                                    {
                                        collection = new HashSet<Chat>();
                                        pushMulticastChatsRequestDictionary[requestNodes[i]] = collection;
                                    }

                                    if (collection.Count < _maxMetadataRequestCount)
                                    {
                                        collection.Add(tag);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e);
                            }
                        }

                        lock (_pushMulticastWikisRequestDictionary.ThisLock)
                        {
                            _pushMulticastWikisRequestDictionary.Clear();

                            foreach (var pair in pushMulticastWikisRequestDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _pushMulticastWikisRequestDictionary.Add(node, new List<Wiki>(targets.Randomize()));
                            }
                        }

                        lock (_pushMulticastChatsRequestDictionary.ThisLock)
                        {
                            _pushMulticastChatsRequestDictionary.Clear();

                            foreach (var pair in pushMulticastChatsRequestDictionary)
                            {
                                var node = pair.Key;
                                var targets = pair.Value;

                                _pushMulticastChatsRequestDictionary.Add(node, new List<Chat>(targets.Randomize()));
                            }
                        }
                    }
                }
            }
        }