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

Loading…
Cancel
Save