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
*