forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.3 KiB
102 lines
2.3 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* From lib/bitmap.c |
|
* Helper functions for bitmap.h. |
|
*/ |
|
#include <linux/bitmap.h> |
|
|
|
int __bitmap_weight(const unsigned long *bitmap, int bits) |
|
{ |
|
int k, w = 0, lim = bits/BITS_PER_LONG; |
|
|
|
for (k = 0; k < lim; k++) |
|
w += hweight_long(bitmap[k]); |
|
|
|
if (bits % BITS_PER_LONG) |
|
w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); |
|
|
|
return w; |
|
} |
|
|
|
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, |
|
const unsigned long *bitmap2, int bits) |
|
{ |
|
int k; |
|
int nr = BITS_TO_LONGS(bits); |
|
|
|
for (k = 0; k < nr; k++) |
|
dst[k] = bitmap1[k] | bitmap2[k]; |
|
} |
|
|
|
size_t bitmap_scnprintf(unsigned long *bitmap, unsigned int nbits, |
|
char *buf, size_t size) |
|
{ |
|
/* current bit is 'cur', most recently seen range is [rbot, rtop] */ |
|
unsigned int cur, rbot, rtop; |
|
bool first = true; |
|
size_t ret = 0; |
|
|
|
rbot = cur = find_first_bit(bitmap, nbits); |
|
while (cur < nbits) { |
|
rtop = cur; |
|
cur = find_next_bit(bitmap, nbits, cur + 1); |
|
if (cur < nbits && cur <= rtop + 1) |
|
continue; |
|
|
|
if (!first) |
|
ret += scnprintf(buf + ret, size - ret, ","); |
|
|
|
first = false; |
|
|
|
ret += scnprintf(buf + ret, size - ret, "%d", rbot); |
|
if (rbot < rtop) |
|
ret += scnprintf(buf + ret, size - ret, "-%d", rtop); |
|
|
|
rbot = cur; |
|
} |
|
return ret; |
|
} |
|
|
|
int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, |
|
const unsigned long *bitmap2, unsigned int bits) |
|
{ |
|
unsigned int k; |
|
unsigned int lim = bits/BITS_PER_LONG; |
|
unsigned long result = 0; |
|
|
|
for (k = 0; k < lim; k++) |
|
result |= (dst[k] = bitmap1[k] & bitmap2[k]); |
|
if (bits % BITS_PER_LONG) |
|
result |= (dst[k] = bitmap1[k] & bitmap2[k] & |
|
BITMAP_LAST_WORD_MASK(bits)); |
|
return result != 0; |
|
} |
|
|
|
int __bitmap_equal(const unsigned long *bitmap1, |
|
const unsigned long *bitmap2, unsigned int bits) |
|
{ |
|
unsigned int k, lim = bits/BITS_PER_LONG; |
|
for (k = 0; k < lim; ++k) |
|
if (bitmap1[k] != bitmap2[k]) |
|
return 0; |
|
|
|
if (bits % BITS_PER_LONG) |
|
if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) |
|
return 0; |
|
|
|
return 1; |
|
} |
|
|
|
int __bitmap_intersects(const unsigned long *bitmap1, |
|
const unsigned long *bitmap2, unsigned int bits) |
|
{ |
|
unsigned int k, lim = bits/BITS_PER_LONG; |
|
for (k = 0; k < lim; ++k) |
|
if (bitmap1[k] & bitmap2[k]) |
|
return 1; |
|
|
|
if (bits % BITS_PER_LONG) |
|
if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) |
|
return 1; |
|
return 0; |
|
}
|
|
|