aboutsummaryrefslogtreecommitdiffstats
path: root/util/generic/bitmap.h
diff options
context:
space:
mode:
authorMaxim Yurchuk <maxim-yurchuk@ydb.tech>2024-11-20 17:37:57 +0000
committerGitHub <noreply@github.com>2024-11-20 17:37:57 +0000
commitf76323e9b295c15751e51e3443aa47a36bee8023 (patch)
tree4113c8cad473a33e0f746966e0cf087252fa1d7a /util/generic/bitmap.h
parent753ecb8d410a4cb459c26f3a0082fb2d1724fe63 (diff)
parenta7b9a6afea2a9d7a7bfac4c5eb4c1a8e60adb9e6 (diff)
downloadydb-f76323e9b295c15751e51e3443aa47a36bee8023.tar.gz
Merge pull request #11788 from ydb-platform/mergelibs-241120-1113
Library import 241120-1113
Diffstat (limited to 'util/generic/bitmap.h')
-rw-r--r--util/generic/bitmap.h97
1 files changed, 63 insertions, 34 deletions
diff --git a/util/generic/bitmap.h b/util/generic/bitmap.h
index 929f23a883..3116c8dd19 100644
--- a/util/generic/bitmap.h
+++ b/util/generic/bitmap.h
@@ -350,19 +350,21 @@ public:
~TReference() = default;
Y_FORCE_INLINE TReference& operator=(bool val) {
- if (val)
+ if (val) {
*Chunk |= static_cast<TChunk>(1) << Offset;
- else
+ } else {
*Chunk &= ~(static_cast<TChunk>(1) << Offset);
+ }
return *this;
}
Y_FORCE_INLINE TReference& operator=(const TReference& ref) {
- if (ref)
+ if (ref) {
*Chunk |= static_cast<TChunk>(1) << Offset;
- else
+ } else {
*Chunk &= ~(static_cast<TChunk>(1) << Offset);
+ }
return *this;
}
@@ -407,8 +409,9 @@ private:
TChunk updateMask = FullChunk << bitOffset;
if (chunk == endChunk) {
updateMask ^= FullChunk << endBitOffset;
- if (!updateMask)
+ if (!updateMask) {
break;
+ }
}
Mask.Data[chunk] = TUpdateOp::Op(Mask.Data[chunk], updateMask);
bitOffset = 0;
@@ -570,16 +573,18 @@ public:
static_assert(std::is_unsigned<TTo>::value, "expect std::is_unsigned<TTo>::value");
to = 0;
size_t chunkpos = pos >> DivCount;
- if (chunkpos >= Mask.GetChunkCapacity())
+ if (chunkpos >= Mask.GetChunkCapacity()) {
return;
+ }
if ((pos & ModMask) == 0) {
- if (sizeof(TChunk) >= sizeof(TTo))
+ if (sizeof(TChunk) >= sizeof(TTo)) {
to = (TTo)Mask.Data[chunkpos];
- else // if (sizeof(TChunk) < sizeof(TTo))
+ } else { // if (sizeof(TChunk) < sizeof(TTo))
NBitMapPrivate::CopyData(&to, 1, Mask.Data + chunkpos, Min(((sizeof(TTo) * 8) >> DivCount), Mask.GetChunkCapacity() - chunkpos));
- } else if ((pos & (sizeof(TTo) * 8 - 1)) == 0 && sizeof(TChunk) >= 2 * sizeof(TTo))
+ }
+ } else if ((pos & (sizeof(TTo) * 8 - 1)) == 0 && sizeof(TChunk) >= 2 * sizeof(TTo)) {
to = (TTo)(Mask.Data[chunkpos] >> (pos & ModMask));
- else {
+ } else {
static constexpr size_t copyToSize = (sizeof(TChunk) >= sizeof(TTo)) ? (sizeof(TChunk) / sizeof(TTo)) + 2 : 3;
TTo temp[copyToSize] = {0, 0};
// or use non defined by now TBitmap<copyToSize, TTo>::CopyData,RShift(pos & ModMask),Export(0,to)
@@ -621,17 +626,20 @@ public:
Y_FORCE_INLINE size_t ValueBitCount() const {
size_t nonZeroChunk = Mask.GetChunkCapacity() - 1;
- while (nonZeroChunk != 0 && !Mask.Data[nonZeroChunk])
+ while (nonZeroChunk != 0 && !Mask.Data[nonZeroChunk]) {
--nonZeroChunk;
+ }
return nonZeroChunk || Mask.Data[nonZeroChunk]
? nonZeroChunk * BitsPerChunk + GetValueBitCount(TIntType(Mask.Data[nonZeroChunk]))
: 0;
}
Y_PURE_FUNCTION Y_FORCE_INLINE bool Empty() const {
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
- if (Mask.Data[i])
+ for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
+ if (Mask.Data[i]) {
return false;
+ }
+ }
return true;
}
@@ -679,11 +687,13 @@ public:
TThis& And(const TThis& bitmap) {
// Don't expand capacity here, because resulting bits in positions,
// which are greater then size of one of these bitmaps, will be zero
- for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
+ for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i) {
Mask.Data[i] &= bitmap.Mask.Data[i];
+ }
// Clear bits if current bitmap size is greater than AND-ed one
- for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i)
+ for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
Mask.Data[i] = 0;
+ }
return *this;
}
@@ -694,8 +704,9 @@ public:
Y_FORCE_INLINE TThis& And(const TChunk& val) {
Mask.Data[0] &= val;
- for (size_t i = 1; i < Mask.GetChunkCapacity(); ++i)
+ for (size_t i = 1; i < Mask.GetChunkCapacity(); ++i) {
Mask.Data[i] = 0;
+ }
return *this;
}
@@ -704,8 +715,9 @@ public:
if (valueBitCount) {
// Memory optimization: expand size only for non-zero bits
Reserve(valueBitCount);
- for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
+ for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i) {
Mask.Data[i] |= bitmap.Mask.Data[i];
+ }
}
return *this;
}
@@ -723,8 +735,9 @@ public:
TThis& Xor(const TThis& bitmap) {
Reserve(bitmap.Size());
- for (size_t i = 0; i < bitmap.Mask.GetChunkCapacity(); ++i)
+ for (size_t i = 0; i < bitmap.Mask.GetChunkCapacity(); ++i) {
Mask.Data[i] ^= bitmap.Mask.Data[i];
+ }
return *this;
}
@@ -740,8 +753,9 @@ public:
}
TThis& SetDifference(const TThis& bitmap) {
- for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
+ for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i) {
Mask.Data[i] &= ~bitmap.Mask.Data[i];
+ }
return *this;
}
@@ -756,8 +770,9 @@ public:
}
Y_FORCE_INLINE TThis& Flip() {
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
+ for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
Mask.Data[i] = ~Mask.Data[i];
+ }
Mask.Sanitize();
return *this;
}
@@ -779,13 +794,16 @@ public:
Mask.Data[i] = Mask.Data[i - eshift];
}
} else {
- for (size_t i = Mask.GetChunkCapacity() - 1; i > eshift; --i)
+ for (size_t i = Mask.GetChunkCapacity() - 1; i > eshift; --i) {
Mask.Data[i] = (Mask.Data[i - eshift] << offset) | (Mask.Data[i - eshift - 1] >> subOffset);
- if (eshift < Mask.GetChunkCapacity())
+ }
+ if (eshift < Mask.GetChunkCapacity()) {
Mask.Data[eshift] = Mask.Data[0] << offset;
+ }
}
- for (size_t i = 0; i < Min(eshift, Mask.GetChunkCapacity()); ++i)
+ for (size_t i = 0; i < Min(eshift, Mask.GetChunkCapacity()); ++i) {
Mask.Data[i] = 0;
+ }
// Cleanup extra high bits in the storage
Mask.Sanitize();
@@ -810,13 +828,15 @@ public:
}
} else {
const size_t subOffset = BitsPerChunk - offset;
- for (size_t i = 0; i < limit; ++i)
+ for (size_t i = 0; i < limit; ++i) {
Mask.Data[i] = (Mask.Data[i + eshift] >> offset) | (Mask.Data[i + eshift + 1] << subOffset);
+ }
Mask.Data[limit] = Mask.Data[Mask.GetChunkCapacity() - 1] >> offset;
}
- for (size_t i = limit + 1; i < Mask.GetChunkCapacity(); ++i)
+ for (size_t i = limit + 1; i < Mask.GetChunkCapacity(); ++i) {
Mask.Data[i] = 0;
+ }
}
}
return *this;
@@ -826,8 +846,9 @@ public:
// This method is optimized combination of Or() and LShift(), which allows reducing memory allocation
// when combining long dynamic bitmaps.
TThis& Or(const TThis& bitmap, size_t offset) {
- if (0 == offset)
+ if (0 == offset) {
return Or(bitmap);
+ }
const size_t otherValueBitCount = bitmap.ValueBitCount();
// Continue only if OR-ed bitmap have non-zero bits
@@ -848,8 +869,9 @@ public:
for (; i < Min(bitmap.Mask.GetChunkCapacity() + chunkShift, Mask.GetChunkCapacity()); ++i) {
Mask.Data[i] |= (bitmap.Mask.Data[i - chunkShift] << subShift) | (bitmap.Mask.Data[i - chunkShift - 1] >> subOffset);
}
- if (i < Mask.GetChunkCapacity())
+ if (i < Mask.GetChunkCapacity()) {
Mask.Data[i] |= bitmap.Mask.Data[i - chunkShift - 1] >> subOffset;
+ }
}
}
@@ -859,19 +881,22 @@ public:
bool Equal(const TThis& bitmap) const {
if (Mask.GetChunkCapacity() > bitmap.Mask.GetChunkCapacity()) {
for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
- if (0 != Mask.Data[i])
+ if (0 != Mask.Data[i]) {
return false;
+ }
}
} else if (Mask.GetChunkCapacity() < bitmap.Mask.GetChunkCapacity()) {
for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
- if (0 != bitmap.Mask.Data[i])
+ if (0 != bitmap.Mask.Data[i]) {
return false;
+ }
}
}
size_t size = Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity());
for (size_t i = 0; i < size; ++i) {
- if (Mask.Data[i] != bitmap.Mask.Data[i])
+ if (Mask.Data[i] != bitmap.Mask.Data[i]) {
return false;
+ }
}
return true;
}
@@ -884,18 +909,21 @@ public:
int Compare(const TThis& bitmap) const {
size_t size = Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity());
int res = ::memcmp(Mask.Data, bitmap.Mask.Data, size * sizeof(TChunk));
- if (0 != res || Mask.GetChunkCapacity() == bitmap.Mask.GetChunkCapacity())
+ if (0 != res || Mask.GetChunkCapacity() == bitmap.Mask.GetChunkCapacity()) {
return res;
+ }
if (Mask.GetChunkCapacity() > bitmap.Mask.GetChunkCapacity()) {
for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
- if (0 != Mask.Data[i])
+ if (0 != Mask.Data[i]) {
return 1;
+ }
}
} else {
for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
- if (0 != bitmap.Mask.Data[i])
+ if (0 != bitmap.Mask.Data[i]) {
return -1;
+ }
}
}
return 0;
@@ -953,8 +981,9 @@ public:
Y_FORCE_INLINE size_t Count() const {
size_t count = 0;
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
+ for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
count += ::NBitMapPrivate::CountBitsPrivate(Mask.Data[i]);
+ }
return count;
}