mirror of
https://github.com/ultrasn0w/huso.git
synced 2025-12-13 12:19:54 +01:00
Add ring log + 429
This commit is contained in:
101
ring.go
Normal file
101
ring.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RingBuf implements an indefinitely writable circular buffer with a fixed size. Old data is overridden if write circle loops. Somewhat threadsafe.
|
||||
type RingBuf struct {
|
||||
sync.RWMutex
|
||||
data []byte
|
||||
writePos int
|
||||
written int
|
||||
loop bool
|
||||
}
|
||||
|
||||
// NewRingBuf initializes a new RingBuf with a fixed size > 0
|
||||
func NewRingBuf(size int) *RingBuf {
|
||||
if size <= 0 {
|
||||
return nil
|
||||
}
|
||||
rb := &RingBuf{
|
||||
data: make([]byte, size),
|
||||
writePos: 0,
|
||||
written: 0,
|
||||
loop: false,
|
||||
}
|
||||
return rb
|
||||
}
|
||||
|
||||
func (rb *RingBuf) WriteLine(in string) (int, error) {
|
||||
return rb.Write([]byte(fmt.Sprintf("[%s]: %s\n", time.Now().Format("2006-01-02 15:04:05"), in)))
|
||||
}
|
||||
|
||||
// Write writes all data from input buf to RingBuf, overriding looped data
|
||||
func (rb *RingBuf) Write(buf []byte) (int, error) {
|
||||
rb.Lock()
|
||||
defer rb.Unlock()
|
||||
|
||||
inLen := len(buf)
|
||||
bufLen := len(rb.data)
|
||||
|
||||
if !rb.loop && rb.written < bufLen {
|
||||
rb.written = rb.written + inLen
|
||||
rb.loop = rb.written >= bufLen
|
||||
}
|
||||
|
||||
// throw away bytes which would get looped over if input bigger than data
|
||||
if inLen > bufLen {
|
||||
buf = buf[inLen-bufLen:]
|
||||
}
|
||||
|
||||
// Copy to data field
|
||||
bytesToEnd := bufLen - rb.writePos
|
||||
copy(rb.data[rb.writePos:], buf)
|
||||
if len(buf) > bytesToEnd {
|
||||
copy(rb.data, buf[bytesToEnd:])
|
||||
}
|
||||
// Move writePos
|
||||
rb.writePos = ((rb.writePos + len(buf)) % bufLen)
|
||||
return inLen, nil
|
||||
}
|
||||
|
||||
// Size returns the maximum size of the RingBuf
|
||||
func (rb *RingBuf) Size() int {
|
||||
return len(rb.data)
|
||||
}
|
||||
|
||||
// Bytes returns content of RingBuf. DON'T WRITE TO SLICE!
|
||||
func (rb *RingBuf) Bytes() []byte {
|
||||
rb.RLock()
|
||||
defer rb.RUnlock()
|
||||
|
||||
bufLen := len(rb.data)
|
||||
if rb.loop {
|
||||
out := make([]byte, bufLen)
|
||||
if rb.writePos == 0 {
|
||||
copy(out, rb.data)
|
||||
} else {
|
||||
copy(out, rb.data[rb.writePos:])
|
||||
copy(out[bufLen-rb.writePos:], rb.data[:rb.writePos])
|
||||
}
|
||||
return out
|
||||
}
|
||||
out := make([]byte, rb.writePos+1)
|
||||
copy(out, rb.data[:rb.writePos])
|
||||
return out
|
||||
}
|
||||
|
||||
// Restart restarts RingBuf from 0
|
||||
func (rb *RingBuf) Restart() {
|
||||
rb.writePos = 0
|
||||
rb.written = 0
|
||||
rb.loop = false
|
||||
}
|
||||
|
||||
// String returns content of RingBuf as string
|
||||
func (rb *RingBuf) String() string {
|
||||
return string(rb.Bytes())
|
||||
}
|
||||
Reference in New Issue
Block a user