diff --git a/cpp/perspective/CMakeLists.txt b/cpp/perspective/CMakeLists.txt index 95bfaab2d4..ba6bebb83d 100644 --- a/cpp/perspective/CMakeLists.txt +++ b/cpp/perspective/CMakeLists.txt @@ -285,6 +285,7 @@ set (SOURCE_FILES src/cpp/context_two.cpp src/cpp/context_zero.cpp src/cpp/custom_column.cpp + src/cpp/data_slice.cpp src/cpp/data.cpp src/cpp/date.cpp src/cpp/dense_nodes.cpp @@ -294,6 +295,7 @@ set (SOURCE_FILES src/cpp/extract_aggregate.cpp src/cpp/filter.cpp src/cpp/flat_traversal.cpp + src/cpp/get_data_extents.cpp src/cpp/gnode.cpp src/cpp/gnode_state.cpp src/cpp/histogram.cpp diff --git a/cpp/perspective/src/cpp/config.cpp b/cpp/perspective/src/cpp/config.cpp index 0c29c3f210..828688b8e5 100644 --- a/cpp/perspective/src/cpp/config.cpp +++ b/cpp/perspective/src/cpp/config.cpp @@ -142,9 +142,11 @@ t_config::t_config(const std::vector& row_pivots, t_config::t_config(const std::vector& row_pivots, const std::vector& col_pivots, const std::vector& aggregates, - const t_totals totals, t_filter_op combiner, const std::vector& fterms) + const t_totals totals, t_filter_op combiner, const std::vector& fterms, + bool column_only) : m_row_pivots(row_pivots) , m_col_pivots(col_pivots) + , m_column_only(column_only) , m_aggregates(aggregates) , m_totals(totals) , m_combiner(combiner) @@ -204,8 +206,9 @@ t_config::t_config(const std::vector& row_pivots, const t_aggspec& t_config::t_config(const std::vector& row_pivots, const std::vector& aggregates, t_filter_op combiner, - const std::vector& fterms) + const std::vector& fterms, bool column_only) : m_row_pivots(row_pivots) + , m_column_only(column_only) , m_aggregates(aggregates) , m_totals(TOTALS_BEFORE) , m_combiner(combiner) @@ -396,7 +399,7 @@ t_config::get_num_cpivots() const { } bool -t_config::get_column_only() const { +t_config::is_column_only() const { return m_column_only; } diff --git a/cpp/perspective/src/cpp/context_grouped_pkey.cpp b/cpp/perspective/src/cpp/context_grouped_pkey.cpp index 204007f75e..b7788d9521 100644 --- a/cpp/perspective/src/cpp/context_grouped_pkey.cpp +++ b/cpp/perspective/src/cpp/context_grouped_pkey.cpp @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include #include @@ -113,11 +113,13 @@ t_ctx_grouped_pkey::get_data( t_index start_row, t_index end_row, t_index start_col, t_index end_col) const { PSP_TRACE_SENTINEL(); PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); - auto ext = sanitize_get_data_extents(*this, start_row, end_row, start_col, end_col); + t_uindex ctx_nrows = get_row_count(); + t_uindex ncols = get_column_count(); + auto ext + = sanitize_get_data_extents(ctx_nrows, ncols, start_row, end_row, start_col, end_col); t_index nrows = ext.m_erow - ext.m_srow; t_index stride = ext.m_ecol - ext.m_scol; - t_uindex ncols = get_column_count(); std::vector values(nrows * stride); std::vector tmpvalues(nrows * ncols); diff --git a/cpp/perspective/src/cpp/context_one.cpp b/cpp/perspective/src/cpp/context_one.cpp index fa882bb46e..e0b37442f7 100644 --- a/cpp/perspective/src/cpp/context_one.cpp +++ b/cpp/perspective/src/cpp/context_one.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -103,12 +103,14 @@ std::vector t_ctx1::get_data(t_index start_row, t_index end_row, t_index start_col, t_index end_col) const { PSP_TRACE_SENTINEL(); PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); - auto ext = sanitize_get_data_extents(*this, start_row, end_row, start_col, end_col); + t_uindex ctx_nrows = get_row_count(); + t_uindex ncols = get_column_count(); + auto ext + = sanitize_get_data_extents(ctx_nrows, ncols, start_row, end_row, start_col, end_col); t_index nrows = ext.m_erow - ext.m_srow; t_index stride = ext.m_ecol - ext.m_scol; - t_uindex ncols = get_column_count(); std::vector tmpvalues(nrows * ncols); std::vector values(nrows * stride); diff --git a/cpp/perspective/src/cpp/context_two.cpp b/cpp/perspective/src/cpp/context_two.cpp index 47a0753b71..2f73233b4c 100644 --- a/cpp/perspective/src/cpp/context_two.cpp +++ b/cpp/perspective/src/cpp/context_two.cpp @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include #include @@ -194,7 +194,10 @@ t_ctx2::get_ctraversal_indices() const { std::vector t_ctx2::get_data(t_index start_row, t_index end_row, t_index start_col, t_index end_col) const { - auto ext = sanitize_get_data_extents(*this, start_row, end_row, start_col, end_col); + t_uindex ctx_nrows = get_row_count(); + t_uindex ctx_ncols = get_column_count(); + auto ext = sanitize_get_data_extents( + ctx_nrows, ctx_ncols, start_row, end_row, start_col, end_col); std::vector> cells; for (t_index ridx = ext.m_srow; ridx < ext.m_erow; ++ridx) { @@ -615,7 +618,10 @@ t_ctx2::get_step_delta(t_index bidx, t_index eidx) { rval.columns_changed = true; std::vector& updvec = rval.cells; - auto ext = sanitize_get_data_extents(*this, start_row, end_row, start_col, end_col); + t_uindex ctx_nrows = get_row_count(); + t_uindex ctx_ncols = get_column_count(); + auto ext = sanitize_get_data_extents( + ctx_nrows, ctx_ncols, start_row, end_row, start_col, end_col); std::vector> cells; diff --git a/cpp/perspective/src/cpp/context_zero.cpp b/cpp/perspective/src/cpp/context_zero.cpp index 98eebdd995..02f5eece9b 100644 --- a/cpp/perspective/src/cpp/context_zero.cpp +++ b/cpp/perspective/src/cpp/context_zero.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -98,8 +98,10 @@ t_ctx0::get_column_count() const { std::vector t_ctx0::get_data(t_index start_row, t_index end_row, t_index start_col, t_index end_col) const { - - auto ext = sanitize_get_data_extents(*this, start_row, end_row, start_col, end_col); + t_uindex ctx_nrows = get_row_count(); + t_uindex ctx_ncols = get_column_count(); + auto ext = sanitize_get_data_extents( + ctx_nrows, ctx_ncols, start_row, end_row, start_col, end_col); t_index nrows = ext.m_erow - ext.m_srow; t_index stride = ext.m_ecol - ext.m_scol; diff --git a/cpp/perspective/src/cpp/data_slice.cpp b/cpp/perspective/src/cpp/data_slice.cpp new file mode 100644 index 0000000000..e0bbc641a0 --- /dev/null +++ b/cpp/perspective/src/cpp/data_slice.cpp @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Copyright (c) 2019, the Perspective Authors. + * + * This file is part of the Perspective library, distributed under the terms of + * the Apache License 2.0. The full license can be found in the LICENSE file. + * + */ + +#include +#include + +namespace perspective { + +template +t_data_slice::t_data_slice(std::shared_ptr ctx, t_uindex start_row, + t_uindex end_row, t_uindex start_col, t_uindex end_col, + std::shared_ptr> slice, + std::shared_ptr> column_names) + : m_ctx(ctx) + , m_start_row(start_row) + , m_end_row(end_row) + , m_start_col(start_col) + , m_end_col(end_col) + , m_slice(slice) + , m_column_names(column_names) {} + +template +t_data_slice::t_data_slice(std::shared_ptr ctx, t_uindex start_row, + t_uindex end_row, t_uindex start_col, t_uindex end_col, + std::shared_ptr> slice, + std::shared_ptr> column_names, + std::shared_ptr> column_indices) + : m_ctx(ctx) + , m_start_row(start_row) + , m_end_row(end_row) + , m_start_col(start_col) + , m_end_col(end_col) + , m_slice(slice) + , m_column_names(column_names) + , m_column_indices(column_indices) {} + +template +t_data_slice::~t_data_slice() {} + +/** + * @brief Returns the t_tscalar at the declared indices in the data slice, + * or an invalid t_tscalar if the indices should be skipped. + * + * @param ridx row index into the slice + * @param cidx column index into the slice + * + * @return t_tscalar a valid scalar containing the underlying data, or a new + * t_tscalar initialized with an invalid flag. + */ +template <> +t_tscalar +t_data_slice::get(t_uindex ridx, t_uindex col) const { + t_tscalar rv; + rv.clear(); + return rv; +} + +template <> +t_tscalar +t_data_slice::get(t_uindex ridx, t_uindex cidx) const { + t_tscalar rv; + rv.clear(); + return rv; +} + +template <> +t_tscalar +t_data_slice::get(t_uindex ridx, t_uindex cidx) const { + t_tscalar rv; + rv.clear(); + return rv; +} + +template <> +std::vector +t_data_slice::get_row_path(t_uindex idx) const { + return std::vector(); +} + +template +std::vector +t_data_slice::get_row_path(t_uindex idx) const { + return m_ctx->unity_get_row_path(idx); +} + +// Getters +template +std::shared_ptr +t_data_slice::get_context() const { + return m_ctx; +} + +template +std::shared_ptr> +t_data_slice::get_slice() const { + return m_slice; +} + +template +std::shared_ptr> +t_data_slice::get_column_names() const { + return m_column_names; +} + +template +std::shared_ptr> +t_data_slice::get_column_indices() const { + return m_column_indices; +} + +template +bool +t_data_slice::is_column_only() const { + auto config = m_ctx->get_config(); + return config.is_column_only(); +} + +template <> +bool +t_data_slice::is_column_only() const { + return false; +} + +template +t_get_data_extents +t_data_slice::get_data_extents() const { + auto nrows = m_ctx->get_row_count(); + auto ncols = m_ctx->get_column_count(); + t_get_data_extents ext = sanitize_get_data_extents( + nrows, ncols, m_start_row, m_end_row, m_start_col, m_end_col); + return ext; +} + +// Explicitly instantiate data slice for each context +template class t_data_slice; +template class t_data_slice; +template class t_data_slice; +} // end namespace perspective diff --git a/cpp/perspective/src/cpp/emscripten.cpp b/cpp/perspective/src/cpp/emscripten.cpp index dda7035d2c..d1f03ef1b9 100644 --- a/cpp/perspective/src/cpp/emscripten.cpp +++ b/cpp/perspective/src/cpp/emscripten.cpp @@ -1662,7 +1662,7 @@ namespace binding { auto schema = gnode->get_tblschema(); t_config view_config = make_view_config(schema, separator, date_parser, config); - bool column_only = view_config.get_column_only(); + bool column_only = view_config.is_column_only(); auto aggregates = view_config.get_aggregates(); auto row_pivots = view_config.get_row_pivots(); auto filter_op = view_config.get_combiner(); @@ -1690,7 +1690,7 @@ namespace binding { auto schema = gnode->get_tblschema(); t_config view_config = make_view_config(schema, separator, date_parser, config); - bool column_only = view_config.get_column_only(); + bool column_only = view_config.is_column_only(); auto column_names = view_config.get_column_names(); auto row_pivots = view_config.get_row_pivots(); auto column_pivots = view_config.get_column_pivots(); @@ -1717,7 +1717,8 @@ namespace binding { } auto ctx = make_context_two(schema, row_pivots, column_pivots, filter_op, filters, - aggregates, sorts, col_sorts, rpivot_depth, cpivot_depth, pool, gnode, name); + aggregates, sorts, col_sorts, rpivot_depth, cpivot_depth, column_only, pool, gnode, + name); auto view_ptr = std::make_shared>(pool, ctx, gnode, name, separator, view_config); @@ -1765,7 +1766,7 @@ namespace binding { std::vector filters, std::vector aggregates, std::vector sorts, std::int32_t pivot_depth, bool column_only, t_pool* pool, std::shared_ptr gnode, std::string name) { - auto cfg = t_config(pivots, aggregates, combiner, filters); + auto cfg = t_config(pivots, aggregates, combiner, filters, column_only); auto ctx1 = std::make_shared(schema, cfg); ctx1->init(); @@ -1798,10 +1799,11 @@ namespace binding { std::vector cpivots, t_filter_op combiner, std::vector filters, std::vector aggregates, std::vector sorts, std::vector col_sorts, std::int32_t rpivot_depth, std::int32_t cpivot_depth, - t_pool* pool, std::shared_ptr gnode, std::string name) { + bool column_only, t_pool* pool, std::shared_ptr gnode, std::string name) { t_totals total = sorts.size() > 0 ? TOTALS_BEFORE : TOTALS_HIDDEN; - auto cfg = t_config(rpivots, cpivots, aggregates, total, combiner, filters); + auto cfg + = t_config(rpivots, cpivots, aggregates, total, combiner, filters, column_only); auto ctx2 = std::make_shared(schema, cfg); ctx2->init(); @@ -1831,6 +1833,19 @@ namespace binding { return ctx2; } + /****************************************************************************** + * + * Data serialization + */ + + /** + * @brief Get a slice of data for a single column, serialized to val. + * + * @tparam + * @param table + * @param colname + * @return val + */ template <> val get_column_data(std::shared_ptr table, std::string colname) { @@ -1843,58 +1858,72 @@ namespace binding { } /** - * - * - * Params - * ------ - * - * - * Returns - * ------- - * + * @brief Get a slice of data foe each column from the underlying view, + * serialized to val. + * + * @tparam CTX_T + * @param view + * @param start_row + * @param end_row + * @param start_col + * @param end_col + * @return val */ - template + template val - get_data(T ctx, std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, - std::uint32_t end_col) { - auto slice = ctx->get_data(start_row, end_row, start_col, end_col); + get_data(std::shared_ptr> view, std::uint32_t start_row, std::uint32_t end_row, + std::uint32_t start_col, std::uint32_t end_col) { val arr = val::array(); - for (auto idx = 0; idx < slice.size(); ++idx) { - arr.set(idx, scalar_to_val(slice[idx])); + auto data_slice = view->get_data(start_row, end_row, start_col, end_col); + auto slice = data_slice.get_slice(); + for (auto idx = 0; idx < slice->size(); ++idx) { + arr.set(idx, scalar_to_val(slice->at(idx))); } return arr; } + /** + * @brief Get a slice of data from the underlying view, serlializing to val + * and, for sorted views, ignoring the sort headers which aren't part of the + * underlying data. + * + * @param view + * @param start_row + * @param end_row + * @param start_col + * @param end_col + * @return val + */ template <> val - get_data_two_skip_headers(std::shared_ptr ctx, std::uint32_t depth, - std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, - std::uint32_t end_col) { - auto col_length = ctx->unity_get_column_count(); - std::vector col_nums; - col_nums.push_back(0); - for (t_uindex i = 0; i < col_length; ++i) { - if (ctx->unity_get_column_path(i + 1).size() == depth) { - col_nums.push_back(i + 1); - } - } - col_nums = std::vector(col_nums.begin() + start_col, - col_nums.begin() + std::min(end_col, (std::uint32_t)col_nums.size())); - auto slice = ctx->get_data(start_row, end_row, col_nums.front(), col_nums.back() + 1); + get_data(std::shared_ptr> view, std::uint32_t start_row, std::uint32_t end_row, + std::uint32_t start_col, std::uint32_t end_col) { val arr = val::array(); - t_uindex i = 0; - auto iter = slice.begin(); - while (iter != slice.end()) { - t_uindex prev = col_nums.front(); - for (auto idx = col_nums.begin(); idx != col_nums.end(); idx++, i++) { - t_uindex col_num = *idx; - iter += col_num - prev; - prev = col_num; - arr.set(i, scalar_to_val(*iter)); + auto data_slice = view->get_data(start_row, end_row, start_col, end_col); + auto slice = data_slice.get_slice(); + auto column_indices = data_slice.get_column_indices(); + + if (column_indices->size() > 0) { + t_uindex i = 0; + auto iter = slice->begin(); + while (iter != slice->end()) { + t_uindex prev = column_indices->front(); + for (auto idx = column_indices->begin(); idx != column_indices->end(); + idx++, i++) { + t_uindex col_num = *idx; + iter += col_num - prev; + prev = col_num; + arr.set(i, scalar_to_val(*iter)); + } + if (iter != slice->end()) + iter++; + } + } else { + for (auto idx = 0; idx < slice->size(); ++idx) { + arr.set(idx, scalar_to_val(slice->at(idx))); } - if (iter != slice.end()) - iter++; } + return arr; } @@ -2036,6 +2065,13 @@ EMSCRIPTEN_BINDINGS(perspective) { .function("reset", &t_gnode::reset) .function("get_table", &t_gnode::get_table, allow_raw_pointers()); + /****************************************************************************** + * + * t_data_slice + */ + class_>("t_data_slice_ctx0"); + class_>("t_data_slice_ctx1"); + class_>("t_data_slice_ctx2"); /****************************************************************************** * * t_ctx0 @@ -2151,10 +2187,9 @@ EMSCRIPTEN_BINDINGS(perspective) { function("clone_gnode_table", &clone_gnode_table, allow_raw_pointers()); function("scalar_vec_to_val", &scalar_vec_to_val); function("table_add_computed_column", &table_add_computed_column); - function("get_data_zero", &get_data>); - function("get_data_one", &get_data>); - function("get_data_two", &get_data>); - function("get_data_two_skip_headers", &get_data_two_skip_headers); + function("get_data_zero", &get_data); + function("get_data_one", &get_data); + function("get_data_two", &get_data); function("col_to_js_typed_array_zero", &col_to_js_typed_array); function("col_to_js_typed_array_one", &col_to_js_typed_array); function("col_to_js_typed_array_two", &col_to_js_typed_array); diff --git a/cpp/perspective/src/include/perspective/context_common.h b/cpp/perspective/src/cpp/get_data_extents.cpp similarity index 69% rename from cpp/perspective/src/include/perspective/context_common.h rename to cpp/perspective/src/cpp/get_data_extents.cpp index f5210c6a80..7a5a4a5e0b 100644 --- a/cpp/perspective/src/include/perspective/context_common.h +++ b/cpp/perspective/src/cpp/get_data_extents.cpp @@ -6,29 +6,15 @@ * the Apache License 2.0. The full license can be found in the LICENSE file. * */ - -#pragma once - #include -#include +#include namespace perspective { - -struct t_get_data_extents { - t_index m_srow; - t_index m_erow; - t_index m_scol; - t_index m_ecol; -}; - -template t_get_data_extents -sanitize_get_data_extents(const CONTEXT_T& ctx, t_index start_row, t_index end_row, +sanitize_get_data_extents(t_index nrows, t_index ncols, t_index start_row, t_index end_row, t_index start_col, t_index end_col) { - t_index ncols = ctx.get_column_count(); - - start_row = std::min(start_row, ctx.get_row_count()); - end_row = std::min(end_row, ctx.get_row_count()); + start_row = std::min(start_row, nrows); + end_row = std::min(end_row, nrows); start_row = std::max(t_index(0), start_row); end_row = std::max(t_index(0), end_row); diff --git a/cpp/perspective/src/cpp/view.cpp b/cpp/perspective/src/cpp/view.cpp index 32b6f40262..b1edb606e5 100644 --- a/cpp/perspective/src/cpp/view.cpp +++ b/cpp/perspective/src/cpp/view.cpp @@ -34,7 +34,7 @@ View::View(t_pool* pool, std::shared_ptr ctx, std::shared_ptr @@ -287,6 +287,61 @@ View::_column_names(bool skip, std::int32_t depth) const { return names; } +/** + * @brief Returns a slice of the underlying data of the view. + * + * @return std::vector + */ +template +t_data_slice +View::get_data(std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, + std::uint32_t end_col) { + auto slice_ptr = std::make_shared>( + m_ctx->get_data(start_row, end_row, start_col, end_col)); + auto names_ptr = std::make_shared>(_column_names()); + auto data_slice = t_data_slice( + m_ctx, start_row, end_row, start_col, end_col, slice_ptr, names_ptr); + return data_slice; +} + +template <> +t_data_slice +View::get_data(std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, + std::uint32_t end_col) { + std::vector slice; + std::vector column_indices; + std::vector column_names; + bool is_sorted = m_sorts.size() > 0; + + if (is_sorted) { + auto depth = m_column_pivots.size(); + auto col_length = m_ctx->unity_get_column_count(); + column_indices.push_back(0); + for (t_uindex i = 0; i < col_length; ++i) { + if (m_ctx->unity_get_column_path(i + 1).size() == depth) { + column_indices.push_back(i + 1); + } + } + + column_names = _column_names(true, depth); + column_indices = std::vector(column_indices.begin() + start_col, + column_indices.begin() + std::min(end_col, (std::uint32_t)column_indices.size())); + + slice = m_ctx->get_data( + start_row, end_row, column_indices.front(), column_indices.back() + 1); + } else { + column_names = _column_names(); + slice = m_ctx->get_data(start_row, end_row, start_col, end_col); + } + + auto slice_ptr = std::make_shared>(slice); + auto names_ptr = std::make_shared>(column_names); + auto indices_ptr = std::make_shared>(column_indices); + auto data_slice = t_data_slice( + m_ctx, start_row, end_row, start_col, end_col, slice_ptr, names_ptr, indices_ptr); + return data_slice; +} + // Getters template std::shared_ptr diff --git a/cpp/perspective/src/include/perspective/binding.h b/cpp/perspective/src/include/perspective/binding.h index 73bfabda51..52cb1fa32d 100644 --- a/cpp/perspective/src/include/perspective/binding.h +++ b/cpp/perspective/src/include/perspective/binding.h @@ -365,7 +365,7 @@ namespace binding { std::vector cpivots, t_filter_op combiner, std::vector filters, std::vector aggregates, std::vector sorts, std::vector col_sorts, std::int32_t rpivot_depth, std::int32_t cpivot_depth, - t_pool* pool, std::shared_ptr gnode, std::string name); + bool column_only, t_pool* pool, std::shared_ptr gnode, std::string name); template void sort(std::shared_ptr ctx2, T j_sortby); @@ -384,12 +384,12 @@ namespace binding { * ------- * */ - template - T get_data(U ctx, std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, - std::uint32_t end_col); + template + T get_data(std::shared_ptr> view, std::uint32_t start_row, + std::uint32_t end_row, std::uint32_t start_col, std::uint32_t end_col); template - T get_data_two_skip_headers(std::shared_ptr ctx, std::uint32_t depth, + T get_data_two_skip_headers(std::shared_ptr> view, std::uint32_t depth, std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, std::uint32_t end_col); diff --git a/cpp/perspective/src/include/perspective/config.h b/cpp/perspective/src/include/perspective/config.h index 29928379c6..e1c358cc9e 100644 --- a/cpp/perspective/src/include/perspective/config.h +++ b/cpp/perspective/src/include/perspective/config.h @@ -73,7 +73,7 @@ class PERSPECTIVE_EXPORT t_config { t_config(const std::vector& row_pivots, const std::vector& col_pivots, const std::vector& aggregates, const t_totals totals, t_filter_op combiner, - const std::vector& fterms); + const std::vector& fterms, bool column_only); t_config(const std::vector& row_pivots, const std::vector& col_pivots, const std::vector& aggregates, @@ -86,7 +86,7 @@ class PERSPECTIVE_EXPORT t_config { t_config(const std::vector& row_pivots, const t_aggspec& agg); t_config(const std::vector& row_pivots, const std::vector& aggregates, - t_filter_op combiner, const std::vector& fterms); + t_filter_op combiner, const std::vector& fterms, bool column_only); t_config(const std::vector& row_pivots, const std::vector& aggregates, t_filter_op combiner, @@ -122,7 +122,7 @@ class PERSPECTIVE_EXPORT t_config { std::vector get_column_names() const; t_uindex get_num_rpivots() const; t_uindex get_num_cpivots() const; - bool get_column_only() const; + bool is_column_only() const; std::vector get_pivots() const; const std::vector& get_row_pivots() const; diff --git a/cpp/perspective/src/include/perspective/data_slice.h b/cpp/perspective/src/include/perspective/data_slice.h new file mode 100644 index 0000000000..0de5a1f070 --- /dev/null +++ b/cpp/perspective/src/include/perspective/data_slice.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * + * Copyright (c) 2019, the Perspective Authors. + * + * This file is part of the Perspective library, distributed under the terms of + * the Apache License 2.0. The full license can be found in the LICENSE file. + * + */ + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace perspective { +/** + * @class t_data_slice + * + * @brief t_data_slice contains a slice of the View's underlying data + * with the metadata required to correctly parse it. + * + * - m_view: a reference to the view from which we output data + * - m_slice: a reference to a vector of t_tscalar objects containing data + * - m_column_names: a reference to a vector of string column names from the view. + * - m_column_indices: an optional reference to a vector of t_uindex column indices, which + * we use for column-pivoted views. + * + */ +template +class PERSPECTIVE_EXPORT t_data_slice { +public: + t_data_slice(std::shared_ptr ctx, t_uindex start_row, t_uindex end_row, + t_uindex start_col, t_uindex end_col, std::shared_ptr> slice, + std::shared_ptr> column_names); + + t_data_slice(std::shared_ptr ctx, t_uindex start_row, t_uindex end_row, + t_uindex start_col, t_uindex end_col, std::shared_ptr> slice, + std::shared_ptr> column_names, + std::shared_ptr> column_indices); + + ~t_data_slice(); + + /** + * @brief Returns the t_tscalar at the declared indices in the data slice, + * or an invalid t_tscalar if the indices should be skipped. + * + * @param ridx row index into the slice + * @param cidx column index into the slice + * + * @return t_tscalar a valid scalar containing the underlying data, or a new + * t_tscalar initialized with an invalid flag. + */ + t_tscalar get(t_uindex ridx, t_uindex cidx) const; + + std::vector get_row_path(t_uindex idx) const; + + std::shared_ptr get_context() const; + std::shared_ptr> get_slice() const; + std::shared_ptr> get_column_names() const; + std::shared_ptr> get_column_indices() const; + t_get_data_extents get_data_extents() const; + bool is_column_only() const; + +private: + std::shared_ptr m_ctx; + t_uindex m_start_row; + t_uindex m_end_row; + t_uindex m_start_col; + t_uindex m_end_col; + std::shared_ptr> m_slice; + std::shared_ptr> m_column_names; + std::shared_ptr> m_column_indices; +}; +} // end namespace perspective diff --git a/cpp/perspective/src/include/perspective/get_data_extents.h b/cpp/perspective/src/include/perspective/get_data_extents.h new file mode 100644 index 0000000000..b94f7cb70f --- /dev/null +++ b/cpp/perspective/src/include/perspective/get_data_extents.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * + * Copyright (c) 2017, the Perspective Authors. + * + * This file is part of the Perspective library, distributed under the terms of + * the Apache License 2.0. The full license can be found in the LICENSE file. + * + */ + +#pragma once + +#include +#include +#include + +namespace perspective { + +struct t_get_data_extents { + t_index m_srow; + t_index m_erow; + t_index m_scol; + t_index m_ecol; +}; + +t_get_data_extents sanitize_get_data_extents(t_index nrows, t_index ncols, t_index start_row, + t_index end_row, t_index start_col, t_index end_col); +} // namespace perspective diff --git a/cpp/perspective/src/include/perspective/view.h b/cpp/perspective/src/include/perspective/view.h index ee87c20f32..264817f2b3 100644 --- a/cpp/perspective/src/include/perspective/view.h +++ b/cpp/perspective/src/include/perspective/view.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,10 @@ class PERSPECTIVE_EXPORT View { t_index collapse(std::int32_t idx); void set_depth(std::int32_t depth, std::int32_t row_pivot_length); + // Data serialization + t_data_slice get_data(std::uint32_t start_row, std::uint32_t end_row, + std::uint32_t start_col, std::uint32_t end_col); + // Getters std::shared_ptr get_context() const; std::vector get_row_pivots() const; diff --git a/packages/perspective/bench/js/bench.js b/packages/perspective/bench/js/bench.js index a2beb03026..82b9a5e690 100644 --- a/packages/perspective/bench/js/bench.js +++ b/packages/perspective/bench/js/bench.js @@ -51,7 +51,6 @@ function transpose(json) { async function run() { // Allow users to set a limit on version lookbacks let psp_urls = URLS; - console.log(`limit: ${LIMIT}`); if (LIMIT !== -1) { let limit_num = Number(args[LIMIT + 1]); if (!isNaN(limit_num) && limit_num > 0 && limit_num <= psp_urls.length) { diff --git a/packages/perspective/src/js/perspective.js b/packages/perspective/src/js/perspective.js index e59bc13ae5..3728c78128 100644 --- a/packages/perspective/src/js/perspective.js +++ b/packages/perspective/src/js/perspective.js @@ -309,13 +309,11 @@ export default function(Module) { } if (this.sides() === 0) { - slice = __MODULE__.get_data_zero(this.ctx, start_row, end_row, start_col, end_col); + slice = __MODULE__.get_data_zero(this._View, start_row, end_row, start_col, end_col); } else if (this.sides() === 1) { - slice = __MODULE__.get_data_one(this.ctx, start_row, end_row, start_col, end_col); - } else if (!sorted) { - slice = __MODULE__.get_data_two(this.ctx, start_row, end_row, start_col, end_col); + slice = __MODULE__.get_data_one(this._View, start_row, end_row, start_col, end_col); } else { - slice = __MODULE__.get_data_two_skip_headers(this.ctx, this.config.column_pivot.length, start_row, end_row, start_col, end_col); + slice = __MODULE__.get_data_two(this._View, start_row, end_row, start_col, end_col); } let data = formatter.initDataValue(); @@ -328,6 +326,19 @@ export default function(Module) { depth = this.config.column_pivot.length; } + /* + let num_rows = this.num_rows(); + let num_cols = this.num_cols(); + let column_names = extract_vector(data_slice.get_column_names()); + for (let ridx = 0; ridx < num_rows; ridx++) { + row = {}; // or array for col, etc; + for (let cidx = 0; cidx < num_cols; cidx++) { + row[column_names[cidx]] = data_slice.get(ridx, cidx); + } + data.push(row); + } + */ + let col_names = [[]].concat(this._column_names(skip, depth)); let row; let ridx = -1; diff --git a/python/perspective/src/python.cpp b/python/perspective/src/python.cpp index 7e3b0e6165..1659876674 100644 --- a/python/perspective/src/python.cpp +++ b/python/perspective/src/python.cpp @@ -504,15 +504,15 @@ py::object get_column_data(std::shared_ptr table, std::string colname) * ------- * */ -template -py::object get_data(T ctx, std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, +template +py::object get_data(std::shared_ptr > view, std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, std::uint32_t end_col) { py::list arr; return arr; } template <> -py::object get_data_two_skip_headers(std::shared_ptr ctx, std::uint32_t depth, +py::object get_data_two_skip_headers(std::shared_ptr > view, std::uint32_t depth, std::uint32_t start_row, std::uint32_t end_row, std::uint32_t start_col, std::uint32_t end_col) { py::list arr;