diff --git a/27-functional-programming/log-parser-exp/textreader.go b/27-functional-programming/log-parser-exp/textreader.go index aaa35cb..3654093 100644 --- a/27-functional-programming/log-parser-exp/textreader.go +++ b/27-functional-programming/log-parser-exp/textreader.go @@ -9,30 +9,20 @@ package main import ( "bufio" - "bytes" "fmt" "io" - "os" "strings" ) func textReader(r io.Reader) inputFn { return func() ([]result, error) { - // first: count the lines, so the parseText can create - // enough buffer. - var buf bytes.Buffer - lines, err := countLines(io.TeeReader(r, &buf)) - if err != nil { - return nil, err - } - - return parseText(bufio.NewScanner(&buf), lines) + return parseText(bufio.NewScanner(r)) } } // TODO: custom error type for line information -func parseText(in *bufio.Scanner, nlines int) ([]result, error) { - res := make([]result, 0, nlines) +func parseText(in *bufio.Scanner) ([]result, error) { + var res []result for l := 1; in.Scan(); l++ { fields := strings.Fields(in.Text()) @@ -46,23 +36,3 @@ func parseText(in *bufio.Scanner, nlines int) ([]result, error) { return res, in.Err() } - -func countLines(r io.Reader) (int, error) { - var ( - lines int - buf = make([]byte, os.Getpagesize()) // read via 16 KB blocks - ) - - for { - n, err := r.Read(buf) - lines += bytes.Count(buf[:n], []byte{'\n'}) - - if err == io.EOF { - return lines, nil - } - - if err != nil { - return lines, err - } - } -} diff --git a/27-functional-programming/log-parser-exp/textreaderfast.go b/27-functional-programming/log-parser-exp/textreaderfast.go index 4558398..9326106 100644 --- a/27-functional-programming/log-parser-exp/textreaderfast.go +++ b/27-functional-programming/log-parser-exp/textreaderfast.go @@ -13,6 +13,7 @@ import ( "errors" "fmt" "io" + "os" ) // this could be made faster. @@ -106,3 +107,23 @@ func atoi(input []byte) (int, error) { } return val, nil } + +func countLines(r io.Reader) (int, error) { + var ( + lines int + buf = make([]byte, os.Getpagesize()) // read via 16 KB blocks + ) + + for { + n, err := r.Read(buf) + lines += bytes.Count(buf[:n], []byte{'\n'}) + + if err == io.EOF { + return lines, nil + } + + if err != nil { + return lines, err + } + } +}