Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8251322: Improve BitMap::iterate
Rewrite and inline BitMap::iterate.

Reviewed-by: stuefe, dholmes, tschatzl
  • Loading branch information
Kim Barrett committed Aug 10, 2020
1 parent fc913d4 commit 785aa0f844f8368b49db3d8de10eb097b468979d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 36 deletions.
@@ -627,32 +627,6 @@ void BitMap::clear_large() {
clear_large_range_of_words(0, size_in_words());
}

// Note that if the closure itself modifies the bitmap
// then modifications in and to the left of the _bit_ being
// currently sampled will not be seen. Note also that the
// interval [leftOffset, rightOffset) is right open.
bool BitMap::iterate(BitMapClosure* blk, idx_t leftOffset, idx_t rightOffset) {
verify_range(leftOffset, rightOffset);

idx_t startIndex = to_words_align_down(leftOffset);
idx_t endIndex = to_words_align_up(rightOffset);
for (idx_t index = startIndex, offset = leftOffset;
offset < rightOffset && index < endIndex;
offset = (++index) << LogBitsPerWord) {
idx_t rest = map(index) >> (offset & (BitsPerWord - 1));
for (; offset < rightOffset && rest != 0; offset++) {
if (rest & 1) {
if (!blk->do_bit(offset)) return false;
// resample at each closure application
// (see, for instance, CMS bug 4525989)
rest = map(index) >> (offset & (BitsPerWord -1));
}
rest = rest >> 1;
}
}
return true;
}

BitMap::idx_t BitMap::count_one_bits_in_range_of_words(idx_t beg_full_word, idx_t end_full_word) const {
idx_t sum = 0;
for (idx_t i = beg_full_word; i < end_full_word; i++) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, 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
@@ -284,14 +284,16 @@ class BitMap {
void clear_large();
inline void clear();

// Iteration support. Returns "true" if the iteration completed, false
// if the iteration terminated early (because the closure "blk" returned
// false).
bool iterate(BitMapClosure* blk, idx_t leftIndex, idx_t rightIndex);
bool iterate(BitMapClosure* blk) {
// call the version that takes an interval
return iterate(blk, 0, size());
}
// Iteration support. Applies the closure to the index for each set bit,
// starting from the least index in the range to the greatest, in order.
// The iteration terminates if the closure returns false. Returns true if
// the iteration completed, false if terminated early because the closure
// returned false. If the closure modifies the bitmap, modifications to
// bits at indices greater than the current index will affect which further
// indices the closure will be applied to.
// precondition: beg and end form a valid range.
bool iterate(BitMapClosure* cl, idx_t beg, idx_t end);
bool iterate(BitMapClosure* cl);

// Looking for 1's and 0's at indices equal to or greater than "l_index",
// stopping if none has been found before "r_index", and returning
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2020, 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
@@ -242,6 +242,21 @@ BitMap::get_next_one_offset_aligned_right(idx_t l_offset, idx_t r_offset) const
return get_next_bit_impl<find_ones_flip, true>(l_offset, r_offset);
}

inline bool BitMap::iterate(BitMapClosure* cl, idx_t beg, idx_t end) {
for (idx_t index = beg; true; ++index) {
index = get_next_one_offset(index, end);
if (index >= end) {
return true;
} else if (!cl->do_bit(index)) {
return false;
}
}
}

inline bool BitMap::iterate(BitMapClosure* cl) {
return iterate(cl, 0, size());
}

// 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

0 comments on commit 785aa0f

Please sign in to comment.