github.com/QuangTung97/bigcache@v0.1.0/ringbuf.go (about)

     1  package bigcache
     2  
     3  import (
     4  	"bytes"
     5  )
     6  
     7  type ringBuf struct {
     8  	begin int
     9  	size  int
    10  	data  []byte
    11  }
    12  
    13  func newRingBuf(size int) ringBuf {
    14  	return ringBuf{
    15  		begin: 0,
    16  		size:  0,
    17  		data:  make([]byte, size),
    18  	}
    19  }
    20  
    21  func (r *ringBuf) append(data []byte) int {
    22  	n := len(data)
    23  	max := len(r.data)
    24  	end := r.getEnd()
    25  	copy(r.data[end:], data)
    26  	if end+n > max {
    27  		firstPart := max - end
    28  		copy(r.data, data[firstPart:])
    29  	}
    30  	r.size += n
    31  	return end
    32  }
    33  
    34  func (r *ringBuf) appendEmpty(n int) {
    35  	r.size += n
    36  }
    37  
    38  func (r *ringBuf) readAt(data []byte, offset int) {
    39  	offset = offset % len(r.data)
    40  
    41  	n := len(data)
    42  	max := len(r.data)
    43  	copy(data, r.data[offset:])
    44  	if offset+n > max {
    45  		firstPart := max - offset
    46  		copy(data[firstPart:], r.data)
    47  	}
    48  }
    49  
    50  func (r *ringBuf) writeAt(data []byte, offset int) {
    51  	offset = offset % len(r.data)
    52  
    53  	n := len(data)
    54  	max := len(r.data)
    55  	copy(r.data[offset:], data)
    56  	if offset+n > max {
    57  		firstPart := max - offset
    58  		secondPart := n - firstPart
    59  		copy(r.data[:secondPart], data[firstPart:])
    60  	}
    61  }
    62  
    63  func (r *ringBuf) getBegin() int {
    64  	return r.begin
    65  }
    66  
    67  func (r *ringBuf) getEnd() int {
    68  	return (r.begin + r.size) % len(r.data)
    69  }
    70  
    71  func (r *ringBuf) getAvailable() int {
    72  	return len(r.data) - r.size
    73  }
    74  
    75  func (r *ringBuf) increaseBegin(n int) {
    76  	r.begin = (r.begin + n) % len(r.data)
    77  }
    78  
    79  func (r *ringBuf) skip(n int) {
    80  	r.increaseBegin(n)
    81  	r.size -= n
    82  }
    83  
    84  func (r *ringBuf) bytesEqual(from int, data []byte) bool {
    85  	from = from % len(r.data)
    86  
    87  	n := len(data)
    88  	toOffset := from + n
    89  	max := len(r.data)
    90  	if toOffset > max {
    91  		firstPart := max - from
    92  		secondPart := n - firstPart
    93  		if !bytes.Equal(r.data[from:], data[:firstPart]) {
    94  			return false
    95  		}
    96  		return bytes.Equal(r.data[:secondPart], data[firstPart:])
    97  	}
    98  	return bytes.Equal(r.data[from:toOffset], data)
    99  }
   100  
   101  func (r *ringBuf) evacuateContinuousSource(from int, end int, size int) {
   102  	max := len(r.data)
   103  
   104  	if end+size > max {
   105  		firstPart := max - end
   106  		secondPart := size - firstPart
   107  		copy(r.data[end:], r.data[from:])
   108  		copy(r.data[:secondPart], r.data[from+firstPart:])
   109  	} else {
   110  		copy(r.data[end:end+size], r.data[from:])
   111  	}
   112  }
   113  
   114  func (r *ringBuf) evacuate(size int) int {
   115  	begin := r.getBegin()
   116  	end := r.getEnd()
   117  	max := len(r.data)
   118  
   119  	if begin+size > max {
   120  		firstPart := max - begin
   121  		secondPart := size - firstPart
   122  		r.evacuateContinuousSource(begin, end, firstPart)
   123  		r.evacuateContinuousSource(0, end+firstPart, secondPart)
   124  	} else {
   125  		r.evacuateContinuousSource(begin, end, size)
   126  	}
   127  
   128  	r.increaseBegin(size)
   129  	return end
   130  }