mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
faster SkipList.find
This commit is contained in:
parent
6f455c7cb1
commit
9788d108e3
1 changed files with 21 additions and 8 deletions
25
skipList.ml
25
skipList.ml
|
|
@ -25,6 +25,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
(** {1 Imperative skip-list} *)
|
(** {1 Imperative skip-list} *)
|
||||||
|
|
||||||
|
(** Most functions are inspired from
|
||||||
|
"A skip list cookbook", William Pugh, 1989. *)
|
||||||
|
|
||||||
type ('a, 'b) t = {
|
type ('a, 'b) t = {
|
||||||
mutable data : ('a, 'b) bucket;
|
mutable data : ('a, 'b) bucket;
|
||||||
cmp : ('a -> 'a -> int); (* comparison function *)
|
cmp : ('a -> 'a -> int); (* comparison function *)
|
||||||
|
|
@ -93,14 +96,24 @@ let next node n =
|
||||||
(** Find given key in the list, or Not_found *)
|
(** Find given key in the list, or Not_found *)
|
||||||
let find l k =
|
let find l k =
|
||||||
let cmp = l.cmp in
|
let cmp = l.cmp in
|
||||||
let x = ref l.data in
|
let rec search x n =
|
||||||
for i = level l.data - 1 downto 0 do
|
if n < 0 then peek_last x
|
||||||
while lower ~cmp (next !x i) k do x := next !x i done
|
else
|
||||||
done;
|
let x' = next x n in
|
||||||
x := next !x 0;
|
match x' with
|
||||||
match !x with
|
| Nil -> search x (n-1)
|
||||||
|
| Node (k', v, _) ->
|
||||||
|
let c = cmp k' k in
|
||||||
|
if c = 0 then !v
|
||||||
|
else if c < 0 then search x' n
|
||||||
|
else search x (n-1)
|
||||||
|
| Init _ -> assert false
|
||||||
|
and peek_last x =
|
||||||
|
match next x 0 with
|
||||||
| Node (k', v, _) when cmp k k' = 0 -> !v
|
| Node (k', v, _) when cmp k k' = 0 -> !v
|
||||||
| _ -> raise Not_found
|
| _ -> raise Not_found
|
||||||
|
in
|
||||||
|
search l.data (level l.data - 1)
|
||||||
|
|
||||||
let mem l k =
|
let mem l k =
|
||||||
try ignore (find l k); true
|
try ignore (find l k); true
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue