/* * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// The first word often contains an interesting bit, either due to // density or because of features of the calling algorithm. So it's // important to examine that first word with a minimum of fuss, // minimizing setup time for later words that will be wasted if the // first word is indeed interesting.
// The benefit from aligned_right being true is relatively small. // It saves an operation in the setup for the word search loop. // It also eliminates the range check on the final result. // However, callers often have a comparison with r_index, and // inlining often allows the two comparisons to be combined; it is // important when !aligned_right that return paths either return // r_index or a value dominated by a comparison with r_index. // aligned_right is still helpful when the caller doesn't have a // range check because features of the calling algorithm guarantee // an interesting bit will be present.
if (l_index < r_index) { // Get the word containing l_index, and shift out low bits.
idx_t index = to_words_align_down(l_index);
bm_word_t cword = (map(index) ^ flip) >> bit_in_word(l_index); if ((cword & 1) != 0) { // The first bit is similarly often interesting. When it matters // (density or features of the calling algorithm make it likely // the first bit is set), going straight to the next clause compares // poorly with doing this check first; count_trailing_zeros can be // relatively expensive, plus there is the additional range check. // But when the first bit isn't set, the cost of having tested for // it is relatively small compared to the rest of the search. return l_index;
} elseif (cword != 0) { // Flipped and shifted first word is non-zero.
idx_t result = l_index + count_trailing_zeros(cword); if (aligned_right || (result < r_index)) return result; // Result is beyond range bound; return r_index.
} else { // Flipped and shifted first word is zero. Word search through // aligned up r_index for a non-zero flipped word.
idx_t limit = aligned_right
? to_words_align_down(r_index) // Minuscule savings when aligned.
: to_words_align_up(r_index); while (++index < limit) {
cword = map(index) ^ flip; if (cword != 0) {
idx_t result = bit_index(index) + count_trailing_zeros(cword); if (aligned_right || (result < r_index)) return result; // Result is beyond range bound; return r_index.
assert((index + 1) == limit, "invariant"); break;
}
} // No bits in range; return r_index.
}
} return r_index;
}
// Returns a bit mask for a range of bits [beg, end) within a single word. Each // bit in the mask is 0 if the bit is in the range, 1 if not in the range. The // returned mask can be used directly to clear the range, or inverted to set the // range. Note: end must not be 0. inline BitMap::bm_word_t
BitMap::inverted_bit_mask_for_range(idx_t beg, idx_t end) const {
assert(end != 0, "does not work when end == 0");
assert(beg == end || to_words_align_down(beg) == to_words_align_down(end - 1), "must be a single-word range");
bm_word_t mask = bit_mask(beg) - 1; // low (right) bits if (bit_in_word(end) != 0) {
mask |= ~(bit_mask(end) - 1); // high (left) bits
} return mask;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.