1 // Copyright (C) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::cmp;
15 use std::collections::HashSet;
16 use std::ops::Deref;
17 
18 use crate::manage::database::{RequestDb, TaskQosInfo};
19 use crate::task::config::{Action, Mode};
20 
21 /// List of sorted apps.
22 pub(crate) struct SortedApps {
23     inner: Vec<App>,
24 }
25 
26 impl SortedApps {
init() -> Self27     pub(crate) fn init() -> Self {
28         Self {
29             inner: reload_all_app_from_database(),
30         }
31     }
32 
sort(&mut self, top_uid: Option<u64>, top_user: u64)33     pub(crate) fn sort(&mut self, top_uid: Option<u64>, top_user: u64) {
34         self.inner.sort_by(|a, b| {
35             (a.uid / 200000 == top_user)
36                 .cmp(&(b.uid / 200000 == top_user))
37                 .then((Some(a.uid) == top_uid).cmp(&(Some(b.uid) == top_uid)))
38         })
39     }
40 
reload_all_tasks(&mut self)41     pub(crate) fn reload_all_tasks(&mut self) {
42         self.inner = reload_all_app_from_database();
43     }
44 
insert_task(&mut self, uid: u64, task: TaskQosInfo)45     pub(crate) fn insert_task(&mut self, uid: u64, task: TaskQosInfo) {
46         let task = Task {
47             uid,
48             task_id: task.task_id,
49             mode: Mode::from(task.mode),
50             action: Action::from(task.action),
51             priority: task.priority,
52         };
53 
54         if let Some(app) = self.inner.iter_mut().find(|app| app.uid == uid) {
55             app.insert(task);
56             return;
57         }
58 
59         let mut app = App::new(uid);
60         app.insert(task);
61         self.inner.push(app);
62     }
63 
remove_task(&mut self, uid: u64, task_id: u32) -> bool64     pub(crate) fn remove_task(&mut self, uid: u64, task_id: u32) -> bool {
65         // Remove target task in target app.
66         if let Some(app) = self.inner.iter_mut().find(|app| app.uid == uid) {
67             app.remove(task_id)
68         } else {
69             false
70         }
71     }
72 }
73 
74 impl Deref for SortedApps {
75     type Target = Vec<App>;
76 
deref(&self) -> &Self::Target77     fn deref(&self) -> &Self::Target {
78         &self.inner
79     }
80 }
81 
82 /// An independent app.
83 pub(crate) struct App {
84     pub(crate) uid: u64,
85     tasks: Vec<Task>,
86 }
87 
88 impl App {
new(uid: u64) -> Self89     fn new(uid: u64) -> Self {
90         Self {
91             uid,
92             tasks: Vec::new(),
93         }
94     }
95 
from_raw(uid: u64, tasks: Vec<Task>) -> Self96     fn from_raw(uid: u64, tasks: Vec<Task>) -> Self {
97         Self { uid, tasks }
98     }
99 
is_empty(&self) -> bool100     pub(crate) fn is_empty(&self) -> bool {
101         self.tasks.is_empty()
102     }
103 
insert(&mut self, task: Task)104     fn insert(&mut self, task: Task) {
105         self.tasks.binary_insert(task)
106     }
107 
remove(&mut self, task_id: u32) -> bool108     fn remove(&mut self, task_id: u32) -> bool {
109         if let Some((i, _)) = self
110             .tasks
111             .iter()
112             .enumerate()
113             .find(|(_, task)| task.task_id == task_id)
114         {
115             self.tasks.remove(i);
116             true
117         } else {
118             false
119         }
120     }
121 }
122 
123 impl Deref for App {
124     type Target = Vec<Task>;
125 
deref(&self) -> &Self::Target126     fn deref(&self) -> &Self::Target {
127         &self.tasks
128     }
129 }
130 
131 pub(crate) struct Task {
132     uid: u64,
133     task_id: u32,
134     mode: Mode,
135     action: Action,
136     priority: u32,
137 }
138 
139 impl Task {
uid(&self) -> u64140     pub(crate) fn uid(&self) -> u64 {
141         self.uid
142     }
143 
task_id(&self) -> u32144     pub(crate) fn task_id(&self) -> u32 {
145         self.task_id
146     }
147 
action(&self) -> Action148     pub(crate) fn action(&self) -> Action {
149         self.action
150     }
151 }
152 
153 impl Eq for Task {}
154 
155 impl Ord for Task {
cmp(&self, other: &Self) -> cmp::Ordering156     fn cmp(&self, other: &Self) -> cmp::Ordering {
157         self.mode
158             .cmp(&other.mode)
159             .then(self.priority.cmp(&other.priority))
160     }
161 }
162 
163 impl PartialEq for Task {
eq(&self, other: &Self) -> bool164     fn eq(&self, other: &Self) -> bool {
165         self.mode == other.mode && self.priority == other.priority
166     }
167 }
168 
169 impl PartialOrd for Task {
partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>170     fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
171         Some(self.cmp(other))
172     }
173 }
174 
175 trait Binary<T: Ord> {
binary_insert(&mut self, value: T)176     fn binary_insert(&mut self, value: T);
177 }
178 
179 impl<T: Ord> Binary<T> for Vec<T> {
binary_insert(&mut self, value: T)180     fn binary_insert(&mut self, value: T) {
181         match self.binary_search(&value) {
182             Ok(n) => self.insert(n, value),
183             Err(n) => self.insert(n, value),
184         }
185     }
186 }
187 
reload_all_app_from_database() -> Vec<App>188 fn reload_all_app_from_database() -> Vec<App> {
189     let mut inner = Vec::new();
190     for uid in reload_app_list_from_database() {
191         let mut tasks = reload_tasks_of_app_from_database(uid);
192         // Ensure that tasks are arranged in order
193         tasks.sort();
194         inner.push(App::from_raw(uid, tasks));
195     }
196     inner
197 }
198 
reload_tasks_of_app_from_database(uid: u64) -> Vec<Task>199 fn reload_tasks_of_app_from_database(uid: u64) -> Vec<Task> {
200     RequestDb::get_instance()
201         .get_app_task_qos_infos(uid)
202         .iter()
203         .map(|info| Task {
204             uid,
205             task_id: info.task_id,
206             mode: Mode::from(info.mode),
207             action: Action::from(info.action),
208             priority: info.priority,
209         })
210         .collect()
211 }
212 
reload_app_list_from_database() -> HashSet<u64>213 fn reload_app_list_from_database() -> HashSet<u64> {
214     RequestDb::get_instance()
215         .get_app_infos()
216         .into_iter()
217         .collect()
218 }
219 
220 impl RequestDb {
get_app_infos(&self) -> Vec<u64>221     fn get_app_infos(&self) -> Vec<u64> {
222         let sql = "SELECT DISTINCT uid FROM request_task";
223         self.query_integer(sql)
224     }
225 }
226 
227 #[cfg(feature = "oh")]
228 #[cfg(test)]
229 mod ut_manage_scheduler_qos_apps {
230     use super::{App, Task};
231     use crate::manage::database::RequestDb;
232     use crate::task::config::Mode;
233     use crate::tests::{lock_database, test_init};
234     use crate::utils::get_current_timestamp;
235     use crate::utils::task_id_generator::TaskIdGenerator;
236     impl Task {
new(task_id: u32, mode: Mode, priority: u32) -> Self237         fn new(task_id: u32, mode: Mode, priority: u32) -> Self {
238             Self {
239                 uid: 0,
240                 action: crate::task::config::Action::Any,
241                 task_id,
242                 mode,
243                 priority,
244             }
245         }
246     }
247 
248     #[test]
ut_app_insert()249     fn ut_app_insert() {
250         let mut app = App::new(1);
251         assert!(app.tasks.is_empty());
252         assert_eq!(app.uid, 1);
253 
254         app.insert(Task::new(1, Mode::FrontEnd, 0));
255         assert_eq!(app.tasks[0].task_id, 1);
256         assert_eq!(app.tasks[0].mode, Mode::FrontEnd);
257         assert_eq!(app.tasks[0].priority, 0);
258 
259         app.insert(Task::new(2, Mode::FrontEnd, 100));
260         assert_eq!(app.tasks[0].task_id, 1);
261         assert_eq!(app.tasks[1].task_id, 2);
262 
263         app.insert(Task::new(3, Mode::FrontEnd, 50));
264         assert_eq!(app.tasks[0].task_id, 1);
265         assert_eq!(app.tasks[1].task_id, 3);
266         assert_eq!(app.tasks[2].task_id, 2);
267 
268         app.insert(Task::new(4, Mode::BackGround, 0));
269         assert_eq!(app.tasks[0].task_id, 1);
270         assert_eq!(app.tasks[1].task_id, 3);
271         assert_eq!(app.tasks[2].task_id, 2);
272         assert_eq!(app.tasks[3].task_id, 4);
273 
274         app.insert(Task::new(5, Mode::BackGround, 100));
275         assert_eq!(app.tasks[0].task_id, 1);
276         assert_eq!(app.tasks[1].task_id, 3);
277         assert_eq!(app.tasks[2].task_id, 2);
278         assert_eq!(app.tasks[3].task_id, 4);
279         assert_eq!(app.tasks[4].task_id, 5);
280 
281         app.insert(Task::new(6, Mode::BackGround, 50));
282         assert_eq!(app.tasks[0].task_id, 1);
283         assert_eq!(app.tasks[1].task_id, 3);
284         assert_eq!(app.tasks[2].task_id, 2);
285         assert_eq!(app.tasks[3].task_id, 4);
286         assert_eq!(app.tasks[4].task_id, 6);
287         assert_eq!(app.tasks[5].task_id, 5);
288     }
289 
290     #[test]
ut_app_remove()291     fn ut_app_remove() {
292         let mut app = App::new(1);
293         for i in 0..5 {
294             app.insert(Task::new(i, Mode::FrontEnd, i));
295         }
296         assert_eq!(app.tasks[0].task_id, 0);
297         assert_eq!(app.tasks[1].task_id, 1);
298         assert_eq!(app.tasks[2].task_id, 2);
299         assert_eq!(app.tasks[3].task_id, 3);
300         assert_eq!(app.tasks[4].task_id, 4);
301 
302         app.remove(3);
303         assert_eq!(app.tasks[0].task_id, 0);
304         assert_eq!(app.tasks[1].task_id, 1);
305         assert_eq!(app.tasks[2].task_id, 2);
306         assert_eq!(app.tasks[3].task_id, 4);
307 
308         app.remove(1);
309         assert_eq!(app.tasks[0].task_id, 0);
310         assert_eq!(app.tasks[1].task_id, 2);
311         assert_eq!(app.tasks[2].task_id, 4);
312 
313         app.remove(4);
314         assert_eq!(app.tasks[0].task_id, 0);
315         assert_eq!(app.tasks[1].task_id, 2);
316 
317         app.remove(0);
318         assert_eq!(app.tasks[0].task_id, 2);
319     }
320 
321     #[test]
ut_task_partial_ord()322     fn ut_task_partial_ord() {
323         let task1 = Task::new(1, Mode::FrontEnd, 0);
324         let task2 = Task::new(2, Mode::FrontEnd, 1);
325         let task3 = Task::new(3, Mode::BackGround, 0);
326         let task4 = Task::new(4, Mode::BackGround, 1);
327         assert!(task1 < task2);
328         assert!(task1 < task3);
329         assert!(task1 < task4);
330         assert!(task2 < task3);
331         assert!(task2 < task4);
332         assert!(task3 < task4);
333     }
334 
335     #[test]
ut_database_app_info()336     fn ut_database_app_info() {
337         test_init();
338         let db = RequestDb::get_instance();
339         let _lock = lock_database();
340         let uid = get_current_timestamp();
341 
342         for i in 0..10 {
343             db.execute(&format!(
344                 "INSERT INTO request_task (task_id, uid, bundle) VALUES ({}, {}, '{}')",
345                 TaskIdGenerator::generate(),
346                 uid + i / 5,
347                 "test_bundle",
348             ))
349             .unwrap();
350         }
351         let v = db.get_app_infos();
352         assert_eq!(v.iter().filter(|a| **a == uid).count(), 1);
353         assert_eq!(v.iter().filter(|a| **a == uid + 1).count(), 1);
354     }
355 }
356