mirror of https://github.com/PentHertz/srsLTE.git
implemented bounded_bitset::find_lowest(...) for both reverse and non-reverse bit ordering. Applied this method to UL scheduling search for PRB intervals
This commit is contained in:
parent
3f15fc2811
commit
22024ac35d
|
@ -27,28 +27,109 @@ constexpr uint32_t ceil_div(uint32_t x, uint32_t y)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Integer>
|
template <typename Integer>
|
||||||
Integer mask_trailing_ones(size_t N)
|
Integer mask_msb_zeros(size_t N)
|
||||||
{
|
{
|
||||||
static_assert(std::is_unsigned<Integer>::value, "T must be unsigned integer");
|
static_assert(std::is_unsigned<Integer>::value, "T must be unsigned integer");
|
||||||
return N == 0 ? 0 : (static_cast<Integer>(-1) >> (sizeof(Integer) * 8U - N));
|
return (N == 0) ? static_cast<Integer>(-1) : (N == sizeof(Integer) * 8U) ? 0 : (static_cast<Integer>(-1) >> (N));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Integer>
|
template <typename Integer>
|
||||||
Integer mask_leading_ones(size_t N)
|
Integer mask_lsb_ones(size_t N)
|
||||||
{
|
{
|
||||||
return ~mask_trailing_ones<Integer>(8U * sizeof(Integer) - N);
|
return mask_msb_zeros<Integer>(sizeof(Integer) * 8U - N);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Integer>
|
template <typename Integer>
|
||||||
Integer mask_trailing_zeros(size_t N)
|
Integer mask_msb_ones(size_t N)
|
||||||
{
|
{
|
||||||
return mask_leading_ones<Integer>(8U * sizeof(Integer) - N);
|
return ~mask_msb_zeros<Integer>(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Integer>
|
template <typename Integer>
|
||||||
Integer mask_leading_zeros(size_t N)
|
Integer mask_lsb_zeros(size_t N)
|
||||||
{
|
{
|
||||||
return mask_trailing_ones<Integer>(8U * sizeof(Integer) - N);
|
return ~mask_lsb_ones<Integer>(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Integer, size_t SizeOf>
|
||||||
|
struct zerobit_counter {
|
||||||
|
static Integer msb_count(Integer value)
|
||||||
|
{
|
||||||
|
if (value == 0) {
|
||||||
|
return std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
Integer ret = 0;
|
||||||
|
for (Integer shift = std::numeric_limits<Integer>::digits >> 1; shift != 0; shift >>= 1) {
|
||||||
|
Integer tmp = value >> shift;
|
||||||
|
if (tmp != 0) {
|
||||||
|
value = tmp;
|
||||||
|
} else {
|
||||||
|
ret |= shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
static Integer lsb_count(Integer value)
|
||||||
|
{
|
||||||
|
if (value == 0) {
|
||||||
|
return std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
Integer ret = 0;
|
||||||
|
for (Integer shift = std::numeric_limits<Integer>::digits >> 1, mask = std::numeric_limits<Integer>::max() >> shift;
|
||||||
|
shift != 0;
|
||||||
|
shift >>= 1, mask >>= shift) {
|
||||||
|
if ((value & mask) == 0) {
|
||||||
|
value >>= shift;
|
||||||
|
ret |= shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Specializations for unsigned
|
||||||
|
template <typename Integer>
|
||||||
|
struct zerobit_counter<Integer, sizeof(unsigned)> {
|
||||||
|
static Integer msb_count(Integer value)
|
||||||
|
{
|
||||||
|
return (value) ? __builtin_clz(value) : std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
static Integer lsb_count(Integer value)
|
||||||
|
{
|
||||||
|
return (value) ? __builtin_ctz(value) : std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Specializations for unsigned long
|
||||||
|
template <typename Integer>
|
||||||
|
struct zerobit_counter<Integer, sizeof(unsigned long)> {
|
||||||
|
static Integer msb_count(Integer value)
|
||||||
|
{
|
||||||
|
return (value) ? __builtin_clzl(value) : std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
static Integer lsb_count(Integer value)
|
||||||
|
{
|
||||||
|
return (value) ? __builtin_ctzl(value) : std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// uses lsb as zero position
|
||||||
|
template <typename Integer>
|
||||||
|
Integer find_first_msb_one(Integer value)
|
||||||
|
{
|
||||||
|
return (value) ? (sizeof(Integer) * 8U - 1 - detail::zerobit_counter<Integer, sizeof(Integer)>::msb_count(value))
|
||||||
|
: std::numeric_limits<Integer>::digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// uses lsb as zero position
|
||||||
|
template <typename Integer>
|
||||||
|
Integer find_first_lsb_one(Integer value)
|
||||||
|
{
|
||||||
|
return detail::zerobit_counter<Integer, sizeof(Integer)>::lsb_count(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N, bool reversed = false>
|
template <size_t N, bool reversed = false>
|
||||||
|
@ -139,35 +220,17 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_first(size_t startpos, size_t endpos, bool value = true) const noexcept
|
int find_lowest(size_t startpos, size_t endpos, bool value = true) const noexcept
|
||||||
{
|
{
|
||||||
assert_range_bounds_(startpos, endpos);
|
assert_range_bounds_(startpos, endpos);
|
||||||
if (startpos == endpos) {
|
if (startpos == endpos) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t startword = startpos / bits_per_word;
|
if (not reversed) {
|
||||||
size_t lastword = (endpos - 1) / bits_per_word;
|
return find_first_(startpos, endpos, value);
|
||||||
|
|
||||||
for (size_t i = startword; i <= lastword; ++i) {
|
|
||||||
word_t w = buffer[i];
|
|
||||||
if (not value) {
|
|
||||||
w = ~w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == startword) {
|
|
||||||
size_t offset = startpos % bits_per_word;
|
|
||||||
w &= mask_trailing_zeros<word_t>(offset);
|
|
||||||
}
|
|
||||||
if (i == lastword) {
|
|
||||||
size_t offset = (endpos - 1) % bits_per_word;
|
|
||||||
w &= mask_trailing_ones<word_t>(offset + 1);
|
|
||||||
}
|
|
||||||
if (w != 0) {
|
|
||||||
return static_cast<int>(i * bits_per_word + (bits_per_word - __builtin_clzl(w) - 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return find_first_reversed_(startpos, endpos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool all() const noexcept
|
bool all() const noexcept
|
||||||
|
@ -328,33 +391,35 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_(size_t pos) const noexcept
|
size_t get_bitidx_(size_t bitpos) const noexcept { return reversed ? size() - 1 - bitpos : bitpos; }
|
||||||
|
|
||||||
|
bool test_(size_t bitpos) const noexcept
|
||||||
{
|
{
|
||||||
pos = reversed ? size() - 1 - pos : pos;
|
bitpos = get_bitidx_(bitpos);
|
||||||
return ((get_word_(pos) & maskbit(pos)) != static_cast<word_t>(0));
|
return ((get_word_(bitpos) & maskbit(bitpos)) != static_cast<word_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_(size_t pos) noexcept
|
void set_(size_t bitpos) noexcept
|
||||||
{
|
{
|
||||||
pos = reversed ? size() - 1 - pos : pos;
|
bitpos = get_bitidx_(bitpos);
|
||||||
get_word_(pos) |= maskbit(pos);
|
get_word_(bitpos) |= maskbit(bitpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_(size_t pos) noexcept
|
void reset_(size_t bitpos) noexcept
|
||||||
{
|
{
|
||||||
pos = reversed ? size() - 1 - pos : pos;
|
bitpos = get_bitidx_(bitpos);
|
||||||
get_word_(pos) &= ~(maskbit(pos));
|
get_word_(bitpos) &= ~(maskbit(bitpos));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nof_words_() const noexcept { return size() > 0 ? (size() - 1) / bits_per_word + 1 : 0; }
|
size_t nof_words_() const noexcept { return size() > 0 ? (size() - 1) / bits_per_word + 1 : 0; }
|
||||||
|
|
||||||
word_t& get_word_(size_t pos) noexcept { return buffer[pos / bits_per_word]; }
|
word_t& get_word_(size_t bitidx) noexcept { return buffer[bitidx / bits_per_word]; }
|
||||||
|
|
||||||
const word_t& get_word_(size_t pos) const { return buffer[pos / bits_per_word]; }
|
const word_t& get_word_(size_t bitidx) const { return buffer[bitidx / bits_per_word]; }
|
||||||
|
|
||||||
size_t word_idx_(size_t pos) const { return pos / bits_per_word; }
|
size_t word_idx_(size_t pos) const { return pos / bits_per_word; }
|
||||||
|
|
||||||
void assert_within_bounds_(size_t pos, bool strict) const
|
void assert_within_bounds_(size_t pos, bool strict) const noexcept
|
||||||
{
|
{
|
||||||
srsran_assert(pos < size() or (not strict and pos == size()),
|
srsran_assert(pos < size() or (not strict and pos == size()),
|
||||||
"ERROR: index=%zd is out-of-bounds for bitset of size=%zd",
|
"ERROR: index=%zd is out-of-bounds for bitset of size=%zd",
|
||||||
|
@ -362,7 +427,7 @@ private:
|
||||||
size());
|
size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void assert_range_bounds_(size_t startpos, size_t endpos) const
|
void assert_range_bounds_(size_t startpos, size_t endpos) const noexcept
|
||||||
{
|
{
|
||||||
srsran_assert(startpos <= endpos and endpos <= size(),
|
srsran_assert(startpos <= endpos and endpos <= size(),
|
||||||
"ERROR: range [%zd, %zd) out-of-bounds for bitsize of size=%zd",
|
"ERROR: range [%zd, %zd) out-of-bounds for bitsize of size=%zd",
|
||||||
|
@ -371,9 +436,89 @@ private:
|
||||||
size());
|
size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static word_t maskbit(size_t pos) { return (static_cast<word_t>(1)) << (pos % bits_per_word); }
|
static word_t maskbit(size_t pos) noexcept { return (static_cast<word_t>(1)) << (pos % bits_per_word); }
|
||||||
|
|
||||||
static size_t max_nof_words_() { return (N - 1) / bits_per_word + 1; }
|
static size_t max_nof_words_() noexcept { return (N - 1) / bits_per_word + 1; }
|
||||||
|
|
||||||
|
int find_last_(size_t startpos, size_t endpos, bool value) const noexcept
|
||||||
|
{
|
||||||
|
size_t startword = startpos / bits_per_word;
|
||||||
|
size_t lastword = (endpos - 1) / bits_per_word;
|
||||||
|
|
||||||
|
for (size_t i = lastword; i != startpos - 1; --i) {
|
||||||
|
word_t w = buffer[i];
|
||||||
|
if (not value) {
|
||||||
|
w = ~w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == startword) {
|
||||||
|
size_t offset = startpos % bits_per_word;
|
||||||
|
w &= (reversed) ? mask_msb_zeros<word_t>(offset) : mask_lsb_zeros<word_t>(offset);
|
||||||
|
}
|
||||||
|
if (i == lastword) {
|
||||||
|
size_t offset = (endpos - 1) % bits_per_word;
|
||||||
|
w &= (reversed) ? mask_msb_ones<word_t>(offset + 1) : mask_lsb_ones<word_t>(offset + 1);
|
||||||
|
}
|
||||||
|
if (w != 0) {
|
||||||
|
return static_cast<int>(i * bits_per_word + find_first_msb_one(w));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_first_(size_t startpos, size_t endpos, bool value) const noexcept
|
||||||
|
{
|
||||||
|
size_t startword = startpos / bits_per_word;
|
||||||
|
size_t lastword = (endpos - 1) / bits_per_word;
|
||||||
|
|
||||||
|
for (size_t i = startword; i <= lastword; ++i) {
|
||||||
|
word_t w = buffer[i];
|
||||||
|
if (not value) {
|
||||||
|
w = ~w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == startword) {
|
||||||
|
size_t offset = startpos % bits_per_word;
|
||||||
|
w &= mask_lsb_zeros<word_t>(offset);
|
||||||
|
}
|
||||||
|
if (i == lastword) {
|
||||||
|
size_t offset = (endpos - 1) % bits_per_word;
|
||||||
|
w &= mask_lsb_ones<word_t>(offset + 1);
|
||||||
|
}
|
||||||
|
if (w != 0) {
|
||||||
|
return static_cast<int>(i * bits_per_word + find_first_lsb_one(w));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_first_reversed_(size_t startpos, size_t endpos, bool value) const noexcept
|
||||||
|
{
|
||||||
|
size_t startbitpos = get_bitidx_(startpos), lastbitpos = get_bitidx_(endpos - 1);
|
||||||
|
size_t startword = startbitpos / bits_per_word;
|
||||||
|
size_t lastword = lastbitpos / bits_per_word;
|
||||||
|
|
||||||
|
for (size_t i = startword; i != lastword - 1; --i) {
|
||||||
|
word_t w = buffer[i];
|
||||||
|
if (not value) {
|
||||||
|
w = ~w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == startword) {
|
||||||
|
size_t offset = startbitpos % bits_per_word;
|
||||||
|
w &= mask_lsb_ones<word_t>(offset + 1);
|
||||||
|
}
|
||||||
|
if (i == lastword) {
|
||||||
|
size_t offset = lastbitpos % bits_per_word;
|
||||||
|
w &= mask_lsb_zeros<word_t>(offset);
|
||||||
|
}
|
||||||
|
if (w != 0) {
|
||||||
|
word_t pos = find_first_msb_one(w);
|
||||||
|
return static_cast<int>(size() - 1 - (pos + i * bits_per_word));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t N, bool reversed>
|
template <size_t N, bool reversed>
|
||||||
|
|
|
@ -15,10 +15,35 @@
|
||||||
|
|
||||||
void test_bit_operations()
|
void test_bit_operations()
|
||||||
{
|
{
|
||||||
TESTASSERT(0 == srsran::mask_trailing_ones<uint32_t>(0));
|
TESTASSERT(0 == srsran::mask_lsb_ones<uint8_t>(0));
|
||||||
TESTASSERT(0b11 == srsran::mask_trailing_ones<uint32_t>(2));
|
TESTASSERT(0 == srsran::mask_msb_ones<uint8_t>(0));
|
||||||
TESTASSERT(0b11111111 == srsran::mask_trailing_ones<uint8_t>(8));
|
TESTASSERT(0 == srsran::mask_lsb_ones<uint32_t>(0));
|
||||||
TESTASSERT(0b1111 == srsran::mask_trailing_ones<uint8_t>(4));
|
TESTASSERT(0 == srsran::mask_msb_ones<uint32_t>(0));
|
||||||
|
TESTASSERT(0b11111111 == srsran::mask_lsb_zeros<uint8_t>(0));
|
||||||
|
TESTASSERT(0b11111111 == srsran::mask_msb_zeros<uint8_t>(0));
|
||||||
|
TESTASSERT((uint32_t)-1 == srsran::mask_lsb_zeros<uint32_t>(0));
|
||||||
|
TESTASSERT((uint32_t)-1 == srsran::mask_msb_zeros<uint32_t>(0));
|
||||||
|
|
||||||
|
TESTASSERT(0b11 == srsran::mask_lsb_ones<uint8_t>(2));
|
||||||
|
TESTASSERT(0b11000000 == srsran::mask_msb_ones<uint8_t>(2));
|
||||||
|
TESTASSERT(0b11111100 == srsran::mask_lsb_zeros<uint8_t>(2));
|
||||||
|
TESTASSERT(0b00111111 == srsran::mask_msb_zeros<uint8_t>(2));
|
||||||
|
|
||||||
|
TESTASSERT(0b11111111 == srsran::mask_lsb_ones<uint8_t>(8));
|
||||||
|
TESTASSERT(0b1111 == srsran::mask_lsb_ones<uint8_t>(4));
|
||||||
|
|
||||||
|
TESTASSERT(srsran::find_first_lsb_one<uint8_t>(0) == std::numeric_limits<uint8_t>::digits);
|
||||||
|
TESTASSERT(srsran::find_first_msb_one<uint8_t>(0) == std::numeric_limits<uint8_t>::digits);
|
||||||
|
TESTASSERT(srsran::find_first_lsb_one<uint8_t>(1) == 0);
|
||||||
|
TESTASSERT(srsran::find_first_msb_one<uint8_t>(1) == 0);
|
||||||
|
TESTASSERT(srsran::find_first_lsb_one<uint8_t>(0b11) == 0);
|
||||||
|
TESTASSERT(srsran::find_first_lsb_one<uint8_t>(0b10) == 1);
|
||||||
|
TESTASSERT(srsran::find_first_msb_one<uint8_t>(0b11) == 1);
|
||||||
|
TESTASSERT(srsran::find_first_msb_one<uint8_t>(0b10) == 1);
|
||||||
|
TESTASSERT(srsran::find_first_lsb_one<uint32_t>(0b11) == 0);
|
||||||
|
TESTASSERT(srsran::find_first_lsb_one<uint32_t>(0b10) == 1);
|
||||||
|
TESTASSERT(srsran::find_first_msb_one<uint32_t>(0b11) == 1);
|
||||||
|
TESTASSERT(srsran::find_first_msb_one<uint32_t>(0b10) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_zero_bitset()
|
int test_zero_bitset()
|
||||||
|
@ -184,21 +209,63 @@ int test_bitset_resize()
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool reversed>
|
||||||
void test_bitset_find()
|
void test_bitset_find()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
srsran::bounded_bitset<25> bitset(6);
|
srsran::bounded_bitset<25, reversed> bitset(6);
|
||||||
|
|
||||||
|
// 0b000000
|
||||||
|
TESTASSERT(bitset.find_lowest(0, bitset.size(), false) == 0);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, bitset.size(), true) == -1);
|
||||||
|
|
||||||
|
// 0b000100
|
||||||
bitset.set(2);
|
bitset.set(2);
|
||||||
TESTASSERT(bitset.find_first(0, 6) == 2);
|
TESTASSERT(bitset.find_lowest(0, 6) == 2);
|
||||||
TESTASSERT(bitset.find_first(3, 6) == -1);
|
TESTASSERT(bitset.find_lowest(0, 6, false) == 0);
|
||||||
|
TESTASSERT(bitset.find_lowest(3, 6) == -1);
|
||||||
|
TESTASSERT(bitset.find_lowest(3, 6, false) == 3);
|
||||||
|
|
||||||
|
// 0b000101
|
||||||
|
bitset.set(0);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, 6) == 0);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, 6, false) == 1);
|
||||||
|
TESTASSERT(bitset.find_lowest(3, 6) == -1);
|
||||||
|
TESTASSERT(bitset.find_lowest(3, 6, false) == 3);
|
||||||
|
|
||||||
|
// 0b100101
|
||||||
bitset.set(5);
|
bitset.set(5);
|
||||||
TESTASSERT(bitset.find_first(3, 6) == 5);
|
TESTASSERT(bitset.find_lowest(0, 6) == 0);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, 6, false) == 1);
|
||||||
|
TESTASSERT(bitset.find_lowest(3, 6) == 5);
|
||||||
|
|
||||||
|
// 0b111111
|
||||||
|
bitset.fill(0, 6);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, 6) == 0);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, 6, false) == -1);
|
||||||
|
TESTASSERT(bitset.find_lowest(3, 6, false) == -1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
srsran::bounded_bitset<100> bitset(95);
|
srsran::bounded_bitset<100, reversed> bitset(95);
|
||||||
|
|
||||||
|
// 0b0...0
|
||||||
|
TESTASSERT(bitset.find_lowest(0, bitset.size()) == -1);
|
||||||
|
|
||||||
|
// 0b1000...
|
||||||
bitset.set(94);
|
bitset.set(94);
|
||||||
TESTASSERT(bitset.find_first(0, 93) == -1);
|
TESTASSERT(bitset.find_lowest(0, 93) == -1);
|
||||||
TESTASSERT(bitset.find_first(0, bitset.size()) == 94);
|
TESTASSERT(bitset.find_lowest(0, bitset.size()) == 94);
|
||||||
|
|
||||||
|
// 0b1000...010
|
||||||
|
bitset.set(1);
|
||||||
|
TESTASSERT(bitset.find_lowest(0, bitset.size()) == 1);
|
||||||
|
TESTASSERT(bitset.find_lowest(1, bitset.size()) == 1);
|
||||||
|
TESTASSERT(bitset.find_lowest(2, bitset.size()) == 94);
|
||||||
|
|
||||||
|
// 0b11..11
|
||||||
|
bitset.fill(0, bitset.size());
|
||||||
|
TESTASSERT(bitset.find_lowest(0, bitset.size()) == 0);
|
||||||
|
TESTASSERT(bitset.find_lowest(5, bitset.size()) == 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +278,8 @@ int main()
|
||||||
TESTASSERT(test_bitset_bitwise_oper() == SRSRAN_SUCCESS);
|
TESTASSERT(test_bitset_bitwise_oper() == SRSRAN_SUCCESS);
|
||||||
TESTASSERT(test_bitset_print() == SRSRAN_SUCCESS);
|
TESTASSERT(test_bitset_print() == SRSRAN_SUCCESS);
|
||||||
TESTASSERT(test_bitset_resize() == SRSRAN_SUCCESS);
|
TESTASSERT(test_bitset_resize() == SRSRAN_SUCCESS);
|
||||||
test_bitset_find();
|
test_bitset_find<false>();
|
||||||
|
test_bitset_find<true>();
|
||||||
printf("Success\n");
|
printf("Success\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,22 +23,25 @@ template <typename RBMask,
|
||||||
typename std::conditional<std::is_same<RBMask, prbmask_t>::value, prb_interval, rbg_interval>::type>
|
typename std::conditional<std::is_same<RBMask, prbmask_t>::value, prb_interval, rbg_interval>::type>
|
||||||
RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size)
|
RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size)
|
||||||
{
|
{
|
||||||
RBInterval interv, max_interv;
|
RBInterval max_interv;
|
||||||
|
|
||||||
for (uint32_t n = 0; n < in_mask.size() and interv.length() < max_size; n++) {
|
for (size_t n = 0; n < in_mask.size(); n++) {
|
||||||
if (not in_mask.test(n) and interv.empty()) {
|
int pos = in_mask.find_lowest(n, in_mask.size(), false);
|
||||||
// new interval
|
if (pos < 0) {
|
||||||
interv.set(n, n + 1);
|
break;
|
||||||
} else if (not in_mask.test(n)) {
|
}
|
||||||
// extend current interval
|
|
||||||
interv.resize_by(1);
|
size_t max_pos = std::min(in_mask.size(), (size_t)pos + max_size);
|
||||||
} else if (not interv.empty()) {
|
int pos2 = in_mask.find_lowest(pos, max_pos, true);
|
||||||
// reset interval
|
RBInterval interv(pos, pos2 < 0 ? max_pos : pos2);
|
||||||
max_interv = interv.length() > max_interv.length() ? interv : max_interv;
|
if (interv.length() >= max_size) {
|
||||||
interv = {};
|
return interv;
|
||||||
|
}
|
||||||
|
if (interv.length() > max_interv.length()) {
|
||||||
|
max_interv = interv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return interv.length() > max_interv.length() ? interv : max_interv;
|
return max_interv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
|
|
Loading…
Reference in New Issue