1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 type 'a t = { mutable inlist : 'a list; mutable outlist : 'a list };;
25 let create () = {inlist = []; outlist = []};;
27 t.inlist <- e :: t.inlist
31 e :: queue -> t.outlist <- queue; e
33 t.outlist <- List.rev t.inlist;
36 e :: queue -> t.outlist <- queue; e
46 t.outlist <- List.rev t.inlist;
52 let empty t = (t.inlist == [] && t.outlist == [])
55 t.outlist <- t.outlist @ (List.rev t.inlist);
59 let length t = List.length t.inlist + List.length t.outlist
60 let put_back t l = t.outlist <- l@t.outlist
70 mutable array
: 'a array
;
71 mutable size
: int; (* bit Mask *)
78 array
= Array.make
4 (Obj.magic
());
84 if t
.inpos
> t
.outpos
then
85 for i
= t
.outpos
to t
.inpos
- 1 do
89 for i
= t
.outpos
to t
.size
do
92 for i
= 0 to t
.inpos
- 1 do
100 if t
.inpos
> t
.outpos
then
101 for i
= t
.outpos
to t
.inpos
- 1 do
102 if t
.array
.(i
) = v
then raise Exit
;
105 for i
= t
.outpos
to t
.size
do
106 if t
.array
.(i
) = v
then raise Exit
108 for i
= 0 to t
.inpos
- 1 do
109 if t
.array
.(i
) = v
then raise Exit
116 let len = Array.length t
.array
in
117 let tab = Array.make
(2*len) t
.array
.(0) in
118 let start = len - t
.inpos
in
119 Array.blit t
.array t
.inpos
tab 0 start;
120 Array.blit t
.array
0 tab start (len - start);
124 t
.size
<- t
.size
* 2 + 1
127 if t
.size
> 3 then begin
128 let len = Array.length t
.array
in
129 let tab = Array.make
(len/2) t
.array
.(0) in
130 if t
.outpos
< t
.inpos
then begin
131 Array.blit t
.array t
.outpos
tab 0 (t
.inpos
- t
.outpos
);
132 t
.inpos
<- t
.inpos
- t
.outpos
;
134 let ol = len - t
.outpos
in
135 Array.blit t
.array t
.outpos
tab 0 ol;
136 Array.blit t
.array
0 tab ol t
.inpos
;
137 t
.inpos
<- ol + t
.inpos
;
141 t
.size
<- (t
.size
- 1) / 2 ;
145 (* lprintf "FIFO PUT"; lprint_newline (); *)
146 if t
.inpos
= t
.outpos
&& not t
.empty then realloc t
;
147 t
.array
.(t
.inpos
) <- e
;
148 t
.inpos
<- (t
.inpos
+ 1) land t
.size
;
151 lprintf "FIFO NOT EMPTY %s" (string_of_bool t.empty); lprint_newline ();
156 (* lprintf "FIFO CLEAR"; lprint_newline (); *)
157 let tab = Array.make
4 t
.array
.(0) in
165 (* lprintf "FIFO LEN"; lprint_newline (); *)
166 if t
.empty then 0 else
167 if t
.inpos
> t
.outpos
then t
.inpos
- t
.outpos
else
168 let s = Array.length t
.array
in
169 s + t
.inpos
- t
.outpos
172 (* lprintf "FIFO TAKE"; lprint_newline (); *)
173 if t
.empty then raise Empty
;
174 if (length t
) < ((t
.size
+ 1) / 4) then shrink t
;
175 let e = t
.array
.(t
.outpos
) in
176 t
.outpos
<- (t
.outpos
+ 1) land t
.size
;
177 if t
.outpos
= t
.inpos
then clear t
;
181 if t
.empty then raise Empty
;
185 (* lprintf "FIFO EMPTY %s" (string_of_bool t.empty); lprint_newline (); *)
189 if t
.empty then [] else
190 if t
.inpos
> t
.outpos
then
191 let len = t
.inpos
- t
.outpos
in
192 let tab = Array.make
len t
.array
.(0) in
193 Array.blit t
.array t
.outpos
tab 0 len;
196 let s = Array.length t
.array
in
197 let len = s + t
.inpos
- t
.outpos
in
198 let tab = Array.make
len t
.array
.(0) in
199 Array.blit t
.array t
.outpos
tab 0 (s - t
.outpos
);
200 Array.blit t
.array
0 tab (s - t
.outpos
) t
.inpos
;
204 if t
.empty then [||] else
205 if t
.inpos
> t
.outpos
then
206 let len = t
.inpos
- t
.outpos
in
207 let tab = Array.make
len t
.array
.(0) in
208 Array.blit t
.array t
.outpos
tab 0 len;
211 let s = Array.length t
.array
in
212 let len = s + t
.inpos
- t
.outpos
in
213 let tab = Array.make
len t
.array
.(0) in
214 Array.blit t
.array t
.outpos
tab 0 (s - t
.outpos
);
215 Array.blit t
.array
0 tab (s - t
.outpos
) t
.inpos
;
218 let put_back_ele t
e =
219 if t
.inpos
= t
.outpos
&& not t
.empty then realloc t
;
220 t
.outpos
<- (t
.outpos
- 1) land t
.size
;
221 t
.array
.(t
.outpos
) <- e;
224 let rec put_back t list
=
228 put_back t tail
; put_back_ele t ele
231 if not t
.empty then begin
232 let s = Array.length t
.array
in
233 let len = s + t
.inpos
- t
.outpos
in
234 let tab = Array.make
s t
.array
.(0) in
235 Array.blit t
.array t
.outpos
tab 0 (s - t
.outpos
);
236 Array.blit t
.array
0 tab (s - t
.outpos
) t
.inpos
;
243 if not t
.empty then begin
244 if t
.outpos
>= t
.inpos
then reformat t
;
246 (* Printf2.lprintf "i=%d j=%d inpos=%d outpos=%d\n"
247 i j t.inpos t.outpos; print_newline (); *)
251 if t
.inpos
= t
.outpos
then clear t
;
254 let ee = t
.array
.(i
) in
259 (* Printf2.lprintf "Move i=%d at j=%d" i j; print_newline (); *)
265 iter t t
.outpos t
.outpos
270 let t = Fifo.create ();;
277 Fifo.put t (Fifo.take t)
288 Printf2.lprintf "%d\n" (Fifo.take t)