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

Fix infinite loop bug in 2-sided context #1219

Merged
merged 1 commit into from
Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cpp/perspective/src/cpp/gnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ t_gnode::_process_mask_existed_rows(t_process_state& process_state) {
t_column* pkey_col =
process_state.m_flattened_data_table->get_column("psp_pkey").get();

process_state.m_added_offset.reserve(flattened_num_rows);
process_state.m_prev_pkey_eq_vec.reserve(flattened_num_rows);
process_state.m_added_offset.resize(flattened_num_rows);
process_state.m_prev_pkey_eq_vec.resize(flattened_num_rows);

t_mask mask(flattened_num_rows);
t_uindex added_count = 0;
Expand All @@ -208,6 +208,7 @@ t_gnode::_process_mask_existed_rows(t_process_state& process_state) {
std::uint8_t op_ = process_state.m_op_base[idx];
t_op op = static_cast<t_op>(op_);

PSP_VERBOSE_ASSERT(idx < process_state.m_lookup.size(), "process_state.m_lookup[idx] out of bounds");
bool row_pre_existed = process_state.m_lookup[idx].m_exists;
process_state.m_prev_pkey_eq_vec[idx] = pkey == prev_pkey;

Expand Down
2 changes: 1 addition & 1 deletion cpp/perspective/src/cpp/sparse_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ t_stree::update_shape_from_static(const t_dtree_ctx& ctx) {
auto root_iter = m_nodes->get<by_idx>().find(0);
auto root_node = *root_iter;
t_index root_nstrands = *(scount->get_nth<t_index>(0)) + root_node.m_nstrands;
root_node.set_nstrands(root_nstrands);
root_node.set_nstrands(std::max(root_nstrands, (t_index)1));
m_nodes->get<by_idx>().replace(root_iter, root_node);

t_tree_unify_rec unif_rec(0, 0, 0, root_nstrands);
Expand Down
61 changes: 61 additions & 0 deletions python/perspective/perspective/tests/table/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -1261,3 +1261,64 @@ def test_view_num_hidden_cols(self):
tbl = Table(data)
view = tbl.view(columns=["a"], sort=[["b", "desc"]])
assert view._num_hidden_cols() == 1

def test_view_context_two_update_clears_column_regression(self, util):
"""Tests that, when a 2-sided View() is updated to a state where one of
the column groups is empty, an infinite loop is not encountered.
"""
data = [
{"a": "a", "b": 1, "c": 1.5, "i": 0},
{"a": "a", "b": 2, "c": 2.5, "i": 1},
{"a": "a", "b": 3, "c": 3.5, "i": 2},
{"a": "b", "b": 1, "c": 4.5, "i": 3},
{"a": "b", "b": 2, "c": 5.5, "i": 4},
{"a": "b", "b": 3, "c": 6.5, "i": 5},
]

tbl = Table(data, index="i")
view = tbl.view(
row_pivots=["b"],
column_pivots=["a"],
columns=["c"],
filter=[["c", ">", 0]],
sort=[["c", "asc"], ["a", "col asc"]],
)

assert view.to_records() == [
{'__ROW_PATH__': [], 'a|c': 7.5, 'b|c': 16.5},
{'__ROW_PATH__': [1], 'a|c': 1.5, 'b|c': 4.5},
{'__ROW_PATH__': [2], 'a|c': 2.5, 'b|c': 5.5},
{'__ROW_PATH__': [3], 'a|c': 3.5, 'b|c': 6.5}
]

tbl.update(
[
{"c": -1, "i": 0},
{"c": -1, "i": 1},
{"c": -1, "i": 2},
]
)

assert view.to_records() == [
{"__ROW_PATH__": [], "b|c": 16.5},
{"__ROW_PATH__": [1], "b|c": 4.5},
{"__ROW_PATH__": [2], "b|c": 5.5},
{"__ROW_PATH__": [3], "b|c": 6.5},
]

tbl.update(
[
{"a": "a", "b": 1, "c": 1.5, "i": 6},
{"a": "a", "b": 2, "c": 2.5, "i": 7},
{"a": "a", "b": 3, "c": 3.5, "i": 8},
]
)

assert view.to_records() == [
{'__ROW_PATH__': [], 'a|c': 7.5, 'b|c': 16.5},
{'__ROW_PATH__': [1], 'a|c': 1.5, 'b|c': 4.5},
{'__ROW_PATH__': [2], 'a|c': 2.5, 'b|c': 5.5},
{'__ROW_PATH__': [3], 'a|c': 3.5, 'b|c': 6.5}
]

assert tbl.size() == 9