Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Paradict, a CTrie implementation #49

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ A collection of Concurrent Lockfree Data Structures for OCaml 5. It contains:

* [MPSC Queue](src/mpsc_queue.mli) A multi-producer, single-consumer, thread-safe queue without support for cancellation. This makes a good data structure for a scheduler's run queue. It is used in [Eio](https://github.com/ocaml-multicore/eio). It is a single consumer version of the queue described in [Implementing lock-free queues](https://people.cs.pitt.edu/~jacklange/teaching/cs2510-f12/papers/implementing_lock_free.pdf).

* [CTrie](src/paradict.mli) A parallel dictionnary, to be used as a thread-safe, lockfree alternative to stdlib's Hashtbl or Map. See also [Wikipedia](https://en.wikipedia.org/wiki/Ctrie).

## Usage

lockfree can be installed from `opam`: `opam install lockfree`. Sample usage of
Expand Down
1 change: 1 addition & 0 deletions lockfree.opam
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ depends: [
"alcotest" {>= "1.6.0"}
"yojson" {>= "2.0.2"}
"dscheck" {>= "0.0.1"}
"kcas" {>= "0.1.4"}
]
depopts: []
build: ["dune" "build" "-p" name "-j" jobs]
2 changes: 1 addition & 1 deletion src/dune
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(library
(name lockfree)
(public_name lockfree)
(libraries dscheck virtual_atomic))
(libraries dscheck kcas virtual_atomic))
48 changes: 48 additions & 0 deletions src/extensions.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module Array = struct
include Array

(** Inserts an element at position index within the array, shifting all elements after it to the right.
@raise Invalid_argument if index is outside the range 0 to length a. *)
let insert a index elem =
let len = length a in
if index < 0 || index > len then invalid_arg "Array.insert";
let new_a = make (len + 1) elem in
blit a 0 new_a 0 index;
blit a index new_a (index + 1) (len - index);
new_a

(** Remove an element at position index within the array, shifting all elements after it to the left.
@raise Invalid_argument if index is outside the range 0 to length a. *)
let remove a index =
let len = length a in
match index with
| 0 -> sub a 1 (len - 1)
| n when n = len - 1 -> sub a 0 (len - 1)
| n when n < 0 || n >= len -> invalid_arg "Array.remove"
| n ->
let new_a = make (len - 1) a.(0) in
blit a 0 new_a 0 n;
blit a (n + 1) new_a n (len - n - 1);
new_a

(** [filter_map f a] applies [f] to all elements in [a], filtering [None] results,
and returning the array of [Some] results, along with a sorted list of the indices of deleted elements. *)
let filter_map f a =
let rec aux i l_mapped l_filtered =
if i < 0 then (of_list l_mapped, l_filtered)
else
match f a.(i) with
| Some x -> aux (i - 1) (x :: l_mapped) l_filtered
| None -> aux (i - 1) l_mapped (i :: l_filtered)
in
aux (length a - 1) [] []
end

let popcount n =
let rec aux n count =
if n = 0 then count
else
let shifted = n lsr 1 in
if 1 land n <> 0 then aux shifted (count + 1) else aux shifted count
in
aux n 0
1 change: 1 addition & 0 deletions src/lockfree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ module Treiber_stack = Treiber_stack
module Michael_scott_queue = Michael_scott_queue
module Backoff = Backoff
module Mpmc_relaxed_queue = Mpmc_relaxed_queue
module Paradict = Paradict
1 change: 1 addition & 0 deletions src/lockfree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ module Treiber_stack = Treiber_stack
module Michael_scott_queue = Michael_scott_queue
module Mpmc_relaxed_queue = Mpmc_relaxed_queue
module Backoff = Backoff
module Paradict = Paradict
Loading