@@ -30,8 +30,8 @@ use crate::ArrowNativeType;
30
30
/// logical array, up to that physical index.
31
31
///
32
32
/// Consider a [`RunEndBuffer`] containing `[3, 4, 6]`. The maximum physical index is `2`,
33
- /// as there are `3` values, and the maximum logical index is `6 `, as the maximum run end
34
- /// is `6`. The physical indices are therefore `[0, 0, 0, 1, 1, 2, 2]`
33
+ /// as there are `3` values, and the maximum logical index is `5 `, as the maximum run end
34
+ /// is `6`. The physical indices are therefore `[0, 0, 0, 1, 2, 2]`
35
35
///
36
36
/// ```text
37
37
/// ┌─────────┐ ┌─────────┐ ┌─────────┐
@@ -41,13 +41,11 @@ use crate::ArrowNativeType;
41
41
/// ├─────────┤ ├─────────┤ │ │ ├─────────┤
42
42
/// │ 6 │ │ 2 │ ─┘ │ ┌──▶ │ 2 │
43
43
/// └─────────┘ ├─────────┤ │ │ └─────────┘
44
- /// run ends │ 3 │ ───┤ │ physical indices
45
- /// ├─────────┤ │ │
46
- /// │ 4 │ ───┘ │
44
+ /// run ends │ 3 │ ───┘ │ physical indices
47
45
/// ├─────────┤ │
48
- /// │ 5 │ ─────┤
46
+ /// │ 4 │ ─────┤
49
47
/// ├─────────┤ │
50
- /// │ 6 │ ─────┘
48
+ /// │ 5 │ ─────┘
51
49
/// └─────────┘
52
50
/// logical indices
53
51
/// ```
90
88
assert ! ( !run_ends. is_empty( ) , "non-empty slice but empty run-ends" ) ;
91
89
let end = E :: from_usize ( offset. saturating_add ( len) ) . unwrap ( ) ;
92
90
assert ! (
93
- * run_ends. first( ) . unwrap( ) >= E :: usize_as( 0 ) ,
91
+ * run_ends. first( ) . unwrap( ) > E :: usize_as( 0 ) ,
94
92
"run-ends not greater than 0"
95
93
) ;
96
94
assert ! (
@@ -169,7 +167,7 @@ where
169
167
170
168
/// Returns the physical index at which the logical array starts
171
169
pub fn get_start_physical_index ( & self ) -> usize {
172
- if self . offset == 0 {
170
+ if self . offset == 0 || self . len == 0 {
173
171
return 0 ;
174
172
}
175
173
// Fallback to binary search
@@ -178,6 +176,9 @@ where
178
176
179
177
/// Returns the physical index at which the logical array ends
180
178
pub fn get_end_physical_index ( & self ) -> usize {
179
+ if self . len == 0 {
180
+ return 0 ;
181
+ }
181
182
if self . max_value ( ) == self . offset + self . len {
182
183
return self . values ( ) . len ( ) - 1 ;
183
184
}
@@ -198,3 +199,26 @@ where
198
199
}
199
200
}
200
201
}
202
+
203
+ #[ cfg( test) ]
204
+ mod tests {
205
+ use crate :: buffer:: RunEndBuffer ;
206
+
207
+ #[ test]
208
+ fn test_zero_length_slice ( ) {
209
+ let buffer = RunEndBuffer :: new ( vec ! [ 1_i32 , 4_i32 ] . into ( ) , 0 , 4 ) ;
210
+ assert_eq ! ( buffer. get_start_physical_index( ) , 0 ) ;
211
+ assert_eq ! ( buffer. get_end_physical_index( ) , 1 ) ;
212
+ assert_eq ! ( buffer. get_physical_index( 3 ) , 1 ) ;
213
+
214
+ for offset in 0 ..4 {
215
+ let sliced = buffer. slice ( offset, 0 ) ;
216
+ assert_eq ! ( sliced. get_start_physical_index( ) , 0 ) ;
217
+ assert_eq ! ( sliced. get_end_physical_index( ) , 0 ) ;
218
+ }
219
+
220
+ let buffer = RunEndBuffer :: new ( Vec :: < i32 > :: new ( ) . into ( ) , 0 , 0 ) ;
221
+ assert_eq ! ( buffer. get_start_physical_index( ) , 0 ) ;
222
+ assert_eq ! ( buffer. get_end_physical_index( ) , 0 ) ;
223
+ }
224
+ }
0 commit comments