58
58
* rightmost_one_pos[x] gives the bit number (0-7) of the rightmost one bit
59
59
* in a nonzero byte value x. The entry for x=0 is never used.
60
60
*
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
+ *
61
64
* number_of_ones[x] gives the number of one-bits (0-8) in a byte value x.
62
65
*
63
66
* We could make these tables larger and reduce the number of iterations
@@ -84,6 +87,25 @@ static const uint8 rightmost_one_pos[256] = {
84
87
4 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0
85
88
};
86
89
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
+
87
109
static const uint8 number_of_ones [256 ] = {
88
110
0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 ,
89
111
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)
1088
1110
return -2 ;
1089
1111
}
1090
1112
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
+
1091
1186
/*
1092
1187
* bms_hash_value - compute a hash key for a Bitmapset
1093
1188
*
0 commit comments