github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/remotestorage/internal/circular/buff.go (about)

     1  // Copyright 2024 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package circular
    16  
    17  type Buff[T any] struct {
    18  	// The backing array.
    19  	arr []T
    20  	// Front() and Pop() refer to this element.
    21  	front int
    22  	// The number of elements in the buffer. [0, len(arr)).
    23  	len int
    24  }
    25  
    26  func NewBuff[T any](initSz int) *Buff[T] {
    27  	return &Buff[T]{
    28  		arr: make([]T, initSz),
    29  	}
    30  }
    31  
    32  // Returns the number of elements currently in Buff.
    33  func (b *Buff[T]) Len() int {
    34  	return b.len
    35  }
    36  
    37  func (b *Buff[T]) At(i int) T {
    38  	if i >= b.Len() {
    39  		panic("At on Buff too small")
    40  	}
    41  	j := (b.front + i) % len(b.arr)
    42  	return b.arr[j]
    43  }
    44  
    45  func (b *Buff[T]) Front() T {
    46  	return b.At(0)
    47  }
    48  
    49  func (b *Buff[T]) Pop() {
    50  	if b.Len() == 0 {
    51  		panic("Pop empty Buff")
    52  	}
    53  	b.front = (b.front + 1) % len(b.arr)
    54  	b.len -= 1
    55  }
    56  
    57  func (b *Buff[T]) ins() int {
    58  	return (b.front + b.len) % len(b.arr)
    59  }
    60  
    61  func (b *Buff[T]) Push(t T) {
    62  	if b.Len() == len(b.arr) {
    63  		newarr := make([]T, len(b.arr)+len(b.arr))
    64  		i := b.ins()
    65  		if i > b.front {
    66  			copy(newarr, b.arr[b.front:i])
    67  		} else {
    68  			first := b.arr[b.front:]
    69  			copy(newarr, first)
    70  			copy(newarr[len(first):], b.arr[:i])
    71  		}
    72  		b.arr = newarr
    73  		b.front = 0
    74  	}
    75  	b.arr[b.ins()] = t
    76  	b.len += 1
    77  }