Browse Source

Some more optimizations. Also I realized that print uses stderr instead of stdout, fixed that.

master
Wim Brand 6 years ago
parent
commit
ef3c887b72
  1. 31
      main.go

31
main.go

@ -30,9 +30,9 @@ func main() {
// Make a channel and a thread for each CPU core // Make a channel and a thread for each CPU core
var cores = runtime.NumCPU() var cores = runtime.NumCPU()
var linechan = make(chan []byte)
var workchannel = make(chan []byte)
for i := 0; i < cores; i++ { for i := 0; i < cores; i++ {
go scannerThread(linechan, []byte(needle), &wg)
go scannerThread(workchannel, []byte(needle), &wg)
wg.Add(1) wg.Add(1)
} }
@ -54,37 +54,36 @@ func main() {
} }
} }
linechan <- append(buf[:nread], remainder...)
workchannel <- append(buf[:nread], remainder...)
if err == io.EOF { if err == io.EOF {
break break
} }
} }
close(linechan)
close(workchannel)
wg.Wait() wg.Wait()
} }
func scannerThread(linechannel chan []byte, needle []byte, wg *sync.WaitGroup) {
var line []byte
func scannerThread(workchannel chan []byte, needle []byte, wg *sync.WaitGroup) {
var batch []byte
var ok bool var ok bool
var start, end int var start, end int
var linelen int var linelen int
var i int var i int
defer wg.Done() defer wg.Done()
for { for {
line, ok = <-linechannel
batch, ok = <-workchannel
if !ok { if !ok {
return // channel closed. we're done return // channel closed. we're done
} }
// This loop is for every result found, when there are no more results it stops // This loop is for every result found, when there are no more results it stops
for i = bytes.Index(line, needle); i != -1; i = bytes.Index(line, needle) {
for i = bytes.Index(batch, needle); i != -1; i = bytes.Index(batch, needle) {
start, end = i, i start, end = i, i
// needle was found, but where? // needle was found, but where?
for { // find the start for { // find the start
if line[start] == lf {
if batch[start] == lf {
start++ // the line feed is from the previous line, so skip it start++ // the line feed is from the previous line, so skip it
break break
} else if start == 0 { } else if start == 0 {
@ -94,18 +93,22 @@ func scannerThread(linechannel chan []byte, needle []byte, wg *sync.WaitGroup) {
} }
for { // find the end for { // find the end
if line[end] == lf || end == linelen-1 {
if batch[end] == lf {
end++ // include the line feed in the line
// https://stackoverflow.com/questions/26857582/in-a-go-slice-why-does-slohi-end-at-element-hi-1
break
} else if end == linelen {
break break
} }
end++ end++
} }
print(string(line[start:end]) + "\n")
os.Stdout.Write(batch[start:end])
// Chop all of the bytes before the result off so it doesn't get // Chop all of the bytes before the result off so it doesn't get
// searched again // searched again
line = line[end:]
linelen = len(line)
batch = batch[end:]
linelen = len(batch)
} }
} }
} }
Loading…
Cancel
Save