Skip to content

Commit be994de

Browse files
committed
xapi-stdext: replace List's chop with split_at
Now users can use out-of-bounds limits without fear. I've used the opportunity to consolidate code that sorts and splits lists in db_gc_util. Signed-off-by: Pau Ruiz Safont <pau.safont@vates.tech>
1 parent 5243d55 commit be994de

File tree

5 files changed

+23
-39
lines changed

5 files changed

+23
-39
lines changed

ocaml/libs/xapi-stdext/lib/xapi-stdext-std/listext.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ module List = struct
9292
in
9393
loop 0 [] list
9494

95-
let chop = split_at
96-
9795
let rec between e = function
9896
| [] ->
9997
[]

ocaml/libs/xapi-stdext/lib/xapi-stdext-std/listext.mli

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,6 @@ module List : sig
7373
When using OCaml compilers 5.1 or later, please use the standard library
7474
instead. *)
7575

76-
(** {1 Using indices to manipulate lists} *)
77-
78-
val chop : int -> 'a list -> 'a list * 'a list
79-
(** [chop k l] is an alias for [split_at k l]. *)
80-
8176
(** {1 Association Lists} *)
8277

8378
val make_assoc : ('a -> 'b) -> 'a list -> ('a * 'b) list

ocaml/libs/xapi-stdext/lib/xapi-stdext-std/listext_test.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ let test_option typ tested_f (name, case, expected) =
2525
let check () = Alcotest.(check @@ option typ) name expected (tested_f case) in
2626
(name, `Quick, check)
2727

28-
let test_chopped_list tested_f (name, case, expected) =
28+
let test_split_at_list tested_f (name, case, expected) =
2929
let check () =
3030
Alcotest.(check @@ pair (list int) (list int)) name expected (tested_f case)
3131
in
@@ -135,7 +135,7 @@ let test_last =
135135
let error_tests = List.map error_test error_specs in
136136
("last", tests @ error_tests)
137137

138-
let test_chop =
138+
let test_split_at =
139139
let specs =
140140
[
141141
([], 0, ([], []))
@@ -151,14 +151,14 @@ let test_chop =
151151
in
152152
let test (whole, number, expected) =
153153
let name =
154-
Printf.sprintf "chop [%s] with %i"
154+
Printf.sprintf "split_at [%s] with %i"
155155
(String.concat "; " (List.map string_of_int whole))
156156
number
157157
in
158-
test_chopped_list (Listext.chop number) (name, whole, expected)
158+
test_split_at_list (Listext.split_at number) (name, whole, expected)
159159
in
160160
let tests = List.map test specs in
161-
("chop", tests)
161+
("split_at", tests)
162162

163163
let test_find_minimum (name, pp, typ, specs) =
164164
let test ((cmp, cmp_name), input, expected) =
@@ -214,7 +214,7 @@ let () =
214214
; test_take
215215
; test_drop
216216
; test_last
217-
; test_chop
217+
; test_split_at
218218
; test_find_minimum_int
219219
; test_find_minimum_tuple
220220
]

ocaml/xapi/binpack.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ let choose l n =
9898
(** Return all permutations of a list *)
9999
let rec permutations : 'a list -> 'a list list =
100100
let rotate n xs =
101-
let a, b = Xapi_stdext_std.Listext.List.chop n xs in
101+
let a, b = Xapi_stdext_std.Listext.List.split_at n xs in
102102
b @ a
103103
in
104104
let insert_at n x xs = rotate (List.length xs - n + 1) (x :: rotate n xs) in

ocaml/xapi/db_gc_util.ml

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ let gc_vtpms ~__context =
293293

294294
let probation_pending_tasks = Hashtbl.create 53
295295

296+
let sort_and_split compare n tasks =
297+
if List.length tasks <= n then
298+
(tasks, [])
299+
else
300+
Listext.List.split_at n (List.sort compare tasks)
301+
296302
let timeout_tasks ~__context =
297303
let all_tasks =
298304
Db.Task.get_internal_records_where ~__context
@@ -368,32 +374,20 @@ let timeout_tasks ~__context =
368374
let lucky, unlucky =
369375
if List.length young <= Xapi_globs.max_tasks then
370376
(young, []) (* keep them all *)
371-
else (* Compute how many we'd like to delete *)
372-
let overflow = List.length young - Xapi_globs.max_tasks in
373-
(* We only consider deleting completed tasks *)
377+
else (* We only consider deleting completed tasks *)
374378
let completed, pending =
375379
List.partition
376380
(fun (_, t) -> TaskHelper.status_is_completed t.Db_actions.task_status)
377381
young
378382
in
379-
(* Sort the completed tasks so we delete oldest tasks in preference *)
380-
let completed =
381-
List.sort
382-
(fun (_, t1) (_, t2) ->
383-
compare
384-
(Date.to_unix_time t1.Db_actions.task_finished)
385-
(Date.to_unix_time t2.Db_actions.task_finished)
386-
)
387-
completed
388-
in
389-
(* From the completes set, choose up to 'overflow' *)
390-
let unlucky, lucky =
391-
if List.length completed > overflow then
392-
Listext.List.chop overflow completed
393-
else
394-
(completed, [])
383+
(* pending tasks limit the amount of completed tasks to keep, negatives
384+
values are equivalent to 0 *)
385+
let limit = Xapi_globs.max_tasks - List.length completed in
386+
(* Reverse compare order so oldest dates (earliest) are sorted last *)
387+
let compare (_, t1) (_, t2) =
388+
Date.compare t2.Db_actions.task_finished t1.Db_actions.task_finished
395389
in
396-
(* not enough to delete, oh well *)
390+
let lucky, unlucky = sort_and_split compare limit completed in
397391
(* Keep all pending and any which were not chosen from the completed set *)
398392
(pending @ lucky, unlucky)
399393
in
@@ -456,11 +450,8 @@ let timeout_sessions_common ~__context sessions limit session_group =
456450
in
457451
(* If there are too many young sessions then we need to delete the oldest *)
458452
let _, unlucky =
459-
if List.length young <= limit then
460-
(young, []) (* keep them all *)
461-
else (* Need to reverse sort by last active and drop the oldest *)
462-
Listext.List.chop limit
463-
(List.sort (fun (_, a, _) (_, b, _) -> compare b a) young)
453+
let compare (_, a, _) (_, b, _) = compare b a in
454+
sort_and_split compare limit young
464455
in
465456
let cancel doc sessions =
466457
List.iter

0 commit comments

Comments
 (0)