blob: document, clean up ChanPeeker

Change-Id: I7c721f1e3fb81011cf2911be8889dcb9abc66dd5
This commit is contained in:
Brad Fitzpatrick 2014-09-22 22:05:48 -04:00
parent 79db18d64d
commit cd5fa05a18
1 changed files with 17 additions and 8 deletions

View File

@ -16,15 +16,18 @@ limitations under the License.
package blob package blob
// TODO: use Generics if/when available // ChanPeeker wraps a channel receiving SizedRefs and adds a 1 element
// buffer on it, with Peek and Take methods.
type ChanPeeker struct { type ChanPeeker struct {
Ch <-chan SizedRef Ch <-chan SizedRef
// A channel should either have a peek value or be closed: // Invariant after a call to Peek: either peekok or closed.
peek *SizedRef
closed bool closed bool
peekok bool // whether peek is valid
peek SizedRef
} }
// MustPeek returns the next SizedRef or panics if none is available.
func (cp *ChanPeeker) MustPeek() SizedRef { func (cp *ChanPeeker) MustPeek() SizedRef {
sr, ok := cp.Peek() sr, ok := cp.Peek()
if !ok { if !ok {
@ -33,27 +36,31 @@ func (cp *ChanPeeker) MustPeek() SizedRef {
return sr return sr
} }
// Peek returns the next SizedRef and whether one was available.
func (cp *ChanPeeker) Peek() (sr SizedRef, ok bool) { func (cp *ChanPeeker) Peek() (sr SizedRef, ok bool) {
if cp.closed { if cp.closed {
return return
} }
if cp.peek != nil { if cp.peekok {
return *cp.peek, true return cp.peek, true
} }
v, ok := <-cp.Ch v, ok := <-cp.Ch
if !ok { if !ok {
cp.closed = true cp.closed = true
return return
} }
cp.peek = &v cp.peek = v
return *cp.peek, true cp.peekok = true
return cp.peek, true
} }
// Closed reports true if no more SizedRef values are available.
func (cp *ChanPeeker) Closed() bool { func (cp *ChanPeeker) Closed() bool {
cp.Peek() cp.Peek()
return cp.closed return cp.closed
} }
// MustTake returns the next SizedRef, else panics if none is available.
func (cp *ChanPeeker) MustTake() SizedRef { func (cp *ChanPeeker) MustTake() SizedRef {
sr, ok := cp.Take() sr, ok := cp.Take()
if !ok { if !ok {
@ -62,15 +69,17 @@ func (cp *ChanPeeker) MustTake() SizedRef {
return sr return sr
} }
// Take returns the next SizedRef and whether one was available for the taking.
func (cp *ChanPeeker) Take() (sr SizedRef, ok bool) { func (cp *ChanPeeker) Take() (sr SizedRef, ok bool) {
v, ok := cp.Peek() v, ok := cp.Peek()
if !ok { if !ok {
return return
} }
cp.peek = nil cp.peekok = false
return v, true return v, true
} }
// ConsumeAll drains the channel of all items.
func (cp *ChanPeeker) ConsumeAll() { func (cp *ChanPeeker) ConsumeAll() {
for !cp.Closed() { for !cp.Closed() {
cp.Take() cp.Take()