mirror of
https://github.com/metabarcoding/obitools4.git
synced 2026-03-25 05:20:52 +00:00
replace fixed-size carry buffer with dynamic slice
Replace the fixed [256]byte carry buffer with a dynamic []byte slice to support arbitrarily long lines without heap allocation during accumulation. Update all carry buffer handling logic to use len(s.carry) and append instead of fixed-size copy operations.
This commit is contained in:
@@ -2,13 +2,12 @@ package obiformats
|
|||||||
|
|
||||||
import "bytes"
|
import "bytes"
|
||||||
|
|
||||||
// ropeScanner reads lines from a PieceOfChunk rope without heap allocation.
|
// ropeScanner reads lines from a PieceOfChunk rope.
|
||||||
// The carry buffer (stack) handles lines that span two rope nodes.
|
// The carry buffer handles lines that span two rope nodes; it grows as needed.
|
||||||
type ropeScanner struct {
|
type ropeScanner struct {
|
||||||
current *PieceOfChunk
|
current *PieceOfChunk
|
||||||
pos int
|
pos int
|
||||||
carry [256]byte // 256 gives ample margin for typical flat-file lines
|
carry []byte
|
||||||
carryN int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRopeScanner(rope *PieceOfChunk) *ropeScanner {
|
func newRopeScanner(rope *PieceOfChunk) *ropeScanner {
|
||||||
@@ -21,10 +20,10 @@ func newRopeScanner(rope *PieceOfChunk) *ropeScanner {
|
|||||||
func (s *ropeScanner) ReadLine() []byte {
|
func (s *ropeScanner) ReadLine() []byte {
|
||||||
for {
|
for {
|
||||||
if s.current == nil {
|
if s.current == nil {
|
||||||
if s.carryN > 0 {
|
if len(s.carry) > 0 {
|
||||||
n := s.carryN
|
line := s.carry
|
||||||
s.carryN = 0
|
s.carry = s.carry[:0]
|
||||||
return s.carry[:n]
|
return line
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -34,13 +33,12 @@ func (s *ropeScanner) ReadLine() []byte {
|
|||||||
|
|
||||||
if idx >= 0 {
|
if idx >= 0 {
|
||||||
var line []byte
|
var line []byte
|
||||||
if s.carryN == 0 {
|
if len(s.carry) == 0 {
|
||||||
line = data[:idx]
|
line = data[:idx]
|
||||||
} else {
|
} else {
|
||||||
n := copy(s.carry[s.carryN:], data[:idx])
|
s.carry = append(s.carry, data[:idx]...)
|
||||||
s.carryN += n
|
line = s.carry
|
||||||
line = s.carry[:s.carryN]
|
s.carry = s.carry[:0]
|
||||||
s.carryN = 0
|
|
||||||
}
|
}
|
||||||
s.pos += idx + 1
|
s.pos += idx + 1
|
||||||
if s.pos >= len(s.current.data) {
|
if s.pos >= len(s.current.data) {
|
||||||
@@ -54,8 +52,7 @@ func (s *ropeScanner) ReadLine() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No \n in this node: accumulate into carry and advance
|
// No \n in this node: accumulate into carry and advance
|
||||||
n := copy(s.carry[s.carryN:], data)
|
s.carry = append(s.carry, data...)
|
||||||
s.carryN += n
|
|
||||||
s.current = s.current.Next()
|
s.current = s.current.Next()
|
||||||
s.pos = 0
|
s.pos = 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user