@@ -1948,6 +1948,11 @@ roaring64_bitmap_t *roaring64_bitmap_add_offset_signed(
19481948 return answer ;
19491949 }
19501950
1951+ // Track the most recently inserted hi container so that the next
1952+ // iteration's lo can merge with it without re-searching the ART.
1953+ leaf_t * prev_hi_leaf = NULL ;
1954+ int64_t prev_hi_k = -1 ;
1955+
19511956 while (it .value != NULL ) {
19521957 leaf_t leaf = (leaf_t )* it .value ;
19531958 int64_t k = (int64_t )(combine_key (it .key , 0 ) >> 16 ) + container_offset ;
@@ -1972,31 +1977,33 @@ roaring64_bitmap_t *roaring64_bitmap_add_offset_signed(
19721977 container_add_offset (c , typecode , lo_ptr , hi_ptr , in_offset );
19731978
19741979 if (lo != NULL ) {
1975- uint8_t lo_high48 [ART_KEY_BYTES ];
1976- split_key ((uint64_t )k << 16 , lo_high48 );
1977- leaf_t * existing_leaf = (leaf_t * )art_find (& answer -> art , lo_high48 );
1978- if (existing_leaf != NULL ) {
1979- uint8_t existing_type = get_typecode (* existing_leaf );
1980- container_t * existing_c = get_container (answer , * existing_leaf );
1980+ if (prev_hi_leaf != NULL && prev_hi_k == k ) {
1981+ uint8_t existing_type = get_typecode (* prev_hi_leaf );
1982+ container_t * existing_c = get_container (answer , * prev_hi_leaf );
19811983 uint8_t merged_type ;
19821984 container_t * merged_c = container_ior (
19831985 existing_c , existing_type , lo , typecode , & merged_type );
19841986 if (merged_c != existing_c ) {
19851987 container_free (existing_c , existing_type );
19861988 }
1987- replace_container (answer , existing_leaf , merged_c , merged_type );
1989+ replace_container (answer , prev_hi_leaf , merged_c , merged_type );
19881990 container_free (lo , typecode );
19891991 } else {
1992+ uint8_t lo_high48 [ART_KEY_BYTES ];
1993+ split_key ((uint64_t )k << 16 , lo_high48 );
19901994 leaf_t new_leaf = add_container (answer , lo , typecode );
19911995 art_insert (& answer -> art , lo_high48 , (art_val_t )new_leaf );
19921996 }
19931997 }
19941998
1999+ prev_hi_leaf = NULL ;
19952000 if (hi != NULL ) {
19962001 uint8_t hi_high48 [ART_KEY_BYTES ];
19972002 split_key ((uint64_t )(k + 1 ) << 16 , hi_high48 );
19982003 leaf_t new_leaf = add_container (answer , hi , typecode );
1999- art_insert (& answer -> art , hi_high48 , (art_val_t )new_leaf );
2004+ prev_hi_leaf = (leaf_t * )art_insert (& answer -> art , hi_high48 ,
2005+ (art_val_t )new_leaf );
2006+ prev_hi_k = k + 1 ;
20002007 }
20012008
20022009 art_iterator_next (& it );
0 commit comments