From 0235c04759eca374fa3998fb9b8934523987372d Mon Sep 17 00:00:00 2001 From: X512 Date: Tue, 25 Jul 2023 05:50:08 +0900 Subject: [PATCH] util/Bitmap: add more utility methods Change-Id: I021c2fafa01266e8a38c1cb2fd748fd89a4b75bd Reviewed-on: https://review.haiku-os.org/c/haiku/+/6742 Reviewed-by: waddlesplash --- headers/private/kernel/util/Bitmap.h | 7 +++- src/system/kernel/util/Bitmap.cpp | 61 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/headers/private/kernel/util/Bitmap.h b/headers/private/kernel/util/Bitmap.h index e6f6d69627..18eb1d8985 100644 --- a/headers/private/kernel/util/Bitmap.h +++ b/headers/private/kernel/util/Bitmap.h @@ -22,7 +22,7 @@ namespace BKernel { class Bitmap { public: - Bitmap(size_t bitCount); + Bitmap(size_t bitCount = 0); ~Bitmap(); status_t InitCheck(); @@ -34,6 +34,11 @@ public: inline void Set(size_t index); inline void Clear(size_t index); + void SetRange(size_t index, size_t count); + void ClearRange(size_t index, size_t count); + + ssize_t GetLowestClear(size_t fromIndex = 0) const; + ssize_t GetLowestContiguousClear(size_t count, size_t fromIndex = 0) const; ssize_t GetHighestSet() const; private: diff --git a/src/system/kernel/util/Bitmap.cpp b/src/system/kernel/util/Bitmap.cpp index a47b871a3f..0a11af94b5 100644 --- a/src/system/kernel/util/Bitmap.cpp +++ b/src/system/kernel/util/Bitmap.cpp @@ -70,6 +70,67 @@ Bitmap::Shift(ssize_t bitCount) } +void +Bitmap::SetRange(size_t index, size_t count) +{ + // TODO: optimize + for (; count > 0; count--) + Set(index++); +} + + +void +Bitmap::ClearRange(size_t index, size_t count) +{ + // TODO: optimize + for (; count > 0; count--) + Clear(index++); +} + + +ssize_t +Bitmap::GetLowestClear(size_t fromIndex) const +{ + // TODO: optimize + + for (size_t i = fromIndex; i < fSize; i++) { + if (!Get(i)) + return i; + } + return -1; +} + + +ssize_t +Bitmap::GetLowestContiguousClear(size_t count, size_t fromIndex) const +{ + // TODO: optimize + + // nothing to find + if (count == 0) + return fromIndex; + + for (;;) { + ssize_t index = GetLowestClear(fromIndex); + if (index < 0) + return index; + + // overflow check + if ((size_t)index + count - 1 < (size_t)index) + return -1; + + size_t curCount = 1; + while (curCount < count && Get(index + curCount)) + curCount++; + + if (curCount == count) + return index; + + fromIndex = index + curCount; + } +} + + ssize_t Bitmap::GetHighestSet() const {