|
|
|
package bucket
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
// Bucket to store volume
|
|
|
|
type Bucket struct {
|
|
|
|
// Capacity amount the bucket can store
|
|
|
|
Capacity uint64
|
|
|
|
// Volume is the current volume of the bucket
|
|
|
|
Volume uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill returns a copy Bucket filled
|
|
|
|
func Fill(b Bucket) Bucket {
|
|
|
|
return Bucket{
|
|
|
|
Volume: b.Capacity,
|
|
|
|
Capacity: b.Capacity,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Empty returns a copy Bucket set to empty
|
|
|
|
func Empty(b Bucket) Bucket {
|
|
|
|
return Bucket{
|
|
|
|
Volume: 0,
|
|
|
|
Capacity: b.Capacity,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pour fills the target bucket to the top
|
|
|
|
func Pour(src, target Bucket) (Bucket, Bucket) {
|
|
|
|
s := Bucket{
|
|
|
|
Capacity: src.Capacity,
|
|
|
|
Volume: src.Volume,
|
|
|
|
}
|
|
|
|
t := Bucket{
|
|
|
|
Capacity: target.Capacity,
|
|
|
|
Volume: target.Volume,
|
|
|
|
}
|
|
|
|
availableVolume := t.Capacity - t.Volume
|
|
|
|
if availableVolume > s.Volume {
|
|
|
|
t.Volume += s.Volume
|
|
|
|
s.Volume = 0
|
|
|
|
} else {
|
|
|
|
s.Volume -= availableVolume
|
|
|
|
t.Volume += availableVolume
|
|
|
|
}
|
|
|
|
return s, t
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill sets the volume to the capacity to fill bucket
|
|
|
|
func (b *Bucket) Fill() {
|
|
|
|
b.Volume = b.Capacity
|
|
|
|
}
|
|
|
|
|
|
|
|
// Empty sets the volume to 0
|
|
|
|
func (b *Bucket) Empty() {
|
|
|
|
b.Volume = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsEmpty is true no volume
|
|
|
|
func (b *Bucket) IsEmpty() bool {
|
|
|
|
return b.Volume == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsFull is true if bucket is at capacity
|
|
|
|
func (b *Bucket) IsFull() bool {
|
|
|
|
return b.Volume == b.Capacity
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pour fills the target bucket to the top
|
|
|
|
func (b *Bucket) Pour(target *Bucket) {
|
|
|
|
availableVolume := target.Capacity - target.Volume
|
|
|
|
if availableVolume > b.Volume {
|
|
|
|
target.Volume += b.Volume
|
|
|
|
b.Volume = 0
|
|
|
|
} else {
|
|
|
|
b.Volume -= availableVolume
|
|
|
|
target.Volume += availableVolume
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// String gets string representation
|
|
|
|
func (b *Bucket) String() string {
|
|
|
|
return fmt.Sprintf("%dvol/%dcap", b.Volume, b.Capacity)
|
|
|
|
}
|