From 093a58d783bd22056c225d5d6450d6879cd5ed96 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Tue, 23 Feb 2021 09:31:16 -0500 Subject: [PATCH] consolidate mlrval-constructor source files --- go/src/auxents/repl/dsl.go | 2 +- go/src/auxents/repl/session.go | 2 +- go/src/dsl/cst/leaves.go | 12 +- go/src/input/record_reader_csv.go | 12 +- go/src/input/record_reader_csvlite.go | 24 +- go/src/input/record_reader_dkvp.go | 8 +- go/src/input/record_reader_nidx.go | 4 +- go/src/input/record_reader_xtab.go | 8 +- go/src/transformers/percentile-keeper.go | 4 +- go/src/transformers/put_or_filter.go | 4 +- go/src/transformers/stats1-accumulators.go | 4 +- go/src/transformers/step.go | 4 +- go/src/types/mlrmap_json.go | 10 +- go/src/types/mlrval_collections.go | 13 +- go/src/types/mlrval_constants.go | 24 -- go/src/types/mlrval_functions_base.go | 4 +- go/src/types/mlrval_functions_collections.go | 20 +- go/src/types/mlrval_functions_stats.go | 4 +- go/src/types/mlrval_functions_test.go | 4 +- go/src/types/mlrval_json.go | 7 +- go/src/types/mlrval_new.go | 281 ++++++++++++------- go/src/types/mlrval_set.go | 174 ------------ go/todo.txt | 26 +- 23 files changed, 276 insertions(+), 379 deletions(-) delete mode 100644 go/src/types/mlrval_constants.go delete mode 100644 go/src/types/mlrval_set.go diff --git a/go/src/auxents/repl/dsl.go b/go/src/auxents/repl/dsl.go index 98e36701d..9a7a774c0 100644 --- a/go/src/auxents/repl/dsl.go +++ b/go/src/auxents/repl/dsl.go @@ -80,7 +80,7 @@ func (this *Repl) handleDSLStringAux( // statment like 'true' or '$x > 0.5' etc. For the REPL, we re-use this for // interactive expressions to be printed to the terminal. For the main DSL, // the default is types.MlrvalFromTrue(); for the REPL, the default is - // types.MlrvalFromVoid(). + // types.MLRVAL_VOID. filterExpression := this.runtimeState.FilterExpression if filterExpression.IsVoid() { // nothing to print diff --git a/go/src/auxents/repl/session.go b/go/src/auxents/repl/session.go index 8d4c421ab..febac5c04 100644 --- a/go/src/auxents/repl/session.go +++ b/go/src/auxents/repl/session.go @@ -63,7 +63,7 @@ func NewRepl( // statment like 'true' or '$x > 0.5' etc. For the REPL, we re-use this for // interactive expressions to be printed to the terminal. For the main DSL, // the default is types.MlrvalFromTrue(); for the REPL, the default is - // types.MlrvalFromVoid(). + // types.MLRVAL_VOID. runtimeState.FilterExpression = types.MLRVAL_VOID // For control-C handling diff --git a/go/src/dsl/cst/leaves.go b/go/src/dsl/cst/leaves.go index 137775d8a..c9fefa17e 100644 --- a/go/src/dsl/cst/leaves.go +++ b/go/src/dsl/cst/leaves.go @@ -210,34 +210,34 @@ func (this *StringLiteralNode) Evaluate( // ---------------------------------------------------------------- type IntLiteralNode struct { - literal types.Mlrval + literal *types.Mlrval } func (this *RootNode) BuildIntLiteralNode(literal string) *IntLiteralNode { return &IntLiteralNode{ - literal: types.MlrvalFromIntString(literal), + literal: types.MlrvalPointerFromIntString(literal), } } func (this *IntLiteralNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return &this.literal + return this.literal } // ---------------------------------------------------------------- type FloatLiteralNode struct { - literal types.Mlrval + literal *types.Mlrval } func (this *RootNode) BuildFloatLiteralNode(literal string) *FloatLiteralNode { return &FloatLiteralNode{ - literal: types.MlrvalFromFloat64String(literal), + literal: types.MlrvalPointerFromFloat64String(literal), } } func (this *FloatLiteralNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return &this.literal + return this.literal } // ---------------------------------------------------------------- diff --git a/go/src/input/record_reader_csv.go b/go/src/input/record_reader_csv.go index d44f9dab3..bcc2f6f50 100644 --- a/go/src/input/record_reader_csv.go +++ b/go/src/input/record_reader_csv.go @@ -120,8 +120,8 @@ func (this *RecordReaderCSV) processHandle( if nh == nd { for i := 0; i < nh; i++ { key := header[i] - value := types.MlrvalFromInferredType(csvRecord[i]) - record.PutReference(key, &value) + value := types.MlrvalPointerFromInferredType(csvRecord[i]) + record.PutReference(key, value) } } else { @@ -140,14 +140,14 @@ func (this *RecordReaderCSV) processHandle( n := lib.IntMin2(nh, nd) for i = 0; i < n; i++ { key := header[i] - value := types.MlrvalFromInferredType(csvRecord[i]) - record.PutReference(key, &value) + value := types.MlrvalPointerFromInferredType(csvRecord[i]) + record.PutReference(key, value) } if nh < nd { // if header shorter than data: use 1-up itoa keys key := strconv.Itoa(i + 1) - value := types.MlrvalFromInferredType(csvRecord[i]) - record.PutCopy(key, &value) + value := types.MlrvalPointerFromInferredType(csvRecord[i]) + record.PutCopy(key, value) } if nh > nd { // if header longer than data: use "" values diff --git a/go/src/input/record_reader_csvlite.go b/go/src/input/record_reader_csvlite.go index 19563a583..619e4c850 100644 --- a/go/src/input/record_reader_csvlite.go +++ b/go/src/input/record_reader_csvlite.go @@ -172,8 +172,8 @@ func (this *RecordReaderCSVLite) processHandleExplicitCSVHeader( record := types.NewMlrmap() if !this.allowRaggedCSVInput { for i, field := range fields { - value := types.MlrvalFromInferredType(field) - record.PutCopy(headerStrings[i], &value) + value := types.MlrvalPointerFromInferredType(field) + record.PutCopy(headerStrings[i], value) } } else { nh := len(headerStrings) @@ -181,15 +181,15 @@ func (this *RecordReaderCSVLite) processHandleExplicitCSVHeader( n := lib.IntMin2(nh, nd) var i int for i = 0; i < n; i++ { - value := types.MlrvalFromInferredType(fields[i]) - record.PutCopy(headerStrings[i], &value) + value := types.MlrvalPointerFromInferredType(fields[i]) + record.PutCopy(headerStrings[i], value) } if nh < nd { // if header shorter than data: use 1-up itoa keys for i = nh; i < nd; i++ { key := strconv.Itoa(i + 1) - value := types.MlrvalFromInferredType(fields[i]) - record.PutCopy(key, &value) + value := types.MlrvalPointerFromInferredType(fields[i]) + record.PutCopy(key, value) } } if nh > nd { @@ -267,8 +267,8 @@ func (this *RecordReaderCSVLite) processHandleImplicitCSVHeader( record := types.NewMlrmap() if !this.allowRaggedCSVInput { for i, field := range fields { - value := types.MlrvalFromInferredType(field) - record.PutCopy(headerStrings[i], &value) + value := types.MlrvalPointerFromInferredType(field) + record.PutCopy(headerStrings[i], value) } } else { nh := len(headerStrings) @@ -276,14 +276,14 @@ func (this *RecordReaderCSVLite) processHandleImplicitCSVHeader( n := lib.IntMin2(nh, nd) var i int for i = 0; i < n; i++ { - value := types.MlrvalFromInferredType(fields[i]) - record.PutCopy(headerStrings[i], &value) + value := types.MlrvalPointerFromInferredType(fields[i]) + record.PutCopy(headerStrings[i], value) } if nh < nd { // if header shorter than data: use 1-up itoa keys key := strconv.Itoa(i + 1) - value := types.MlrvalFromInferredType(fields[i]) - record.PutCopy(key, &value) + value := types.MlrvalPointerFromInferredType(fields[i]) + record.PutCopy(key, value) } if nh > nd { // if header longer than data: use "" values diff --git a/go/src/input/record_reader_dkvp.go b/go/src/input/record_reader_dkvp.go index 733193797..97e6b9315 100644 --- a/go/src/input/record_reader_dkvp.go +++ b/go/src/input/record_reader_dkvp.go @@ -97,12 +97,12 @@ func recordFromDKVPLine( // "a=". Here we use the positional index as the key. This way // DKVP is a generalization of NIDX. key := strconv.Itoa(i + 1) // Miller userspace indices are 1-up - value := types.MlrvalFromInferredType(kv[0]) - record.PutReference(key, &value) + value := types.MlrvalPointerFromInferredType(kv[0]) + record.PutReference(key, value) } else { key := kv[0] - value := types.MlrvalFromInferredType(kv[1]) - record.PutReference(key, &value) + value := types.MlrvalPointerFromInferredType(kv[1]) + record.PutReference(key, value) } } return record diff --git a/go/src/input/record_reader_nidx.go b/go/src/input/record_reader_nidx.go index 3c574c13e..78f61d3fe 100644 --- a/go/src/input/record_reader_nidx.go +++ b/go/src/input/record_reader_nidx.go @@ -94,8 +94,8 @@ func recordFromNIDXLine( for _, value := range values { i++ key := strconv.Itoa(i) - mval := types.MlrvalFromInferredType(value) - record.PutReference(key, &mval) + mval := types.MlrvalPointerFromInferredType(value) + record.PutReference(key, mval) } return record } diff --git a/go/src/input/record_reader_xtab.go b/go/src/input/record_reader_xtab.go index 04a1ddf22..9c032f3a3 100644 --- a/go/src/input/record_reader_xtab.go +++ b/go/src/input/record_reader_xtab.go @@ -136,11 +136,11 @@ func (this *RecordReaderXTAB) recordFromXTABLines( key := kv[0] if len(kv) == 1 { - value := types.MlrvalFromVoid() - record.PutReference(key, &value) + value := types.MLRVAL_VOID + record.PutReference(key, value) } else { - value := types.MlrvalFromInferredType(kv[1]) - record.PutReference(key, &value) + value := types.MlrvalPointerFromInferredType(kv[1]) + record.PutReference(key, value) } } diff --git a/go/src/transformers/percentile-keeper.go b/go/src/transformers/percentile-keeper.go index 0aa664fa5..3d2a04c5a 100644 --- a/go/src/transformers/percentile-keeper.go +++ b/go/src/transformers/percentile-keeper.go @@ -269,7 +269,7 @@ func (this *PercentileKeeper) Emit(percentile float64) types.Mlrval { func (this *PercentileKeeper) EmitNonInterpolated(percentile float64) types.Mlrval { if len(this.data) == 0 { - return types.MlrvalFromAbsent() + return *types.MLRVAL_ABSENT } this.sortIfNecessary() return *this.data[computeIndexNoninterpolated(int(len(this.data)), percentile)].Copy() @@ -277,7 +277,7 @@ func (this *PercentileKeeper) EmitNonInterpolated(percentile float64) types.Mlrv func (this *PercentileKeeper) EmitLinearlyInterpolated(percentile float64) types.Mlrval { if len(this.data) == 0 { - return types.MlrvalFromAbsent() + return *types.MLRVAL_ABSENT } this.sortIfNecessary() output := getPercentileLinearlyInterpolated(this.data, int(len(this.data)), percentile) diff --git a/go/src/transformers/put_or_filter.go b/go/src/transformers/put_or_filter.go index a5882dc3a..aa075133e 100644 --- a/go/src/transformers/put_or_filter.go +++ b/go/src/transformers/put_or_filter.go @@ -338,8 +338,8 @@ func NewTransformerPut( } key := pair[0] svalue := pair[1] - mvalue := types.MlrvalFromInferredType(svalue) - runtimeState.Oosvars.PutCopy(key, &mvalue) + mvalue := types.MlrvalPointerFromInferredType(svalue) + runtimeState.Oosvars.PutCopy(key, mvalue) } } diff --git a/go/src/transformers/stats1-accumulators.go b/go/src/transformers/stats1-accumulators.go index a001905fb..a501e0458 100644 --- a/go/src/transformers/stats1-accumulators.go +++ b/go/src/transformers/stats1-accumulators.go @@ -308,7 +308,7 @@ func (this *Stats1ModeAccumulator) Ingest(value *types.Mlrval) { } func (this *Stats1ModeAccumulator) Emit() types.Mlrval { if this.countsByValue.FieldCount == 0 { - return types.MlrvalFromError() + return *types.MLRVAL_ERROR } maxValue := "" var maxCount = int(0) @@ -346,7 +346,7 @@ func (this *Stats1AntimodeAccumulator) Ingest(value *types.Mlrval) { } func (this *Stats1AntimodeAccumulator) Emit() types.Mlrval { if this.countsByValue.FieldCount == 0 { - return types.MlrvalFromError() + return *types.MLRVAL_ERROR } minValue := "" var minCount = int(0) diff --git a/go/src/transformers/step.go b/go/src/transformers/step.go index d40cfa96e..a75aecaea 100644 --- a/go/src/transformers/step.go +++ b/go/src/transformers/step.go @@ -402,8 +402,8 @@ func (this *tStepperShift) process( inrec *types.Mlrmap, ) { if this.previous == nil { - shift := types.MlrvalFromVoid() - inrec.PutCopy(this.outputFieldName, &shift) + shift := types.MLRVAL_VOID + inrec.PutCopy(this.outputFieldName, shift) } else { inrec.PutCopy(this.outputFieldName, this.previous) this.previous = valueFieldValue.Copy() diff --git a/go/src/types/mlrmap_json.go b/go/src/types/mlrmap_json.go index f32cbdada..13b76848d 100644 --- a/go/src/types/mlrmap_json.go +++ b/go/src/types/mlrmap_json.go @@ -144,11 +144,9 @@ func (this *mlrmapEntry) JSONStringifyInPlace( ) { outputBytes, err := this.Value.MarshalJSON(jsonFormatting) if err != nil { - newValue := MlrvalFromError() - this.Value = &newValue + this.Value = MLRVAL_ERROR } else { - newValue := MlrvalFromString(string(outputBytes)) - this.Value = &newValue + this.Value = MlrvalPointerFromString(string(outputBytes)) } } @@ -158,8 +156,6 @@ func (this *mlrmapEntry) JSONParseInPlace() { input := this.Value.String() err := this.Value.UnmarshalJSON([]byte(input)) if err != nil { - // TODO: make a pointer-return method and simplify callsites - newValue := MlrvalFromError() - this.Value = &newValue + this.Value = MLRVAL_ERROR } } diff --git a/go/src/types/mlrval_collections.go b/go/src/types/mlrval_collections.go index b5fbdd3f6..bf1b0c6c2 100644 --- a/go/src/types/mlrval_collections.go +++ b/go/src/types/mlrval_collections.go @@ -77,16 +77,17 @@ import ( ) // ================================================================ +// TODO: copy-reduction refactor func (this *Mlrval) ArrayGet(mindex *Mlrval) Mlrval { if this.mvtype != MT_ARRAY { - return MlrvalFromError() + return *MLRVAL_ERROR } if mindex.mvtype != MT_INT { - return MlrvalFromError() + return *MLRVAL_ERROR } value := arrayGetAliased(&this.arrayval, mindex.intval) if value == nil { - return MlrvalFromAbsent() + return *MLRVAL_ABSENT } else { return *value } @@ -218,15 +219,15 @@ func (this *Mlrval) ArrayAppend(value *Mlrval) { // ================================================================ func (this *Mlrval) MapGet(key *Mlrval) Mlrval { if this.mvtype != MT_MAP { - return MlrvalFromError() + return *MLRVAL_ERROR } mval, err := this.mapval.GetWithMlrvalIndex(key) if err != nil { // xxx maybe error-return in the API - return MlrvalFromError() + return *MLRVAL_ERROR } if mval == nil { - return MlrvalFromAbsent() + return *MLRVAL_ABSENT } // This returns a reference, not a (deep) copy. In general in Miller, we // copy only on write/put. diff --git a/go/src/types/mlrval_constants.go b/go/src/types/mlrval_constants.go deleted file mode 100644 index 5fb612076..000000000 --- a/go/src/types/mlrval_constants.go +++ /dev/null @@ -1,24 +0,0 @@ -// ================================================================ -// TODO: comment how these are part of the copy-reduction project. - -package types - -var value_MLRVAL_ERROR = MlrvalFromError() -var value_MLRVAL_ABSENT = MlrvalFromAbsent() -var value_MLRVAL_VOID = MlrvalFromVoid() -var value_MLRVAL_INT_0 = MlrvalFromInt(0) -var value_MLRVAL_INT_1 = MlrvalFromInt(1) -var value_MLRVAL_FLOAT_0 = MlrvalFromFloat64(0) -var value_MLRVAL_FLOAT_1 = MlrvalFromFloat64(1) -var value_MLRVAL_TRUE = MlrvalFromTrue() -var value_MLRVAL_FALSE = MlrvalFromFalse() - -var MLRVAL_ERROR = &value_MLRVAL_ERROR -var MLRVAL_ABSENT = &value_MLRVAL_ABSENT -var MLRVAL_VOID = &value_MLRVAL_VOID -var MLRVAL_INT_0 = &value_MLRVAL_INT_0 -var MLRVAL_INT_1 = &value_MLRVAL_INT_1 -var MLRVAL_FLOAT_0 = &value_MLRVAL_FLOAT_0 -var MLRVAL_FLOAT_1 = &value_MLRVAL_FLOAT_1 -var MLRVAL_TRUE = &value_MLRVAL_TRUE -var MLRVAL_FALSE = &value_MLRVAL_FALSE diff --git a/go/src/types/mlrval_functions_base.go b/go/src/types/mlrval_functions_base.go index 964958fd6..d6976dcfe 100644 --- a/go/src/types/mlrval_functions_base.go +++ b/go/src/types/mlrval_functions_base.go @@ -139,12 +139,12 @@ func _s2__(input1, input2 *Mlrval) *Mlrval { // Return integer zero (binary) func _i0__(input1, input2 *Mlrval) *Mlrval { - return MLRVAL_INT_0 + return MlrvalPointerFromInt(0) } // Return float zero (binary) func _f0__(input1, input2 *Mlrval) *Mlrval { - return MLRVAL_FLOAT_0 + return MlrvalPointerFromFloat64(0) } // Return boolean true (binary) diff --git a/go/src/types/mlrval_functions_collections.go b/go/src/types/mlrval_functions_collections.go index 277833a59..fb1e0b3e6 100644 --- a/go/src/types/mlrval_functions_collections.go +++ b/go/src/types/mlrval_functions_collections.go @@ -89,7 +89,7 @@ func leafcount_from_array(input1 *Mlrval) *Mlrval { // Golang initialization loop if we do this :( // childLeafCount := MlrvalLeafCount(&child) - childLeafCount := MLRVAL_INT_1 + childLeafCount := MlrvalPointerFromInt(1) if child.mvtype == MT_ARRAY { childLeafCount = leafcount_from_array(&child) } else if child.mvtype == MT_MAP { @@ -111,7 +111,7 @@ func leafcount_from_map(input1 *Mlrval) *Mlrval { // Golang initialization loop if we do this :( // childLeafCount := MlrvalLeafCount(child) - childLeafCount := MLRVAL_INT_1 + childLeafCount := MlrvalPointerFromInt(1) if child.mvtype == MT_ARRAY { childLeafCount = leafcount_from_array(child) } else if child.mvtype == MT_MAP { @@ -434,12 +434,12 @@ func MlrvalSplitKV(input1, input2, input3 *Mlrval) *Mlrval { pair := strings.SplitN(field, pairSeparator, 2) if len(pair) == 1 { key := strconv.Itoa(i + 1) // Miller user-space indices are 1-up - value := MlrvalFromInferredType(pair[0]) - output.mapval.PutReference(key, &value) + value := MlrvalPointerFromInferredType(pair[0]) + output.mapval.PutReference(key, value) } else if len(pair) == 2 { key := pair[0] - value := MlrvalFromInferredType(pair[1]) - output.mapval.PutReference(key, &value) + value := MlrvalPointerFromInferredType(pair[1]) + output.mapval.PutReference(key, value) } else { lib.InternalCodingErrorIf(true) } @@ -498,8 +498,8 @@ func MlrvalSplitNV(input1, input2 *Mlrval) *Mlrval { fields := lib.SplitString(input1.printrep, input2.printrep) for i, field := range fields { key := strconv.Itoa(i + 1) // Miller user-space indices are 1-up - value := MlrvalFromInferredType(field) - output.mapval.PutReference(key, &value) + value := MlrvalPointerFromInferredType(field) + output.mapval.PutReference(key, value) } return output @@ -543,8 +543,8 @@ func MlrvalSplitA(input1, input2 *Mlrval) *Mlrval { output := NewSizedMlrvalArray(int(len(fields))) for i, field := range fields { - value := MlrvalFromInferredType(field) - output.arrayval[i] = value + value := MlrvalPointerFromInferredType(field) + output.arrayval[i] = *value } return output diff --git a/go/src/types/mlrval_functions_stats.go b/go/src/types/mlrval_functions_stats.go index a34cd5a63..f5897d742 100644 --- a/go/src/types/mlrval_functions_stats.go +++ b/go/src/types/mlrval_functions_stats.go @@ -90,7 +90,7 @@ func MlrvalGetSkewness(mn, msum, msum2, msum3 *Mlrval) Mlrval { n, isInt := mn.GetIntValue() lib.InternalCodingErrorIf(!isInt) if n < 2 { - return MlrvalFromVoid() + return *MLRVAL_VOID } fn := float64(n) sum, isNumber := msum.GetNumericToFloatValue() @@ -127,7 +127,7 @@ func MlrvalGetKurtosis(mn, msum, msum2, msum3, msum4 *Mlrval) Mlrval { n, isInt := mn.GetIntValue() lib.InternalCodingErrorIf(!isInt) if n < 2 { - return MlrvalFromVoid() + return *MLRVAL_VOID } fn := float64(n) sum, isNumber := msum.GetNumericToFloatValue() diff --git a/go/src/types/mlrval_functions_test.go b/go/src/types/mlrval_functions_test.go index fcda75475..a1fbeec13 100644 --- a/go/src/types/mlrval_functions_test.go +++ b/go/src/types/mlrval_functions_test.go @@ -34,9 +34,9 @@ func TestComparctors(t *testing.T) { sabc := MlrvalFromString("abc") sdef := MlrvalFromString("def") - e := MlrvalFromError() + e := *MLRVAL_ERROR - a := MlrvalFromAbsent() + a := *MLRVAL_ABSENT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Within-type lexical comparisons diff --git a/go/src/types/mlrval_json.go b/go/src/types/mlrval_json.go index 7d9ca5189..9c2b2d59b 100644 --- a/go/src/types/mlrval_json.go +++ b/go/src/types/mlrval_json.go @@ -134,8 +134,7 @@ func MlrvalDecodeFromJSON(decoder *json.Decoder) ( delimiter, isDelim := startToken.(json.Delim) if !isDelim { if startToken == nil { - mlrval := MlrvalFromVoid() - return &mlrval, false, nil + return MLRVAL_VOID, false, nil } sval, ok := startToken.(string) @@ -152,8 +151,8 @@ func MlrvalDecodeFromJSON(decoder *json.Decoder) ( nval, ok := startToken.(json.Number) if ok { - mlrval := MlrvalFromInferredType(nval.String()) - return &mlrval, false, nil + mlrval := MlrvalPointerFromInferredType(nval.String()) + return mlrval, false, nil } return nil, false, errors.New( diff --git a/go/src/types/mlrval_new.go b/go/src/types/mlrval_new.go index fe9dcf76d..4815d8be9 100644 --- a/go/src/types/mlrval_new.go +++ b/go/src/types/mlrval_new.go @@ -11,6 +11,178 @@ import ( ) // ---------------------------------------------------------------- +// TODO: comment how these are part of the copy-reduction project. + +var value_MLRVAL_ERROR = mlrvalFromError() +var value_MLRVAL_ABSENT = mlrvalFromAbsent() +var value_MLRVAL_VOID = mlrvalFromVoid() +var value_MLRVAL_TRUE = mlrvalFromTrue() +var value_MLRVAL_FALSE = mlrvalFromFalse() + +var MLRVAL_ERROR = &value_MLRVAL_ERROR +var MLRVAL_ABSENT = &value_MLRVAL_ABSENT +var MLRVAL_VOID = &value_MLRVAL_VOID +var MLRVAL_TRUE = &value_MLRVAL_TRUE +var MLRVAL_FALSE = &value_MLRVAL_FALSE + +// ---------------------------------------------------------------- +func MlrvalPointerFromString(input string) *Mlrval { + if input == "" { + return MLRVAL_VOID + } + var this Mlrval + this.mvtype = MT_STRING + this.printrep = input + this.printrepValid = true + return &this +} + +// xxx comment why two -- one for from parsed user data; other for from math ops +func MlrvalPointerFromIntString(input string) *Mlrval { + ival, ok := lib.TryIntFromString(input) + // xxx comment assummption is input-string already deemed parseable so no error return + lib.InternalCodingErrorIf(!ok) + var this Mlrval + this.mvtype = MT_INT + this.printrep = input + this.printrepValid = true + this.intval = ival + return &this +} + +func MlrvalPointerFromInt(input int) *Mlrval { + var this Mlrval + this.mvtype = MT_INT + this.printrepValid = false + this.intval = input + return &this +} + +// xxx comment why two -- one for from parsed user data; other for from math ops +// xxx comment assummption is input-string already deemed parseable so no error return +func MlrvalPointerFromFloat64String(input string) *Mlrval { + fval, ok := lib.TryFloat64FromString(input) + // xxx comment assummption is input-string already deemed parseable so no error return + lib.InternalCodingErrorIf(!ok) + var this Mlrval + this.mvtype = MT_FLOAT + this.printrep = input + this.printrepValid = true + this.floatval = fval + return &this +} + +func MlrvalPointerFromFloat64(input float64) *Mlrval { + var this Mlrval + this.mvtype = MT_FLOAT + this.printrepValid = false + this.floatval = input + return &this +} + +func MlrvalPointerFromBool(input bool) *Mlrval { + if input == true { + return MLRVAL_TRUE + } else { + return MLRVAL_FALSE + } +} + +func MlrvalPointerFromBoolString(input string) *Mlrval { + if input == "true" { + return MLRVAL_TRUE + } else if input == "false" { + return MLRVAL_FALSE + } else { + lib.InternalCodingErrorIf(true) + return MLRVAL_ERROR // not reached + } +} + +func MlrvalPointerFromInferredType(input string) *Mlrval { + // xxx the parsing has happened so stash it ... + // xxx emphasize the invariant that a non-invalid printrep always + // matches the nval ... + if input == "" { + return MLRVAL_VOID + } + + _, iok := lib.TryIntFromString(input) + if iok { + return MlrvalPointerFromIntString(input) + } + + _, fok := lib.TryFloat64FromString(input) + if fok { + return MlrvalPointerFromFloat64String(input) + } + + _, bok := lib.TryBoolFromBoolString(input) + if bok { + return MlrvalPointerFromBoolString(input) + } + + return MlrvalPointerFromString(input) +} + +func MlrvalPointerFromEmptyMap() *Mlrval { + var this Mlrval + this.mvtype = MT_MAP + this.printrepValid = false + this.mapval = NewMlrmap() + return &this +} + +// ---------------------------------------------------------------- +// Does not copy the data. We can make a SetFromArrayLiteralCopy if needed +// using values.CopyMlrvalArray(). +func MlrvalPointerFromArrayLiteralReference(input []Mlrval) *Mlrval { + var this Mlrval + this.mvtype = MT_ARRAY + this.printrepValid = false + this.arrayval = input + return &this +} + +func MlrvalPointerFromMap(that *Mlrmap) *Mlrval { + this := MlrvalPointerFromEmptyMap() + if that == nil { + // TODO maybe return 2nd-arg error in the API + return MLRVAL_ERROR + } + + for pe := that.Head; pe != nil; pe = pe.Next { + this.mapval.PutCopy(pe.Key, pe.Value) + } + return this +} + +// Like previous but doesn't copy. Only safe when the argument's sole purpose +// is to be passed into here. +func MlrvalPointerFromMapReferenced(that *Mlrmap) *Mlrval { + this := MlrvalPointerFromEmptyMap() + if that == nil { + // xxx maybe return 2nd-arg error in the API + return MLRVAL_ERROR + } + + for pe := that.Head; pe != nil; pe = pe.Next { + this.mapval.PutReference(pe.Key, pe.Value) + } + return this +} + +// TODO: comment not MLRVAL_PENDING constants since this intended to be mutated +// by the JSON parser. +func MlrvalPointerFromPending() *Mlrval { + var this Mlrval + this.mvtype = MT_PENDING + this.printrepValid = false + return &this +} + +// ---------------------------------------------------------------- +// TODO: comment about being designed to be mutated for JSON API. func MlrvalFromPending() Mlrval { return Mlrval{ mvtype: MT_PENDING, @@ -24,7 +196,7 @@ func MlrvalFromPending() Mlrval { } } -func MlrvalFromError() Mlrval { +func mlrvalFromError() Mlrval { return Mlrval{ mvtype: MT_ERROR, printrep: "(error)", // xxx const somewhere @@ -37,7 +209,7 @@ func MlrvalFromError() Mlrval { } } -func MlrvalFromAbsent() Mlrval { +func mlrvalFromAbsent() Mlrval { return Mlrval{ mvtype: MT_ABSENT, printrep: "(absent)", @@ -50,7 +222,7 @@ func MlrvalFromAbsent() Mlrval { } } -func MlrvalFromVoid() Mlrval { +func mlrvalFromVoid() Mlrval { return Mlrval{ mvtype: MT_VOID, printrep: "", @@ -65,7 +237,7 @@ func MlrvalFromVoid() Mlrval { func MlrvalFromString(input string) Mlrval { if input == "" { - return MlrvalFromVoid() + return mlrvalFromVoid() } else { return Mlrval{ mvtype: MT_STRING, @@ -80,23 +252,6 @@ func MlrvalFromString(input string) Mlrval { } } -// xxx comment why two -- one for from parsed user data; other for from math ops -func MlrvalFromIntString(input string) Mlrval { - ival, ok := lib.TryIntFromString(input) - // xxx comment assummption is input-string already deemed parseable so no error return - lib.InternalCodingErrorIf(!ok) - return Mlrval{ - mvtype: MT_INT, - printrep: input, - printrepValid: true, - intval: ival, - floatval: 0.0, - boolval: false, - arrayval: nil, - mapval: nil, - } -} - func MlrvalFromInt(input int) Mlrval { return Mlrval{ mvtype: MT_INT, @@ -110,24 +265,6 @@ func MlrvalFromInt(input int) Mlrval { } } -// xxx comment why two -- one for from parsed user data; other for from math ops -// xxx comment assummption is input-string already deemed parseable so no error return -func MlrvalFromFloat64String(input string) Mlrval { - fval, ok := lib.TryFloat64FromString(input) - // xxx comment assummption is input-string already deemed parseable so no error return - lib.InternalCodingErrorIf(!ok) - return Mlrval{ - mvtype: MT_FLOAT, - printrep: input, - printrepValid: true, - intval: 0, - floatval: fval, - boolval: false, - arrayval: nil, - mapval: nil, - } -} - func MlrvalFromFloat64(input float64) Mlrval { return Mlrval{ mvtype: MT_FLOAT, @@ -141,7 +278,7 @@ func MlrvalFromFloat64(input float64) Mlrval { } } -func MlrvalFromTrue() Mlrval { +func mlrvalFromTrue() Mlrval { return Mlrval{ mvtype: MT_BOOL, printrep: "true", @@ -154,7 +291,7 @@ func MlrvalFromTrue() Mlrval { } } -func MlrvalFromFalse() Mlrval { +func mlrvalFromFalse() Mlrval { return Mlrval{ mvtype: MT_BOOL, printrep: "false", @@ -169,62 +306,24 @@ func MlrvalFromFalse() Mlrval { func MlrvalFromBool(input bool) Mlrval { if input == true { - return MlrvalFromTrue() + return mlrvalFromTrue() } else { - return MlrvalFromFalse() + return mlrvalFromFalse() } } func MlrvalFromBoolString(input string) Mlrval { if input == "true" { - return MlrvalFromTrue() + return mlrvalFromTrue() } else { - return MlrvalFromFalse() + return mlrvalFromFalse() } // else panic } -func MlrvalFromInferredType(input string) Mlrval { - // xxx the parsing has happened so stash it ... - // xxx emphasize the invariant that a non-invalid printrep always - // matches the nval ... - if input == "" { - return MlrvalFromVoid() - } - - _, iok := lib.TryIntFromString(input) - if iok { - return MlrvalFromIntString(input) - } - - _, fok := lib.TryFloat64FromString(input) - if fok { - return MlrvalFromFloat64String(input) - } - - _, bok := lib.TryBoolFromBoolString(input) - if bok { - return MlrvalFromBoolString(input) - } - - return MlrvalFromString(input) -} - // ---------------------------------------------------------------- // Does not copy the data. We can make a MlrvalFromArrayLiteralCopy if needed, // using values.CopyMlrvalArray(). -func MlrvalFromArrayLiteralReference(input []Mlrval) Mlrval { - return Mlrval{ - mvtype: MT_ARRAY, - printrep: "(bug-if-you-see-this-array-type)", - printrepValid: false, - intval: 0, - floatval: 0.0, - boolval: false, - arrayval: input, - mapval: nil, - } -} func MlrvalEmptyArray() Mlrval { return Mlrval{ @@ -297,27 +396,13 @@ func MlrvalEmptyMap() Mlrval { } } -func MlrvalFromMap(that *Mlrmap) Mlrval { - this := MlrvalEmptyMap() - if that == nil { - // xxx maybe return 2nd-arg error in the API - return MlrvalFromError() - } - - for pe := that.Head; pe != nil; pe = pe.Next { - this.mapval.PutCopy(pe.Key, pe.Value) - } - - return this -} - // Like previous but doesn't copy. Only safe when the argument's sole purpose // is to be passed into here. func MlrvalFromMapReferenced(that *Mlrmap) Mlrval { this := MlrvalEmptyMap() if that == nil { // xxx maybe return 2nd-arg error in the API - return MlrvalFromError() + return *MLRVAL_ERROR } for pe := that.Head; pe != nil; pe = pe.Next { diff --git a/go/src/types/mlrval_set.go b/go/src/types/mlrval_set.go deleted file mode 100644 index a23d60f14..000000000 --- a/go/src/types/mlrval_set.go +++ /dev/null @@ -1,174 +0,0 @@ -// ================================================================ -// Constructors -// ================================================================ - -package types - -import ( - "miller/src/lib" -) - -//// ---------------------------------------------------------------- -//func (this *Mlrval) CopyFrom(that *Mlrval) { -// *this = *that -// if this.mvtype == MT_MAP { -// this.mapval = that.mapval.Copy() -// } else if this.mvtype == MT_ARRAY { -// this.arrayval = CopyMlrvalArray(that.arrayval) -// } -//} - -func MlrvalPointerFromString(input string) *Mlrval { - if input == "" { - return MLRVAL_VOID - } - var this Mlrval - this.mvtype = MT_STRING - this.printrep = input - this.printrepValid = true - return &this -} - -// xxx comment why two -- one for from parsed user data; other for from math ops -func MlrvalPointerFromIntString(input string) *Mlrval { - ival, ok := lib.TryIntFromString(input) - // xxx comment assummption is input-string already deemed parseable so no error return - lib.InternalCodingErrorIf(!ok) - var this Mlrval - this.mvtype = MT_INT - this.printrep = input - this.printrepValid = true - this.intval = ival - return &this -} - -func MlrvalPointerFromInt(input int) *Mlrval { - var this Mlrval - this.mvtype = MT_INT - this.printrepValid = false - this.intval = input - return &this -} - -// xxx comment why two -- one for from parsed user data; other for from math ops -// xxx comment assummption is input-string already deemed parseable so no error return -func MlrvalPointerFromFloat64String(input string) *Mlrval { - fval, ok := lib.TryFloat64FromString(input) - // xxx comment assummption is input-string already deemed parseable so no error return - lib.InternalCodingErrorIf(!ok) - var this Mlrval - this.mvtype = MT_FLOAT - this.printrep = input - this.printrepValid = true - this.floatval = fval - return &this -} - -func MlrvalPointerFromFloat64(input float64) *Mlrval { - var this Mlrval - this.mvtype = MT_FLOAT - this.printrepValid = false - this.floatval = input - return &this -} - -func MlrvalPointerFromBool(input bool) *Mlrval { - if input == true { - return MLRVAL_TRUE - } else { - return MLRVAL_FALSE - } -} - -func MlrvalPointerFromBoolString(input string) *Mlrval { - if input == "true" { - return MLRVAL_TRUE - } else if input == "false" { - return MLRVAL_FALSE - } else { - lib.InternalCodingErrorIf(true) - return MLRVAL_ERROR // not reached - } -} - -func MlrvalPointerFromInferredType(input string) *Mlrval { - // xxx the parsing has happened so stash it ... - // xxx emphasize the invariant that a non-invalid printrep always - // matches the nval ... - if input == "" { - return MLRVAL_VOID - } - - _, iok := lib.TryIntFromString(input) - if iok { - return MlrvalPointerFromIntString(input) - } - - _, fok := lib.TryFloat64FromString(input) - if fok { - return MlrvalPointerFromFloat64String(input) - } - - _, bok := lib.TryBoolFromBoolString(input) - if bok { - return MlrvalPointerFromBoolString(input) - } - - return MlrvalPointerFromString(input) -} - -func MlrvalPointerFromEmptyMap() *Mlrval { - var this Mlrval - this.mvtype = MT_MAP - this.printrepValid = false - this.mapval = NewMlrmap() - return &this -} - -// ---------------------------------------------------------------- -// Does not copy the data. We can make a SetFromArrayLiteralCopy if needed -// using values.CopyMlrvalArray(). -func MlrvalPointerFromArrayLiteralReference(input []Mlrval) *Mlrval { - var this Mlrval - this.mvtype = MT_ARRAY - this.printrepValid = false - this.arrayval = input - return &this -} - -func MlrvalPointerFromMap(that *Mlrmap) *Mlrval { - this := MlrvalPointerFromEmptyMap() - if that == nil { - // TODO maybe return 2nd-arg error in the API - return MLRVAL_ERROR - } - - for pe := that.Head; pe != nil; pe = pe.Next { - this.mapval.PutCopy(pe.Key, pe.Value) - } - return this -} - -// Like previous but doesn't copy. Only safe when the argument's sole purpose -// is to be passed into here. -func MlrvalPointerFromMapReferenced(that *Mlrmap) *Mlrval { - this := MlrvalPointerFromEmptyMap() - if that == nil { - // xxx maybe return 2nd-arg error in the API - return MLRVAL_ERROR - } - - for pe := that.Head; pe != nil; pe = pe.Next { - this.mapval.PutReference(pe.Key, pe.Value) - } - return this -} - -// TODO: comment not MLRVAL_PENDING constants since this intended to be mutated -// by the JSON parser. -func MlrvalPointerFromPending() *Mlrval { - var this Mlrval - this.mvtype = MT_PENDING - this.printrepValid = false - return &this -} diff --git a/go/todo.txt b/go/todo.txt index 1dfd6f7a1..faf50ace8 100644 --- a/go/todo.txt +++ b/go/todo.txt @@ -28,6 +28,26 @@ TOP OF LIST: - bonus: return MlrvalSqrt(MlrvalDivide(input1, input2)) - maybe MT_PENDING_MUTABLE -- ? + info: + for i in 100 200 500 1000 2000 5000 10000 20000; do echo $i; justtime GOGC=$i mlr -n put -q + 100 TIME IN SECONDS 21.046 -- GOGC=100 mlr -n put -q -s silent=true -f u/mand.mlr + 200 TIME IN SECONDS 17.233 -- GOGC=200 mlr -n put -q -s silent=true -f u/mand.mlr + 500 TIME IN SECONDS 15.535 -- GOGC=500 mlr -n put -q -s silent=true -f u/mand.mlr + 1000 TIME IN SECONDS 15.125 -- GOGC=1000 mlr -n put -q -s silent=true -f u/mand.mlr + 2000 TIME IN SECONDS 15.428 -- GOGC=2000 mlr -n put -q -s silent=true -f u/mand.mlr + 5000 TIME IN SECONDS 15.083 -- GOGC=5000 mlr -n put -q -s silent=true -f u/mand.mlr + 10000 TIME IN SECONDS 15.175 -- GOGC=10000 mlr -n put -q -s silent=true -f u/mand.mlr + 20000 TIME IN SECONDS 15.419 -- GOGC=20000 mlr -n put -q -s silent=true -f u/mand.mlr + + mlr --cpuprofile cpu.pprof --from ~tmp/big sort -f a -nr x then nothing + GOGC=1000 mlr --cpuprofile cpu.pprof --from /Users/kerl/tmp/huge sort -f a -nr x then nothing + + wc -l ~/tmp/big + 1000000 /Users/kerl/tmp/big + + wc -l ~/tmp/huge + 10000000 /Users/kerl/tmp/huge + * next round of data-copy reduction: o $z = min($x, $y) -- needs to return pointer to x or y o $z = $x + $y -- needs to have space for sum, and return pointer to it @@ -41,12 +61,6 @@ TOP OF LIST: o check for under/over copy at Assign o global *ERROR / *ABSENT / etc - ! GAH!! rethink MlrvalFromX(...) - -g/(output, input.*{$/s/{$/ *Mlrval {/ - -g/(output, input.*{$/s/(output, input/(input/ - ---------------------------------------------------------------- * regexes o finish stats1 -r