Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ func analyzeFunction(c *cli.Context) error {
batcher := helpers.BuildBatcherFromArguments(c)
ext := helpers.BuildExtractorFromArguments(c, batcher)

helpers.RunAggregationLoop(ext, aggr, func() {
interrupt := helpers.RunAggregationLoop(ext, aggr, func() {
line := writeAggrOutput(writer, aggr, extra, quantiles)
writer.WriteForLine(line+1, helpers.BuildExtractorSummary(ext, aggr.ParseErrors()))
writer.WriteForLine(line+2, batcher.StatusString())
})

writer.Close()

return helpers.DetermineErrorState(batcher, ext, aggr)
return helpers.DetermineErrorState(interrupt, batcher, ext, aggr)
}

func analyzeCommand() *cli.Command {
Expand Down
4 changes: 2 additions & 2 deletions cmd/bargraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func bargraphFunction(c *cli.Context) error {
ext := helpers.BuildExtractorFromArguments(c, batcher)
sorter := helpers.BuildSorterOrFail(sortName)

helpers.RunAggregationLoop(ext, counter, func() {
interrupt := helpers.RunAggregationLoop(ext, counter, func() {
line := 0

writer.SetKeys(counter.SubKeys()...)
Expand All @@ -62,7 +62,7 @@ func bargraphFunction(c *cli.Context) error {
return err
}

return helpers.DetermineErrorState(batcher, ext, counter)
return helpers.DetermineErrorState(interrupt, batcher, ext, counter)
}

func bargraphCommand() *cli.Command {
Expand Down
73 changes: 45 additions & 28 deletions cmd/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"bufio"
"os"
"os/signal"
"unicode/utf8"

"github.com/zix99/rare/cmd/helpers"
Expand All @@ -27,40 +28,56 @@ func filterFunction(c *cli.Context, fileGlobs ...string) error {

stdout := bufio.NewWriter(os.Stdout)

exitSignal := make(chan os.Signal, 1)
signal.Notify(exitSignal, os.Interrupt)
interrupted := false

readChan := extractor.ReadFull()

OUTER_LOOP:
for matchBatch := range extractor.ReadFull() {
for _, match := range matchBatch {
if writeLines {
color.WriteString(stdout, color.BrightGreen, match.Source)
stdout.WriteByte(' ')
color.WriteUint64(stdout, color.BrightYellow, match.LineNumber)
stdout.WriteString(": ")
for {
select {
case <-exitSignal:
interrupted = true
break OUTER_LOOP
case matchBatch, more := <-readChan:
if !more {
break OUTER_LOOP
}

switch {
case customExtractor:
stdout.WriteString(match.Extracted)
case onlyText && !utf8.ValidString(match.Line):
color.WriteString(stdout, color.BrightBlue, "Binary Match")
case len(match.Indices) == 2:
// Single match, highlight entire phrase
color.WrapIndices(stdout, match.Line, match.Indices)
default:
// Multi-match groups, highlight individual groups
color.WrapIndices(stdout, match.Line, match.Indices[2:])
for _, match := range matchBatch {
if writeLines {
color.WriteString(stdout, color.BrightGreen, match.Source)
stdout.WriteByte(' ')
color.WriteUint64(stdout, color.BrightYellow, match.LineNumber)
stdout.WriteString(": ")
}

switch {
case customExtractor:
stdout.WriteString(match.Extracted)
case onlyText && !utf8.ValidString(match.Line):
color.WriteString(stdout, color.BrightBlue, "Binary Match")
case len(match.Indices) == 2:
// Single match, highlight entire phrase
color.WrapIndices(stdout, match.Line, match.Indices)
default:
// Multi-match groups, highlight individual groups
color.WrapIndices(stdout, match.Line, match.Indices[2:])
}
stdout.WriteByte('\n')

readLines++
if numLineLimit > 0 && readLines >= numLineLimit {
break OUTER_LOOP
}
}
stdout.WriteByte('\n')

readLines++
if numLineLimit > 0 && readLines >= numLineLimit {
break OUTER_LOOP
// Flush after each batch to make file-following work as expected
if err := stdout.Flush(); err != nil {
logger.Fatal(helpers.ExitCodeOutputError, err)
}
}

// Flush after each batch to make file-following work as expected
if err := stdout.Flush(); err != nil {
logger.Fatal(helpers.ExitCodeOutputError, err)
}
}

// Final flush
Expand All @@ -80,7 +97,7 @@ OUTER_LOOP:
}
os.Stderr.WriteString("\n")

return helpers.DetermineErrorState(batcher, extractor, nil)
return helpers.DetermineErrorState(interrupted, batcher, extractor, nil)
}

func getFilterArgs(isSearch bool) []cli.Flag {
Expand Down
4 changes: 2 additions & 2 deletions cmd/heatmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func heatmapFunction(c *cli.Context) error {
writer.Scaler = helpers.BuildScalerOrFail(scalerName)
writer.Formatter = helpers.BuildFormatterOrFail(formatName)

helpers.RunAggregationLoop(ext, counter, func() {
interrupt := helpers.RunAggregationLoop(ext, counter, func() {
writer.WriteTable(counter, rowSorter, colSorter)
writer.WriteFooter(0, helpers.BuildExtractorSummary(ext, counter.ParseErrors(),
fmt.Sprintf("(R: %v; C: %v)", color.Wrapi(color.Yellow, counter.RowCount()), color.Wrapi(color.BrightBlue, counter.ColumnCount()))))
Expand All @@ -60,7 +60,7 @@ func heatmapFunction(c *cli.Context) error {
return err
}

return helpers.DetermineErrorState(batcher, ext, counter)
return helpers.DetermineErrorState(interrupt, batcher, ext, counter)
}

func heatmapCommand() *cli.Command {
Expand Down
6 changes: 5 additions & 1 deletion cmd/helpers/exitCodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const (
ExitCodeInvalidUsage = 2
ExitCodeReadError = 3
ExitCodeOutputError = 4
ExitCodeSigInt = 128 + 2 // 2 is SIGINT
)

type (
Expand All @@ -23,7 +24,10 @@ type (
}
)

func DetermineErrorState(b BatcherErrors, e ExtractorSummary, agg AggregationErrors) error {
func DetermineErrorState(interrupt bool, b BatcherErrors, e ExtractorSummary, agg AggregationErrors) error {
if interrupt {
return cli.Exit("", ExitCodeSigInt)
}
if b.ReadErrors() > 0 {
return cli.Exit("Read errors", ExitCodeReadError)
}
Expand Down
11 changes: 7 additions & 4 deletions cmd/helpers/exitCodes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@ func (s *mockExitState) MatchedLines() uint64 {

func TestDetermineErrorState(t *testing.T) {
s := mockExitState{0, 0, 1}
assert.NoError(t, DetermineErrorState(&s, &s, &s))
assert.NoError(t, DetermineErrorState(false, &s, &s, &s))

s = mockExitState{0, 0, 0}
assert.Error(t, DetermineErrorState(&s, &s, &s))
assert.Error(t, DetermineErrorState(false, &s, &s, &s))

s = mockExitState{0, 1, 1}
assert.Error(t, DetermineErrorState(&s, &s, &s))
assert.Error(t, DetermineErrorState(false, &s, &s, &s))

s = mockExitState{1, 0, 1}
assert.Error(t, DetermineErrorState(&s, &s, &s))
assert.Error(t, DetermineErrorState(false, &s, &s, &s))

s = mockExitState{0, 0, 1}
assert.Error(t, DetermineErrorState(true, &s, &s, &s))
}
5 changes: 4 additions & 1 deletion cmd/helpers/updatingAggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
// writeOutput - triggered after a delay, only if there's an update
//
// The two functions are guaranteed to never happen at the same time
func RunAggregationLoop(ext *extractor.Extractor, aggregator aggregation.Aggregator, writeOutput func()) {
func RunAggregationLoop(ext *extractor.Extractor, aggregator aggregation.Aggregator, writeOutput func()) (interrupt bool) {
logger.DeferLogs()

// Updater sync variables
Expand Down Expand Up @@ -47,6 +47,7 @@ PROCESSING_LOOP:
for {
select {
case <-exitSignal:
interrupt = true
break PROCESSING_LOOP
case matchBatch, more := <-reader:
if !more {
Expand All @@ -62,4 +63,6 @@ PROCESSING_LOOP:
outputDone <- true

writeOutput()

return
}
4 changes: 2 additions & 2 deletions cmd/histo.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func histoFunction(c *cli.Context) error {
fmt.Sprintf("(Groups: %s)", color.Wrapi(color.BrightBlue, counter.GroupCount())))
}

helpers.RunAggregationLoop(ext, counter, func() {
interrupt := helpers.RunAggregationLoop(ext, counter, func() {
writeHistoOutput(writer, counter, topItems, sorter, atLeast)
writer.WriteFooter(0, progressString())
writer.WriteFooter(1, batcher.StatusString())
Expand All @@ -81,7 +81,7 @@ func histoFunction(c *cli.Context) error {
return err
}

return helpers.DetermineErrorState(batcher, ext, counter)
return helpers.DetermineErrorState(interrupt, batcher, ext, counter)
}

// HistogramCommand Exported command
Expand Down
8 changes: 5 additions & 3 deletions cmd/reduce.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ func reduceFunction(c *cli.Context) error {
formatters := buildFormatterSetOrFail(aggr, formatNames...)

// run the aggregation
interrupted := false

if aggr.GroupColCount() > 0 || table {
// Table output
table := termrenderers.NewTable(vt, colCount, rowCount)
Expand All @@ -88,7 +90,7 @@ func reduceFunction(c *cli.Context) error {
table.WriteRow(0, rowBuf...)
}

helpers.RunAggregationLoop(extractor, aggr, func() {
interrupted = helpers.RunAggregationLoop(extractor, aggr, func() {
// write data
for i, group := range aggr.Groups(sorter) {
rowBuf := make([]string, aggr.ColCount())
Expand All @@ -110,7 +112,7 @@ func reduceFunction(c *cli.Context) error {
})
} else {
// Simple output
helpers.RunAggregationLoop(extractor, aggr, func() {
interrupted = helpers.RunAggregationLoop(extractor, aggr, func() {
items := aggr.Data("")
colNames := aggr.DataCols()
for idx, expr := range items {
Expand All @@ -127,7 +129,7 @@ func reduceFunction(c *cli.Context) error {
return err
}

return helpers.DetermineErrorState(batcher, extractor, aggr)
return helpers.DetermineErrorState(interrupted, batcher, extractor, aggr)
}

func parseKeyValInitial(s, defaultInitial string) (key, initial, val string) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/spark.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func sparkFunction(c *cli.Context) error {
writer.Scaler = helpers.BuildScalerOrFail(scalerName)
writer.Formatter = helpers.BuildFormatterOrFail(formatName)

helpers.RunAggregationLoop(ext, counter, func() {
interrupt := helpers.RunAggregationLoop(ext, counter, func() {

// Trim unused data from the data store (keep memory tidy!)
if !noTruncate {
Expand Down Expand Up @@ -69,7 +69,7 @@ func sparkFunction(c *cli.Context) error {
return err
}

return helpers.DetermineErrorState(batcher, ext, counter)
return helpers.DetermineErrorState(interrupt, batcher, ext, counter)
}

func sparkCommand() *cli.Command {
Expand Down
4 changes: 2 additions & 2 deletions cmd/tabulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func tabulateFunction(c *cli.Context) error {
writer.SetFormatter(helpers.BuildFormatterOrFail(formatExp))
}

helpers.RunAggregationLoop(ext, counter, func() {
interrupt := helpers.RunAggregationLoop(ext, counter, func() {
writer.WriteTable(counter, rowSorter, colSorter)

writer.WriteFooter(0, helpers.BuildExtractorSummary(ext, counter.ParseErrors(),
Expand All @@ -54,7 +54,7 @@ func tabulateFunction(c *cli.Context) error {
return err
}

return helpers.DetermineErrorState(batcher, ext, counter)
return helpers.DetermineErrorState(interrupt, batcher, ext, counter)
}

func tabulateCommand() *cli.Command {
Expand Down
Loading