Skip to content

Commit

Permalink
Add time array (#346)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex-PLACET authored Feb 11, 2025
1 parent cceb32e commit 733eae0
Show file tree
Hide file tree
Showing 12 changed files with 859 additions and 15 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,12 @@ set(SPARROW_HEADERS
${SPARROW_INCLUDE_DIR}/sparrow/layout/struct_layout/struct_value.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/date_array.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/duration_array.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/interval_types.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/time_array.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/time_types.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/timestamp_array.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/timestamp_concepts.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/timestamp_reference.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/temporal/interval_types.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/trivial_copyable_data_access.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/variable_size_binary_layout/variable_size_binary_array.hpp
${SPARROW_INCLUDE_DIR}/sparrow/layout/variable_size_binary_layout/variable_size_binary_iterator.hpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ namespace sparrow
case data_type::TIMESTAMP_MILLISECONDS:
case data_type::TIMESTAMP_MICROSECONDS:
case data_type::TIMESTAMP_NANOSECONDS:
case data_type::TIME_SECONDS:
case data_type::TIME_MILLISECONDS:
case data_type::TIME_MICROSECONDS:
case data_type::TIME_NANOSECONDS:
case data_type::DURATION_SECONDS:
case data_type::DURATION_MILLISECONDS:
case data_type::DURATION_MICROSECONDS:
Expand Down
47 changes: 33 additions & 14 deletions include/sparrow/builder/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@
#include <utility>
#include <vector>

#include <sparrow/array.hpp>
#include <sparrow/builder/builder_utils.hpp>
#include <sparrow/builder/nested_eq.hpp>
#include <sparrow/builder/nested_less.hpp>
#include <sparrow/layout/dictionary_encoded_array.hpp>
#include <sparrow/layout/fixed_width_binary_array.hpp>
#include <sparrow/layout/list_layout/list_array.hpp>
#include <sparrow/layout/primitive_array.hpp>
#include <sparrow/layout/struct_layout/struct_array.hpp>
#include <sparrow/layout/temporal/date_array.hpp>
#include <sparrow/layout/union_array.hpp>
#include <sparrow/layout/variable_size_binary_layout/variable_size_binary_array.hpp>
#include <sparrow/utils/ranges.hpp>

#include "sparrow/array.hpp"
#include "sparrow/builder/builder_utils.hpp"
#include "sparrow/builder/nested_eq.hpp"
#include "sparrow/builder/nested_less.hpp"
#include "sparrow/layout/dictionary_encoded_array.hpp"
#include "sparrow/layout/fixed_width_binary_array.hpp"
#include "sparrow/layout/list_layout/list_array.hpp"
#include "sparrow/layout/primitive_array.hpp"
#include "sparrow/layout/struct_layout/struct_array.hpp"
#include "sparrow/layout/temporal/date_array.hpp"
#include "sparrow/layout/temporal/interval_array.hpp"
#include "sparrow/layout/temporal/time_array.hpp"
#include "sparrow/layout/union_array.hpp"
#include "sparrow/layout/variable_size_binary_layout/variable_size_binary_array.hpp"
#include "sparrow/utils/ranges.hpp"

namespace sparrow
{
Expand Down Expand Up @@ -144,6 +144,13 @@ namespace sparrow
mpl::predicate::same_as<ensured_range_value_t<T>>{}
);

template <typename T>
concept translates_to_time_layout = std::ranges::input_range<T>
&& mpl::any_of(
time_types_t{},
mpl::predicate::same_as<ensured_range_value_t<T>>{}
);

template <class T>
concept translate_to_variable_sized_list_layout = std::ranges::input_range<T>
&& std::ranges::input_range<ensured_range_value_t<T>>
Expand Down Expand Up @@ -264,6 +271,18 @@ namespace sparrow
}
};

template <translates_to_time_layout T, class OPTION_FLAGS>
struct builder<T, dont_enforce_layout, OPTION_FLAGS>
{
using type = sparrow::time_array<ensured_range_value_t<T>>;

template <class U>
static type create(U&& t)
{
return type(std::forward<U>(t));
}
};

template <translate_to_variable_sized_list_layout T, class OPTION_FLAGS>
struct builder<T, dont_enforce_layout, OPTION_FLAGS>
{
Expand Down
9 changes: 9 additions & 0 deletions include/sparrow/layout/dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "sparrow/layout/temporal/date_array.hpp"
#include "sparrow/layout/temporal/duration_array.hpp"
#include "sparrow/layout/temporal/interval_array.hpp"
#include "sparrow/layout/temporal/time_array.hpp"
#include "sparrow/layout/temporal/timestamp_array.hpp"
#include "sparrow/layout/union_array.hpp"
#include "sparrow/layout/variable_size_binary_layout/variable_size_binary_array.hpp"
Expand Down Expand Up @@ -145,6 +146,14 @@ namespace sparrow
return func(unwrap_array<timestamp_array<timestamp<std::chrono::microseconds>>>(ar));
case data_type::TIMESTAMP_NANOSECONDS:
return func(unwrap_array<timestamp_array<timestamp<std::chrono::nanoseconds>>>(ar));
case data_type::TIME_SECONDS:
return func(unwrap_array<time_seconds_array>(ar));
case data_type::TIME_MILLISECONDS:
return func(unwrap_array<time_milliseconds_array>(ar));
case data_type::TIME_MICROSECONDS:
return func(unwrap_array<time_microseconds_array>(ar));
case data_type::TIME_NANOSECONDS:
return func(unwrap_array<time_nanoseconds_array>(ar));
case data_type::DURATION_SECONDS:
return func(unwrap_array<duration_seconds_array>(ar));
case data_type::DURATION_MILLISECONDS:
Expand Down
66 changes: 66 additions & 0 deletions include/sparrow/layout/temporal/time_array.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024 Man Group Operations Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "sparrow/layout/array_trivial_copyable.hpp"
#include "sparrow/layout/temporal/time_types.hpp"

// tts : std::chrono::seconds

namespace sparrow
{
using time_types_t = mpl::
typelist<chrono::time_seconds, chrono::time_milliseconds, chrono::time_microseconds, chrono::time_nanoseconds>;

static constexpr time_types_t time_types;
template <typename T>
concept time_type = mpl::contains<T>(time_types);

/**
* Array of time values.
*
* As the other arrays in sparrow, \c time_array<T> provides an API as if it was holding
* \c nullable<T> values instead of \c T values.
*
* Internally, the array contains a validity bitmap and a contiguous memory buffer
* holding the values.
*
* @tparam T the type of the values in the array.
* @see https://arrow.apache.org/docs/dev/format/Columnar.html#fixed-size-primitive-layout
*/
template <time_type T>
using time_array = array_trivial_copyable<T>;

using time_seconds_array = time_array<chrono::time_seconds>;
using time_milliseconds_array = time_array<chrono::time_milliseconds>;
using time_microseconds_array = time_array<chrono::time_microseconds>;
using time_nanoseconds_array = time_array<chrono::time_nanoseconds>;

template <class T>
struct is_time_array : std::false_type
{
};

template <class T>
struct is_time_array<time_array<T>> : std::true_type
{
};

/**
* Checks whether T is a time_array type.
*/
template <class T>
constexpr bool is_time_array_v = is_time_array<T>::value;
}
99 changes: 99 additions & 0 deletions include/sparrow/layout/temporal/time_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2024 Man Group Operations Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <chrono>
#include <cstdint>

#if defined(__cpp_lib_format)
# include <format>
#endif

namespace sparrow::chrono
{
/**
* A duration representing time elapsed since midnight.
*/
struct time_seconds : public std::chrono::duration<int32_t>
{
time_seconds() = default;

explicit time_seconds(int32_t seconds)
: std::chrono::duration<int32_t>(seconds)
{
}
};

/**
* A duration representing time elapsed since midnight, in milliseconds.
*/
struct time_milliseconds : public std::chrono::duration<int32_t, std::milli>
{
time_milliseconds() = default;

explicit time_milliseconds(int32_t milliseconds)
: std::chrono::duration<int32_t, std::milli>(milliseconds)
{
}
};

/**
* A duration representing time elapsed since midnight, in microseconds.
*/
struct time_microseconds : public std::chrono::duration<int64_t, std::micro>
{
time_microseconds() = default;

explicit time_microseconds(int64_t microseconds)
: std::chrono::duration<int64_t, std::micro>(microseconds)
{
}
};

/**
* A duration representing time elapsed since midnight, in nanoseconds.
*/
struct time_nanoseconds : public std::chrono::duration<int64_t, std::nano>
{
time_nanoseconds() = default;

explicit time_nanoseconds(int64_t nanoseconds)
: std::chrono::duration<int64_t, std::nano>(nanoseconds)
{
}
};
}

#if defined(__cpp_lib_format)

template <typename T>
requires std::same_as<T, sparrow::chrono::time_seconds>
|| std::same_as<T, sparrow::chrono::time_milliseconds>
|| std::same_as<T, sparrow::chrono::time_microseconds>
|| std::same_as<T, sparrow::chrono::time_nanoseconds>
struct std::formatter<T>
{
constexpr auto parse(std::format_parse_context& ctx)
{
return ctx.begin(); // Simple implementation
}

auto format(const T& time, std::format_context& ctx) const
{
return std::format_to(ctx.out(), "{}", time.count());
}
};

#endif
25 changes: 25 additions & 0 deletions include/sparrow/types/data_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "sparrow/layout/temporal/date_array.hpp"
#include "sparrow/layout/temporal/interval_types.hpp"
#include "sparrow/layout/temporal/time_types.hpp"
#include "sparrow/types/data_type.hpp"
#include "sparrow/utils/nullable.hpp"
#include "sparrow/utils/vector_view.hpp"
Expand Down Expand Up @@ -181,6 +182,30 @@ namespace sparrow
using const_reference = timestamp<std::chrono::nanoseconds>;
};

template <>
struct arrow_traits<chrono::time_seconds> : common_native_types_traits<chrono::time_seconds>
{
static constexpr data_type type_id = data_type::TIME_SECONDS;
};

template <>
struct arrow_traits<chrono::time_milliseconds> : common_native_types_traits<chrono::time_milliseconds>
{
static constexpr data_type type_id = data_type::TIME_MILLISECONDS;
};

template <>
struct arrow_traits<chrono::time_microseconds> : common_native_types_traits<chrono::time_microseconds>
{
static constexpr data_type type_id = data_type::TIME_MICROSECONDS;
};

template <>
struct arrow_traits<chrono::time_nanoseconds> : common_native_types_traits<chrono::time_nanoseconds>
{
static constexpr data_type type_id = data_type::TIME_NANOSECONDS;
};

template <>
struct arrow_traits<chrono::months> : common_native_types_traits<chrono::months>
{
Expand Down
Loading

0 comments on commit 733eae0

Please sign in to comment.