Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorting #79

Merged
merged 19 commits into from
Sep 10, 2022
16 changes: 8 additions & 8 deletions cmd/bargraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ go run . bars -sz -m "\[(.+?)\].*\" (\d+)" -e "{$ {buckettime {1} year nginx} {2

func bargraphFunction(c *cli.Context) error {
var (
stacked = c.Bool("stacked")
reverseSort = c.Bool("reverse")
stacked = c.Bool("stacked")
)

counter := aggregation.NewSubKeyCounter()
Expand All @@ -26,12 +25,13 @@ func bargraphFunction(c *cli.Context) error {

batcher := helpers.BuildBatcherFromArguments(c)
ext := helpers.BuildExtractorFromArguments(c, batcher)
sorter := helpers.BuildSorterFromFlags(c)

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

writer.SetKeys(counter.SubKeys()...)
for _, row := range counter.ItemsSorted(reverseSort) {
for _, row := range counter.ItemsSorted(sorter) {
writer.WriteBar(line, row.Name, row.Item.Items()...)
line++
}
Expand All @@ -46,7 +46,7 @@ func bargraphFunction(c *cli.Context) error {
}

func bargraphCommand() *cli.Command {
return helpers.AdaptCommandForExtractor(cli.Command{
cmd := helpers.AdaptCommandForExtractor(cli.Command{
Name: "bargraph",
Aliases: []string{"bars", "bar", "b"},
Usage: "Create a bargraph of the given 1 or 2 dimension data",
Expand All @@ -61,10 +61,10 @@ func bargraphCommand() *cli.Command {
Aliases: []string{"s"},
Usage: "Display bargraph as stacked",
},
&cli.BoolFlag{
Name: "reverse",
Usage: "Reverses the display sort-order",
},
},
})

helpers.AddSortFlag(cmd, "smart")

return cmd
}
9 changes: 7 additions & 2 deletions cmd/heatmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func heatmapFunction(c *cli.Context) error {

batcher := helpers.BuildBatcherFromArguments(c)
ext := helpers.BuildExtractorFromArguments(c, batcher)
sorter := helpers.BuildSorterFromFlags(c)

writer := termrenderers.NewHeatmap(multiterm.New(), numRows, numCols)

Expand All @@ -37,7 +38,7 @@ func heatmapFunction(c *cli.Context) error {
}

helpers.RunAggregationLoop(ext, counter, func() {
writer.WriteTable(counter)
writer.WriteTable(counter, sorter)
writer.WriteFooter(0, helpers.FWriteExtractorSummary(ext, counter.ParseErrors(),
fmt.Sprintf("(R: %v; C: %v)", color.Wrapi(color.Yellow, counter.RowCount()), color.Wrapi(color.BrightBlue, counter.ColumnCount()))))
writer.WriteFooter(1, batcher.StatusString())
Expand All @@ -47,7 +48,7 @@ func heatmapFunction(c *cli.Context) error {
}

func heatmapCommand() *cli.Command {
return helpers.AdaptCommandForExtractor(cli.Command{
cmd := helpers.AdaptCommandForExtractor(cli.Command{
Name: "heatmap",
Aliases: []string{"heat", "hm"},
Usage: "Create a 2D heatmap of extracted data",
Expand Down Expand Up @@ -82,4 +83,8 @@ func heatmapCommand() *cli.Command {
},
},
})

helpers.AddSortFlag(cmd, "smart")

return cmd
}
60 changes: 60 additions & 0 deletions cmd/helpers/sorting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package helpers

import (
"errors"
"rare/pkg/aggregation/sorting"
"rare/pkg/logger"
"strings"

"github.com/urfave/cli/v2"
)

func AddSortFlag(command *cli.Command, defaultMode string) {
if _, err := lookupSorter(defaultMode); err != nil {
panic(err)
}

command.Flags = append(command.Flags,
&cli.StringFlag{
Name: "sort",
Usage: "Sets sorting method (value, text, numeric, contextual)",
zix99 marked this conversation as resolved.
Show resolved Hide resolved
Value: defaultMode,
},
&cli.BoolFlag{
Name: "sort-reverse",
Aliases: []string{"reverse"},
Usage: "Reverses the display sort-order",
},
)
}

func lookupSorter(name string) (sorting.NameValueSorter, error) {
name = strings.ToLower(name)
switch name {
case "text", "":
return sorting.ValueNilSorter(sorting.ByName), nil
case "smart", "numeric":
return sorting.ValueNilSorter(sorting.ByNameSmart), nil
case "contextual", "context":
return sorting.ValueNilSorter(sorting.ByContextual()), nil
case "value":
return sorting.ValueSorterEx(sorting.ByName), nil
}
return nil, errors.New("unknown sort")
}

func BuildSorter(name string, reverse bool) sorting.NameValueSorter {
sorter, err := lookupSorter(name)
if err != nil {
logger.Fatalf("Unknown sort: %s (%v)", name, err)
zix99 marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
if reverse {
sorter = sorting.Reverse(sorter)
}
return sorter
}

func BuildSorterFromFlags(c *cli.Context) sorting.NameValueSorter {
return BuildSorter(c.String("sort"), c.Bool("sort-reverse"))
}
44 changes: 44 additions & 0 deletions cmd/helpers/sorting_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package helpers

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
)

func TestAddSortingCommands(t *testing.T) {
cmd := &cli.Command{}
assert.Panics(t, func() {
AddSortFlag(cmd, "no-exist")
})

AddSortFlag(cmd, "value")

assert.Equal(t, "sort", cmd.Flags[0].Names()[0])
assert.Equal(t, "sort-reverse", cmd.Flags[1].Names()[0])
}

func TestBuildSorter(t *testing.T) {
assert.NotNil(t, BuildSorter("text", false))
assert.NotNil(t, BuildSorter("smart", false))
assert.NotNil(t, BuildSorter("contextual", false))
assert.NotNil(t, BuildSorter("value", false))
assert.NotNil(t, BuildSorter("value", true))
}

func TestBuildSorterFromFlags(t *testing.T) {
app := cli.NewApp()
cmd := &cli.Command{
Name: "test",
Action: func(ctx *cli.Context) error {
sorter := BuildSorterFromFlags(ctx)
assert.NotNil(t, sorter)
return nil
},
}
AddSortFlag(cmd, "text")
app.Commands = []*cli.Command{cmd}

assert.NoError(t, app.Run([]string{"", "test", "--sort=smart"}))
}
40 changes: 15 additions & 25 deletions cmd/histo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,16 @@ import (
"os"
"rare/cmd/helpers"
"rare/pkg/aggregation"
"rare/pkg/aggregation/sorting"
"rare/pkg/color"
"rare/pkg/multiterm"
"rare/pkg/multiterm/termrenderers"

"github.com/urfave/cli/v2"
)

func writeHistoOutput(writer *termrenderers.HistoWriter, counter *aggregation.MatchCounter, count int, reverse bool, sortByKey bool, atLeast int64) {
var items []aggregation.MatchPair
if sortByKey {
items = counter.ItemsSortedByKey(count, reverse)
} else {
items = counter.ItemsSorted(count, reverse)
}
func writeHistoOutput(writer *termrenderers.HistoWriter, counter *aggregation.MatchCounter, count int, sorter sorting.NameValueSorter, atLeast int64) {
items := counter.ItemsSortedBy(count, sorter)
line := 0
writer.UpdateSamples(counter.Count())
for _, match := range items {
Expand All @@ -32,12 +28,10 @@ func writeHistoOutput(writer *termrenderers.HistoWriter, counter *aggregation.Ma

func histoFunction(c *cli.Context) error {
var (
topItems = c.Int("n")
reverseSort = c.Bool("reverse")
sortByKey = c.Bool("sk")
atLeast = c.Int64("atleast")
extra = c.Bool("extra")
all = c.Bool("all")
topItems = c.Int("n")
atLeast = c.Int64("atleast")
extra = c.Bool("extra")
all = c.Bool("all")
)

counter := aggregation.NewCounter()
Expand All @@ -47,6 +41,7 @@ func histoFunction(c *cli.Context) error {

batcher := helpers.BuildBatcherFromArguments(c)
ext := helpers.BuildExtractorFromArguments(c, batcher)
sorter := helpers.BuildSorterFromFlags(c)

progressString := func() string {
return helpers.FWriteExtractorSummary(ext,
Expand All @@ -55,7 +50,7 @@ func histoFunction(c *cli.Context) error {
}

helpers.RunAggregationLoop(ext, counter, func() {
writeHistoOutput(writer, counter, topItems, reverseSort, sortByKey, atLeast)
writeHistoOutput(writer, counter, topItems, sorter, atLeast)
writer.WriteFooter(0, progressString())
writer.WriteFooter(1, batcher.StatusString())
})
Expand All @@ -66,7 +61,7 @@ func histoFunction(c *cli.Context) error {
fmt.Println("Full Table:")
vterm := multiterm.NewVirtualTerm()
vWriter := termrenderers.NewHistogram(vterm, counter.GroupCount())
writeHistoOutput(vWriter, counter, counter.GroupCount(), reverseSort, sortByKey, atLeast)
writeHistoOutput(vWriter, counter, counter.GroupCount(), sorter, atLeast)

vterm.WriteToOutput(os.Stdout)
fmt.Println(progressString())
Expand All @@ -77,7 +72,7 @@ func histoFunction(c *cli.Context) error {

// HistogramCommand Exported command
func histogramCommand() *cli.Command {
return helpers.AdaptCommandForExtractor(cli.Command{
cmd := helpers.AdaptCommandForExtractor(cli.Command{
Name: "histogram",
Usage: "Summarize results by extracting them to a histogram",
Description: `Generates a live-updating histogram of the extracted information from a file
Expand Down Expand Up @@ -121,15 +116,10 @@ func histogramCommand() *cli.Command {
Usage: "Only show results if there are at least this many samples",
Value: 0,
},
&cli.BoolFlag{
Name: "reverse",
Usage: "Reverses the display sort-order",
},
&cli.BoolFlag{
Name: "sortkey",
Aliases: []string{"sk"},
Usage: "Sort by key, rather than value",
},
},
})

helpers.AddSortFlag(cmd, "value")

return cmd
}
37 changes: 13 additions & 24 deletions cmd/tabulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,22 @@ func minColSlice(count int, cols []string) []string {

func tabulateFunction(c *cli.Context) error {
var (
delim = c.String("delim")
numRows = c.Int("num")
numCols = c.Int("cols")
sortByKeys = c.Bool("sortkey")
rowtotals = c.Bool("rowtotal") || c.Bool("x")
coltotals = c.Bool("coltotal") || c.Bool("x")
delim = c.String("delim")
numRows = c.Int("num")
numCols = c.Int("cols")
rowtotals = c.Bool("rowtotal") || c.Bool("x")
coltotals = c.Bool("coltotal") || c.Bool("x")
)

counter := aggregation.NewTable(delim)
writer := termrenderers.NewTable(multiterm.New(), numCols+2, numRows+2)

batcher := helpers.BuildBatcherFromArguments(c)
ext := helpers.BuildExtractorFromArguments(c, batcher)
sorter := helpers.BuildSorterFromFlags(c)

helpers.RunAggregationLoop(ext, counter, func() {
var cols []string
if sortByKeys {
cols = counter.OrderedColumnsByName()
} else {
cols = counter.OrderedColumns()
}
cols := counter.OrderedColumns(sorter)
cols = minColSlice(numCols, cols) // Cap columns

// Write header row
Expand All @@ -58,12 +53,7 @@ func tabulateFunction(c *cli.Context) error {
}

// Write each row
var rows []*aggregation.TableRow
if sortByKeys {
rows = counter.OrderedRowsByName()
} else {
rows = counter.OrderedRows()
}
rows := counter.OrderedRows(sorter)

line := 1
for i := 0; i < len(rows) && i < numRows; i++ {
Expand Down Expand Up @@ -107,7 +97,7 @@ func tabulateFunction(c *cli.Context) error {
}

func tabulateCommand() *cli.Command {
return helpers.AdaptCommandForExtractor(cli.Command{
cmd := helpers.AdaptCommandForExtractor(cli.Command{
Name: "tabulate",
Aliases: []string{"table", "t"},
Usage: "Create a 2D summarizing table of extracted data",
Expand All @@ -132,11 +122,6 @@ func tabulateCommand() *cli.Command {
Usage: "Number of columns to display",
Value: 10,
},
&cli.BoolFlag{
Name: "sortkey",
Aliases: []string{"sk"},
Usage: "Sort rows by key name rather than by values",
},
&cli.BoolFlag{
Name: "rowtotal",
Usage: "Show row totals",
Expand All @@ -152,4 +137,8 @@ func tabulateCommand() *cli.Command {
},
},
})

helpers.AddSortFlag(cmd, "value")

return cmd
}
Loading