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); } }
/// <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; }
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; }
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; } }
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())); } } } } } }