From 5919d8526ef1711c862adc157d10a783d501c289 Mon Sep 17 00:00:00 2001 From: Vesa Karvonen Date: Fri, 8 Dec 2023 14:00:18 +0200 Subject: [PATCH] Add `Dllist.create_node value` 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. --- src/kcas_data/dllist.ml | 20 +++++++++++++++----- src/kcas_data/dllist.mli | 7 ++++++- test/kcas_data/dllist_test.ml | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/kcas_data/dllist.ml b/src/kcas_data/dllist.ml index 23003ae9..9be89070 100644 --- a/src/kcas_data/dllist.ml +++ b/src/kcas_data/dllist.ml @@ -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 @@ -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 @@ -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 @@ -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 } diff --git a/src/kcas_data/dllist.mli b/src/kcas_data/dllist.mli index eb43aef7..efda041c 100644 --- a/src/kcas_data/dllist.mli +++ b/src/kcas_data/dllist.mli @@ -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} *) diff --git a/test/kcas_data/dllist_test.ml b/test/kcas_data/dllist_test.ml index 6b16c6cc..993c45d8 100644 --- a/test/kcas_data/dllist_test.ml +++ b/test/kcas_data/dllist_test.ml @@ -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';