wip: optimized append for pvec

This commit is contained in:
Simon Cruanes 2024-02-17 11:48:54 -05:00
parent 69cd3ca78d
commit dc4be279cf
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
2 changed files with 29 additions and 1 deletions

View file

@ -344,6 +344,14 @@ let map f (self : _ t) : _ t =
{ self with t = map_t f self.t; tail = Array.map f self.tail } { self with t = map_t f self.t; tail = Array.map f self.tail }
let append a b = let append a b =
let a = ref a in
let b = ref b in
let tail = ref @@ Array.copy (!a).tail in
while
if is_empty b then if is_empty b then
a a
else else

View file

@ -160,6 +160,8 @@ module Op = struct
| Pop | Pop
(* TODO: set *) (* TODO: set *)
| Add_list of 'a list | Add_list of 'a list
| Append of 'a list
| Append_iter of 'a list
| Check_get of int | Check_get of int
| Check_choose | Check_choose
| Check_is_empty | Check_is_empty
@ -175,7 +177,8 @@ module Op = struct
| [] -> true | [] -> true
| Push _ :: tl -> loop (size + 1) tl | Push _ :: tl -> loop (size + 1) tl
| Pop :: tl -> size >= 0 && loop (size - 1) tl | Pop :: tl -> size >= 0 && loop (size - 1) tl
| Add_list l :: tl -> loop (size + List.length l) tl | Append_iter l :: tl | Append l :: tl | Add_list l :: tl ->
loop (size + List.length l) tl
| Check_get x :: tl -> x < size && loop size tl | Check_get x :: tl -> x < size && loop size tl
| Check_choose :: tl | Check_choose :: tl
| Check_is_empty :: tl | Check_is_empty :: tl
@ -194,6 +197,9 @@ module Op = struct
| Push x -> spf "push %s" (show_x x) | Push x -> spf "push %s" (show_x x)
| Pop -> "pop" | Pop -> "pop"
| Add_list l -> spf "add_list [%s]" (String.concat ";" @@ List.map show_x l) | Add_list l -> spf "add_list [%s]" (String.concat ";" @@ List.map show_x l)
| Append l -> spf "append [%s]" (String.concat ";" @@ List.map show_x l)
| Append_iter l ->
spf "append_iter [%s]" (String.concat ";" @@ List.map show_x l)
| Check_get i -> spf "check_get %d" i | Check_get i -> spf "check_get %d" i
| Check_choose -> "check_choose" | Check_choose -> "check_choose"
| Check_is_empty -> "check_is_empty" | Check_is_empty -> "check_is_empty"
@ -211,6 +217,8 @@ module Op = struct
| Push x -> shrink_x x >|= fun x -> Push x | Push x -> shrink_x x >|= fun x -> Push x
| Pop -> empty | Pop -> empty
| Add_list l -> list ~shrink:shrink_x l >|= fun x -> Add_list x | Add_list l -> list ~shrink:shrink_x l >|= fun x -> Add_list x
| Append l -> list ~shrink:shrink_x l >|= fun x -> Append x
| Append_iter l -> list ~shrink:shrink_x l >|= fun x -> Append_iter x
| Check_get _ | Check_choose | Check_is_empty | Check_len | Check_to_list | Check_get _ | Check_choose | Check_is_empty | Check_len | Check_to_list
| Check_to_gen | Check_last | Check_rev_iter | Check_iter -> | Check_to_gen | Check_last | Check_rev_iter | Check_iter ->
empty empty
@ -252,6 +260,12 @@ module Op = struct
( 1, ( 1,
small_list gen_x >|= fun l -> small_list gen_x >|= fun l ->
Add_list l, size + List.length l ); Add_list l, size + List.length l );
( 1,
small_list gen_x >|= fun l ->
Append l, size + List.length l );
( 1,
small_list gen_x >|= fun l ->
Append_iter l, size + List.length l );
]; ];
] ]
in in
@ -292,6 +306,12 @@ let check_ops ~show_x (ops : 'a Op.t list) : unit =
| Op.Add_list l -> | Op.Add_list l ->
cur := add_list !cur l; cur := add_list !cur l;
cur_ref := Ref_impl.add_list !cur_ref l cur_ref := Ref_impl.add_list !cur_ref l
| Op.Append l ->
cur := append !cur (of_list l);
cur_ref := Ref_impl.add_list !cur_ref l
| Op.Append_iter l ->
cur := add_iter !cur (Iter.of_list l);
cur_ref := Ref_impl.add_list !cur_ref l
| Op.Check_get i -> if get !cur i <> Ref_impl.get i !cur_ref then fail () | Op.Check_get i -> if get !cur i <> Ref_impl.get i !cur_ref then fail ()
| Op.Check_is_empty -> | Op.Check_is_empty ->
if is_empty !cur <> Ref_impl.is_empty !cur_ref then fail () if is_empty !cur <> Ref_impl.is_empty !cur_ref then fail ()