10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-12-23 21:03:56 +01:00
quantum_package/ocaml/Queuing_system.ml

210 lines
5.0 KiB
OCaml
Raw Normal View History

2016-10-13 12:32:22 +02:00
module RunningMap = Map.Make (Id.Task)
module TasksMap = Map.Make (Id.Task)
module ClientsSet = Set.Make (Id.Client)
2015-12-03 23:51:10 +01:00
type t =
{ queued_front : Id.Task.t list ;
queued_back : Id.Task.t list ;
2016-10-13 12:32:22 +02:00
running : Id.Client.t RunningMap.t;
tasks : string TasksMap.t;
clients : ClientsSet.t;
2015-12-03 23:51:10 +01:00
next_client_id : Id.Client.t;
next_task_id : Id.Task.t;
2016-10-13 12:32:22 +02:00
number_of_queued : int;
number_of_running : int;
number_of_tasks : int;
number_of_clients : int;
2015-12-03 23:51:10 +01:00
}
let create () =
{ queued_front = [] ;
queued_back = [] ;
2016-10-13 12:32:22 +02:00
running = RunningMap.empty ;
tasks = TasksMap.empty;
clients = ClientsSet.empty;
2015-12-03 23:51:10 +01:00
next_client_id = Id.Client.of_int 1;
next_task_id = Id.Task.of_int 1;
2016-10-13 12:32:22 +02:00
number_of_queued = 0;
number_of_running = 0;
number_of_tasks = 0;
number_of_clients = 0;
2015-12-03 23:51:10 +01:00
}
let add_task ~task q =
let task_id =
q.next_task_id
in
{ q with
queued_front = task_id :: q.queued_front ;
2016-10-13 12:32:22 +02:00
tasks = TasksMap.add task_id task q.tasks;
2015-12-03 23:51:10 +01:00
next_task_id = Id.Task.increment task_id ;
2016-08-02 17:44:41 +02:00
number_of_queued = q.number_of_queued + 1;
2016-10-13 12:32:22 +02:00
number_of_tasks = q.number_of_tasks + 1;
2016-02-19 00:20:28 +01:00
}
2015-12-03 23:51:10 +01:00
2015-12-03 23:51:10 +01:00
let add_client q =
let client_id =
q.next_client_id
in
{ q with
2016-10-13 12:32:22 +02:00
clients = ClientsSet.add client_id q.clients;
2015-12-03 23:51:10 +01:00
next_client_id = Id.Client.increment client_id;
2016-10-13 12:32:22 +02:00
number_of_clients = q.number_of_clients + 1;
2015-12-03 23:51:10 +01:00
}, client_id
let pop_task ~client_id q =
let { queued_front ; queued_back ; running ; _ } =
2015-12-03 23:51:10 +01:00
q
in
2016-10-13 12:32:22 +02:00
assert (ClientsSet.mem client_id q.clients);
let queued_front', queued_back' =
match queued_front, queued_back with
| (l, []) -> ( [], List.rev l)
| t -> t
in
match queued_back' with
2015-12-03 23:51:10 +01:00
| task_id :: new_queue ->
let new_q =
{ q with
queued_front= queued_front' ;
queued_back = new_queue ;
2016-10-13 12:32:22 +02:00
running = RunningMap.add task_id client_id running;
number_of_queued = q.number_of_queued - 1;
number_of_running = q.number_of_running + 1;
2015-12-03 23:51:10 +01:00
}
2016-10-13 12:32:22 +02:00
and found =
try Some (TasksMap.find task_id q.tasks)
with Not_found -> None
in new_q, Some task_id, found
2015-12-03 23:51:10 +01:00
| [] -> q, None, None
let del_client ~client_id q =
2016-10-13 12:32:22 +02:00
assert (ClientsSet.mem client_id q.clients);
2015-12-03 23:51:10 +01:00
{ q with
2016-10-13 12:32:22 +02:00
clients = ClientsSet.remove client_id q.clients;
number_of_clients = q.number_of_clients - 1
}
2015-12-03 23:51:10 +01:00
let end_task ~task_id ~client_id q =
let { running ; tasks ; _ } =
q
in
2016-10-13 12:32:22 +02:00
assert (ClientsSet.mem client_id q.clients);
let () =
let client_id_check =
try RunningMap.find task_id running with
Not_found -> failwith "Task already finished"
in
assert (client_id_check = client_id)
2015-12-03 23:51:10 +01:00
in
{ q with
2016-10-13 12:32:22 +02:00
running = RunningMap.remove task_id running ;
number_of_running = q.number_of_running - 1
2015-12-03 23:51:10 +01:00
}
2016-10-13 12:32:22 +02:00
2016-02-19 00:20:28 +01:00
let del_task ~task_id q =
let { tasks ; _ } =
q
in
2016-10-13 12:32:22 +02:00
if (TasksMap.mem task_id tasks) then
2016-02-19 00:20:28 +01:00
{ q with
2016-10-13 12:32:22 +02:00
tasks = TasksMap.remove task_id tasks;
number_of_tasks = q.number_of_tasks - 1;
2016-02-19 00:20:28 +01:00
}
else
Printf.sprintf "Task %d is already deleted" (Id.Task.to_int task_id)
|> failwith
2015-12-03 23:51:10 +01:00
2016-02-19 00:20:28 +01:00
2015-12-03 23:51:10 +01:00
2016-10-13 12:32:22 +02:00
let number_of_tasks q =
assert (q.number_of_tasks >= 0);
q.number_of_tasks
2015-12-03 23:51:10 +01:00
2016-08-01 17:34:36 +02:00
let number_of_queued q =
2016-10-13 12:32:22 +02:00
assert (q.number_of_queued >= 0);
2016-08-02 17:44:41 +02:00
q.number_of_queued
2016-08-01 17:34:36 +02:00
2015-12-03 23:51:10 +01:00
let number_of_running q =
2016-10-13 12:32:22 +02:00
assert (q.number_of_running >= 0);
q.number_of_running
let number_of_clients q =
assert (q.number_of_clients >= 0);
q.number_of_clients
2015-12-03 23:51:10 +01:00
2016-10-13 12:32:22 +02:00
let to_string qs =
let { queued_back ; queued_front ; running ; tasks ; _ } = qs in
2015-12-03 23:51:10 +01:00
let q =
(List.map Id.Task.to_string queued_front) @
(List.map Id.Task.to_string @@ List.rev queued_back)
2016-10-13 12:32:22 +02:00
|> String.concat " ; "
2015-12-03 23:51:10 +01:00
and r =
2016-10-13 12:32:22 +02:00
RunningMap.bindings running
|> List.map (fun (t,c) -> "("^(Id.Task.to_string t)^", "
2015-12-03 23:51:10 +01:00
^(Id.Client.to_string c)^")")
2016-10-13 12:32:22 +02:00
|> String.concat " ; "
2015-12-03 23:51:10 +01:00
and t =
2016-10-13 12:32:22 +02:00
TasksMap.bindings tasks
|> List.map (fun (t,c) -> "("^(Id.Task.to_string t)^", \""
2015-12-03 23:51:10 +01:00
^c^"\")")
2016-10-13 12:32:22 +02:00
|> String.concat " ; "
2015-12-03 23:51:10 +01:00
in
Printf.sprintf "{
2016-10-13 12:32:22 +02:00
Tasks : %d Queued : %d Running : %d Clients : %d
2015-12-03 23:51:10 +01:00
queued : { %s }
running : { %s }
tasks : [ %s
]
2016-10-13 12:32:22 +02:00
}"
(number_of_tasks qs) (number_of_queued qs) (number_of_running qs) (number_of_clients qs)
q r t
2015-12-03 23:51:10 +01:00
2016-10-13 12:32:22 +02:00
let test () =
let q =
create ()
|> add_task ~task:"First Task"
|> add_task ~task:"Second Task"
in
let q, client_id =
add_client q
in
let q, task_id, task_content =
match pop_task ~client_id q with
| q, Some x, Some y -> q, Id.Task.to_int x, y
| _ -> assert false
in
Printf.printf "Task_id : %d \t\t Task : %s\n" task_id task_content;
to_string q |> print_endline ;
2016-10-13 12:32:22 +02:00
let q, task_id, task_content =
match pop_task ~client_id q with
| q, Some x, Some y -> q, Id.Task.to_int x, y
| _ -> assert false
in
Printf.printf "Task_id : %d \t\t Task : %s\n" task_id task_content;
let q, task_id, task_content =
match pop_task ~client_id q with
| q, None, None -> q, 0, "None"
| _ -> assert false
in
Printf.printf "Task_id : %d \t\t Task : %s\n" task_id task_content;
q
|> to_string
|> print_endline