Skip to content

Commit 304c8f5

Browse files
committed
test coverage and ensure buffer resuse
1 parent cd2d688 commit 304c8f5

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

arrow-array/src/array/boolean_array.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,41 @@ impl From<BooleanBuffer> for BooleanArray {
887887
#[cfg(test)]
888888
mod tests {
889889
use super::*;
890+
891+
// Captures the values-buffer identity for a BooleanArray so tests can assert
892+
// whether an operation reused the original allocation or produced a new one.
893+
struct PointerInfo {
894+
ptr: *const u8,
895+
offset: usize,
896+
len: usize,
897+
}
898+
899+
impl PointerInfo {
900+
// Record the current values buffer pointer plus bit offset/length. The
901+
// offset/length checks ensure a logically equivalent slice wasn't rebuilt
902+
// with a different view over the same allocation.
903+
fn new(array: &BooleanArray) -> Self {
904+
Self {
905+
ptr: array.values().inner().as_ptr(),
906+
offset: array.values().offset(),
907+
len: array.values().len(),
908+
}
909+
}
910+
911+
// Assert that the array still points at the exact same values buffer and
912+
// preserves the same bit view.
913+
fn assert_same(&self, array: &BooleanArray) {
914+
assert_eq!(array.values().inner().as_ptr(), self.ptr);
915+
assert_eq!(array.values().offset(), self.offset);
916+
assert_eq!(array.values().len(), self.len);
917+
}
918+
919+
// Assert that the array now points at a different values allocation,
920+
// indicating the operation fell back to an allocating path.
921+
fn assert_different(&self, array: &BooleanArray) {
922+
assert_ne!(array.values().inner().as_ptr(), self.ptr);
923+
}
924+
}
890925
use arrow_buffer::Buffer;
891926
use rand::{Rng, rng};
892927

@@ -1330,20 +1365,24 @@ mod tests {
13301365
#[test]
13311366
fn test_bitwise_unary_mut_unshared() {
13321367
let arr = BooleanArray::from(vec![true, false, true, false]);
1368+
let info = PointerInfo::new(&arr);
13331369
let result = arr.bitwise_unary_mut(|x| !x).unwrap();
13341370
let expected = BooleanArray::from(vec![false, true, false, true]);
13351371
assert_eq!(result, expected);
1372+
info.assert_same(&result);
13361373
}
13371374

13381375
#[test]
13391376
fn test_bitwise_unary_mut_shared() {
13401377
let arr = BooleanArray::from(vec![true, false, true, false]);
1378+
let info = PointerInfo::new(&arr);
13411379
let _shared = arr.clone();
13421380
let result = arr.bitwise_unary_mut(|x| !x);
13431381
assert!(result.is_err());
13441382

13451383
let returned = result.unwrap_err();
13461384
assert_eq!(returned, BooleanArray::from(vec![true, false, true, false]));
1385+
info.assert_same(&returned);
13471386
}
13481387

13491388
#[test]
@@ -1360,9 +1399,21 @@ mod tests {
13601399
#[test]
13611400
fn test_bitwise_unary_mut_or_clone_shared() {
13621401
let arr = BooleanArray::from(vec![true, false, true]);
1402+
let info = PointerInfo::new(&arr);
13631403
let _shared = arr.clone();
13641404
let result = arr.bitwise_unary_mut_or_clone(|x| !x);
13651405
assert_eq!(result, BooleanArray::from(vec![false, true, false]));
1406+
info.assert_different(&result);
1407+
}
1408+
1409+
#[test]
1410+
fn test_bitwise_unary_mut_or_clone_unshared() {
1411+
// Covers the uniquely-owned fast path in bitwise_unary_mut_or_clone.
1412+
let arr = BooleanArray::from(vec![true, false, true]);
1413+
let info = PointerInfo::new(&arr);
1414+
let result = arr.bitwise_unary_mut_or_clone(|x| !x);
1415+
assert_eq!(result, BooleanArray::from(vec![false, true, false]));
1416+
info.assert_same(&result);
13661417
}
13671418

13681419
#[test]
@@ -1419,20 +1470,25 @@ mod tests {
14191470
#[test]
14201471
fn test_bitwise_bin_op_mut_unshared() {
14211472
let a = BooleanArray::from(vec![true, false, true, true]);
1473+
let info = PointerInfo::new(&a);
14221474
let b = BooleanArray::from(vec![true, true, false, true]);
14231475
let result = a.bitwise_bin_op_mut(&b, |a, b| a & b).unwrap();
14241476
assert_eq!(result, BooleanArray::from(vec![true, false, false, true]));
1477+
info.assert_same(&result);
14251478
}
14261479

14271480
#[test]
14281481
fn test_bitwise_bin_op_mut_shared() {
14291482
let a = BooleanArray::from(vec![true, false, true, true]);
1483+
let info = PointerInfo::new(&a);
14301484
let _shared = a.clone();
14311485
let result = a.bitwise_bin_op_mut(
14321486
&BooleanArray::from(vec![true, true, false, true]),
14331487
|a, b| a & b,
14341488
);
14351489
assert!(result.is_err());
1490+
let returned = result.unwrap_err();
1491+
info.assert_same(&returned);
14361492
}
14371493

14381494
#[test]
@@ -1451,17 +1507,20 @@ mod tests {
14511507
#[test]
14521508
fn test_bitwise_bin_op_mut_or_clone_shared() {
14531509
let a = BooleanArray::from(vec![true, false, true, true]);
1510+
let info = PointerInfo::new(&a);
14541511
let _shared = a.clone();
14551512
let b = BooleanArray::from(vec![true, true, false, true]);
14561513
let result = a.bitwise_bin_op_mut_or_clone(&b, |a, b| a & b);
14571514
assert_eq!(result, BooleanArray::from(vec![true, false, false, true]));
1515+
info.assert_different(&result);
14581516
}
14591517

14601518
#[test]
14611519
fn test_bitwise_bin_op_mut_or_clone_shared_with_nulls() {
14621520
// When the buffer is shared, _mut_or_clone falls back to bitwise_bin_op.
14631521
// The null union must only be applied once, not double-applied.
14641522
let a = BooleanArray::from(vec![Some(true), None, Some(true), Some(false)]);
1523+
let info = PointerInfo::new(&a);
14651524
let _shared = a.clone();
14661525
let b = BooleanArray::from(vec![Some(true), Some(true), None, Some(true)]);
14671526

@@ -1472,6 +1531,24 @@ mod tests {
14721531
assert_eq!(result.null_count(), 2);
14731532
assert!(result.is_null(1));
14741533
assert!(result.is_null(2));
1534+
info.assert_different(&result);
1535+
}
1536+
1537+
#[test]
1538+
fn test_bitwise_bin_op_mut_or_clone_unshared_with_nulls() {
1539+
// Covers the uniquely-owned fast path in bitwise_bin_op_mut_or_clone,
1540+
// including null union on the in-place path.
1541+
let a = BooleanArray::from(vec![Some(true), None, Some(true), Some(false)]);
1542+
let info = PointerInfo::new(&a);
1543+
let b = BooleanArray::from(vec![Some(true), Some(true), None, Some(true)]);
1544+
let result = a.bitwise_bin_op_mut_or_clone(&b, |a, b| a & b);
1545+
1546+
assert_eq!(result.null_count(), 2);
1547+
assert!(result.is_null(1));
1548+
assert!(result.is_null(2));
1549+
assert!(result.value(0));
1550+
assert!(!result.value(3));
1551+
info.assert_same(&result);
14751552
}
14761553

14771554
#[test]

0 commit comments

Comments
 (0)