From 07f0afcd28fbd8d44176b6cd02722599b09fa7a7 Mon Sep 17 00:00:00 2001 From: carm Date: Sat, 14 Feb 2015 08:31:54 -0500 Subject: [PATCH] add deque style functions to ring buffer module, bug fixes --- src/data/CCRingBuffer.ml | 46 ++++++++++++++++++++++++++++----------- src/data/CCRingBuffer.mli | 24 ++++++++++++++------ 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/data/CCRingBuffer.ml b/src/data/CCRingBuffer.ml index ad13c2e5..57fc189d 100644 --- a/src/data/CCRingBuffer.ml +++ b/src/data/CCRingBuffer.ml @@ -1,5 +1,5 @@ (* - * CCRingBufferIO - Polymorphic circular buffer with + * CCRingBuffer - Polymorphic circular buffer with * deque semantics for accessing both the head and tail. * * Copyright (C) 2014 Simon Cruanes @@ -75,22 +75,23 @@ let resize b cap elem = let blit_from_bounded b from_buf o len = let cap = capacity b - len in (* resize if needed, with a constant to amortize *) - if cap < len then + if cap < len then begin let new_size = let desired = Array.length b.buf + len + 24 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 capacity = capacity b in - let iter 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.start = b.stop then + let iter x = + let capacity = capacity b in + Array.set b.buf b.stop x; + if b.stop = capacity-1 then b.stop <- 0 else b.stop <- b.stop + 1; + if b.start = b.stop then begin - if b.start = capacity-1 then b.start <- 0 else b.start <- b.start + 1 + if b.start = capacity-1 then b.start <- 0 else b.start <- b.start + 1 end - in - Array.iter iter sub + in + Array.iter iter sub let blit_from_unbounded b from_buf o len = @@ -117,7 +118,7 @@ let blit_from_unbounded b from_buf o len = let blit_from b from_buf o len = if (Array.length from_buf) = 0 then () else - if b.bounded then + if b.bounded then blit_from_bounded b from_buf o len else blit_from_unbounded b from_buf o len @@ -165,7 +166,7 @@ let next b = if b.start = b.stop then raise Empty; b.buf.(b.start) -let pop b = +let take_front b = if b.start = b.stop then raise Empty; let c = b.buf.(b.start) in if b.start + 1 = Array.length b.buf @@ -173,6 +174,13 @@ let pop b = else b.start <- b.start + 1; 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 = if b.start = b.stop then raise Empty; 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 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) + + + + diff --git a/src/data/CCRingBuffer.mli b/src/data/CCRingBuffer.mli index b7b409e6..6ec2d42a 100644 --- a/src/data/CCRingBuffer.mli +++ b/src/data/CCRingBuffer.mli @@ -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)]). @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 (** 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) @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 (** Drop next element. @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 is returned by [next buf] after [i-1] calls to [junk 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 *) + +