diff -urN src/gtk2/gui/graphTypes.ml src/gtk2/gui/graphTypes.ml
--- src/gtk2/gui/graphTypes.ml	2005-10-31 19:34:01.000000000 +0100
+++ src/gtk2/gui/graphTypes.ml	2006-08-15 15:37:15.000000000 +0200
@@ -19,17 +19,260 @@
 
 open CommonTypes
 
-type graph =
-  {
-   mutable quarter : (float * float) list;
-   mutable hour    : (float * float) list;
-   mutable halfday : (float * float) list;
-   mutable day     : (float * float) list;
-   mutable week    : (float * float) list;
-   mutable month   : (float * float) list;
-   mutable year    : (float * float) list;
+module GStack = struct
+
+  type t = {
+    mutable gstack_queue   : (float * float) array;
+    mutable gstack_empty   : bool;
+    mutable gstack_max_pts : int;
+    mutable gstack_inpos   : int;
+    mutable gstack_outpos  : int;
+    mutable gstack_size    : int;
+  }
+
+  type index = {
+    nextpos     : bool;
+    mutable pos : int;
+  }
+
+  exception Empty
+
+  let make max_pts =
+    let size = max 1 (max_pts / 5) in {
+      gstack_queue   = Array.make size (0.,0.);
+      gstack_empty   = true;
+      gstack_max_pts = max_pts;
+      gstack_inpos   = 0;
+      gstack_outpos  = 0;
+      gstack_size    = size;
+    }
+
+  let shrink q =
+    if (q.gstack_inpos - q.gstack_outpos) <= q.gstack_size / 2
+    then begin
+      let new_size = max 1 ((q.gstack_inpos - q.gstack_outpos) * 140 / 100) in
+      let new_size = min q.gstack_max_pts new_size in
+      let new_stack = Array.make new_size (0.,0.) in
+      Array.blit q.gstack_queue q.gstack_outpos new_stack 0 (q.gstack_inpos - q.gstack_outpos);
+      q.gstack_queue <- new_stack;
+      q.gstack_inpos <- q.gstack_inpos - q.gstack_outpos;
+      q.gstack_outpos <- 0;
+      q.gstack_size <- new_size
+    end
+
+  let reallocate q =
+    if q.gstack_outpos > 0
+    then begin
+      Array.blit q.gstack_queue q.gstack_outpos q.gstack_queue 0 (q.gstack_inpos - q.gstack_outpos);
+      q.gstack_inpos <- q.gstack_inpos - q.gstack_outpos;
+      q.gstack_outpos <- 0;
+    end;
+    if q.gstack_size = q.gstack_max_pts && q.gstack_size = q.gstack_inpos
+    then begin
+      Array.blit q.gstack_queue 1 q.gstack_queue 0 (q.gstack_inpos - 1);
+      q.gstack_inpos <- q.gstack_inpos - 1
+    end else begin
+      if q.gstack_size - q.gstack_inpos <= q.gstack_size / 5
+      then begin
+        let new_size = min q.gstack_max_pts (q.gstack_size + q.gstack_max_pts / 5) in
+        let new_stack = Array.make new_size (0.,0.) in
+        Array.blit q.gstack_queue q.gstack_outpos new_stack 0 (q.gstack_inpos - q.gstack_outpos);
+        q.gstack_queue <- new_stack;
+        q.gstack_size <- new_size
+      end
+    end
+
+  let clear q =
+    let size = max 1 (q.gstack_max_pts / 5) in
+    let new_queue = Array.make size (0.,0.) in
+    q.gstack_queue <- new_queue;
+    q.gstack_empty <- true;
+    q.gstack_inpos <- 0;
+    q.gstack_outpos <- 0;
+    q.gstack_size <- size
+
+  let put (t, r) q =
+    reallocate q;
+    q.gstack_queue.(q.gstack_inpos) <- (t,r);
+    q.gstack_inpos <- q.gstack_inpos + 1;
+    if q.gstack_empty then q.gstack_empty <- false
+
+  let add r q =
+    let t = BasicSocket.current_time () in
+    put (t, r) q
+
+  let take q =
+    if q.gstack_empty then raise Empty;
+    let res = q.gstack_queue.(q.gstack_outpos) in
+    q.gstack_outpos <- q.gstack_outpos + 1;
+    if q.gstack_outpos = q.gstack_inpos then clear q;
+    shrink q;
+    res
+
+  let peek q =
+    if q.gstack_empty
+    then raise Empty
+    else q.gstack_queue.(q.gstack_outpos)
+
+  let last q =
+    if q.gstack_empty
+    then raise Empty
+    else q.gstack_queue.(q.gstack_inpos - 1)
+
+  let copy q = {
+    gstack_queue   = Array.copy q.gstack_queue;
+    gstack_empty   = q.gstack_empty;
+    gstack_max_pts = q.gstack_max_pts;
+    gstack_inpos   = q.gstack_inpos;
+    gstack_outpos  = q.gstack_outpos;
+    gstack_size    = q.gstack_size;
   }
 
+  let is_empty q = q.gstack_empty
+
+  let length q = q.gstack_inpos - q.gstack_outpos
+
+  let iter f q =
+    for i = q.gstack_outpos to q.gstack_inpos - 1 do
+      f (Array.unsafe_get q.gstack_queue i)
+    done
+
+  let rev_iter f q =
+    for i = q.gstack_inpos - 1 downto q.gstack_outpos do
+      f (Array.unsafe_get q.gstack_queue i)
+    done
+
+  let iteri f q =
+    for i = q.gstack_outpos to q.gstack_inpos - 1 do
+      f (i - q.gstack_outpos) (Array.unsafe_get q.gstack_queue i)
+    done
+
+  let rev_iteri f q =
+    for i = q.gstack_inpos - 1 downto q.gstack_outpos do
+      f (i - q.gstack_outpos) (Array.unsafe_get q.gstack_queue i)
+    done
+
+  let map f q =
+    if q.gstack_empty
+    then [||]
+    else begin
+      let r = Array.create (q.gstack_inpos - q.gstack_outpos) (f(Array.unsafe_get q.gstack_queue q.gstack_outpos)) in
+      for i = q.gstack_outpos to q.gstack_inpos - 1 do
+        Array.unsafe_set r (i - q.gstack_outpos) (f(Array.unsafe_get q.gstack_queue i))
+      done;
+      r
+    end
+
+  let rev_map f q =
+    if q.gstack_empty
+    then [||]
+    else begin
+      let r = Array.create (q.gstack_inpos - q.gstack_outpos) (f(Array.unsafe_get q.gstack_queue (q.gstack_inpos - 1))) in
+      for i = q.gstack_inpos - 1 downto q.gstack_outpos do
+        Array.unsafe_set r (i - q.gstack_outpos) (f(Array.unsafe_get q.gstack_queue i))
+      done;
+      r
+    end
+
+  let mapi f q =
+    if q.gstack_empty
+    then [||]
+    else begin
+      let r = Array.create (q.gstack_inpos - q.gstack_outpos) (f 0 (Array.unsafe_get q.gstack_queue q.gstack_outpos)) in
+      for i = q.gstack_outpos to q.gstack_inpos - 1 do
+        Array.unsafe_set r (i - q.gstack_outpos) (f (i - q.gstack_outpos) (Array.unsafe_get q.gstack_queue i))
+      done;
+      r
+    end
+
+  let rev_mapi f q =
+    if q.gstack_empty
+    then [||]
+    else begin
+      let r = Array.create (q.gstack_inpos - q.gstack_outpos) (f 0 (Array.unsafe_get q.gstack_queue (q.gstack_inpos - 1))) in
+      for i = q.gstack_inpos - 1 downto q.gstack_outpos do
+        Array.unsafe_set r (i - q.gstack_outpos) (f (i - q.gstack_outpos) (Array.unsafe_get q.gstack_queue i))
+      done;
+      r
+    end
+
+  let fold_left f accu q =
+    let r = ref accu in
+    for i = q.gstack_outpos to q.gstack_inpos - 1 do
+      r := f !r (Array.unsafe_get q.gstack_queue i)
+    done;
+    !r
+
+  let fold_right f accu q =
+    let r = ref accu in
+    for i = q.gstack_inpos - 1 downto q.gstack_outpos do
+      r := f !r (Array.unsafe_get q.gstack_queue i)
+    done;
+    !r
+
+  (* ordered from the most recently entered to the least recently entered *)
+  let to_list_lif q =
+    let rec iter l i n =
+      if i = n
+      then l
+      else iter ((Array.unsafe_get q.gstack_queue i) :: l) (i+1) n
+    in
+    iter [] q.gstack_outpos q.gstack_inpos
+
+  (* ordered from the least recently entered to the most recently entered *)
+  let to_list_fif q =
+    let rec iter l i n =
+      if i < n
+      then l
+      else iter ((Array.unsafe_get q.gstack_queue i) :: l) (i-1) n
+    in
+    iter [] (q.gstack_inpos - 1) q.gstack_outpos
+
+  (* l shall be ordered from the least recently entered to the most recently entered *)
+  let from_list nbpts l =
+    let pos = max 0 (List.length l - nbpts) in
+    let _, _l = List2.cut pos l in
+    let q = make nbpts in
+    List.iter (fun (t,r) ->
+      put (t,r) q
+    ) _l;
+    q
+
+  let get_index_first q =
+    if q.gstack_empty
+    then None
+    else Some {pos = q.gstack_outpos; nextpos = true}
+
+  let get_index_last q =
+    if q.gstack_empty
+    then None
+    else Some {pos = q.gstack_inpos - 1; nextpos = false}
+
+  let iter_next index q =
+    let nextpos = index.pos + (match index.nextpos with true -> 1 | false -> (-1)) in
+    if nextpos >= q.gstack_outpos && nextpos < q.gstack_inpos
+    then begin
+      index.pos <- nextpos;
+      true
+    end else false
+
+  let get_at_index index q =
+    if index.pos >= q.gstack_outpos && index.pos < q.gstack_inpos
+    then Array.unsafe_get q.gstack_queue index.pos
+    else failwith "GStack.t index out of bound"
+
+end
+
+type graph = {
+  mutable quarter : GStack.t;
+  mutable hour    : GStack.t;
+  mutable halfday : GStack.t;
+  mutable day     : GStack.t;
+  mutable week    : GStack.t;
+  mutable month   : GStack.t;
+  mutable year    : GStack.t;
+}
+
 type graph_record =
   GraphDownloads
 | GraphUploads
diff -urN src/gtk2/gui/graphTypes.mli src/gtk2/gui/graphTypes.mli
--- src/gtk2/gui/graphTypes.mli	1970-01-01 01:00:00.000000000 +0100
+++ src/gtk2/gui/graphTypes.mli	2006-08-15 15:36:32.000000000 +0200
@@ -0,0 +1,81 @@
+(* Copyright 2004 b8_bavard, INRIA *)
+(*
+    This file is part of mldonkey.
+
+    mldonkey is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    mldonkey is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with mldonkey; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*)
+open CommonTypes
+
+module GStack :
+  sig
+
+    type t
+    type index
+
+    exception Empty
+
+    val make : int -> t
+    val clear : t -> unit
+    val put : float * float -> t -> unit
+    val add : float -> t -> unit
+    val take : t -> float * float
+    val peek : t -> float * float
+    val last : t -> float * float
+    val copy : t -> t
+    val is_empty : t -> bool
+    val length : t -> int
+    val iter : (float * float -> 'a) -> t -> unit
+    val rev_iter : (float * float -> 'a) -> t -> unit
+    val iteri : (int -> float * float -> 'a) -> t -> unit
+    val rev_iteri : (int -> float * float -> 'a) -> t -> unit
+    val map : (float * float -> 'a) -> t -> 'a array
+    val rev_map : (float * float -> 'a) -> t -> 'a array
+    val mapi : (int -> float * float -> 'a) -> t -> 'a array
+    val rev_mapi : (int -> float * float -> 'a) -> t -> 'a array
+    val fold_left : ('a -> float * float -> 'a) -> 'a -> t -> 'a
+    val fold_right : ('a -> float * float -> 'a) -> 'a -> t -> 'a
+    val to_list_lif : t -> (float * float) list
+    val to_list_fif : t -> (float * float) list
+    val from_list : int -> (float * float) list -> t
+    val get_index_first : t -> index option
+    val get_index_last : t -> index option
+    val iter_next : index -> t -> bool
+    val get_at_index : index -> t -> float * float
+  end
+
+
+type graph = {
+  mutable quarter : GStack.t;
+  mutable hour    : GStack.t;
+  mutable halfday : GStack.t;
+  mutable day     : GStack.t;
+  mutable week    : GStack.t;
+  mutable month   : GStack.t;
+  mutable year    : GStack.t;
+}
+
+type graph_record =
+  GraphDownloads
+| GraphUploads
+| GraphFile of (uid_type * graph_record)
+
+type graph_time =
+  GraphQuarter
+| GraphHour
+| GraphHalfDay
+| GraphDay
+| GraphWeek
+| GraphMonth
+| GraphYear
diff -urN src/gtk2/gui/guiGraphBase.ml src/gtk2/gui/guiGraphBase.ml
--- src/gtk2/gui/guiGraphBase.ml	2005-11-27 15:04:33.000000000 +0100
+++ src/gtk2/gui/guiGraphBase.ml	2006-08-15 20:30:36.000000000 +0200
@@ -31,18 +31,25 @@
 let lprintf' fmt =
   Printf2.lprintf ("GuiGraphBase: " ^^ fmt)
 
-let last_time = BasicSocket.current_time ()
+let last_time () = BasicSocket.current_time ()
 
-let dummy_graph () =
-  {
-   quarter = [last_time, 0.];
-   hour    = [last_time, 0.];
-   halfday = [last_time, 0.];
-   day     = [last_time, 0.];
-   week    = [last_time, 0.];
-   month   = [last_time, 0.];
-   year    = [last_time, 0.];
-  }
+let max_points = 200.
+let max_points_int = int_of_float max_points
+
+let init_queue () =
+  let q = GStack.make max_points_int in
+  GStack.add 0. q;
+  q
+
+let dummy_graph () = {
+  quarter = init_queue ();
+  hour    = init_queue ();
+  halfday = init_queue ();
+  day     = init_queue ();
+  week    = init_queue ();
+  month   = init_queue ();
+  year    = init_queue ();
+}
 
 let quarter = 15. *. 60.
 let hour = 4. *. quarter
@@ -52,6 +59,12 @@
 let month = 4. *. week
 let year = 52. *. week
 
+
+let get_t (v : float * float) = fst v
+let get_r (v : float * float) = snd v
+let get_d v = fst v
+let get_u v = snd v
+
 (*************************************************************************)
 (*                                                                       *)
 (*                         GraphOption                                   *)
@@ -74,78 +87,87 @@
         (v1, v2)
       )
 
-    let check_graph_time l time_ref =
-      let last_graph_time, _ = List.hd (List.rev l) in
-      if last_time -. last_graph_time > time_ref
-        then [last_time, 0.] else l
+    let hook_graph_time l time_ref =
+      let t_ref = last_time () in
+      let l = List.filter (fun (t, _) -> t_ref -. t < time_ref) l in
+      match l with
+        [] -> [t_ref, 0.]
+      | _ -> l
 
     let value_to_graph v =
+      let t = last_time () in
       match v with
         Options.Module assocs ->
           let get_value name conv = conv (List.assoc name assocs) in
           let graph_quarter =
             try
               let l = get_value "graph_quarter" (value_to_list value_to_floats) in
-              check_graph_time l quarter
-            with _ -> [last_time, 0.]
+              let l = hook_graph_time l quarter in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
           in
           let graph_hour =
             try
               let l = get_value "graph_hour" (value_to_list value_to_floats) in
-              check_graph_time l hour
-            with _ -> [last_time, 0.]
+              let l = hook_graph_time l hour in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
           in
           let graph_halfday =
             try
               let l = get_value "graph_halfday" (value_to_list value_to_floats) in
-              check_graph_time l halfday
-            with _ -> [last_time, 0.]
+              let l = hook_graph_time l halfday in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
           in
           let graph_day =
             try
               let l = get_value "graph_day" (value_to_list value_to_floats) in
-              check_graph_time l day
-            with _ -> [last_time, 0.]
+              let l = hook_graph_time l day in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
           in
           let graph_week =
             try
               let l = get_value "graph_week" (value_to_list value_to_floats) in
-              check_graph_time l week
-            with _ -> [last_time, 0.]
+              let l = hook_graph_time l week in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
           in
           let graph_month =
             try
               let l = get_value "graph_month" (value_to_list value_to_floats) in
-              check_graph_time l month
-            with _ -> [last_time, 0.]
+              let l = hook_graph_time l month in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
           in
           let graph_year =
             try
               let l = get_value "graph_year" (value_to_list value_to_floats) in
-              check_graph_time l year
-            with _ -> [last_time, 0.]
-          in
-          {
-             quarter = graph_quarter;
-             hour    = graph_hour;
-             halfday = graph_halfday;
-             day     = graph_day;
-             week    = graph_week;
-             month   = graph_month;
-             year    = graph_year;
+              let l = hook_graph_time l year in
+              GStack.from_list max_points_int l
+            with _ -> init_queue ()
+          in {
+            quarter = graph_quarter;
+            hour    = graph_hour;
+            halfday = graph_halfday;
+            day     = graph_day;
+            week    = graph_week;
+            month   = graph_month;
+            year    = graph_year;
           }
 
       | _ -> assert false
 
     let graph_to_value graph =
       Options.Module (
-        ("graph_quarter", list_to_value floats_to_value graph.quarter) ::
-        ("graph_hour",    list_to_value floats_to_value graph.hour)    ::
-        ("graph_halfday", list_to_value floats_to_value graph.halfday) ::
-        ("graph_day",     list_to_value floats_to_value graph.day)     ::
-        ("graph_week",    list_to_value floats_to_value graph.week)    ::
-        ("graph_month",   list_to_value floats_to_value graph.month)   ::
-        ("graph_year",    list_to_value floats_to_value graph.year)    ::
+        ("graph_quarter", list_to_value floats_to_value (GStack.to_list_fif graph.quarter)) ::
+        ("graph_hour",    list_to_value floats_to_value (GStack.to_list_fif graph.hour))    ::
+        ("graph_halfday", list_to_value floats_to_value (GStack.to_list_fif graph.halfday)) ::
+        ("graph_day",     list_to_value floats_to_value (GStack.to_list_fif graph.day))     ::
+        ("graph_week",    list_to_value floats_to_value (GStack.to_list_fif graph.week))    ::
+        ("graph_month",   list_to_value floats_to_value (GStack.to_list_fif graph.month))   ::
+        ("graph_year",    list_to_value floats_to_value (GStack.to_list_fif graph.year))    ::
         []
       )
 
@@ -183,14 +205,21 @@
 (*                                                                       *)
 (*************************************************************************)
 
-let (global_queue : (graph_record, (float * float) list ref) Hashtbl.t) = Hashtbl.create 63
+let (global_queue : (graph_record, (float * float) Queue.t) Hashtbl.t) = Hashtbl.create 63
 
 let _ =
-  Hashtbl.add  global_queue GraphDownloads (ref [List.hd (List.rev (fst !!global_graph).quarter)]);
-  Hashtbl.add  global_queue GraphUploads (ref [List.hd (List.rev (snd !!global_graph).quarter)]);
+  let q = Queue.create () in
+  Queue.add (GStack.last (get_d !!global_graph).quarter) q;
+  Hashtbl.add global_queue GraphDownloads q;
+  let q = Queue.create () in
+  Queue.add (GStack.last (get_u !!global_graph).quarter) q;
   List.iter (fun (file_uid, (down, up)) ->
-    Hashtbl.add  global_queue (GraphFile (file_uid, GraphDownloads)) (ref [List.hd (List.rev down.quarter)]);
-    Hashtbl.add  global_queue (GraphFile (file_uid, GraphUploads)) (ref [List.hd (List.rev up.quarter)]);
+    let q_d = Queue.create () in
+    Queue.add (GStack.last down.quarter) q_d;
+    let q_u = Queue.create () in
+    Queue.add (GStack.last up.quarter) q_u;
+    Hashtbl.add  global_queue (GraphFile (file_uid, GraphDownloads)) q_d;
+    Hashtbl.add  global_queue (GraphFile (file_uid, GraphUploads)) q_u;
   ) !!files_graph
 
 (*************************************************************************)
@@ -199,8 +228,6 @@
 (*                                                                       *)
 (*************************************************************************)
 
-let max_points = 200.
-
 let quarter_step = quarter /. max_points
 let hour_step = hour /. max_points
 let halfday_step = halfday /. max_points
@@ -215,18 +242,20 @@
 (*                                                                       *)
 (*************************************************************************)
 
-let r_avg l0 l1 =
-  let rx = ref 0. in
-  let min_t = ref (fst (List.hd l0)) in
-  let max_t = ref (fst (List.hd l1)) in
-  List.iter2 (fun (t0, r0) (t1, r1) ->
-    rx := !rx +. (r0 +. r1) *. (t1 -. t0) /. 2.;
-    min_t := min !min_t t0;
-    max_t := max !max_t t1;
-  ) l0 l1;
-  if (!max_t -. !min_t) > 0.
-    then !rx /. (!max_t -. !min_t)
-    else 0.
+let r_avg l =
+  match l with
+    [] -> 0.
+  | (x, y) :: _ ->
+      begin
+        let (r, tmin, tmax, _) =
+          List.fold_left (fun (s, tmin, tmax, (x0, y0)) (x1, y1) ->
+            if x1 = x0
+              then (s, tmin, tmax, (x1, y1))
+              else (s +. (y1 +. y0) *. (x0 -. x1) /. 2., min tmin x1, max tmax x1, (x1, y1))
+          ) (0., x, x, (x, y))  l
+        in
+        if tmax = tmin then r else r /. (tmax -. tmin)
+      end
 
 (*************************************************************************)
 (*                                                                       *)
@@ -235,50 +264,24 @@
 (*************************************************************************)
 
 let vect_from previous current =
-  if !!verbose then
-    begin
-      lprintf' "In vect_from : current length %d\n" (List.length current);
-      List.iter (fun (a, b) ->
-        lprintf' "     * [%f, %f]\n" a b
-      ) current;
-      lprintf' "In vect_from : previous length %d\n" (List.length previous);
-      List.iter (fun (a, b) ->
-        lprintf' "     * [%f, %f]\n" a b
-      ) previous
-    end;
-  let (t_current, r_current) = List.nth current (List.length current - 1) in
-  (if !!verbose then lprintf' "In vect_from : (t_current, r_current) = (%f, %f)\n" t_current r_current);
-  let l = ref [] in
-  let store = ref true in
-  let n = ref (List.length previous - 1) in
-  let (t, _) = List.nth previous !n in
-  (if !!verbose then lprintf' "In vect_from : t = %f\n" t);
-  while !store && (!n >= 0) do
-    let (t_n, r_n) = List.nth previous !n in
-    if t_n > t_current
-      then begin
-        l := (t_n, r_n) :: !l;
-        decr n
-      end else store := false
-  done;
-  l := (t_current, r_current) :: !l;
-  let l2 = List.tl !l in
-  let l1 = List.rev (List.tl (List.rev !l)) in
-  if !!verbose
-    then begin
-      lprintf' "In vect_from : l1 length %d\n" (List.length l1);
-      List.iter (fun (a, b) ->
-        lprintf' "     * [%f, %f]\n" a b
-      ) l1;
-      lprintf' "In vect_from : l2 length %d\n" (List.length l2);
-      List.iter (fun (a, b) ->
-        lprintf' "     * [%f, %f]\n" a b
-      ) l2
-    end;
-  let r_avg = r_avg l1 l2 in
-  (if !!verbose then lprintf' "In vect_from : r_avg %f\n" r_avg);
-  (t, r_avg)
-
+  let t_ref, _ = GStack.last current in
+  let last_t, _ = GStack.last previous in
+  let index =
+    match (GStack.get_index_last previous) with
+      Some i -> i
+    | None -> raise Exit (* all stacks are init with dummy_graph so can't be empty *)
+  in
+  let rec iter l =
+    let (t, r) = GStack.get_at_index index previous in
+    if t > t_ref
+    then if (GStack.iter_next index previous)
+      then iter ((t, r) :: l)
+      else ((t, r) :: l)
+    else l
+  in
+  let pts = iter [] in
+  let r_avg = r_avg (List.rev pts) in
+  (last_t, r_avg)
 
 (*************************************************************************)
 (*                                                                       *)
@@ -287,12 +290,8 @@
 (*************************************************************************)
 
 let record_year graph =
-  (if !!verbose then lprintf' "calculating record_year\n");
-  let vect = vect_from graph.month graph.year in
-  (if List.length graph.year < int_of_float max_points
-     then graph.year <- graph.year @ [vect]
-     else graph.year <- (List.tl graph.year) @ [vect]);
-  if !!verbose then lprintf' "record_year calculated successfully\n"
+  let (t, r) = vect_from graph.month graph.year in
+  GStack.put (t, r) graph.year
 
 (*************************************************************************)
 (*                                                                       *)
@@ -301,14 +300,10 @@
 (*************************************************************************)
 
 let record_month graph =
-  (if !!verbose then lprintf' "calculating record_month\n");
   let (t, r) = vect_from graph.week graph.month in
-  (if List.length graph.month < int_of_float max_points
-     then graph.month <- graph.month @ [t, r]
-     else graph.month <- (List.tl graph.month) @ [t, r]);
-  (if !!verbose then lprintf' "record_month calculated successfully\n");
-  let (t_h, _) = List.nth graph.year (List.length graph.year - 1) in
-  if (t -. t_h) > year_step
+  GStack.put (t, r) graph.month;
+  let next_t, _ = GStack.last graph.year in
+  if (t -. next_t) > year_step
     then record_year graph
 
 (*************************************************************************)
@@ -318,14 +313,10 @@
 (*************************************************************************)
 
 let record_week graph =
-  (if !!verbose then lprintf' "calculating record_week\n");
   let (t, r) = vect_from graph.day graph.week in
-  (if List.length graph.week < int_of_float max_points
-     then graph.week <- graph.week @ [t, r]
-     else graph.week <- (List.tl graph.week) @ [t, r]);
-  (if !!verbose then lprintf' "record_week calculated successfully\n");
-  let (t_h, _) = List.nth graph.month (List.length graph.month - 1) in
-  if (t -. t_h) > month_step
+  GStack.put (t, r) graph.week;
+  let next_t, _ = GStack.last graph.month in
+  if (t -. next_t) > month_step
     then record_month graph
 
 (*************************************************************************)
@@ -335,14 +326,10 @@
 (*************************************************************************)
 
 let record_day graph =
-  (if !!verbose then lprintf' "calculating record_day\n");
   let (t, r) = vect_from graph.halfday graph.day in
-  (if List.length graph.day < int_of_float max_points
-     then graph.day <- graph.day @ [t, r]
-     else graph.day <- (List.tl graph.day) @ [t, r]);
-  (if !!verbose then lprintf' "record_day calculated successfully\n");
-  let (t_h, _) = List.nth graph.week (List.length graph.week - 1) in
-  if (t -. t_h) > week_step
+  GStack.put (t, r) graph.day;
+  let next_t, _ = GStack.last graph.week in
+  if (t -. next_t) > week_step
     then record_week graph
 
 (*************************************************************************)
@@ -352,17 +339,12 @@
 (*************************************************************************)
 
 let record_halfday graph =
-  (if !!verbose then lprintf' "calculating record_halfday\n");
   let (t, r) = vect_from graph.hour graph.halfday in
-  (if List.length graph.halfday < int_of_float max_points
-     then graph.halfday <- graph.halfday @ [t, r]
-     else graph.halfday <- (List.tl graph.halfday) @ [t, r]);
-  (if !!verbose then lprintf' "record_halfday calculated successfully\n");
-  let (t_h, _) = List.nth graph.day (List.length graph.day - 1) in
-  if (t -. t_h) > day_step
+  GStack.put (t, r) graph.halfday;
+  let next_t, _ = GStack.last graph.day in
+  if (t -. next_t) > day_step
     then record_day graph
 
-
 (*************************************************************************)
 (*                                                                       *)
 (*                         record_hour                                   *)
@@ -370,14 +352,10 @@
 (*************************************************************************)
 
 let record_hour graph =
-  (if !!verbose then lprintf' "calculating record_hour\n");
   let (t, r) = vect_from graph.quarter graph.hour in
-  (if List.length graph.hour < int_of_float max_points
-     then graph.hour <- graph.hour @ [t, r]
-     else graph.hour <- (List.tl graph.hour) @ [t, r]);
-  (if !!verbose then lprintf' "record_hour calculated successfully\n");
-  let (t_h, _) = List.nth graph.halfday (List.length graph.halfday - 1) in
-  if (t -. t_h) > halfday_step
+  GStack.put (t, r) graph.hour;
+  let next_t, _ = GStack.last graph.halfday in
+  if (t -. next_t) > halfday_step
     then record_halfday graph
 
 (*************************************************************************)
@@ -387,20 +365,18 @@
 (*************************************************************************)
 
 let record_quarter queue graph =
-  (if !!verbose then lprintf' "calculating record_quarter\n");
-  let (t, _) = List.hd !queue in
-  let l1 = List.tl !queue in
-  let l2 = List.rev (List.tl (List.rev !queue)) in
-  let r_avg = r_avg l1 l2 in
-  let vect = (t, r_avg) in
-  queue := [vect];
-  (if List.length graph.quarter < int_of_float max_points
-     then graph.quarter <- graph.quarter @ [vect]
-     else graph.quarter <- (List.tl graph.quarter) @ [vect]);
-  (if !!verbose then lprintf' "record_quarter calculated successfully\n");
-  let (t_h, _) = List.nth graph.hour (List.length graph.hour - 1) in
-  if (t -. t_h) > hour_step
+  if not (Queue.is_empty queue)
+  then begin
+    let l = Queue.fold (fun accu v -> v :: accu) [] queue in
+    Queue.clear queue;
+    let (t, _) = List.hd l in
+    let r = r_avg l in
+    Queue.add (t, r) queue;
+    GStack.put (t, r) graph.quarter;
+    let next_t, _ = GStack.last graph.hour in
+    if (t -. next_t) > hour_step
     then record_hour graph
+  end
 
 (*************************************************************************)
 (*                                                                       *)
@@ -409,7 +385,7 @@
 (*************************************************************************)
 
 let print_graph q t s =
-  let n = List.length !q in
+  let n = Queue.length q in
   let str =
     match t with
       GraphDownloads -> Printf.sprintf "Global Downloads %d %s" n s
@@ -430,27 +406,27 @@
       (if !!verbose then lprintf' "Record %s\n" (print_graph q graph_type "old"));
       q
     with _ ->
-      let q = ref [last_time, 0.] in
+      let q = Queue.create () in
       Hashtbl.add global_queue graph_type q;
        (if !!verbose then lprintf' "Record %s\n" (print_graph q graph_type "new"));
       q
   in
-  queue := last_vect :: !queue;
-  let first_vect = List.hd (List.rev !queue) in
-  let t_i = fst first_vect in
+  Queue.add last_vect queue;
+  let first_vect = Queue.peek queue in
+  let t_i = get_t first_vect in
   if (t -. t_i) > quarter_step
     then begin
       try
         match graph_type with
              GraphDownloads ->
                begin
-                 let graph = fst (!!global_graph) in
+                 let graph = get_d (!!global_graph) in
                  record_quarter queue graph
                end
 
            | GraphUploads ->
                begin
-                 let graph = snd (!!global_graph) in
+                 let graph = get_u (!!global_graph) in
                  record_quarter queue graph
                end
 
@@ -471,7 +447,7 @@
                        with _ -> assert false
                      end
                  in
-                 let graph = fst records in
+                 let graph = get_d records in
                  (if !!verbose then lprintf'
                     "Found fst of %s GraphDownloads in !!files_graph\n" (string_of_uid file_uid));
                  record_quarter queue graph;
@@ -496,7 +472,7 @@
                        with _ -> assert false
                      end
                  in
-                 let graph = snd records in
+                 let graph = get_u records in
                  (if !!verbose then lprintf'
                     "Found fst of %s GraphUploads in !!files_graph\n" (string_of_uid file_uid));
                  record_quarter queue graph;
@@ -538,7 +514,7 @@
         let uid = uid_of_string suid in
         (if !!verbose then lprintf' "In add_file : Adding file %s\n" suid);
         files_graph =:= (file_uid, (dummy_graph (), dummy_graph ())) :: !!files_graph;
-        let q = ref [last_time, 0.] in
+        let q = Queue.create () in
         Hashtbl.add global_queue (GraphFile (file_uid, GraphDownloads)) q;
         Hashtbl.add global_queue (GraphFile (file_uid, GraphUploads)) q
       with _ -> ()
diff -urN src/gtk2/gui/guiGraph.ml src/gtk2/gui/guiGraph.ml
--- src/gtk2/gui/guiGraph.ml	2005-10-31 19:34:02.000000000 +0100
+++ src/gtk2/gui/guiGraph.ml	2006-08-15 20:31:41.000000000 +0200
@@ -106,28 +106,6 @@
     incr n
   ) graph_times
 
-
-(*************************************************************************)
-(*                                                                       *)
-(*                         c_values                                      *)
-(*                                                                       *)
-(*************************************************************************)
-
-let c_values nbpts =
-  let step = 1. /. nbpts in
-  let rec r_values t l =
-    let t2 = t *. t in 
-    let t3 = t2 *. t in
-    let ct = 1. -. t
-      and ct2 = 1. -. 2. *. t +. t2
-      and ct3 = 1. -. 3. *. t +. 3. *. t2 -. t3
-    in
-    if t > 1.
-      then l
-      else r_values (t +. step) ((t3, 3. *. t2 *. ct, 3. *. t *. ct2, ct3) :: l)
-  in
-  r_values 0. []
-
 (*************************************************************************)
 (*                                                                       *)
 (*                         Module Curve                                  *)
@@ -156,7 +134,7 @@
 
       val module_name      : string
 
-    end) = 
+    end) =
   (struct
 
   open C
@@ -195,19 +173,35 @@
 
 (*************************************************************************)
 (*                                                                       *)
-(*                         graph_data_to_list                            *)
+(*                         get_stack                                     *)
 (*                                                                       *)
 (*************************************************************************)
 
-let graph_data_to_list g =
+let get_stack g =
   match !!graph_time with
-      GraphQuarter -> g.quarter
-    | GraphHour -> g.hour
-    | GraphHalfDay -> g.halfday
-    | GraphDay -> g.day
-    | GraphWeek -> g.week
-    | GraphMonth -> g.month
-    | GraphYear -> g.year
+    GraphQuarter -> g.quarter
+  | GraphHour -> g.hour
+  | GraphHalfDay -> g.halfday
+  | GraphDay -> g.day
+  | GraphWeek -> g.week
+  | GraphMonth -> g.month
+  | GraphYear -> g.year
+
+(*************************************************************************)
+(*                                                                       *)
+(*                         ref_time                                      *)
+(*                                                                       *)
+(*************************************************************************)
+
+let ref_time () =
+  match !!graph_time with
+    GraphQuarter -> Gb.quarter
+  | GraphHour -> Gb.hour
+  | GraphHalfDay -> Gb.halfday
+  | GraphDay -> Gb.day
+  | GraphWeek -> Gb.week
+  | GraphMonth -> Gb.month
+  | GraphYear -> Gb.year
 
 (*************************************************************************)
 (*                                                                       *)
@@ -226,7 +220,10 @@
       | GraphMonth -> Gb.month
       | GraphYear -> Gb.year
   in
-  float_of_int graph_width /. t
+  let r = float_of_int graph_width /. t in
+  if r = 0.
+  then 1.
+  else r
 
 (*************************************************************************)
 (*                                                                       *)
@@ -234,13 +231,25 @@
 (*                                                                       *)
 (*************************************************************************)
 
+let max_from t =
+  let m = GStack.fold_left (fun accu (_, r) -> max accu r) 0. t in
+  max 2. m
+
 let scaley () =
-  let max_rate = ref 1. in
-  let l = graph_data_to_list !graph_data in
-  List.iter (fun (_, r) ->
-    max_rate := max !max_rate r
-  ) l;
-  float_of_int graph_height /. (!max_rate *. 1.2)
+  let max_rate =
+    match !!graph_time with
+      GraphQuarter -> max_from !graph_data.quarter
+    | GraphHour -> max_from !graph_data.hour
+    | GraphHalfDay -> max_from !graph_data.halfday
+    | GraphDay -> max_from !graph_data.day
+    | GraphWeek -> max_from !graph_data.week
+    | GraphMonth -> max_from !graph_data.month
+    | GraphYear -> max_from !graph_data.year
+  in
+  let r = float_of_int graph_height /. (max_rate *. 1.2) in
+  if r = 0.
+  then 1.
+  else r
 
 (*************************************************************************)
 (*                                                                       *)
@@ -259,28 +268,40 @@
 (*                                                                       *)
 (*************************************************************************)
 
-let draw_bezier_curve (x1, y1) (x2, y2) (x3, y3) (x4, y4) p =
+let draw_quadratic_curve (x1, y1) (x2, y2) (x3, y3) p =
   let fore_col = `NAME !!graph_foreground in
   let light_fore_col = lighten fore_col in
-  let points = float_of_int g_width (* (x4 -. x1) *. 1.3 *. !scale_x *) in
-  let draw_point (a, b, c, d) =
-    p#set_foreground fore_col;
-    let x = int_of_float ((x1 *. a +. x2 *. b +. x3 *. c +. x4 *. d) *. !scale_x) in
-    let y =
-      if vertical_flip
-        then int_of_float ((y1 *. a +. y2 *. b +. y3 *. c +. y4 *. d) *. !scale_y)
-        else graph_height - int_of_float ((y1 *. a +. y2 *. b +. y3 *. c +. y4 *. d) *. !scale_y)
-    in
-    let y0 =
-      if vertical_flip
-      then 0
-      else graph_height
+  let nbpts = floor ((x3 -. x1) *. !scale_x) in
+  let nbpts_int = int_of_float nbpts in
+  if nbpts_int > 0
+  then begin
+    let f i =
+      let v = (nbpts -. i) in
+      let v1 = v *. v in
+      let v2 = 2. *. i *. v in
+      let v3 = i *. i in
+      (y1 *. v1 +. y2 *. v2 +. y3 *. v3) /. nbpts /. nbpts
     in
-    p#line ~x ~y ~x ~y:y0;
-    p#set_foreground light_fore_col;
-    p#point ~x ~y
-  in
-  List.iter draw_point (c_values points)
+    let x1 = int_of_float (x1 *. !scale_x) in
+    for n = 0 to nbpts_int do
+      p#set_foreground fore_col;
+      let y = !scale_y *. (f (float_of_int n)) in
+      let y =
+        if vertical_flip
+          then int_of_float y
+          else graph_height - int_of_float y
+      in
+      let y0 =
+        if vertical_flip
+        then 0
+        else graph_height
+      in
+      let x = x1 + n in
+      p#line ~x ~y ~x ~y:y0;
+      p#set_foreground light_fore_col;
+      p#point ~x ~y
+    done
+  end
 
 (*************************************************************************)
 (*                                                                       *)
@@ -304,26 +325,31 @@
   let grid_col = `NAME !!O.gtk_graph_grid in
   p#set_foreground (`NAME !!O.gtk_graph_background);
   p#rectangle ~x:0 ~y:0 ~width:graph_width ~height:graph_height ~filled:true ();
-  let l = graph_data_to_list !graph_data in
-  let n = List.length l - 4 in
-  (if !!verbose then lprintf'' "In draw_curve: data length = %d\n" (n + 4));
   p#set_line_attributes ~width:1 ~style:`SOLID ();
-  let x0 =
-    match l with
-        [] -> BasicSocket.current_time ()
-      | v :: _ -> fst v
+  let stack = get_stack !graph_data in
+  let ind_opt = GStack.get_index_last stack in
+  let x0 = Gb.last_time () -. ref_time () in
+  let _ =
+    match ind_opt with
+      None -> ()
+    | Some index ->
+        begin
+          let count = ref true in
+          let l = ref [] in
+          while !count do
+            let (t, r) = normalize_vector (GStack.get_at_index index stack) x0 in
+            l := (t, r) :: !l;
+            if (List.length !l) = 3 then begin
+              let v1 = List.nth !l 0 in
+              let v2 = List.nth !l 1 in
+              let v3 = List.nth !l 2 in
+              draw_quadratic_curve v1 v2 v3 p;
+              l := [v1]
+            end;
+            count := GStack.iter_next index stack && (t > 0.);
+          done
+        end
   in
-  let i = ref 0 in
-  (try
-     while !i <= n do
-       let v1 = normalize_vector (List.nth l !i) x0 in
-       let v2 = normalize_vector (List.nth l (!i + 1)) x0 in
-       let v3 = normalize_vector (List.nth l (!i + 2)) x0 in
-       let v4 = normalize_vector (List.nth l (!i + 3)) x0 in
-       draw_bezier_curve v1 v2 v3 v4 p;
-       i := !i + 3
-     done
-  with _ -> ());
   p#set_foreground grid_col;
   p#set_line_attributes ~width:1 ~style:`ON_OFF_DASH ();
   for i = 0 to step do
@@ -431,7 +457,7 @@
       val reset_graph_timer : unit -> unit
       val title             : string
 
-    end) = 
+    end) =
   (struct
 
   open D
diff -urN src/gtk2/gui/guiMisc.ml src/gtk2/gui/guiMisc.ml
--- src/gtk2/gui/guiMisc.ml	2006-06-12 12:02:59.000000000 +0200
+++ src/gtk2/gui/guiMisc.ml	2006-08-15 20:03:40.000000000 +0200
@@ -786,14 +786,14 @@
 let relative_availability_of avail chunks =
   match chunks with
   | None -> "0."
-  | Some chunks ->
+  | Some c ->
       let rec loop i p n =
 	if i < 0 then
 	  if n = 0 then "0." (* Watch out !! Don't modify, we have to keep a float format *)
 	  else Printf.sprintf "%5.1f" ((float p) /. (float n) *. 100.)
 	else 
 	  loop (i - 1) 
-	    (if CommonGlobals.partial_chunk (VerificationBitmap.get chunks i) then p + 1 else p)
+	    (try if CommonGlobals.partial_chunk (VerificationBitmap.get c i) then p + 1 else p with _ -> p)
             (if avail.[i] <> (char_of_int 0) then n + 1 else n) in
       loop ((String.length avail) - 1) 0 0
 
