Mercurial > dedupe
diff FastBitDecoder.cpp @ 46:877327e9061a
N-Tree for decoding.
| author | Tom Fredrik Blenning Klaussen <bfg@blenning.no> |
|---|---|
| date | Mon, 10 Sep 2012 21:31:10 +0200 |
| parents | |
| children | f8d0ea827db3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastBitDecoder.cpp Mon Sep 10 21:31:10 2012 +0200 @@ -0,0 +1,103 @@ +#include "FastBitDecoder.hpp" + +#include "BitDecoder.hpp" + +#include <QtCore/QDebug> + +#include <cassert> + +unsigned char FastBitDecoder::getPaddedChar(const QBitArray& bits, uint offset) +{ + unsigned char retVal = 0; + size_t n = std::min(8u, bits.size() - offset); + for (size_t i = 0; i < n; ++i) { + retVal |= (bits.testBit(i + offset) ? 1 : 0) << (7 - i) ; + } + return retVal; +} + +QBitArray FastBitDecoder::removeFirst(const QBitArray& bits) +{ + size_t N = bits.size(); + assert(N - 8 > 0); + size_t n = N - 8; + QBitArray retVal(n); + for (size_t i = 0; i < n; ++i) { + retVal.setBit(i, bits.at(i + 8)); + } + return retVal; +} + + +void FastBitDecoder::fill() +{ + for (size_t i = 0; i < N; ++i) { + if (decoder[i] != 0) { + decoder[i]->fill(); + } + else if (data[i] == 0) { + assert(data[i - 1]); + data[i] = data[i - 1]; + numBits[i] = numBits[i - 1]; + } + } +} + +void FastBitDecoder::blank() +{ + for (size_t i = 0; i < N; ++i) { + decoder[i] = 0; + data[i] = 0; + numBits[i] = 0; + } +} + +FastBitDecoder::FastBitDecoder() +{ + blank(); +} + + +FastBitDecoder::FastBitDecoder(const QMap<QString, QBitArray>& encoder) +{ + blank(); + for(QMap<QString, QBitArray>::const_iterator it = encoder.begin(); + it != encoder.end(); ++it) { + insert(it.value(), it.key()); + } + fill(); +} + + +void FastBitDecoder::insert(const QBitArray& key, const QString& value) +{ + unsigned char l = getPaddedChar(key); + if (key.size() <= 8) { + data[l] = new QString(value); + numBits[l] = key.size(); + } + else { + if (!decoder[l]) + decoder[l] = new FastBitDecoder(); + decoder[l]->insert(removeFirst(key), value); + numBits[l] = 8; + } +} + + +uint FastBitDecoder::decode(QString& resString, const QBitArray& bits, uint offset) const +{ + unsigned char l = getPaddedChar(bits, offset); + if (data[l]) { + resString.append(*data[l]); + return numBits[l]; + } + else { + return decoder[l]->decode(resString, bits, offset + 8) + 8; + } +} + +QString FastBitDecoder::decode(const QString& bits) const +{ + return decode(BitDecoder::bitsFromString(bits)); +}
