mirror of https://github.com/hrfee/jfa-go
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.3 KiB
67 lines
1.3 KiB
4 years ago
|
// Package linecache provides a writer that stores n lines of text at once, overwriting old content as it reaches its capacity. Its contents can be read from with a String() method.
|
||
|
package linecache
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
// LineCache provides an io.Writer that stores a fixed number of lines of text.
|
||
|
type LineCache struct {
|
||
|
count int
|
||
|
lines [][]byte
|
||
|
current int
|
||
|
lock *sync.Mutex
|
||
|
}
|
||
|
|
||
|
// NewLineCache returns a new line cache of capacity (n) lines.
|
||
|
func NewLineCache(n int) *LineCache {
|
||
|
return &LineCache{
|
||
|
current: 0,
|
||
|
count: n,
|
||
|
lines: make([][]byte, n),
|
||
|
lock: &sync.Mutex{},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Write writes a given byte array to the cache.
|
||
|
func (l *LineCache) Write(p []byte) (n int, err error) {
|
||
|
l.lock.Lock()
|
||
|
defer l.lock.Unlock()
|
||
|
lines := strings.Split(string(p), "\n")
|
||
|
for _, line := range lines {
|
||
|
if string(line) == "" {
|
||
|
continue
|
||
|
}
|
||
|
if l.current == l.count {
|
||
|
l.current = 0
|
||
|
}
|
||
|
l.lines[l.current] = []byte(line)
|
||
|
l.current++
|
||
|
}
|
||
|
n = len(p)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// String returns a string representation of the cache contents.
|
||
|
func (l *LineCache) String() string {
|
||
|
i := 0
|
||
|
if l.lines[l.count-1] != nil && l.current != l.count {
|
||
|
i = l.current
|
||
|
}
|
||
|
out := ""
|
||
|
for {
|
||
|
if l.lines[i] == nil {
|
||
|
return out
|
||
|
}
|
||
|
out += string(l.lines[i]) + "\n"
|
||
|
i++
|
||
|
if i == l.current {
|
||
|
return out
|
||
|
}
|
||
|
if i == l.count {
|
||
|
i = 0
|
||
|
}
|
||
|
}
|
||
|
}
|