go-reader - 解説
実装の詳細解説
バッファ管理のポイント
// グローバルなバッファマップ
var fdBuffers = make(map[int][]byte)
複数のファイルディスクリプタを同時に扱うため、各fdに対応するバッファをマップで管理します。
改行検索のアルゴリズム
for i, b := range buffer {
if b == '\n' {
line := string(buffer[:i+1]) // 改行を含む
fdBuffers[fd] = buffer[i+1:] // 残りを保持
return line, nil
}
}
バッファを線形探索して改行文字を見つけます。見つかったら:
- 改行までを返り値として返す
- 改行以降をバッファに保持
EOF 処理
if err != nil || n == 0 {
if len(buffer) > 0 {
line := string(buffer)
fdBuffers[fd] = nil
return line, nil
}
return "", io.EOF
}
ファイル末尾に達したとき:
- バッファに残りがあれば返す(改行なしの最終行)
- なければ
io.EOFを返す
よくある間違い
1. バッファのクリア忘れ
// 間違い: バッファをクリアしない
delete(fdBuffers, fd) // これを忘れるとメモリリーク
2. 改行を含めない
// 間違い
line := string(buffer[:i]) // 改行を含まない
// 正しい
line := string(buffer[:i+1]) // 改行を含む
最適化のヒント
sync.Pool でバッファを再利用