123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package chunks
- import (
- "fmt"
- "iter"
- "strconv"
- "strings"
- )
- type Chunk struct {
- Start, End int64
- }
- func New(start, end int64) Chunk {
- return Chunk{start, end}
- }
- // ParseRange parses a string in the form "unit=range" where unit is a string
- // and range is a string in the form "start-end". It returns the unit and the
- // range as a Chunk.
- func ParseRange(s string) (unit string, _ Chunk, _ error) {
- unit, r, _ := strings.Cut(s, "=")
- if r == "" {
- return unit, Chunk{}, nil
- }
- c, err := Parse(r)
- if err != nil {
- return "", Chunk{}, err
- }
- return unit, c, err
- }
- // Parse parses a string in the form "start-end" and returns the Chunk.
- func Parse(s string) (Chunk, error) {
- startStr, endStr, _ := strings.Cut(s, "-")
- start, err := strconv.ParseInt(startStr, 10, 64)
- if err != nil {
- return Chunk{}, fmt.Errorf("invalid start: %v", err)
- }
- end, err := strconv.ParseInt(endStr, 10, 64)
- if err != nil {
- return Chunk{}, fmt.Errorf("invalid end: %v", err)
- }
- if start > end {
- return Chunk{}, fmt.Errorf("invalid range %d-%d: start > end", start, end)
- }
- return Chunk{start, end}, nil
- }
- // Of returns a sequence of contiguous Chunks of size chunkSize that cover
- // the range [0, size), in order.
- func Of(size, chunkSize int64) iter.Seq[Chunk] {
- return func(yield func(Chunk) bool) {
- for start := int64(0); start < size; start += chunkSize {
- end := min(start+chunkSize-1, size-1)
- if !yield(Chunk{start, end}) {
- break
- }
- }
- }
- }
- // Count returns the number of Chunks of size chunkSize needed to cover the
- // range [0, size).
- func Count(size, chunkSize int64) int64 {
- return (size + chunkSize - 1) / chunkSize
- }
- // Size returns end minus start plus one.
- func (c Chunk) Size() int64 {
- return c.End - c.Start + 1
- }
- // String returns the string representation of the Chunk in the form
- // "{start}-{end}".
- func (c Chunk) String() string {
- return fmt.Sprintf("%d-%d", c.Start, c.End)
- }
|