From e479df0090adcbe00ccdd9cc054635a09484c7c0 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Wed, 2 Mar 2016 22:05:58 -0500 Subject: [PATCH] unset iterate: not yet feature-complete --- c/containers/mlhmmv.c | 15 +++++++++++++-- c/containers/mlhmmv.h | 33 +++++++++++++++++++++++++++++---- c/reg_test/input/Makefile.am | 2 ++ c/reg_test/input/unset1.dkvp | 1 + c/reg_test/input/unset4.dkvp | 4 ++++ c/reg_test/run | 20 ++++++++++++++++++++ 6 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 c/reg_test/input/unset1.dkvp create mode 100644 c/reg_test/input/unset4.dkvp diff --git a/c/containers/mlhmmv.c b/c/containers/mlhmmv.c index 35508d277..bba1e1bf6 100644 --- a/c/containers/mlhmmv.c +++ b/c/containers/mlhmmv.c @@ -30,6 +30,8 @@ static void mlhmmv_level_put_no_enlarge(mlhmmv_level_t* plevel, sllmve_t* prest_ static void mlhmmv_level_enlarge(mlhmmv_level_t* plevel); static void mlhmmv_level_move(mlhmmv_level_t* plevel, mv_t* plevel_key, mlhmmv_level_value_t* plevel_value); +static mlhmmv_level_entry_t* mlhmmv_get_next_level_entry(mlhmmv_level_t* pmap, mv_t* plevel_key, int* pindex); + static void mlhmmv_to_lrecs_aux(mlhmmv_level_t* plevel, mv_t* pfirstname, sllmve_t* prestnames, lrec_t* ptemplate, sllv_t* poutrecs); static void mlhmmv_to_lrecs_aux_flatten(mlhmmv_level_t* plevel, char* prefix, lrec_t* ptemplate, sllv_t* poutrecs); @@ -314,7 +316,7 @@ mv_t* mlhmmv_get(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror) { return &plevel_entry->level_value.u.mlrval; } -mlhmmv_level_entry_t* mlhmmv_get_next_level_entry(mlhmmv_level_t* plevel, mv_t* plevel_key, int* pindex) { +static mlhmmv_level_entry_t* mlhmmv_get_next_level_entry(mlhmmv_level_t* plevel, mv_t* plevel_key, int* pindex) { int ideal_index = 0; int index = mlhmmv_level_find_index_for_key(plevel, plevel_key, &ideal_index); mlhmmv_level_entry_t* pentry = &plevel->entries[index]; @@ -374,8 +376,13 @@ static void mlhmmv_remove_aux(mlhmmv_level_t* plevel, sllmve_t* prestkeys, int* return; int descendant_emptied = FALSE; mlhmmv_remove_aux(pentry->level_value.u.pnext_level, prestkeys->pnext, &descendant_emptied, depth+1); - if (descendant_emptied) { + // If the recursive call emptied the next-level slot, remove it from our level as well. This may continue all + // the way back up. Example: the map is '{"a":{"b":{"c":4}}}' and we're asked to remove keylist ["a", "b", "c"]. + // The recursive call to the terminal will leave '{"a":{"b":{}}}' -- note the '{}'. Then we remove + // that to leave '{"a":{}}'. Since this leaves another '{}', passing emptied==TRUE back to our caller + // leaves empty top-level map '{}'. + if (descendant_emptied) { plevel->num_occupied--; plevel->num_freed++; plevel->states[index] = DELETED; @@ -409,6 +416,10 @@ static void mlhmmv_remove_aux(mlhmmv_level_t* plevel, sllmve_t* prestkeys, int* exit(1); } + // xxx + // echo 'a=1,b=2,x=9' | mlr put -q @s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u[1][2]; dump} + // still not right. + pentry->ideal_index = -1; plevel->states[index] = DELETED; diff --git a/c/containers/mlhmmv.h b/c/containers/mlhmmv.h index 9c3344ffc..54a803990 100644 --- a/c/containers/mlhmmv.h +++ b/c/containers/mlhmmv.h @@ -78,12 +78,37 @@ void mlhmmv_put(mlhmmv_t* pmap, sllmv_t* pmvkeys, mv_t* pterminal_value); // The caller shouldn't free it, or modify it. mv_t* mlhmmv_get(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror); +// Unset value/submap from a specified level onward. pmvkeys must have length at least 1, i.e. +// the oosvar name. Example: +// { +// "a" : { +// "x" : 1, +// "y" : 2 +// }, +// "b" : { +// "x" : 3, +// "y" : 4 +// }, +// } +// with pmvkeys = ["a"] leaves +// { +// "b" : { +// "x" : 3, +// "y" : 4 +// }, +// } +// but with pmvkeys = ["a", "y"] leaves +// { +// "a" : { +// "x" : 1 +// }, +// "b" : { +// "x" : 3, +// "y" : 4 +// }, +// } void mlhmmv_remove(mlhmmv_t* pmap, sllmv_t* pmvkeys); -// Made public for the oosvar-emitter. -// xxx make private again after reorg -mlhmmv_level_entry_t* mlhmmv_get_next_level_entry(mlhmmv_level_t* pmap, mv_t* plevel_key, int* pindex); - // xxx comment: // * names // * these allocate unbacked lrecs diff --git a/c/reg_test/input/Makefile.am b/c/reg_test/input/Makefile.am index 3dbffb14d..cd92427a6 100644 --- a/c/reg_test/input/Makefile.am +++ b/c/reg_test/input/Makefile.am @@ -130,6 +130,8 @@ EXTRA_DIST= \ truncated.pprint \ truncated.xtab \ truncated.xtab-crlf \ + unset1.dkvp \ + unset4.dkvp \ utf8-1.csv \ utf8-2.csv \ utf8-align.dkvp \ diff --git a/c/reg_test/input/unset1.dkvp b/c/reg_test/input/unset1.dkvp new file mode 100644 index 000000000..170643ec4 --- /dev/null +++ b/c/reg_test/input/unset1.dkvp @@ -0,0 +1 @@ +a=1,b=2=,x=9 diff --git a/c/reg_test/input/unset4.dkvp b/c/reg_test/input/unset4.dkvp new file mode 100644 index 000000000..64dbe4121 --- /dev/null +++ b/c/reg_test/input/unset4.dkvp @@ -0,0 +1,4 @@ +a=1,b=2=,x=9 +a=1,b=3=,x=9 +a=4,b=5=,x=9 +a=4,b=6=,x=9 diff --git a/c/reg_test/run b/c/reg_test/run index 42e182cbc..79bfe2073 100755 --- a/c/reg_test/run +++ b/c/reg_test/run @@ -1239,6 +1239,26 @@ run_mlr put '@y[$a]=$y; end{dump}' $indir/abixy run_mlr stats1 -a sum -f y -g a $indir/abixy run_mlr put '@y_sum[$a] = $y; end{dump}' $indir/abixy + +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @s ; dump}' $indir/unset1.dkvp + +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @t ; dump}' $indir/unset1.dkvp +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @t[1] ; dump}' $indir/unset1.dkvp + +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u ; dump}' $indir/unset1.dkvp +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u[1] ; dump}' $indir/unset1.dkvp +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u[1][2]; dump}' $indir/unset1.dkvp + + +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @s ; dump}' $indir/unset4.dkvp + +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @t ; dump}' $indir/unset4.dkvp +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @t[1] ; dump}' $indir/unset4.dkvp + +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u ; dump}' $indir/unset4.dkvp +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u[1] ; dump}' $indir/unset4.dkvp +run_mlr put -q '@s=$x; @t[$a]=$x; @u[$a][$b]=$x; end{dump; unset @u[1][2]; dump}' $indir/unset4.dkvp + # ---------------------------------------------------------------- announce DSL PATTERN-ACTION BLOCKS