externalsort: make Merge user responsible for flushing writer.

This commit is contained in:
Arseny Balobanov 2020-03-12 23:12:36 +03:00
parent 68fa75d882
commit bd4ee323bd
5 changed files with 27 additions and 15 deletions

View file

@ -14,15 +14,14 @@ type LineReader interface {
ReadLine() (string, error) ReadLine() (string, error)
} }
type LineWriterFlusher interface { type LineWriter interface {
Write(l string) error Write(l string) error
Flush() error
} }
``` ```
и два конструктора: и два конструктора:
``` ```
func NewReader(r io.Reader) LineReader func NewReader(r io.Reader) LineReader
func NewWriterFlusher(w io.Writer) LineWriterFlusher func NewWriter(w io.Writer) LineWriter
``` ```
`NewLineReader` оборачивает переданный `io.Reader` в `LineReader`. `NewLineReader` оборачивает переданный `io.Reader` в `LineReader`.
@ -38,7 +37,7 @@ func NewWriterFlusher(w io.Writer) LineWriterFlusher
Функция слияния произвольного количества отсортированных групп строк: Функция слияния произвольного количества отсортированных групп строк:
``` ```
func Merge(w LineWriterFlusher, readers ...LineReader) error func Merge(w LineWriter, readers ...LineReader) error
``` ```
`Merge` по необходимости читает из reader'ов и пишет во writer. `Merge` по необходимости читает из reader'ов и пишет во writer.

View file

@ -6,7 +6,6 @@ type LineReader interface {
ReadLine() (string, error) ReadLine() (string, error)
} }
type LineWriterFlusher interface { type LineWriter interface {
Write(l string) error Write(l string) error
Flush() error
} }

View file

@ -1,6 +1,7 @@
package externalsort package externalsort
import ( import (
"bufio"
"bytes" "bytes"
"errors" "errors"
"io" "io"
@ -118,7 +119,7 @@ func TestLineReader_error(t *testing.T) {
require.True(t, errors.Is(err, io.EOF)) require.True(t, errors.Is(err, io.EOF))
} }
func TestLineWriterFlusher(t *testing.T) { func TestLineWriter(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
name string name string
lines []string lines []string
@ -130,17 +131,25 @@ func TestLineWriterFlusher(t *testing.T) {
name: "simple", name: "simple",
lines: []string{"a\n", "b\n", "c\n"}, lines: []string{"a\n", "b\n", "c\n"},
}, },
{
name: "large-line",
lines: []string{strings.Repeat("xx", 2049), "x", "y"},
},
{
name: "huge-line",
lines: []string{strings.Repeat("?", 65537), "?", "!"},
},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var buf bytes.Buffer var buf bytes.Buffer
w := NewWriterFlusher(&buf) w := bufio.NewWriter(&buf)
lw := NewWriter(w)
for _, l := range tc.lines { for _, l := range tc.lines {
require.NoError(t, w.Write(l)) require.NoError(t, lw.Write(l))
} }
require.NoError(t, w.Flush()) require.NoError(t, w.Flush())
require.Equal(t, strings.Join(tc.lines, ""), buf.String()) require.Equal(t, strings.Join(tc.lines, ""), buf.String())
}) })
} }

View file

@ -10,11 +10,11 @@ func NewReader(r io.Reader) LineReader {
panic("implement me") panic("implement me")
} }
func NewWriterFlusher(w io.Writer) LineWriterFlusher { func NewWriter(w io.Writer) LineWriter {
panic("implement me") panic("implement me")
} }
func Merge(w LineWriterFlusher, readers ...LineReader) error { func Merge(w LineWriter, readers ...LineReader) error {
panic("implement me") panic("implement me")
} }

View file

@ -1,6 +1,7 @@
package externalsort package externalsort
import ( import (
"bufio"
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"path" "path"
@ -38,16 +39,18 @@ func TestMerge(t *testing.T) {
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
out := &bytes.Buffer{} out := &bytes.Buffer{}
w := NewWriterFlusher(out) w := bufio.NewWriter(out)
lw := NewWriter(w)
var readers []LineReader var readers []LineReader
for _, s := range tc.in { for _, s := range tc.in {
readers = append(readers, newStringReader(s)) readers = append(readers, newStringReader(s))
} }
err := Merge(w, readers...) err := Merge(lw, readers...)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, w.Flush())
require.Equal(t, tc.out, out.String()) require.Equal(t, tc.out, out.String())
}) })
} }
@ -85,12 +88,14 @@ func TestSort(t *testing.T) {
in, out := readTestCase(testCaseDir) in, out := readTestCase(testCaseDir)
var buf bytes.Buffer var buf bytes.Buffer
err := Sort(&buf, in...) w := bufio.NewWriter(&buf)
err := Sort(w, in...)
require.NoError(t, err) require.NoError(t, err)
expected, err := ioutil.ReadFile(out) expected, err := ioutil.ReadFile(out)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, w.Flush())
require.Equal(t, string(expected), buf.String()) require.Equal(t, string(expected), buf.String())
}) })
} }