@@ -794,6 +794,171 @@ bool container_iterator_skip_backward(const container_t *c, uint8_t typecode,
794794 return has_value ;
795795}
796796
797+ uint16_t container_iterator_find_run_end (const container_t * c , uint8_t typecode ,
798+ roaring_container_iterator_t * it ,
799+ uint16_t * value , bool * has_more ) {
800+ switch (typecode ) {
801+ case RUN_CONTAINER_TYPE : {
802+ const run_container_t * rc = const_CAST_run (c );
803+ uint16_t run_end =
804+ rc -> runs [it -> index ].value + rc -> runs [it -> index ].length ;
805+ it -> index ++ ;
806+ if (it -> index < rc -> n_runs ) {
807+ * has_more = true;
808+ * value = rc -> runs [it -> index ].value ;
809+ } else {
810+ * has_more = false;
811+ }
812+ return run_end ;
813+ }
814+ case ARRAY_CONTAINER_TYPE : {
815+ const array_container_t * ac = const_CAST_array (c );
816+ uint16_t v = * value ;
817+ while (it -> index + 1 < ac -> cardinality &&
818+ ac -> array [it -> index + 1 ] == (uint16_t )(v + 1 )) {
819+ it -> index ++ ;
820+ v ++ ;
821+ }
822+ it -> index ++ ;
823+ if (it -> index < ac -> cardinality ) {
824+ * has_more = true;
825+ * value = ac -> array [it -> index ];
826+ } else {
827+ * has_more = false;
828+ }
829+ return v ;
830+ }
831+ case BITSET_CONTAINER_TYPE : {
832+ const bitset_container_t * bc = const_CAST_bitset (c );
833+ uint32_t pos = (uint32_t )* value + 1 ;
834+ uint16_t run_end ;
835+ if (pos >= (1 << 16 )) {
836+ * has_more = false;
837+ return UINT16_MAX ;
838+ }
839+ uint32_t wordindex = pos / 64 ;
840+ uint64_t word = ~bc -> words [wordindex ] & (UINT64_MAX << (pos % 64 ));
841+ while (word == 0 &&
842+ wordindex + 1 < BITSET_CONTAINER_SIZE_IN_WORDS ) {
843+ wordindex ++ ;
844+ word = ~bc -> words [wordindex ];
845+ }
846+ if (word != 0 ) {
847+ run_end = (uint16_t )(wordindex * 64 +
848+ roaring_trailing_zeroes (word ) - 1 );
849+ } else {
850+ run_end = UINT16_MAX ;
851+ }
852+ uint32_t next_pos = (uint32_t )run_end + 1 ;
853+ if (next_pos >= (1 << 16 )) {
854+ * has_more = false;
855+ } else {
856+ wordindex = next_pos / 64 ;
857+ word = bc -> words [wordindex ] & (UINT64_MAX << (next_pos % 64 ));
858+ while (word == 0 &&
859+ wordindex + 1 < BITSET_CONTAINER_SIZE_IN_WORDS ) {
860+ wordindex ++ ;
861+ word = bc -> words [wordindex ];
862+ }
863+ if (word != 0 ) {
864+ * has_more = true;
865+ it -> index = wordindex * 64 + roaring_trailing_zeroes (word );
866+ * value = (uint16_t )it -> index ;
867+ } else {
868+ * has_more = false;
869+ }
870+ }
871+ return run_end ;
872+ }
873+ default :
874+ assert (false);
875+ roaring_unreachable ;
876+ return 0 ;
877+ }
878+ }
879+
880+ uint16_t container_iterator_find_run_start (const container_t * c ,
881+ uint8_t typecode ,
882+ roaring_container_iterator_t * it ,
883+ uint16_t * value , bool * has_more ) {
884+ switch (typecode ) {
885+ case RUN_CONTAINER_TYPE : {
886+ const run_container_t * rc = const_CAST_run (c );
887+ uint16_t run_start = rc -> runs [it -> index ].value ;
888+ it -> index -- ;
889+ if (it -> index >= 0 ) {
890+ * has_more = true;
891+ * value = rc -> runs [it -> index ].value + rc -> runs [it -> index ].length ;
892+ } else {
893+ * has_more = false;
894+ }
895+ return run_start ;
896+ }
897+ case ARRAY_CONTAINER_TYPE : {
898+ const array_container_t * ac = const_CAST_array (c );
899+ uint16_t v = * value ;
900+ while (it -> index > 0 &&
901+ ac -> array [it -> index - 1 ] == (uint16_t )(v - 1 )) {
902+ it -> index -- ;
903+ v -- ;
904+ }
905+ it -> index -- ;
906+ if (it -> index >= 0 ) {
907+ * has_more = true;
908+ * value = ac -> array [it -> index ];
909+ } else {
910+ * has_more = false;
911+ }
912+ return v ;
913+ }
914+ case BITSET_CONTAINER_TYPE : {
915+ const bitset_container_t * bc = const_CAST_bitset (c );
916+ if (* value == 0 ) {
917+ * has_more = false;
918+ return 0 ;
919+ }
920+ uint32_t pos = (uint32_t )* value - 1 ;
921+ int32_t wordindex = (int32_t )(pos / 64 );
922+ uint64_t word =
923+ ~bc -> words [wordindex ] & (UINT64_MAX >> (63 - (pos % 64 )));
924+ while (word == 0 && -- wordindex >= 0 ) {
925+ word = ~bc -> words [wordindex ];
926+ }
927+ uint16_t run_start ;
928+ if (word != 0 ) {
929+ run_start = (uint16_t )(wordindex * 64 +
930+ (63 - roaring_leading_zeroes (word )) + 1 );
931+ } else {
932+ run_start = 0 ;
933+ }
934+ if (run_start == 0 ) {
935+ * has_more = false;
936+ } else {
937+ int32_t prev_pos = (int32_t )run_start - 1 ;
938+ wordindex = prev_pos / 64 ;
939+ word = bc -> words [wordindex ] &
940+ (UINT64_MAX >> (63 - (prev_pos % 64 )));
941+ while (word == 0 && -- wordindex >= 0 ) {
942+ word = bc -> words [wordindex ];
943+ }
944+ if (word != 0 ) {
945+ * has_more = true;
946+ it -> index =
947+ wordindex * 64 + (63 - roaring_leading_zeroes (word ));
948+ * value = (uint16_t )it -> index ;
949+ } else {
950+ * has_more = false;
951+ }
952+ }
953+ return run_start ;
954+ }
955+ default :
956+ assert (false);
957+ roaring_unreachable ;
958+ return 0 ;
959+ }
960+ }
961+
797962#ifdef __cplusplus
798963}
799964}
0 commit comments