Initial complex counter

master
DustyP 5 years ago
parent 05a7cdd9d7
commit 8bf0a25c88

@ -0,0 +1,58 @@
package wc
import (
"bytes"
"unicode"
)
type ComplexCount struct {
CharCount int64
WordCount int64
LineCount int64
MaxLineLength int64
}
func GetComplexCount(chunk []byte) ComplexCount {
var count = ComplexCount{}
word := false
var lineLength int64
runes := bytes.Runes(chunk)
for _, b := range runes {
count.CharCount++
if b == '\n' {
if lineLength > count.MaxLineLength {
count.MaxLineLength = lineLength
}
lineLength = 0
count.LineCount++
if word {
word = false
count.WordCount++
}
} else if unicode.IsSpace(b) {
lineLength++
if word {
word = false
count.WordCount++
}
} else {
lineLength++
word = true
}
}
return count
}
func ConcurrentComplexChunkCounter(chunks <-chan []byte, counts chan<- ComplexCount) {
var totalCount ComplexCount
for chunk := range chunks {
count := GetComplexCount(chunk)
totalCount.CharCount += count.CharCount
totalCount.WordCount += count.WordCount
totalCount.LineCount += count.LineCount
if count.MaxLineLength > totalCount.MaxLineLength {
totalCount.MaxLineLength = count.MaxLineLength
}
}
counts <- totalCount
}

@ -31,17 +31,48 @@ func Count(filename string, cw, cc, cl, cb, mll bool) {
return
}
defer file.Close()
processLine := cw || cc
var c = &Counter{}
numWorkers := runtime.NumCPU()
if cl && !processLine {
c.Lines = CountLines(file, numWorkers)
} else {
c = CountComplex(file, numWorkers)
}
if cb {
fi, err := file.Stat()
if err != nil {
fmt.Println(err)
return
}
size := fi.Size()
c.Bytes = fi.Size()
}
processLine := cw || cc
if cl {
fmt.Printf("%d ", c.Lines)
}
if cw {
fmt.Printf("%d ", c.Words)
}
if cc {
fmt.Printf("%d ", c.Words)
}
if cb {
fmt.Printf("%d ", c.Bytes)
}
if mll {
fmt.Printf("%d ", c.MaxLineLength)
}
fmt.Printf("%s\n", filename)
}
var c = &Counter{}
numWorkers := runtime.NumCPU()
func CountLines(file *os.File, numWorkers int) int64 {
var lines int64
chunks := make(chan []byte, numWorkers)
counts := make(chan int64, numWorkers)
@ -50,7 +81,6 @@ func Count(filename string, cw, cc, cl, cb, mll bool) {
go ConcurrentChunkCounter(chunks, counts)
}
if cl && !processLine {
for {
buf := make([]byte, BufferSize)
bytes, err := file.Read(buf)
@ -65,45 +95,44 @@ func Count(filename string, cw, cc, cl, cb, mll bool) {
}
close(chunks)
for i := 0; i < numWorkers; i++ {
c.Lines += <-counts
lines += <-counts
}
close(counts)
return lines
}
if cb {
c.Bytes = size
func CountComplex(file *os.File, numWorkers int) *Counter {
counter := Counter{}
chunks := make(chan []byte, numWorkers)
counts := make(chan ComplexCount, numWorkers)
for i := 0; i < numWorkers; i++ {
go ConcurrentComplexChunkCounter(chunks, counts)
}
if c.Lines > 0 {
fmt.Printf("%d ", c.Lines)
for {
buf := make([]byte, BufferSize)
count, err := file.Read(buf)
chunks <- buf[:count]
if err != nil {
if err == io.EOF {
break
} else {
panic(err)
}
if c.Words > 0 {
fmt.Printf("%d ", c.Words)
}
if c.Chars > 0 {
fmt.Printf("%d ", c.Words)
}
if c.Bytes > 0 {
fmt.Printf("%d ", c.Bytes)
close(chunks)
for i := 0; i < numWorkers; i++ {
count := <-counts
counter.Lines += count.LineCount
counter.Words += count.WordCount
counter.Chars += count.CharCount
if count.MaxLineLength > counter.MaxLineLength {
counter.MaxLineLength = count.MaxLineLength
}
if c.MaxLineLength > 0 {
fmt.Printf("%d ", c.MaxLineLength)
}
fmt.Printf("%s\n", filename)
close(counts)
return &counter
}
//func (c *Counter) CountLines() {
// for {
// _, p, err := c.FileReader.ReadLine()
// if err != nil && err != io.EOF {
// panic(err)
// }
// if err == io.EOF {
// break
// }
// if !p {
// c.Lines++
// }
// }
// c.Lines--
//}

Loading…
Cancel
Save