This commit is contained in:
John Kerl 2020-09-16 09:41:15 -04:00
parent 83b1550b5a
commit 8fc5945d76
3 changed files with 41 additions and 17 deletions

View file

@ -126,15 +126,31 @@ func mapperSortUsage(
}
// ----------------------------------------------------------------
// Example:
// * mlr sort -f a -n i
// * group-by field-name list is "a,i"
// * input record 'a=pan,b=pan,i=1,x=0.3467,y=0.7268'
// o values at a,i are "pan",1
// o grouping key for the ordered map from string to record-bucket is the string "pan,1"
// o we also need a map from "pan,1" to the array of mlrvals ["pan", 1].
// * next input record 'a=eks,b=pan,i=2,x=0.7586,y=0.5221'
// o values at a,i are "eks",2
// o grouping key for the ordered map from string to record-bucket is the string "eks,2"
// o we also need a map from "eks,2" to the array of mlrvals ["eks", 2].
// * what gets sorted are the bucket-heading arrays of mlrvals:
// o make an array [ ("pan,1", ["pan", 1]), ("eks,2", ["eks", 2])
// o sort that
// * output is simply for each slot in the array, emit each record in the bucket
type MapperSort struct {
// input
// xxx change for group-by -> sort
// Input
groupByFieldNameList []string
// state
// map from string to *list.List
// State
// Map from string to *list.List:
recordListsByGroup *lib.OrderedMap
// xxx for group-by -> sort: need map from string to exemplar srec
// Map from string to []lib.Mlrval:
bucketHeads *lib.OrderedMap
}
func NewMapperSort(
@ -147,6 +163,7 @@ func NewMapperSort(
groupByFieldNameList: groupByFieldNameList,
recordListsByGroup: lib.NewOrderedMap(),
bucketHeads: lib.NewOrderedMap(),
}
return this, nil
@ -158,8 +175,10 @@ func (this *MapperSort) Map(
outputChannel chan<- *types.RecordAndContext,
) {
inrec := inrecAndContext.Record
if inrec != nil { // not end of record stream
if inrec != nil {
// Not end of record stream
// xxx need to factor out the joined and non-joined -- this verb needs both
groupByKey, ok := inrec.GetSelectedValuesJoined(this.groupByFieldNameList)
if !ok {
return
@ -169,12 +188,17 @@ func (this *MapperSort) Map(
if recordListForGroup == nil {
recordListForGroup = list.New()
this.recordListsByGroup.Put(groupByKey, recordListForGroup)
this.bucketHeads.Put(groupByKey, recordListForGroup)
}
recordListForGroup.(*list.List).PushBack(inrecAndContext)
// xxx put the bucket-heads data
// bucketHeads.(*list.List).PushBack(xxx)
} else {
// xxx sort ... then output
// End of record stream
// xxx stub from group-by (no sorting):
for outer := this.recordListsByGroup.Head; outer != nil; outer = outer.Next {
recordListForGroup := outer.Value.(*list.List)
for inner := recordListForGroup.Front(); inner != nil; inner = inner.Next() {

View file

@ -13,7 +13,7 @@ import (
type RecordWriterCSV struct {
csvWriter *csv.Writer
// For reporting schema changes: we print a newline and the new header
lastJoinedHeader *string
lastJoinedHeader *string
doHeaderlessOutput bool
}
@ -23,8 +23,8 @@ func NewRecordWriterCSV(writerOptions *clitypes.TWriterOptions) *RecordWriterCSV
csvWriter.Comma = rune(writerOptions.OFS[0])
return &RecordWriterCSV{
csvWriter: csvWriter,
lastJoinedHeader: nil,
csvWriter: csvWriter,
lastJoinedHeader: nil,
doHeaderlessOutput: writerOptions.HeaderlessCSVOutput,
}
}

View file

@ -2,19 +2,19 @@
TOP OF LIST:
* go-try:
! sort
! filter
! emit; print/dump
! quoted NIDX
- how with whitespace regex -- ?
! quoted DKVP
- what about csvlite-style -- ? needs a --dkvplite ?
! --implicit-csv-header
! cat -n -g a,b,c
! sort
o clean up mlr --help to not advertise things it doesn't do yet
o ASV?
* array/map
o err-return for array/map get/put if incorrect types ... currently go-void ...
* widen verb coverage
o count
o sort
@ -43,19 +43,19 @@ TOP OF LIST:
o '_' as empty-marker in pprint -- ? backwards-incompatible if so ...
* widen DSL coverage
! print/dump/emit
o c/reg_test/run reorgs
o err-return for array/map get/put if incorrect types ... currently go-void ...
! the DSL needs a full, written-down-and-published spell-out of error-eval semantics
o begin/end hygiene:
- AST tree-walk / CST build: must be at top level
- tree-walk begin/end to check for invalids ($-anything etc)
- bare-boolean last statement in main block, & not in begin/end
o support the filter verb
o print/dump/emit
o UDFs
o localvars
o if/for/etc
! the DSL needs a full, written-down-and-published spell-out of error-eval semantics
----------------------------------------------------------------
MAYBE: