externalsort: make Merge user responsible for flushing writer.
This commit is contained in:
parent
68fa75d882
commit
bd4ee323bd
5 changed files with 27 additions and 15 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue