2 * ExtHashtbl, extra functions over hashtables.
3 * Copyright (C) 2003 Nicolas Cannasse
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version,
9 * with the special exception on linking described in file LICENSE.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 type ('a
, 'b
) h_bucketlist
=
27 | Cons
of 'a
* 'b
* ('a
, 'b
) h_bucketlist
31 mutable data
: ('a
, 'b
) h_bucketlist array
36 external h_conv
: ('a
, 'b
) t
-> ('a
, 'b
) h_t
= "%identity"
37 external h_make
: ('a
, 'b
) h_t
-> ('a
, 'b
) t
= "%identity"
42 let rec make ipos ibuck idata icount
=
44 let buck = ref ibuck
in
45 let hdata = ref idata
in
46 let hcount = ref icount
in
48 (** this is a hack in order to keep an O(1) enum constructor **)
49 if !hcount = -1 then begin
50 hcount := (h_conv h
).size
;
51 hdata := Array.copy
(h_conv h
).data
;
58 if !hcount = 0 then raise
Enum.No_more_elements
;
60 buck := Array.unsafe_get
!hdata !pos;
62 | Cons
(k
,i
,next_buck
) ->
68 if !hcount = -1 then (h_conv h
).size
else !hcount
72 make !pos !buck !hdata !hcount
74 Enum.make ~
next ~
count ~
clone
76 make (-1) Empty
(Obj.magic
()) (-1)
79 Enum.map
(fun (k
,_
) -> k
) (enum h
)
82 Enum.map
(fun (_
,v
) -> v
) (enum h
)
85 let rec loop = function
87 | Cons
(k
,v
,next) -> Cons
(k
,f v
,loop next)
90 size
= (h_conv h
).size
;
91 data
= Array.map loop (h_conv h
).data
;
94 let remove_all h key
=
96 let rec loop = function
100 hc.size
<- pred
hc.size
;
105 let pos = (hash key
) mod (Array.length
hc.data
) in
106 Array.unsafe_set
hc.data
pos (loop (Array.unsafe_get
hc.data
pos))
108 let find_default h key defval
=
109 let rec loop = function
112 if k
= key
then v
else loop next
114 let pos = (hash key
) mod (Array.length
(h_conv h
).data
) in
115 loop (Array.unsafe_get
(h_conv h
).data
pos)
117 let find_option h key
=
118 let rec loop = function
121 if k
= key
then Some v
else loop next
123 let pos = (hash key
) mod (Array.length
(h_conv h
).data
) in
124 loop (Array.unsafe_get
(h_conv h
).data
pos)
127 let h = create
(if Enum.fast_count e
then Enum.count e
else 0) in
128 Enum.iter
(fun (k
,v
) -> add
h k v
) e
;