@@ -22,9 +22,9 @@ use crate::bit_iterator::BitSliceIterator;
22
22
use arrow_buffer:: buffer:: { BooleanBuffer , NullBuffer } ;
23
23
use arrow_buffer:: { bit_util, i256, ArrowNativeType , Buffer , MutableBuffer } ;
24
24
use arrow_schema:: { ArrowError , DataType , UnionMode } ;
25
- use std:: mem;
26
25
use std:: ops:: Range ;
27
26
use std:: sync:: Arc ;
27
+ use std:: { mem, usize} ;
28
28
29
29
use crate :: { equal, validate_binary_view, validate_string_view} ;
30
30
@@ -929,6 +929,41 @@ impl ArrayData {
929
929
Ok ( ( ) )
930
930
}
931
931
932
+ /// Does a cheap sanity check that the `self.len` values in `buffer` are valid
933
+ /// offsets and sizes (of type T) into some other buffer of `values_length` bytes long
934
+ fn validate_offsets_and_sizes < T : ArrowNativeType + num:: Num + std:: fmt:: Display > (
935
+ & self ,
936
+ values_length : usize ,
937
+ ) -> Result < ( ) , ArrowError > {
938
+ let offsets: & [ T ] = self . typed_buffer ( 0 , self . len ) ?;
939
+ let sizes: & [ T ] = self . typed_buffer ( 1 , self . len ) ?;
940
+ for i in 0 ..values_length {
941
+ let size = sizes[ i] . to_usize ( ) . ok_or_else ( || {
942
+ ArrowError :: InvalidArgumentError ( format ! (
943
+ "Error converting size[{}] ({}) to usize for {}" ,
944
+ i, sizes[ i] , self . data_type
945
+ ) )
946
+ } ) ?;
947
+ let offset = offsets[ i] . to_usize ( ) . ok_or_else ( || {
948
+ ArrowError :: InvalidArgumentError ( format ! (
949
+ "Error converting offset[{}] ({}) to usize for {}" ,
950
+ i, offsets[ i] , self . data_type
951
+ ) )
952
+ } ) ?;
953
+ if size
954
+ . checked_add ( offset)
955
+ . expect ( "Offset and size have exceeded the usize boundary" )
956
+ > values_length
957
+ {
958
+ return Err ( ArrowError :: InvalidArgumentError ( format ! (
959
+ "Size {} at index {} is larger than the remaining values for {}" ,
960
+ size, i, self . data_type
961
+ ) ) ) ;
962
+ }
963
+ }
964
+ Ok ( ( ) )
965
+ }
966
+
932
967
/// Validates the layout of `child_data` ArrayData structures
933
968
fn validate_child_data ( & self ) -> Result < ( ) , ArrowError > {
934
969
match & self . data_type {
@@ -942,6 +977,16 @@ impl ArrayData {
942
977
self . validate_offsets :: < i64 > ( values_data. len ) ?;
943
978
Ok ( ( ) )
944
979
}
980
+ DataType :: ListView ( field) => {
981
+ let values_data = self . get_single_valid_child_data ( field. data_type ( ) ) ?;
982
+ self . validate_offsets_and_sizes :: < i32 > ( values_data. len ) ?;
983
+ Ok ( ( ) )
984
+ }
985
+ DataType :: LargeListView ( field) => {
986
+ let values_data = self . get_single_valid_child_data ( field. data_type ( ) ) ?;
987
+ self . validate_offsets_and_sizes :: < i64 > ( values_data. len ) ?;
988
+ Ok ( ( ) )
989
+ }
945
990
DataType :: FixedSizeList ( field, list_size) => {
946
991
let values_data = self . get_single_valid_child_data ( field. data_type ( ) ) ?;
947
992
@@ -1546,9 +1591,8 @@ pub fn layout(data_type: &DataType) -> DataTypeLayout {
1546
1591
DataType :: BinaryView | DataType :: Utf8View => DataTypeLayout :: new_view ( ) ,
1547
1592
DataType :: FixedSizeList ( _, _) => DataTypeLayout :: new_nullable_empty ( ) , // all in child data
1548
1593
DataType :: List ( _) => DataTypeLayout :: new_fixed_width :: < i32 > ( ) ,
1549
- DataType :: ListView ( _) | DataType :: LargeListView ( _) => {
1550
- unimplemented ! ( "ListView/LargeListView not implemented" )
1551
- }
1594
+ DataType :: ListView ( _) => DataTypeLayout :: new_list_view :: < i32 > ( ) ,
1595
+ DataType :: LargeListView ( _) => DataTypeLayout :: new_list_view :: < i64 > ( ) ,
1552
1596
DataType :: LargeList ( _) => DataTypeLayout :: new_fixed_width :: < i64 > ( ) ,
1553
1597
DataType :: Map ( _, _) => DataTypeLayout :: new_fixed_width :: < i32 > ( ) ,
1554
1598
DataType :: Struct ( _) => DataTypeLayout :: new_nullable_empty ( ) , // all in child data,
@@ -1661,6 +1705,24 @@ impl DataTypeLayout {
1661
1705
variadic : true ,
1662
1706
}
1663
1707
}
1708
+
1709
+ /// Describes a list view type
1710
+ pub fn new_list_view < T > ( ) -> Self {
1711
+ Self {
1712
+ buffers : vec ! [
1713
+ BufferSpec :: FixedWidth {
1714
+ byte_width: mem:: size_of:: <T >( ) ,
1715
+ alignment: mem:: align_of:: <T >( ) ,
1716
+ } ,
1717
+ BufferSpec :: FixedWidth {
1718
+ byte_width: mem:: size_of:: <T >( ) ,
1719
+ alignment: mem:: align_of:: <T >( ) ,
1720
+ } ,
1721
+ ] ,
1722
+ can_contain_null_mask : true ,
1723
+ variadic : true ,
1724
+ }
1725
+ }
1664
1726
}
1665
1727
1666
1728
/// Layout specification for a single data type buffer
0 commit comments