@@ -9,8 +9,10 @@ use vortex_array::arrays::TemporalArray;
99use vortex_array:: builtins:: ArrayBuiltins ;
1010use vortex_array:: dtype:: DType ;
1111use vortex_array:: dtype:: PType ;
12+ use vortex_array:: extension:: datetime:: TimeUnit ;
1213use vortex_buffer:: BufferMut ;
1314use vortex_error:: VortexResult ;
15+ use vortex_error:: vortex_bail;
1416
1517use crate :: timestamp;
1618pub struct TemporalParts {
@@ -39,25 +41,41 @@ pub fn split_temporal(array: TemporalArray, ctx: &mut ExecutionCtx) -> VortexRes
3941 ) ) ?
4042 . execute :: < PrimitiveArray > ( ctx) ?;
4143
42- let length = timestamps. len ( ) ;
43- let mut days = BufferMut :: with_capacity ( length) ;
44- let mut seconds = BufferMut :: with_capacity ( length) ;
45- let mut subseconds = BufferMut :: with_capacity ( length) ;
46-
47- for & ts in timestamps. as_slice :: < i64 > ( ) {
48- let ts_parts = timestamp:: split ( ts, array. temporal_metadata ( ) . time_unit ( ) ) ?;
49- days. push ( ts_parts. days ) ;
50- seconds. push ( ts_parts. seconds ) ;
51- subseconds. push ( ts_parts. subseconds ) ;
52- }
44+ let ( days, seconds, subseconds) = match array. temporal_metadata ( ) . time_unit ( ) {
45+ TimeUnit :: Nanoseconds => split_slice :: < 1_000_000_000 > ( timestamps. as_slice :: < i64 > ( ) ) ,
46+ TimeUnit :: Microseconds => split_slice :: < 1_000_000 > ( timestamps. as_slice :: < i64 > ( ) ) ,
47+ TimeUnit :: Milliseconds => split_slice :: < 1_000 > ( timestamps. as_slice :: < i64 > ( ) ) ,
48+ TimeUnit :: Seconds => split_slice :: < 1 > ( timestamps. as_slice :: < i64 > ( ) ) ,
49+ TimeUnit :: Days => vortex_bail ! ( "Cannot handle day-level data" ) ,
50+ } ;
5351
5452 Ok ( TemporalParts {
55- days : PrimitiveArray :: new ( days, temporal_values. validity ( ) ?) . into_array ( ) ,
53+ days : PrimitiveArray :: new ( days. freeze ( ) , temporal_values. validity ( ) ?) . into_array ( ) ,
5654 seconds : seconds. into_array ( ) ,
5755 subseconds : subseconds. into_array ( ) ,
5856 } )
5957}
6058
59+ fn split_slice < const DIVISOR : i64 > (
60+ timestamps : & [ i64 ] ,
61+ ) -> ( BufferMut < i64 > , BufferMut < i64 > , BufferMut < i64 > ) {
62+ let mut days = BufferMut :: zeroed ( timestamps. len ( ) ) ;
63+ let mut seconds = BufferMut :: zeroed ( timestamps. len ( ) ) ;
64+ let mut subseconds = BufferMut :: zeroed ( timestamps. len ( ) ) ;
65+ let ( days_out, seconds_out, subseconds_out) = (
66+ days. as_mut_slice ( ) ,
67+ seconds. as_mut_slice ( ) ,
68+ subseconds. as_mut_slice ( ) ,
69+ ) ;
70+ for ( i, & ts) in timestamps. iter ( ) . enumerate ( ) {
71+ let ts_parts = timestamp:: split_with_divisor :: < DIVISOR > ( ts) ;
72+ days_out[ i] = ts_parts. days ;
73+ seconds_out[ i] = ts_parts. seconds ;
74+ subseconds_out[ i] = ts_parts. subseconds ;
75+ }
76+ ( days, seconds, subseconds)
77+ }
78+
6179#[ cfg( test) ]
6280mod tests {
6381 use rstest:: rstest;
0 commit comments