Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs @ 9399

Last change on this file since 9399 was 9399, checked in by pfleck, 11 years ago

#2030
Removed unnecessary UpdatePlugins in UpdateTask.
Optimized GetTask and GetPlugin with compiled queries.

File size: 8.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Data.Linq;
25using System.Linq;
26using DT = HeuristicLab.Services.Hive.DataTransfer;
27
28namespace HeuristicLab.Services.Hive.DataAccess {
29  public class HiveDao : IHiveDao {
30    private HiveDataContext Db { get { return HiveOperationContext.Current.DataContext; } }
31
32    #region Task Methods
33    public Task GetTaskById(Guid taskId) {
34      return GetTaskByIdQuery(Db, taskId).SingleOrDefault();
35    }
36
37    private static Func<HiveDataContext, Guid, IQueryable<Task>> GetTaskByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
38      from t in db.Tasks
39      where t.TaskId == taskId
40      select t
41    );
42
43    public Task GetTaskByDto(DT.Task taskDto) {
44      var task = GetTaskById(taskDto.Id);
45      DT.Convert.ToEntity(taskDto, task);
46      return task;
47    }
48
49    public Tuple<Task, Guid?> GetTaskByIdAndLastStateLogSlaveId(Guid taskId) {
50      return GetTaskByIdAndLastStateLogSlaveIdQuery(Db, taskId).SingleOrDefault();
51    }
52
53    private static Func<HiveDataContext, Guid, IQueryable<Tuple<Task, Guid?>>> GetTaskByIdAndLastStateLogSlaveIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
54       from t in db.Tasks
55       join sl in db.StateLogs on t.TaskId equals sl.TaskId
56       where t.TaskId == taskId
57       orderby sl.DateTime descending
58       group sl by t into logs
59       select new Tuple<Task, Guid?>(logs.Key, logs.First().SlaveId)
60    );
61
62    private const string GetWaitingTasksQueryString = @"
63      WITH pr AS (
64        SELECT ResourceId, ParentResourceId
65        FROM [Resource]
66        WHERE ResourceId = {0}
67        UNION ALL
68        SELECT r.ResourceId, r.ParentResourceId
69        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
70      )
71      SELECT DISTINCT t.TaskId, t.JobId, t.Priority
72      FROM pr JOIN AssignedResources ar ON ar.ResourceId = pr.ResourceId
73          JOIN Task t ON t.TaskId = ar.TaskId
74      WHERE NOT (t.IsParentTask = 1 AND t.FinishWhenChildJobsFinished = 1)
75          AND t.TaskState = {1}
76          AND t.CoresNeeded <= {2}
77          AND t.MemoryNeeded <= {3}
78    ";
79
80    public IEnumerable<TaskInfoForScheduler> GetWaitingTasks(Slave slave) {
81      //Originally we checked here if there are parent tasks which should be calculated (with GetParentTasks(resourceIds, count, false);).
82      //Because there is at the moment no case where this makes sense (there don't exist parent tasks which need to be calculated),
83      //we skip this step because it's wasted runtime
84      return Db.ExecuteQuery<TaskInfoForScheduler>(GetWaitingTasksQueryString, slave.ResourceId, Enum.GetName(typeof(TaskState), TaskState.Waiting), slave.FreeCores, slave.FreeMemory);
85    }
86
87    public IQueryable<DT.LightweightTask> GetLightweightTasks(Guid jobId) {
88      return GetLightweightTasksQuery(Db, jobId);
89    }
90
91    private static Func<HiveDataContext, Guid, IQueryable<DT.LightweightTask>> GetLightweightTasksQuery = CompiledQuery.Compile((HiveDataContext db, Guid jobId) =>
92        from task in db.Tasks
93        where task.JobId == jobId
94        select new DT.LightweightTask {
95          Id = task.TaskId,
96          ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs),
97          ParentTaskId = task.ParentTaskId,
98          StateLog = task.StateLogs.Select(sl => ConvertStateLog(sl)).ToList(),
99          State = ConvertTaskState(task.State),
100          Command = ConvertCommand(task.Command),
101          LastTaskDataUpdate = task.JobData.LastUpdate
102        }
103    );
104
105    static Func<StateLog, DT.StateLog> ConvertStateLog = sl => DT.Convert.ToDto(sl);
106    static Func<TaskState, DT.TaskState> ConvertTaskState = ts => DT.Convert.ToDto(ts);
107    static Func<Command?, DT.Command?> ConvertCommand = c => DT.Convert.ToDto(c);
108
109    public void UpdateTask(Task task) {
110      Db.SubmitChanges();
111    }
112
113    public Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
114      Db.StateLogs.InsertOnSubmit(new StateLog {
115        TaskId = taskId,
116        State = taskState,
117        SlaveId = slaveId,
118        UserId = userId,
119        Exception = exception,
120        DateTime = DateTime.Now
121      });
122
123      var task = GetTaskById(taskId);
124      task.State = taskState;
125
126      Db.SubmitChanges();
127
128      return task;
129    }
130
131    private const string TaskIsAllowedToBeCalculatedBySlaveQueryString = @"
132      WITH pr AS (
133        SELECT ResourceId, ParentResourceId
134        FROM [Resource]
135        WHERE ResourceId = {0}
136        UNION ALL
137        SELECT r.ResourceId, r.ParentResourceId
138        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
139      )
140      SELECT COUNT(ar.TaskId)
141      FROM pr JOIN AssignedResources ar ON pr.ResourceId = ar.ResourceId
142      WHERE ar.TaskId = {1}
143    ";
144
145    public bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId) {
146      return Db.ExecuteQuery<int>(TaskIsAllowedToBeCalculatedBySlaveQueryString, slaveId, taskId).First() > 0;
147    }
148    #endregion
149
150    #region TaskData Methods
151    public TaskData GetTaskDataById(Guid id) {
152      return GetTaskDataByIdQuery(Db, id).SingleOrDefault();
153    }
154
155    private static Func<HiveDataContext, Guid, IQueryable<TaskData>> GetTaskDataByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid id) =>
156      from t in db.TaskDatas
157      where t.TaskId == id
158      select t
159    );
160
161    public TaskData GetTaskDataByDto(DT.TaskData dto) {
162      var taskData = GetTaskDataById(dto.TaskId);
163      DT.Convert.ToEntity(dto, taskData);
164      return taskData;
165    }
166
167    public void UpdateTaskData(TaskData taskData) {
168      Db.SubmitChanges();
169    }
170    #endregion
171
172    #region StateLog Methods
173
174    #endregion
175
176    #region Job Methods
177
178    #endregion
179
180    #region JobPermission Methods
181
182    #endregion
183
184    #region Plugin Methods
185    public Plugin GetPluginById(Guid pluginId) {
186      return GetPluginByIdQuery(Db, pluginId).SingleOrDefault();
187    }
188
189    private static Func<HiveDataContext, Guid, IQueryable<Plugin>> GetPluginByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid pluginId) =>
190      from p in db.Plugins
191      where p.PluginId == pluginId
192      select p
193    );
194
195    #endregion
196
197    #region PluginData Methods
198
199    #endregion
200
201    #region Slave Methods
202    public Slave GetSlaveById(Guid id) {
203      return GetSlaveByIdQuery(Db, id).SingleOrDefault();
204    }
205
206    private static Func<HiveDataContext, Guid, IQueryable<Slave>> GetSlaveByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid slaveId) =>
207      from s in db.Resources.OfType<Slave>()
208      where s.ResourceId == slaveId
209      select s
210    );
211
212    public void UpdateSlave(Slave slave) {
213      Db.SubmitChanges();
214    }
215
216    private const string DowntimeQueryString = @"
217      WITH pr AS (
218        SELECT ResourceId, ParentResourceId
219        FROM [Resource]
220        WHERE ResourceId = {0}
221        UNION ALL
222        SELECT r.ResourceId, r.ParentResourceId
223        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
224      )
225      SELECT COUNT(dt.DowntimeId)
226      FROM pr JOIN [Downtime] dt ON pr.ResourceId = dt.ResourceId
227      WHERE {1} BETWEEN dt.StartDate AND dt.EndDate
228        AND dt.DowntimeType = {2}
229      ";
230
231    public bool SlaveHasToShutdownComputer(Guid slaveId) {
232      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Shutdown).First() > 0;
233    }
234
235    public bool SlaveIsAllowedToCalculate(Guid slaveId) {
236      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Offline).First() == 0;
237    }
238    #endregion
239
240    #region SlaveGroup Methods
241
242    #endregion
243
244    #region Resource Methods
245    #endregion
246
247    #region ResourcePermission Methods
248
249    #endregion
250
251    #region Authorization Methods
252
253    #endregion
254
255    #region Lifecycle Methods
256
257    #endregion
258
259    #region Downtime Methods
260    #endregion
261
262    #region Statistics Methods
263
264    #endregion
265
266    #region UserPriority Methods
267
268    #endregion
269
270    #region Helpers
271
272    #endregion
273  }
274}
Note: See TracBrowser for help on using the repository browser.