Bug 1586977 - Remove MapBasedHuffmanTable. r=Yoric

Differential Revision: https://phabricator.services.mozilla.com/D48652

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tooru Fujisawa 2019-10-11 03:46:36 +00:00
Родитель a1c0a017c1
Коммит 712cf567f2
2 изменённых файлов: 0 добавлений и 164 удалений

Просмотреть файл

@ -1958,77 +1958,6 @@ HuffmanEntry<const T*> NaiveHuffmanTable<T, N>::lookup(
return HuffmanEntry<const T*>(0, 0, nullptr);
}
template <typename T>
JS::Result<Ok> MapBasedHuffmanTable<T>::initWithSingleValue(JSContext* cx,
T&& value) {
MOZ_ASSERT(values_.empty()); // Make sure that we're initializing.
const HuffmanKey key(0, 0);
if (MOZ_UNLIKELY(!values_.put(FlatHuffmanKey(key), std::move(value)) ||
!keys_.append(key))) {
ReportOutOfMemory(cx);
return cx->alreadyReportedError();
}
return Ok();
}
template <typename T>
JS::Result<Ok> MapBasedHuffmanTable<T>::initStart(JSContext* cx,
size_t numberOfSymbols,
uint8_t) {
MOZ_ASSERT(values_.empty()); // Make sure that we're initializing.
if (MOZ_UNLIKELY(!values_.reserve(numberOfSymbols) ||
!keys_.reserve(numberOfSymbols))) {
ReportOutOfMemory(cx);
return cx->alreadyReportedError();
}
return Ok();
}
template <typename T>
JS::Result<Ok> MapBasedHuffmanTable<T>::initComplete() {
#if DEBUG
// Check that there is a bijection between `keys_` and `values_`.
// 1. Injection.
for (const auto& key : keys_) {
MOZ_ALWAYS_TRUE(values_.has(FlatHuffmanKey(key)));
}
// 2. Cardinality.
MOZ_ASSERT(values_.count() == keys_.length());
#endif // DEBUG
return Ok();
}
template <typename T>
JS::Result<Ok> MapBasedHuffmanTable<T>::addSymbol(uint32_t bits,
uint8_t bitLength,
T&& value) {
MOZ_ASSERT_IF(bitLength != 32 /* >> 32 is UB */, bits >> bitLength == 0);
const HuffmanKey key(bits, bitLength);
const FlatHuffmanKey flat(key);
values_.putNewInfallible(
flat, std::move(value)); // Memory was reserved in `init()`.
keys_.infallibleAppend(std::move(key));
return Ok();
}
template <typename T>
HuffmanEntry<const T*> MapBasedHuffmanTable<T>::lookup(
HuffmanLookup lookup) const {
for (auto bitLength = 0; bitLength < MAX_CODE_BIT_LENGTH; ++bitLength) {
const uint32_t bits = lookup.leadingBits(bitLength);
const HuffmanKey key(bits, bitLength);
const FlatHuffmanKey flat(key);
if (auto ptr = values_.lookup(flat)) {
// Entry found.
return HuffmanEntry<const T*>(bits, bitLength, &ptr->value());
}
}
// Error: no entry found.
return HuffmanEntry<const T*>(0, 0, nullptr);
}
template <typename T>
SingleEntryHuffmanTable<T>::Iterator::Iterator(const T* position)
: position_(position) {}

Просмотреть файл

@ -262,99 +262,6 @@ class NaiveHuffmanTable {
friend class HuffmanPreludeReader;
};
// An implementation of Huffman Tables as a hash map. Space-Efficient,
// faster than NaiveHuffmanTable for large tables but not terribly
// fast, either.
//
// Complexity:
//
// - We assume that hashing is sufficient to guarantee `O(1)` lookups
// inside the hashmap.
// - On a well-formed file, all lookups are successful and a Huffman
// lookup will take exactly `bitLen` Hashmap lookups. This makes it
// `O(MAX_CODE_BIT_LENGTH)` worst case. This also makes it
// `O(ln(N))` in the best case (perfectly balanced Huffman table)
// and `O(N)` in the worst case (perfectly linear Huffman table),
// where `N` is the number of entries.
// - On an invalid file, the number of lookups is also bounded by
// `MAX_CODE_BIT_LENGTH`.
template <typename T>
class MapBasedHuffmanTable {
public:
explicit MapBasedHuffmanTable(JSContext* cx) : values_(cx), keys_(cx) {}
MapBasedHuffmanTable(MapBasedHuffmanTable&& other) noexcept
: values_(std::move(other.values_)), keys_(std::move(other.keys_)) {}
// Initialize a Huffman table containing a single value.
JS::Result<Ok> initWithSingleValue(JSContext* cx, T&& value);
// Initialize a Huffman table containing `numberOfSymbols`.
// Symbols must be added with `addSymbol`.
// If you initialize with `initStart`, you MUST call `initComplete()`
// at the end of initialization.
JS::Result<Ok> initStart(JSContext* cx, size_t numberOfSymbols,
uint8_t maxBitLength);
// Add a `(bit, bitLength) => value` mapping.
JS::Result<Ok> addSymbol(uint32_t bits, uint8_t bitLength, T&& value);
JS::Result<Ok> initComplete();
MapBasedHuffmanTable() = delete;
MapBasedHuffmanTable(MapBasedHuffmanTable&) = delete;
// Lookup a value in the table.
//
// Return an entry with a value of `nullptr` if the value is not in the table.
//
// The lookup may advance `key` by `[0, key.bitLength_]` bits. Typically, in a
// table with a single instance, or if the value is not in the table, it
// will advance by 0 bits. The caller is responsible for advancing its
// bitstream by `result.key_.bitLength_` bits.
HuffmanEntry<const T*> lookup(HuffmanLookup key) const;
// The number of values in the table.
size_t length() const { return values_.length(); }
// Iterating in the order of insertion.
struct Iterator {
Iterator(const js::HashMap<FlatHuffmanKey, T, FlatHuffmanKey>& values,
const HuffmanKey* position)
: values_(values), position_(position) {}
void operator++() { ++position_; }
const T* operator*() const {
const FlatHuffmanKey key(position_);
if (const auto ptr = values_.lookup(key)) {
return &ptr->value();
}
MOZ_CRASH();
}
bool operator==(const Iterator& other) const {
MOZ_ASSERT(&values_ == &other.values_);
return position_ == other.position_;
}
bool operator!=(const Iterator& other) const {
MOZ_ASSERT(&values_ == &other.values_);
return position_ != other.position_;
}
private:
const js::HashMap<FlatHuffmanKey, T, FlatHuffmanKey>& values_;
const HuffmanKey* position_;
};
Iterator begin() const { return Iterator(values_, keys_.begin()); }
Iterator end() const { return Iterator(values_, keys_.end()); }
private:
// The entries in this Huffman table, prepared for lookup.
js::HashMap<FlatHuffmanKey, T, FlatHuffmanKey> values_;
// The entries in this Huffman Table, sorted in the order of insertion.
Vector<HuffmanKey> keys_;
friend class HuffmanPreludeReader;
};
// An implementation of Huffman Tables for single-entry table.
template <typename T>
class SingleEntryHuffmanTable {