diff --git a/luna/include/luna/Bitmap.h b/luna/include/luna/Bitmap.h index 1ef3e239..1302a399 100644 --- a/luna/include/luna/Bitmap.h +++ b/luna/include/luna/Bitmap.h @@ -39,6 +39,10 @@ class Bitmap Option find_and_toggle(bool value, usize begin = 0); + Option find_region(bool value, usize count, usize begin = 0) const; + + Option find_and_toggle_region(bool value, usize count, usize begin = 0); + void clear(bool value); void clear_region(usize start, usize bits, bool value); diff --git a/luna/src/Bitmap.cpp b/luna/src/Bitmap.cpp index d5ba4aa8..9ee2d099 100644 --- a/luna/src/Bitmap.cpp +++ b/luna/src/Bitmap.cpp @@ -132,3 +132,38 @@ Option Bitmap::find_and_toggle(bool value, usize begin) set(index, !value); return index; } + +Option Bitmap::find_region(bool value, usize count, usize begin) const +{ + // FIXME: Optimize this using bit and byte manipulation. + u64 region_bits_found = 0; + u64 region_start = 0; + + for (u64 index = begin; index < m_size_in_bytes * 8; index++) + { + if (get(index) != value) + { + region_bits_found = 0; + continue; + } + + if (region_bits_found == 0) + { + region_start = index; + region_bits_found++; + } + else + region_bits_found++; + + if (region_bits_found == count) return region_start; + } + + return {}; +} + +Option Bitmap::find_and_toggle_region(bool value, usize count, usize begin) +{ + usize index = TRY(find_region(value, count, begin)); + clear_region(index, count, !value); + return index; +}