mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-24 07:29:44 +00:00
183 lines
4.4 KiB
C++
183 lines
4.4 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef jit_BitSet_h
|
|
#define jit_BitSet_h
|
|
|
|
#include "mozilla/MathAlgorithms.h"
|
|
|
|
#include "jit/JitAllocPolicy.h"
|
|
|
|
namespace js {
|
|
namespace jit {
|
|
|
|
// Provides constant time set insertion and removal, and fast linear
|
|
// set operations such as intersection, difference, and union.
|
|
// N.B. All set operations must be performed on sets with the same number
|
|
// of bits.
|
|
class BitSet
|
|
{
|
|
public:
|
|
static const size_t BitsPerWord = 8 * sizeof(uint32_t);
|
|
|
|
static size_t RawLengthForBits(size_t bits) {
|
|
return (bits + BitsPerWord - 1) / BitsPerWord;
|
|
}
|
|
|
|
private:
|
|
uint32_t* bits_;
|
|
const unsigned int numBits_;
|
|
|
|
static inline uint32_t bitForValue(unsigned int value) {
|
|
return 1l << uint32_t(value % BitsPerWord);
|
|
}
|
|
|
|
static inline unsigned int wordForValue(unsigned int value) {
|
|
return value / BitsPerWord;
|
|
}
|
|
|
|
inline unsigned int numWords() const {
|
|
return RawLengthForBits(numBits_);
|
|
}
|
|
|
|
BitSet(const BitSet&) = delete;
|
|
void operator=(const BitSet&) = delete;
|
|
|
|
public:
|
|
class Iterator;
|
|
|
|
explicit BitSet(unsigned int numBits) :
|
|
bits_(nullptr),
|
|
numBits_(numBits) {}
|
|
|
|
bool init(TempAllocator& alloc);
|
|
|
|
unsigned int getNumBits() const {
|
|
return numBits_;
|
|
}
|
|
|
|
// O(1): Check if this set contains the given value.
|
|
bool contains(unsigned int value) const {
|
|
MOZ_ASSERT(bits_);
|
|
MOZ_ASSERT(value < numBits_);
|
|
|
|
return !!(bits_[wordForValue(value)] & bitForValue(value));
|
|
}
|
|
|
|
// O(numBits): Check if this set contains any value.
|
|
bool empty() const;
|
|
|
|
// O(1): Insert the given value into this set.
|
|
void insert(unsigned int value) {
|
|
MOZ_ASSERT(bits_);
|
|
MOZ_ASSERT(value < numBits_);
|
|
|
|
bits_[wordForValue(value)] |= bitForValue(value);
|
|
}
|
|
|
|
// O(numBits): Insert every element of the given set into this set.
|
|
void insertAll(const BitSet& other);
|
|
|
|
// O(1): Remove the given value from this set.
|
|
void remove(unsigned int value) {
|
|
MOZ_ASSERT(bits_);
|
|
MOZ_ASSERT(value < numBits_);
|
|
|
|
bits_[wordForValue(value)] &= ~bitForValue(value);
|
|
}
|
|
|
|
// O(numBits): Remove the every element of the given set from this set.
|
|
void removeAll(const BitSet& other);
|
|
|
|
// O(numBits): Intersect this set with the given set.
|
|
void intersect(const BitSet& other);
|
|
|
|
// O(numBits): Intersect this set with the given set; return whether the
|
|
// intersection caused the set to change.
|
|
bool fixedPointIntersect(const BitSet& other);
|
|
|
|
// O(numBits): Does inplace complement of the set.
|
|
void complement();
|
|
|
|
// O(numBits): Clear this set.
|
|
void clear();
|
|
|
|
uint32_t* raw() const {
|
|
return bits_;
|
|
}
|
|
size_t rawLength() const {
|
|
return numWords();
|
|
}
|
|
};
|
|
|
|
class BitSet::Iterator
|
|
{
|
|
private:
|
|
BitSet& set_;
|
|
unsigned index_;
|
|
unsigned word_;
|
|
uint32_t value_;
|
|
|
|
void skipEmpty() {
|
|
// Skip words containing only zeros.
|
|
unsigned numWords = set_.numWords();
|
|
const uint32_t* bits = set_.bits_;
|
|
while (value_ == 0) {
|
|
word_++;
|
|
if (word_ == numWords)
|
|
return;
|
|
|
|
index_ = word_ * BitSet::BitsPerWord;
|
|
value_ = bits[word_];
|
|
}
|
|
|
|
// Be careful: the result of CountTrailingZeroes32 is undefined if the
|
|
// input is 0.
|
|
int numZeros = mozilla::CountTrailingZeroes32(value_);
|
|
index_ += numZeros;
|
|
value_ >>= numZeros;
|
|
|
|
MOZ_ASSERT_IF(index_ < set_.numBits_, set_.contains(index_));
|
|
}
|
|
|
|
public:
|
|
explicit Iterator(BitSet& set) :
|
|
set_(set),
|
|
index_(0),
|
|
word_(0),
|
|
value_(set.bits_[0])
|
|
{
|
|
skipEmpty();
|
|
}
|
|
|
|
inline bool more() const {
|
|
return word_ < set_.numWords();
|
|
}
|
|
explicit operator bool() const {
|
|
return more();
|
|
}
|
|
|
|
inline void operator++() {
|
|
MOZ_ASSERT(more());
|
|
MOZ_ASSERT(index_ < set_.numBits_);
|
|
|
|
index_++;
|
|
value_ >>= 1;
|
|
|
|
skipEmpty();
|
|
}
|
|
|
|
unsigned int operator*() {
|
|
MOZ_ASSERT(index_ < set_.numBits_);
|
|
return index_;
|
|
}
|
|
};
|
|
|
|
} // namespace jit
|
|
} // namespace js
|
|
|
|
#endif /* jit_BitSet_h */
|