Mercurial > dedupe
changeset 27:95a10553ff90
Optimize BitDecoder, and refactor functions that are not timecritical
out of header.
| author | Tom Fredrik Blenning Klaussen <bfg@blenning.no> |
|---|---|
| date | Thu, 06 Sep 2012 18:20:11 +0200 |
| parents | c0ddc978475a |
| children | b2c2c2bf2bbd |
| files | BitDecoder.cpp BitDecoder.hpp CMakeLists.txt |
| diffstat | 3 files changed, 91 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BitDecoder.cpp Thu Sep 06 18:20:11 2012 +0200 @@ -0,0 +1,63 @@ +#include "BitDecoder.hpp" + +BitDecoder::BitDecoder(BitDecoder* low_in, BitDecoder* high_in) : low(low_in), high(high_in) +{ +} + +BitDecoder::BitDecoder(const QString& d) : low(0), high(0), _data(d) +{ +} + +BitDecoder::~BitDecoder() +{ + delete low; + delete high; +} + +const QString& BitDecoder::data() const +{ + return _data; +} + +BitDecoder* BitDecoder::merge(BitDecoder* low, BitDecoder* high) +{ + return new BitDecoder(low, high); +} + +/* +QBitArray BitDecoder::unite(const QBitArray& first, const QBitArray& second) +{ + QBitArray result(first.size() + second.size()); + int n = first.size(); + for (int i = 0; i < n; ++i) { + result[i] = first[i]; + } + for (int i = 0; i < second.size(); ++i) { + result[n + i] = second[i]; + } + return result; +} +*/ + +QMap<QString, QBitArray> BitDecoder::createEncoder() const +{ + QMap<QString, QBitArray> retVal; + if (!_data.isNull()) { + retVal.insert(_data, QBitArray()); + } + if (low) { + QMap<QString, QBitArray> vals = low->createEncoder(); + for(QMap<QString, QBitArray>::const_iterator it = vals.begin(); + it != vals.end(); ++it) { + retVal.insert(it.key(), unite(QBitArray(1, false), it.value())); + } + } + if (high) { + QMap<QString, QBitArray> vals = high->createEncoder(); + for(QMap<QString, QBitArray>::const_iterator it = vals.begin(); + it != vals.end(); ++it) { + retVal.insert(it.key(), unite(QBitArray(1, true), it.value())); + } + } + return retVal; +}
--- a/BitDecoder.hpp Thu Sep 06 18:18:49 2012 +0200 +++ b/BitDecoder.hpp Thu Sep 06 18:20:11 2012 +0200 @@ -1,9 +1,9 @@ #ifndef BITDECODER_HPP #define BITDECODER_HPP -#include <QtCore/QPair> -#include <QtCore/QDebug> #include <QtCore/QBitArray> +#include <QtCore/QString> +#include <QtCore/QMap> class BitDecoder { BitDecoder* low; @@ -11,91 +11,53 @@ QString _data; private: - BitDecoder(BitDecoder* low_in, BitDecoder* high_in) : low(low_in), high(high_in) - { - } - + BitDecoder(BitDecoder* low_in, BitDecoder* high_in); -public: - BitDecoder(const QString& d) : low(0), high(0), _data(d) - { - } - - ~BitDecoder() + uint decode(QString& resString, const QBitArray& bits, uint offset) { - delete low; - delete high; - } - - const QString& data() const - { - return _data; - } - - QPair<QString, uint> decode(const QBitArray& bits, uint offset) - { - if (_data.isNull()) { - QPair<QString, uint> retVal = (bits[offset]?high:low)->decode(bits, offset + 1); - ++retVal.second; - return retVal; + //Data is always stored in a leaf node. + if (high) { + return (bits.testBit(offset) ? high : low)->decode(resString, bits, offset + 1) + 1; } else { - return QPair<QString, uint>(_data, 1); + resString.append(_data); + return 1; } } +public: + BitDecoder(const QString& d); + ~BitDecoder(); + const QString& data() const; + QString decode(const QBitArray& bits) { - QPair<QString, uint> d; QString combined; uint n = bits.size(); - for (uint decodedBits = 0; decodedBits < n; decodedBits += d.second - 1) { - d = decode(bits, decodedBits); - combined.append(d.first); - } + //Just a qualified overestimate guess on what we will need. + combined.reserve(n/4); + for (uint decodedBits = 0; decodedBits < n; decodedBits += decode(combined, bits, decodedBits) - 1); + combined.squeeze(); return combined; } - static BitDecoder* merge(BitDecoder* low, BitDecoder* high) - { - return new BitDecoder(low, high); - } - + static BitDecoder* merge(BitDecoder* low, BitDecoder* high); static QBitArray unite(const QBitArray& first, const QBitArray& second) { - QBitArray result(first.size() + second.size()); int n = first.size(); + int n2 = second.size(); + QBitArray result(n + n2); for (int i = 0; i < n; ++i) { - result[i] = first[i]; + result.setBit(i, first.testBit(i)); } - for (int i = 0; i < second.size(); ++i) { - result[n + i] = second[i]; + for (int i = 0; i < n2; ++i) { + result.setBit(n + i, second.testBit(i)); } return result; } - QMap<QString, QBitArray> createEncoder() const - { - QMap<QString, QBitArray> retVal; - if (!_data.isNull()) { - retVal.insert(_data, QBitArray()); - } - if (low) { - QMap<QString, QBitArray> vals = low->createEncoder(); - for(QMap<QString, QBitArray>::const_iterator it = vals.begin(); - it != vals.end(); ++it) { - retVal.insert(it.key(), unite(QBitArray(1, false), it.value())); - } - } - if (high) { - QMap<QString, QBitArray> vals = high->createEncoder(); - for(QMap<QString, QBitArray>::const_iterator it = vals.begin(); - it != vals.end(); ++it) { - retVal.insert(it.key(), unite(QBitArray(1, true), it.value())); - } - } - return retVal; - } + + QMap<QString, QBitArray> createEncoder() const; }; #endif //BITDECODER_HPP
--- a/CMakeLists.txt Thu Sep 06 18:18:49 2012 +0200 +++ b/CMakeLists.txt Thu Sep 06 18:20:11 2012 +0200 @@ -24,6 +24,7 @@ SET(CLASS_SOURCES + BitDecoder.cpp DataController.cpp HuffmanString.cpp HuffmanSet.cpp @@ -69,7 +70,7 @@ -SET(CMAKE_CXX_FLAGS "-g2 -pg -Wall -fno-inline") +SET(CMAKE_CXX_FLAGS "-O3 -Wall") ADD_EXECUTABLE(DeDupe DeDupe.cpp ${SOURCES} ${MOC_SOURCES}) TARGET_LINK_LIBRARIES(DeDupe ${QT_LIBRARIES} ${SQLITE3_LIBRARIES} ${Boost_LIBRARIES})
