5858 * rightmost_one_pos[x] gives the bit number (0-7) of the rightmost one bit
5959 * in a nonzero byte value x. The entry for x=0 is never used.
6060 *
61+ * leftmost_one_pos[x] gives the bit number (0-7) of the leftmost one bit in a
62+ * nonzero byte value x. The entry for x=0 is never used.
63+ *
6164 * number_of_ones[x] gives the number of one-bits (0-8) in a byte value x.
6265 *
6366 * We could make these tables larger and reduce the number of iterations
@@ -84,6 +87,25 @@ static const uint8 rightmost_one_pos[256] = {
8487 4 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0
8588};
8689
90+ static const uint8 leftmost_one_pos [256 ] = {
91+ 0 , 0 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 ,
92+ 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 ,
93+ 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
94+ 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
95+ 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
96+ 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
97+ 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
98+ 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
99+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
100+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
101+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
102+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
103+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
104+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
105+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
106+ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7
107+ };
108+
87109static const uint8 number_of_ones [256 ] = {
88110 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 ,
89111 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,
@@ -1088,6 +1110,79 @@ bms_next_member(const Bitmapset *a, int prevbit)
10881110 return -2 ;
10891111}
10901112
1113+ /*
1114+ * bms_prev_member - find prev member of a set
1115+ *
1116+ * Returns largest member less than "prevbit", or -2 if there is none.
1117+ * "prevbit" must NOT be more than one above the highest possible bit that can
1118+ * be set at the Bitmapset at its current size.
1119+ *
1120+ * To ease finding the highest set bit for the initial loop, the special
1121+ * prevbit value of -1 can be passed to have the function find the highest
1122+ * valued member in the set.
1123+ *
1124+ * This is intended as support for iterating through the members of a set in
1125+ * reverse. The typical pattern is
1126+ *
1127+ * x = -1;
1128+ * while ((x = bms_prev_member(inputset, x)) >= 0)
1129+ * process member x;
1130+ *
1131+ * Notice that when there are no more members, we return -2, not -1 as you
1132+ * might expect. The rationale for that is to allow distinguishing the
1133+ * loop-not-started state (x == -1) from the loop-completed state (x == -2).
1134+ * It makes no difference in simple loop usage, but complex iteration logic
1135+ * might need such an ability.
1136+ */
1137+
1138+ int
1139+ bms_prev_member (const Bitmapset * a , int prevbit )
1140+ {
1141+ int wordnum ;
1142+ int ushiftbits ;
1143+ bitmapword mask ;
1144+
1145+ /*
1146+ * If set is NULL or if there are no more bits to the right then we've
1147+ * nothing to do.
1148+ */
1149+ if (a == NULL || prevbit == 0 )
1150+ return -2 ;
1151+
1152+ /* transform -1 to the highest possible bit we could have set */
1153+ if (prevbit == -1 )
1154+ prevbit = a -> nwords * BITS_PER_BITMAPWORD - 1 ;
1155+ else
1156+ prevbit -- ;
1157+
1158+ ushiftbits = BITS_PER_BITMAPWORD - (BITNUM (prevbit ) + 1 );
1159+ mask = (~(bitmapword ) 0 ) >> ushiftbits ;
1160+ for (wordnum = WORDNUM (prevbit ); wordnum >= 0 ; wordnum -- )
1161+ {
1162+ bitmapword w = a -> words [wordnum ];
1163+
1164+ /* mask out bits left of prevbit */
1165+ w &= mask ;
1166+
1167+ if (w != 0 )
1168+ {
1169+ int result ;
1170+ int shift = 24 ;
1171+ result = wordnum * BITS_PER_BITMAPWORD ;
1172+
1173+ while ((w >> shift ) == 0 )
1174+ shift -= 8 ;
1175+
1176+ result += shift + leftmost_one_pos [(w >> shift ) & 255 ];
1177+ return result ;
1178+ }
1179+
1180+ /* in subsequent words, consider all bits */
1181+ mask = (~(bitmapword ) 0 );
1182+ }
1183+ return -2 ;
1184+ }
1185+
10911186/*
10921187 * bms_hash_value - compute a hash key for a Bitmapset
10931188 *
0 commit comments