add deque style functions to ring buffer module, bug fixes

This commit is contained in:
carm 2015-02-14 08:31:54 -05:00
parent a43145b107
commit 07f0afcd28
2 changed files with 50 additions and 20 deletions

View file

@ -1,5 +1,5 @@
(* (*
* CCRingBufferIO - Polymorphic circular buffer with * CCRingBuffer - Polymorphic circular buffer with
* deque semantics for accessing both the head and tail. * deque semantics for accessing both the head and tail.
* *
* Copyright (C) 2014 Simon Cruanes * Copyright (C) 2014 Simon Cruanes
@ -75,14 +75,15 @@ let resize b cap elem =
let blit_from_bounded b from_buf o len = let blit_from_bounded b from_buf o len =
let cap = capacity b - len in let cap = capacity b - len in
(* resize if needed, with a constant to amortize *) (* resize if needed, with a constant to amortize *)
if cap < len then if cap < len then begin
let new_size = let new_size =
let desired = Array.length b.buf + len + 24 in let desired = Array.length b.buf + len + 24 in
min (b.size+1) desired in min (b.size+1) desired in
resize b new_size from_buf.(0); resize b new_size from_buf.(0)
end;
let sub = Array.sub from_buf o len in let sub = Array.sub from_buf o len in
let capacity = capacity b in
let iter x = let iter x =
let capacity = capacity b in
Array.set b.buf b.stop x; Array.set b.buf b.stop x;
if b.stop = capacity-1 then b.stop <- 0 else b.stop <- b.stop + 1; if b.stop = capacity-1 then b.stop <- 0 else b.stop <- b.stop + 1;
if b.start = b.stop then if b.start = b.stop then
@ -165,7 +166,7 @@ let next b =
if b.start = b.stop then raise Empty; if b.start = b.stop then raise Empty;
b.buf.(b.start) b.buf.(b.start)
let pop b = let take_front b =
if b.start = b.stop then raise Empty; if b.start = b.stop then raise Empty;
let c = b.buf.(b.start) in let c = b.buf.(b.start) in
if b.start + 1 = Array.length b.buf if b.start + 1 = Array.length b.buf
@ -173,6 +174,13 @@ let pop b =
else b.start <- b.start + 1; else b.start <- b.start + 1;
c c
let take_back b =
if b.start = b.stop then raise Empty;
if b.stop - 1 = 0
then b.stop <- Array.length b.buf - 1
else b.stop <- b.stop - 1;
b.buf.(b.stop)
let junk b = let junk b =
if b.start = b.stop then raise Empty; if b.start = b.stop then raise Empty;
if b.start + 1 = Array.length b.buf if b.start + 1 = Array.length b.buf
@ -232,4 +240,16 @@ let to_list b =
(Array.to_list (Array.sub b.buf b.start (Array.length b.buf - b.start))) (Array.to_list (Array.sub b.buf b.start (Array.length b.buf - b.start)))
(Array.to_list (Array.sub b.buf 0 b.stop)) (Array.to_list (Array.sub b.buf 0 b.stop))
let push_back b e = add b (Array.of_list [e])
let peek_front b = if is_empty b then
raise Empty else Array.get b.buf b.start
let peek_back b = if is_empty b then
raise Empty else Array.get b.buf
(if b.stop = 0 then capacity b - 1 else b.stop-1)

View file

@ -57,9 +57,6 @@ val blit_into : 'a t -> 'a array -> int -> int -> int
@return the number of elements actually copied ([min len (length buf)]). @return the number of elements actually copied ([min len (length buf)]).
@raise Invalid_argument if [o,len] is not a valid slice of [s] *) @raise Invalid_argument if [o,len] is not a valid slice of [s] *)
val add : 'a t -> 'a array -> unit
(** [add buf t] adds elements [t] at the end of [buf]. *)
val to_list : 'a t -> 'a list val to_list : 'a t -> 'a list
(** extract the current content into a list *) (** extract the current content into a list *)
@ -76,10 +73,6 @@ val next : 'a t -> 'a
(** obtain next element (the first one of the buffer) (** obtain next element (the first one of the buffer)
@raise Empty if the buffer is empty *) @raise Empty if the buffer is empty *)
val pop : 'a t -> 'a
(** obtain and remove next element (the first one)
@raise Empty if the buffer is empty *)
val junk : 'a t -> unit val junk : 'a t -> unit
(** Drop next element. (** Drop next element.
@raise Empty if the buffer is already empty *) @raise Empty if the buffer is already empty *)
@ -96,3 +89,20 @@ val get : 'a t -> int -> 'a
(** [get buf i] returns the [i]-th element of [buf], ie the one that (** [get buf i] returns the [i]-th element of [buf], ie the one that
is returned by [next buf] after [i-1] calls to [junk buf]. is returned by [next buf] after [i-1] calls to [junk buf].
@raise Invalid_argument if the index is invalid (> [length buf]) *) @raise Invalid_argument if the index is invalid (> [length buf]) *)
val push_back : 'a t -> 'a -> unit
(** Push value at the back *)
val peek_front : 'a t -> 'a
(** First value, or Empty *)
val peek_back : 'a t -> 'a
(** Last value, or Empty *)
val take_back : 'a t -> 'a
(** Take last value, or raise Empty *)
val take_front : 'a t -> 'a
(** Take first value, or raise Empty *)