Skip to content

Commit

Permalink
Add Dllist.create_node value
Browse files Browse the repository at this point in the history
This is useful in some situtations where you might want to be able to refer to a
new node before it is actually added to a list.
  • Loading branch information
polytypic committed Dec 8, 2023
1 parent 854a41d commit 5919d85
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
20 changes: 15 additions & 5 deletions src/kcas_data/dllist.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ let create () =
Loc.set next list;
list

let create_node ~prev ~next value =
let create_node value =
let node =
let node_prev = Loc.make (Obj.magic ())
and node_next = Loc.make (Obj.magic ()) in
{ node_prev; node_next; value }
in
Loc.set node.node_prev (as_list node);
Loc.set node.node_next (as_list node);
node

let create_node_with ~prev ~next value =
{ node_prev = Loc.make prev; node_next = Loc.make next; value }

module Xt = struct
Expand All @@ -41,7 +51,7 @@ module Xt = struct

let add_l ~xt value list =
let next = Xt.get ~xt list.next in
let node = create_node ~prev:list ~next value in
let node = create_node_with ~prev:list ~next value in
Xt.set ~xt list.next (as_list node);
Xt.set ~xt next.prev (as_list node);
node
Expand All @@ -56,7 +66,7 @@ module Xt = struct

let add_r ~xt value list =
let prev = Xt.get ~xt list.prev in
let node = create_node ~prev ~next:list value in
let node = create_node_with ~prev ~next:list value in
Xt.set ~xt list.prev (as_list node);
Xt.set ~xt prev.next (as_list node);
node
Expand Down Expand Up @@ -163,11 +173,11 @@ let remove node = Kcas.Xt.commit { tx = Xt.remove node }
let is_empty list = Loc.get list.prev == list

let add_l value list =
let node = create_node ~prev:list ~next:list value in
let node = create_node_with ~prev:list ~next:list value in
Kcas.Xt.commit { tx = Xt.add_node_l node list }

let add_r value list =
let node = create_node ~prev:list ~next:list value in
let node = create_node_with ~prev:list ~next:list value in
Kcas.Xt.commit { tx = Xt.add_node_r node list }

let move_l node list = Kcas.Xt.commit { tx = Xt.move_l node list }
Expand Down
7 changes: 6 additions & 1 deletion src/kcas_data/dllist.mli
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ val get : 'a node -> 'a
(** [get node] returns the value stored in the {!node}. *)

val create : unit -> 'a t
(** [create ()] return a new doubly-linked list. *)
(** [create ()] creates a new doubly-linked list. *)

val create_node : 'a -> 'a node
(** [create_node value] creates a new doubly-linked list node that is not in any
list. The node can then e.g. be added to a list using {!move_l} or
{!move_r}. *)

(** {1 Compositional interface} *)

Expand Down
2 changes: 1 addition & 1 deletion test/kcas_data/dllist_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ let basics () =
assert (Dllist.to_list_r t1 = [] && Dllist.to_list_l t1' = []);
Dllist.transfer_r t1' t1';
Dllist.add_r 2 t1' |> ignore;
Dllist.add_r 3 t1' |> ignore;
Dllist.move_r (Dllist.create_node 3) t1';
Dllist.swap t1' t1';
Dllist.add_l 1 t1' |> ignore;
Dllist.transfer_r t1' t1';
Expand Down

0 comments on commit 5919d85

Please sign in to comment.