Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs @ 15584

Last change on this file since 15584 was 15584, checked in by swagner, 6 years ago

#2640: Updated year of copyrights in license headers on stable

File size: 12.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Text;
27using System.Windows.Forms;
28using HeuristicLab.Clients.Hive.JobManager.ExtensionMethods;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33
34namespace HeuristicLab.Clients.Hive.JobManager.Views {
35  [View("Hive Resource Selector View")]
36  [Content(typeof(IItemList<Resource>), true)]
37  public partial class HiveResourceSelector : ItemView, IDisposable {
38    private const int slaveImageIndex = 0;
39    private const int slaveGroupImageIndex = 1;
40    private string currentSearchString;
41    private ISet<TreeNode> mainTreeNodes;
42    private ISet<TreeNode> filteredTreeNodes;
43    private ISet<TreeNode> nodeStore;
44   
45    private ISet<Resource> selectedResources;
46    public ISet<Resource> SelectedResources {
47      get { return selectedResources; }
48      set { selectedResources = value; }
49    }
50
51    public new IItemList<Resource> Content {
52      get { return (IItemList<Resource>)base.Content; }
53      set { base.Content = value; }
54    }
55
56    public HiveResourceSelector() {
57      InitializeComponent();
58      mainTreeNodes = new HashSet<TreeNode>();
59      filteredTreeNodes = new HashSet<TreeNode>();
60      nodeStore = new HashSet<TreeNode>();
61      selectedResources = new HashSet<Resource>();
62      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge);
63      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge);
64    }
65 
66    public void StartProgressView() {
67      if (InvokeRequired) {
68        Invoke(new Action(StartProgressView));
69      } else {
70        var message = "Downloading resources. Please be patient.";
71        MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().AddOperationProgressToView(this, message);
72      }
73    }
74
75    public void FinishProgressView() {
76      if (InvokeRequired) {
77        Invoke(new Action(FinishProgressView));
78      } else {
79        MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().RemoveOperationProgressFromView(this);
80      }
81    }
82
83    protected override void OnContentChanged() {
84      base.OnContentChanged();
85
86      if (Content != null) {
87        selectedResources = new HashSet<Resource>(Content.Where(x => selectedResources.Any(y => x.Id == y.Id)));
88        UpdateMainTree();
89        ExtractStatistics();
90      } else {
91        mainTreeNodes.Clear();
92        UpdateFilteredTree();
93      }
94    }
95
96    #region MainTree Methods
97    private void UpdateMainTree() {
98      mainTreeNodes.Clear();
99
100      foreach (Resource g in Content) {
101        if (g.GetType() == typeof(SlaveGroup)) {
102          //root node
103          if (g.ParentResourceId == null) {
104            TreeNode tn = new TreeNode();
105            tn.ImageIndex = slaveGroupImageIndex;
106            tn.SelectedImageIndex = tn.ImageIndex;
107
108            tn.Tag = g;
109            tn.Text = g.Name;
110            tn.Checked = selectedResources.Any(x => x.Id == g.Id);
111
112            BuildMainTree(tn);
113            mainTreeNodes.Add(tn);
114          }
115        }
116      }
117      UpdateFilteredTree();
118    }
119
120    private void BuildMainTree(TreeNode tn) {
121      foreach (Resource r in Content.Where(s => s.ParentResourceId != null && s.ParentResourceId == ((Resource)tn.Tag).Id)) {
122        TreeNode stn = new TreeNode(r.Name);
123        if (r is Slave) stn.ImageIndex = slaveImageIndex;
124        else if (r is SlaveGroup) stn.ImageIndex = slaveGroupImageIndex;
125        stn.SelectedImageIndex = stn.ImageIndex;
126        stn.Tag = r;
127        stn.Checked = selectedResources.Any(x => x.Id == r.Id);
128        tn.Nodes.Add(stn);
129        mainTreeNodes.Add(stn);
130
131        BuildMainTree(stn);
132      }
133    }
134    #endregion
135
136    #region FilteredTree Methods
137    private void UpdateFilteredTree() {
138      filteredTreeNodes.Clear();
139      foreach (TreeNode n in mainTreeNodes) {
140        n.BackColor = SystemColors.Window;
141        if (currentSearchString == null || ((Resource)n.Tag).Name.ToLower().Contains(currentSearchString)) {
142          n.BackColor = string.IsNullOrEmpty(currentSearchString) ? SystemColors.Window : Color.LightBlue;
143          filteredTreeNodes.Add(n);
144          TraverseParentNodes(n);
145        }
146      }
147      UpdateResourceTree();
148    }
149
150    private void TraverseParentNodes(TreeNode node) {
151      if (node != null) {
152        for (TreeNode parent = node.Parent; parent != null; parent = parent.Parent)
153          filteredTreeNodes.Add(parent);
154      }
155    }
156    #endregion
157
158    #region ResourceTree Methods
159    private void UpdateResourceTree() {
160      resourcesTreeView.Nodes.Clear();
161      nodeStore.Clear();
162
163      foreach (TreeNode node in filteredTreeNodes) {
164        var clone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
165        if (clone == null) {
166          clone = (TreeNode)node.Clone();
167          nodeStore.Add(clone);
168          clone.Nodes.Clear();
169        }
170        foreach (TreeNode child in node.Nodes)
171          if (filteredTreeNodes.Any(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id)) {
172            var childClone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id);
173            if (childClone == null) {
174              childClone = (TreeNode)child.Clone();
175              nodeStore.Add(childClone);
176              childClone.Nodes.Clear();
177            }
178            clone.Nodes.Add(childClone);
179          }
180      }
181      resourcesTreeView.Nodes.AddRange(nodeStore.Where(x => ((Resource)x.Tag).ParentResourceId == null).ToArray());
182      if (string.IsNullOrEmpty(currentSearchString)) ExpandSlaveGroupNodes();
183      else resourcesTreeView.ExpandAll();
184    }
185    #endregion
186
187    #region Events
188    private void resourcesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
189      if (e.Action != TreeViewAction.Unknown) {
190        if (e.Node.Checked) {
191          IncludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
192          IncludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
193        } else {
194          ExcludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
195          ExcludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
196        }
197        ExtractStatistics();
198      }
199    }
200
201    private void resourcesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
202      if (e.Action != TreeViewAction.Unknown) {
203        ExtractStatistics(e.Node);
204      }
205    }
206
207    private void searchTextBox_TextChanged(object sender, System.EventArgs e) {
208      currentSearchString = searchTextBox.Text.ToLower();
209      UpdateFilteredTree();
210    }
211    #endregion
212
213    #region Helpers
214    private void IncludeChildNodes(TreeNode node) {
215      if (node != null) {
216        node.Checked = true;
217        selectedResources.Add((Resource)node.Tag);
218        AdjustNodeCheckedState(node);
219        foreach (TreeNode n in node.Nodes) IncludeChildNodes(n);
220      }
221    }
222
223    private void IncludeParentNodes(TreeNode node) {
224      if (node != null && node.Parent != null) {
225        TreeNode parent = node.Parent;
226        if (parent.Nodes.OfType<TreeNode>().All(x => x.Checked)) {
227          parent.Checked = true;
228          selectedResources.Add((Resource)parent.Tag);
229          AdjustNodeCheckedState(parent);
230          IncludeParentNodes(parent);
231        }
232      }
233    }
234
235    private void ExcludeChildNodes(TreeNode node) {
236      if (node != null) {
237        node.Checked = false;
238        selectedResources.Remove((Resource)node.Tag);
239        AdjustNodeCheckedState(node);
240        foreach (TreeNode n in node.Nodes) ExcludeChildNodes(n);
241      }
242    }
243
244    private void ExcludeParentNodes(TreeNode node) {
245      if (node != null) {
246        node.Checked = false;
247        selectedResources.Remove((Resource)node.Tag);
248        AdjustNodeCheckedState(node);
249        ExcludeParentNodes(node.Parent);
250      }
251    }
252
253    private void AdjustNodeCheckedState(TreeNode node) {
254      var filterdNode = filteredTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
255      var storedNode = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
256      if (filterdNode != null) filterdNode.Checked = node.Checked;
257      if (storedNode != null) storedNode.Checked = node.Checked;
258    }
259
260    private void ExpandSlaveGroupNodes() {
261      foreach (TreeNode n in nodeStore.Where(x => x.Tag is SlaveGroup)) {
262        TreeNode[] children = new TreeNode[n.Nodes.Count];
263        n.Nodes.CopyTo(children, 0);
264        if (children.Any(x => x.Tag is SlaveGroup)) n.Expand();
265      }
266    }
267
268    private void ExtractStatistics(TreeNode treeNode = null) {
269      StringBuilder sb = new StringBuilder();
270      Resource resource = treeNode == null ? null : treeNode.Tag as Resource;
271      ISet<Resource> resources = treeNode == null ? selectedResources : new HashSet<Resource>(treeNode.DescendantNodes().Select(x => x.Tag as Resource)); ;
272      IEnumerable<SlaveGroup> slaveGroups = resources.OfType<SlaveGroup>();
273      IEnumerable<Slave> slaves = resources.OfType<Slave>();
274      int cpuSpeed = 0, cores = 0, freeCores = 0, memory = 0, freeMemory = 0;
275      string contextString = treeNode == null ? "Selected" : "Included";
276
277      if (resources.Any() || resource != null) {
278        foreach (Slave s in slaves) {
279          cpuSpeed += s.CpuSpeed.GetValueOrDefault();
280          cores += s.Cores.GetValueOrDefault();
281          freeCores += s.FreeCores.GetValueOrDefault();
282          memory += s.Memory.GetValueOrDefault();
283          freeMemory += s.FreeMemory.GetValueOrDefault();
284        }
285        if (resource != null) {
286          if (resource is SlaveGroup) sb.Append("Slave group: ");
287          else if (resource is Slave) {
288            sb.Append("Slave: ");
289            if (!resources.Any()) {
290              Slave s = resource as Slave;
291              cpuSpeed = s.CpuSpeed.GetValueOrDefault();
292              cores = s.Cores.GetValueOrDefault();
293              freeCores = s.FreeCores.GetValueOrDefault();
294              memory = s.Memory.GetValueOrDefault();
295              freeMemory = s.FreeMemory.GetValueOrDefault();
296            }
297          }
298          sb.AppendLine(string.Format("{0}", resource.Name));
299        }
300        if (resource == null || resource is SlaveGroup) {
301          if (resources.Any()) {
302            sb.AppendFormat("{0} slave groups ({1}): ", contextString, slaveGroups.Count());
303            foreach (SlaveGroup sg in slaveGroups) sb.AppendFormat("{0}; ", sg.Name);
304            sb.AppendLine();
305            sb.AppendFormat("{0} slaves ({1}): ", contextString, slaves.Count());
306            foreach (Slave s in slaves) sb.AppendFormat("{0}; ", s.Name);
307            sb.AppendLine();
308          } else {
309            sb.Append("The selection does not inlcude any further resources.");
310          }
311        }
312        sb.AppendLine();
313        sb.AppendLine(string.Format("CPU speed: {0} MHz", cpuSpeed));
314        if (resources.Any()) sb.AppendLine(string.Format("Avg. CPU speed: {0:0.00} MHz", (double)cpuSpeed / resources.Count()));
315        sb.AppendLine(string.Format("Cores: {0}", cores));
316        sb.AppendLine(string.Format("Free cores: {0}", freeCores));
317        if (resources.Any()) sb.AppendLine(string.Format("Avg. free cores: {0:0.00}", (double)freeCores / resources.Count()));
318        sb.AppendLine(string.Format("Memory: {0} MB", memory));
319        sb.AppendFormat("Free memory: {0} MB", freeMemory);
320        if (resources.Any()) sb.Append(string.Format("{0}Avg. free memory: {1:0.00} MB", Environment.NewLine, (double)freeMemory / resources.Count()));
321      } else {
322        sb.Append("No resources selected.");
323      }
324
325      descriptionTextBox.Text = sb.ToString();
326    }
327    #endregion
328  }
329}
Note: See TracBrowser for help on using the repository browser.