From 07924fcf85e4a56757fee86818e849e748e11167 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sun, 16 Apr 2017 17:37:00 -0400 Subject: [PATCH] mapexcept iterate --- c/containers/xvfuncs.c | 40 ++++++++++++++++++++++++++++++++++++++++ c/containers/xvfuncs.h | 3 +++ c/dsl/function_manager.c | 7 ++++++- c/oo | 7 +------ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/c/containers/xvfuncs.c b/c/containers/xvfuncs.c index 645bda4c5..c46bc1e05 100644 --- a/c/containers/xvfuncs.c +++ b/c/containers/xvfuncs.c @@ -158,6 +158,46 @@ boxed_xval_t variadic_mapdiff_xfunc(boxed_xval_t* pbxvals, int nxvals) { return box_ephemeral_xval(diff); } +// ---------------------------------------------------------------- +boxed_xval_t variadic_mapexcept_xfunc( + boxed_xval_t* pbxvals, + int nxvals) +{ + mlhmmv_xvalue_t except = mlhmmv_xvalue_alloc_empty_map(); + if (nxvals == 0) { + return box_ephemeral_xval(except); + } + // xxx to-do optmization: transfer arg 1 if it's ephemeral + + // xxx methodize + int i = 0; + if (!pbxvals[i].xval.is_terminal) { + mlhmmv_level_t* plevel = pbxvals[i].xval.pnext_level; + for (mlhmmv_level_entry_t* pe = plevel->phead; pe != NULL; pe = pe->pnext) { + // xxx do refs/copies correctly + mlhmmv_xvalue_t xval_copy = mlhmmv_xvalue_copy(&pe->level_xvalue); + sllmve_t e = (sllmve_t) { .value = pe->level_key, .free_flags = 0, .pnext = NULL }; + mlhmmv_level_put_xvalue(except.pnext_level, &e, &xval_copy); + } + if (pbxvals[i].is_ephemeral) + mlhmmv_xvalue_free(&pbxvals[i].xval); + } + + for (i = 1; i < nxvals; i++) { + if (!pbxvals[i].xval.is_terminal) { + mlhmmv_level_t* plevel = pbxvals[i].xval.pnext_level; + for (mlhmmv_level_entry_t* pe = plevel->phead; pe != NULL; pe = pe->pnext) { + sllmve_t e = (sllmve_t) { .value = pe->level_key, .free_flags = 0, .pnext = NULL }; + mlhmmv_level_remove(except.pnext_level, &e); + } + } + if (pbxvals[i].is_ephemeral) + mlhmmv_xvalue_free(&pbxvals[i].xval); + } + + return box_ephemeral_xval(except); +} + // ---------------------------------------------------------------- // Precondition: the caller has ensured that both arguments are string-valued terminals. boxed_xval_t m_ss_splitnv_xfunc(boxed_xval_t* pstringval, boxed_xval_t* psepval) { diff --git a/c/containers/xvfuncs.h b/c/containers/xvfuncs.h index 0f5976d34..a4aa5716b 100644 --- a/c/containers/xvfuncs.h +++ b/c/containers/xvfuncs.h @@ -312,6 +312,9 @@ boxed_xval_t variadic_mapsum_xfunc( boxed_xval_t variadic_mapdiff_xfunc( boxed_xval_t* pbxvals, int nxvals); +boxed_xval_t variadic_mapexcept_xfunc( + boxed_xval_t* pbxvals, int nxvals); + boxed_xval_t m_ss_splitnv_xfunc( boxed_xval_t* pstringval, boxed_xval_t* psepval); diff --git a/c/dsl/function_manager.c b/c/dsl/function_manager.c index 5b0fc1c9f..3f1c10eeb 100644 --- a/c/dsl/function_manager.c +++ b/c/dsl/function_manager.c @@ -391,8 +391,10 @@ static function_lookup_t FUNCTION_LOOKUP_TABLE[] = { {FUNC_CLASS_MAPS, "length", 1,0, "Counts number of top-level entries in hashmap. Scalars have length 1."}, {FUNC_CLASS_MAPS, "mapdiff", 0,1, "With 0 args, returns empty map. With 1 arg, returns copy of arg.\n" "With 2 or more, returns copy of arg 1 with all keys from any of remaining argument maps removed."}, + {FUNC_CLASS_MAPS, "mapexcept", 0,1, "With 1 args, returns argument map. With >= 2 args, returns a map with\n" + "keys from remaining arguments unset. E.g. 'mapexcept({1:2,3:4,5:6}, 1, 5, 7)' is '{3:4}'."}, {FUNC_CLASS_MAPS, "mapsum", 0,1, "With 0 args, returns empty map. With >= 1 arg, returns a map with\n" - "key-value pairs from all arguments. Rightmost collisions win, e.g. 'mapsum({1:2,3,4},{1:5})' is '{1:5,3:4}'."}, + "key-value pairs from all arguments. Rightmost collisions win, e.g. 'mapsum({1:2,3:4},{1:5})' is '{1:5,3:4}'."}, {FUNC_CLASS_MAPS, "splitkv", 3,0, "Splits string by separators into map with type inference.\n" "E.g. 'splitkv(\"a=1,b=2,c=3\", \"=\", \",\")' gives '{\"a\" : 1, \"b\" : 2, \"c\" : 3}'."}, {FUNC_CLASS_MAPS, "splitkvx", 3,0, "Splits string by separators into map without type inference (keys and\n" @@ -1280,6 +1282,9 @@ static rxval_evaluator_t* fmgr_alloc_xevaluator_from_variadic_func_name( } else if (streq(function_name, "mapdiff")) { return rxval_evaluator_alloc_from_variadic_func(variadic_mapdiff_xfunc, parg_nodes, pfmgr, type_inferencing, context_flags); + } else if (streq(function_name, "mapexcept")) { + return rxval_evaluator_alloc_from_variadic_func(variadic_mapexcept_xfunc, parg_nodes, + pfmgr, type_inferencing, context_flags); } else { return NULL; } diff --git a/c/oo b/c/oo index c219b8190..b3037ec67 100755 --- a/c/oo +++ b/c/oo @@ -39,9 +39,4 @@ vee= # ---------------------------------------------------------------- announce -run_mlr cat $indir/joina.dkvp -run_mlr cat $indir/joinb.dkvp - -run_mlr join -l l -r r -j j -f $indir/joina.dkvp $indir/joinb.dkvp -run_mlr join -l l -j r -f $indir/joina.dkvp $indir/joinb.dkvp -run_mlr join -r r -j l -f $indir/joina.dkvp $indir/joinb.dkvp +run_mlr --from $indir/abixy put 'dump mapexcept($*, "a")'