@@ -38,6 +38,49 @@ pub struct BinaryViewVector<T: BinaryViewType> {
3838 _marker : std:: marker:: PhantomData < T > ,
3939}
4040
41+ impl < T : BinaryViewType > PartialEq for BinaryViewVector < T > {
42+ fn eq ( & self , other : & Self ) -> bool {
43+ if self . views . len ( ) != other. views . len ( ) {
44+ return false ;
45+ }
46+ // Validity patterns must match
47+ if self . validity != other. validity {
48+ return false ;
49+ }
50+ // Compare all views, OR with !validity to ignore invalid positions
51+ self . views
52+ . iter ( )
53+ . zip ( other. views . iter ( ) )
54+ . enumerate ( )
55+ . all ( |( i, ( self_view, other_view) ) | {
56+ // If invalid, treat as equal
57+ if !self . validity . value ( i) {
58+ return true ;
59+ }
60+ // For valid elements, compare the actual byte content via the view
61+ let self_bytes: & [ u8 ] = if self_view. is_inlined ( ) {
62+ self_view. as_inlined ( ) . value ( )
63+ } else {
64+ let view_ref = self_view. as_view ( ) ;
65+ let buffer = & self . buffers [ view_ref. buffer_index as usize ] ;
66+ & buffer[ view_ref. as_range ( ) ]
67+ } ;
68+
69+ let other_bytes: & [ u8 ] = if other_view. is_inlined ( ) {
70+ other_view. as_inlined ( ) . value ( )
71+ } else {
72+ let view_ref = other_view. as_view ( ) ;
73+ let buffer = & other. buffers [ view_ref. buffer_index as usize ] ;
74+ & buffer[ view_ref. as_range ( ) ]
75+ } ;
76+
77+ self_bytes == other_bytes
78+ } )
79+ }
80+ }
81+
82+ impl < T : BinaryViewType > Eq for BinaryViewVector < T > { }
83+
4184impl < T : BinaryViewType > BinaryViewVector < T > {
4285 /// Creates a new [`BinaryViewVector`] from the provided components.
4386 ///
@@ -388,4 +431,150 @@ mod tests {
388431
389432 assert ! ( shared_vec. try_into_mut( ) . is_ok( ) ) ;
390433 }
434+
435+ #[ test]
436+ fn test_binaryview_eq_identical_inlined ( ) {
437+ // Test equality with inlined strings (<=12 bytes).
438+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
439+ v1. append_values ( "hello" , 1 ) ;
440+ v1. append_values ( "world" , 1 ) ;
441+ v1. append_values ( "test" , 1 ) ;
442+ let v1 = v1. freeze ( ) ;
443+
444+ let mut v2 = StringVectorMut :: with_capacity ( 3 ) ;
445+ v2. append_values ( "hello" , 1 ) ;
446+ v2. append_values ( "world" , 1 ) ;
447+ v2. append_values ( "test" , 1 ) ;
448+ let v2 = v2. freeze ( ) ;
449+
450+ assert_eq ! ( v1, v2) ;
451+ }
452+
453+ #[ test]
454+ fn test_binaryview_eq_identical_outlined ( ) {
455+ // Test equality with outlined strings (>12 bytes).
456+ let mut v1 = StringVectorMut :: with_capacity ( 2 ) ;
457+ v1. append_values ( "this is a longer string that won't be inlined" , 1 ) ;
458+ v1. append_values ( "another long string for testing purposes" , 1 ) ;
459+ let v1 = v1. freeze ( ) ;
460+
461+ let mut v2 = StringVectorMut :: with_capacity ( 2 ) ;
462+ v2. append_values ( "this is a longer string that won't be inlined" , 1 ) ;
463+ v2. append_values ( "another long string for testing purposes" , 1 ) ;
464+ let v2 = v2. freeze ( ) ;
465+
466+ assert_eq ! ( v1, v2) ;
467+ }
468+
469+ #[ test]
470+ fn test_binaryview_eq_different_length ( ) {
471+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
472+ v1. append_values ( "a" , 1 ) ;
473+ v1. append_values ( "b" , 1 ) ;
474+ v1. append_values ( "c" , 1 ) ;
475+ let v1 = v1. freeze ( ) ;
476+
477+ let mut v2 = StringVectorMut :: with_capacity ( 2 ) ;
478+ v2. append_values ( "a" , 1 ) ;
479+ v2. append_values ( "b" , 1 ) ;
480+ let v2 = v2. freeze ( ) ;
481+
482+ assert_ne ! ( v1, v2) ;
483+ }
484+
485+ #[ test]
486+ fn test_binaryview_eq_different_validity ( ) {
487+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
488+ v1. append_values ( "a" , 1 ) ;
489+ v1. append_values ( "b" , 1 ) ;
490+ v1. append_values ( "c" , 1 ) ;
491+ let v1 = v1. freeze ( ) ;
492+
493+ let mut v2 = StringVectorMut :: with_capacity ( 3 ) ;
494+ v2. append_values ( "a" , 1 ) ;
495+ v2. append_nulls ( 1 ) ;
496+ v2. append_values ( "c" , 1 ) ;
497+ let v2 = v2. freeze ( ) ;
498+
499+ assert_ne ! ( v1, v2) ;
500+ }
501+
502+ #[ test]
503+ fn test_binaryview_eq_different_values ( ) {
504+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
505+ v1. append_values ( "hello" , 1 ) ;
506+ v1. append_values ( "world" , 1 ) ;
507+ v1. append_values ( "test" , 1 ) ;
508+ let v1 = v1. freeze ( ) ;
509+
510+ let mut v2 = StringVectorMut :: with_capacity ( 3 ) ;
511+ v2. append_values ( "hello" , 1 ) ;
512+ v2. append_values ( "DIFFERENT" , 1 ) ;
513+ v2. append_values ( "test" , 1 ) ;
514+ let v2 = v2. freeze ( ) ;
515+
516+ assert_ne ! ( v1, v2) ;
517+ }
518+
519+ #[ test]
520+ fn test_binaryview_eq_ignores_invalid_positions_inlined ( ) {
521+ // Two vectors with different values at invalid positions should be equal.
522+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
523+ v1. append_values ( "hello" , 1 ) ;
524+ v1. append_values ( "value_a" , 1 ) ; // This will be masked as invalid
525+ v1. append_values ( "test" , 1 ) ;
526+ let mut v1 = v1. freeze ( ) ;
527+ // Mask position 1 as invalid
528+ v1. mask_validity ( & Mask :: from_iter ( [ true , false , true ] ) ) ;
529+
530+ let mut v2 = StringVectorMut :: with_capacity ( 3 ) ;
531+ v2. append_values ( "hello" , 1 ) ;
532+ v2. append_values ( "value_b" , 1 ) ; // Different value at invalid position
533+ v2. append_values ( "test" , 1 ) ;
534+ let mut v2 = v2. freeze ( ) ;
535+ v2. mask_validity ( & Mask :: from_iter ( [ true , false , true ] ) ) ;
536+
537+ assert_eq ! ( v1, v2) ;
538+ }
539+
540+ #[ test]
541+ fn test_binaryview_eq_ignores_invalid_positions_outlined ( ) {
542+ // Test with outlined strings at invalid positions.
543+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
544+ v1. append_values ( "this is a very long string that will be outlined" , 1 ) ;
545+ v1. append_values ( "another long value that differs between vectors A" , 1 ) ;
546+ v1. append_values ( "yet another long string for the test" , 1 ) ;
547+ let mut v1 = v1. freeze ( ) ;
548+ v1. mask_validity ( & Mask :: from_iter ( [ true , false , true ] ) ) ;
549+
550+ let mut v2 = StringVectorMut :: with_capacity ( 3 ) ;
551+ v2. append_values ( "this is a very long string that will be outlined" , 1 ) ;
552+ v2. append_values ( "different long value at the invalid position B" , 1 ) ;
553+ v2. append_values ( "yet another long string for the test" , 1 ) ;
554+ let mut v2 = v2. freeze ( ) ;
555+ v2. mask_validity ( & Mask :: from_iter ( [ true , false , true ] ) ) ;
556+
557+ assert_eq ! ( v1, v2) ;
558+ }
559+
560+ #[ test]
561+ fn test_binaryview_eq_empty ( ) {
562+ let v1 = StringVectorMut :: with_capacity ( 0 ) . freeze ( ) ;
563+ let v2 = StringVectorMut :: with_capacity ( 0 ) . freeze ( ) ;
564+
565+ assert_eq ! ( v1, v2) ;
566+ }
567+
568+ #[ test]
569+ fn test_binaryview_eq_all_nulls ( ) {
570+ let mut v1 = StringVectorMut :: with_capacity ( 3 ) ;
571+ v1. append_nulls ( 3 ) ;
572+ let v1 = v1. freeze ( ) ;
573+
574+ let mut v2 = StringVectorMut :: with_capacity ( 3 ) ;
575+ v2. append_nulls ( 3 ) ;
576+ let v2 = v2. freeze ( ) ;
577+
578+ assert_eq ! ( v1, v2) ;
579+ }
391580}
0 commit comments