Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2030
Changed recursive Linq2Sql queries to native SQL queries.

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