Skip to content

Instantly share code, notes, and snippets.

@ayende
Last active June 11, 2020 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayende/fb0ee0b4a238f4e1619101f7c2e0c4a6 to your computer and use it in GitHub Desktop.
Save ayende/fb0ee0b4a238f4e1619101f7c2e0c4a6 to your computer and use it in GitHub Desktop.
static bool handle_zero_word(struct range_finder *restrict range) {
range->current_set_bit = (range->index + 1) * 64;
if (range->current_set_bit > range->previous_set_bit + range->size_required) {
range->selected_position =
range->previous_set_bit + 1; // intentionally overflowing here
range->size_available = (range->current_set_bit - range->selected_position);
return true;
}
return false;
}
static bool find_range_once(struct range_finder *restrict range) {
uint64_t bitset = range->current;
if (bitset == ULONG_MAX) {
// all bits are set, can skip whole thing
range->previous_set_bit = (range->index + 1) * 64 - 1;
return false;
}
if (bitset == 0) {
return handle_zero_word(range);
}
while (bitset != 0) {
int r = __builtin_ctzl(bitset);
range->current_set_bit = (range->index) * 64 + (uint64_t)r;
if (range->current_set_bit >
range->previous_set_bit + range->size_required) {
// intentionally overflowing here
range->selected_position = range->previous_set_bit + 1;
range->size_available =
(range->current_set_bit - range->selected_position);
range->previous_set_bit = range->current_set_bit;
return true;
}
range->previous_set_bit = range->current_set_bit;
bitset ^= (bitset & -bitset);
}
return handle_zero_word(range);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment