From f70512a191ee40d2759772713683fb767fa10045 Mon Sep 17 00:00:00 2001 From: Corey Kosak Date: Sat, 21 Sep 2024 18:57:09 -0400 Subject: [PATCH] feat(cpp-client): Additional Cython support for LocalDate and LocalTime --- .../dhcore/column/array_column_source.h | 2 + .../include/public/deephaven/dhcore/types.h | 45 +++++++++++++++++++ .../deephaven/dhcore/utility/cython_support.h | 4 ++ .../dhcore/src/utility/cython_support.cc | 30 +++++++++++++ 4 files changed, 81 insertions(+) diff --git a/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/column/array_column_source.h b/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/column/array_column_source.h index 16e5bb5947b..19576e98dc4 100644 --- a/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/column/array_column_source.h +++ b/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/column/array_column_source.h @@ -247,4 +247,6 @@ class GenericArrayColumnSource final : public deephaven::dhcore::column::Mutable using BooleanArrayColumnSource = GenericArrayColumnSource; using StringArrayColumnSource = GenericArrayColumnSource; using DateTimeArrayColumnSource = GenericArrayColumnSource; +using LocalDateArrayColumnSource = GenericArrayColumnSource; +using LocalTimeArrayColumnSource = GenericArrayColumnSource; } // namespace deephaven::dhcore::column diff --git a/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/types.h b/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/types.h index 190423437a4..1f5cd02763c 100644 --- a/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/types.h +++ b/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/types.h @@ -342,6 +342,21 @@ struct DeephavenTraits { */ class DateTime { public: + using rep_t = int64_t; + + /** + * This method exists to document and enforce an assumption in Cython, namely that this + * class has the same representation as an int64_t. This constexpr method always returns + * true (or fails to compile). + */ + static constexpr bool IsBlittableToInt64() { + static_assert( + std::is_trivially_copyable_v && + std::has_unique_object_representations_v && + std::is_same_v); + return true; + } + /** * Converts nanoseconds-since-UTC-epoch to DateTime. The Deephaven null value sentinel is * turned into DateTime(0). @@ -431,6 +446,21 @@ class DateTime { */ class LocalDate { public: + using rep_t = int64_t; + + /** + * This method exists to document and enforce an assumption in Cython, namely that this + * class has the same representation as an int64_t. This constexpr method always returns + * true (or fails to compile). + */ + static constexpr bool IsBlittableToInt64() { + static_assert( + std::is_trivially_copyable_v && + std::has_unique_object_representations_v && + std::is_same_v); + return true; + } + /** * Creates an instance of LocalDate from the specified year, month, and day. */ @@ -488,6 +518,21 @@ class LocalDate { */ class LocalTime { public: + using rep_t = int64_t; + + /** + * This method exists to document and enforce an assumption in Cython, namely that this + * class has the same representation as an int64_t. This constexpr method always returns + * true (or fails to compile). + */ + static constexpr bool IsBlittableToInt64() { + static_assert( + std::is_trivially_copyable_v && + std::has_unique_object_representations_v && + std::is_same_v); + return true; + } + /** * Creates an instance of LocalTime from the specified hour, minute, and second. */ diff --git a/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/utility/cython_support.h b/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/utility/cython_support.h index a2718952636..39fcc885d41 100644 --- a/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/utility/cython_support.h +++ b/cpp-client/deephaven/dhcore/include/public/deephaven/dhcore/utility/cython_support.h @@ -20,6 +20,10 @@ class CythonSupport { const uint8_t *validity_begin, const uint8_t *validity_end, size_t num_elements); static std::shared_ptr CreateDateTimeColumnSource(const int64_t *data_begin, const int64_t *data_end, const uint8_t *validity_begin, const uint8_t *validity_end, size_t num_elements); + static std::shared_ptr CreateLocalDateColumnSource(const int64_t *data_begin, const int64_t *data_end, + const uint8_t *validity_begin, const uint8_t *validity_end, size_t num_elements); + static std::shared_ptr CreateLocalTimeColumnSource(const int64_t *data_begin, const int64_t *data_end, + const uint8_t *validity_begin, const uint8_t *validity_end, size_t num_elements); static ElementTypeId::Enum GetElementTypeId(const ColumnSource &column_source); }; diff --git a/cpp-client/deephaven/dhcore/src/utility/cython_support.cc b/cpp-client/deephaven/dhcore/src/utility/cython_support.cc index 6609e356b56..d6108cf5b2e 100644 --- a/cpp-client/deephaven/dhcore/src/utility/cython_support.cc +++ b/cpp-client/deephaven/dhcore/src/utility/cython_support.cc @@ -15,6 +15,8 @@ using deephaven::dhcore::column::BooleanArrayColumnSource; using deephaven::dhcore::column::ColumnSource; using deephaven::dhcore::column::ColumnSourceVisitor; using deephaven::dhcore::column::DateTimeArrayColumnSource; +using deephaven::dhcore::column::LocalDateArrayColumnSource; +using deephaven::dhcore::column::LocalTimeArrayColumnSource; using deephaven::dhcore::column::StringArrayColumnSource; namespace deephaven::dhcore::utility { @@ -66,6 +68,34 @@ CythonSupport::CreateDateTimeColumnSource(const int64_t *data_begin, const int64 num_elements); } +std::shared_ptr +CythonSupport::CreateLocalDateColumnSource(const int64_t *data_begin, const int64_t *data_end, + const uint8_t *validity_begin, const uint8_t *validity_end, size_t num_elements) { + auto elements = std::make_unique(num_elements); + auto nulls = std::make_unique(num_elements); + + for (size_t i = 0; i != num_elements; ++i) { + elements[i] = LocalDate(data_begin[i]); + } + populateArrayFromPackedData(validity_begin, nulls.get(), num_elements, true); + return LocalDateArrayColumnSource::CreateFromArrays(std::move(elements), std::move(nulls), + num_elements); +} + +std::shared_ptr +CythonSupport::CreateLocalTimeColumnSource(const int64_t *data_begin, const int64_t *data_end, + const uint8_t *validity_begin, const uint8_t *validity_end, size_t num_elements) { + auto elements = std::make_unique(num_elements); + auto nulls = std::make_unique(num_elements); + + for (size_t i = 0; i != num_elements; ++i) { + elements[i] = LocalTime(data_begin[i]); + } + populateArrayFromPackedData(validity_begin, nulls.get(), num_elements, true); + return LocalTimeArrayColumnSource::CreateFromArrays(std::move(elements), std::move(nulls), + num_elements); +} + namespace { struct ElementTypeIdVisitor final : ColumnSourceVisitor { void Visit(const column::CharColumnSource &/*source*/) final {