#ifndef ALIHLTHUFFMAN_H
#define ALIHLTHUFFMAN_H
#include "AliHLTLogging.h"
#include "TNamed.h"
#include <vector>
#include <bitset>
#include <string>
class AliHLTHuffmanNode: public TObject {
public:
AliHLTHuffmanNode();
AliHLTHuffmanNode(const AliHLTHuffmanNode& other);
AliHLTHuffmanNode& operator=(const AliHLTHuffmanNode& other);
virtual ~AliHLTHuffmanNode();
void SetValue(AliHLTInt64_t v) {
fValue = v;
}
void AddWeight(Float_t w) {
fWeight += w;
}
void SetWeight(Float_t w) {
fWeight = w;
}
AliHLTInt64_t GetValue() const {
return fValue;
}
Float_t GetWeight() const {
return fWeight;
}
void AssignCode(bool bReverse=false);
virtual void SetBinaryCode(AliHLTUInt64_t length, std::bitset<64> code) = 0;
virtual void SetLeftChild(AliHLTHuffmanNode* n) = 0;
virtual void SetRightChild(AliHLTHuffmanNode* n) = 0;
virtual AliHLTUInt64_t GetBinaryCodeLength() const = 0;
virtual const std::bitset<64>& GetBinaryCode() const = 0;
virtual AliHLTHuffmanNode* GetLeftChild() const = 0;
virtual AliHLTHuffmanNode* GetRightChild() const = 0;
void Print(Option_t* option = "") const;
Bool_t operator <(const AliHLTHuffmanNode& other) const {
return (this->GetWeight() < other.GetWeight());
}
class less {
public:
bool operator()(const AliHLTHuffmanNode* i1,
const AliHLTHuffmanNode* i2) const {
return ((*i1) < (*i2));
}
};
private:
AliHLTInt64_t fValue;
Float_t fWeight;
ClassDef(AliHLTHuffmanNode, 1)
};
class AliHLTHuffmanTreeNode: public AliHLTHuffmanNode {
public:
AliHLTHuffmanTreeNode();
AliHLTHuffmanTreeNode(const AliHLTHuffmanTreeNode& other);
AliHLTHuffmanTreeNode& operator=(const AliHLTHuffmanTreeNode& other);
AliHLTHuffmanTreeNode(AliHLTHuffmanNode* l, AliHLTHuffmanNode* r);
~AliHLTHuffmanTreeNode();
void SetBinaryCode(AliHLTUInt64_t length, std::bitset<64> code) {
fBinaryCodeLength = length;
fBinaryCode = code;
}
void SetLeftChild(AliHLTHuffmanNode* n) {
fLeft = n;
}
void SetRightChild(AliHLTHuffmanNode* n) {
fRight = n;
}
AliHLTUInt64_t GetBinaryCodeLength() const {
return fBinaryCodeLength;
}
const std::bitset<64>& GetBinaryCode() const {
return fBinaryCode;
}
AliHLTHuffmanNode* GetLeftChild() const {
return fLeft;
}
AliHLTHuffmanNode* GetRightChild() const {
return fRight;
}
private:
AliHLTUInt8_t fBinaryCodeLength;
std::bitset<64> fBinaryCode;
AliHLTHuffmanNode* fLeft;
AliHLTHuffmanNode* fRight;
ClassDef(AliHLTHuffmanTreeNode, 1)
};
class AliHLTHuffmanLeaveNode: public AliHLTHuffmanNode {
public:
AliHLTHuffmanLeaveNode();
AliHLTHuffmanLeaveNode(const AliHLTHuffmanLeaveNode& other);
AliHLTHuffmanLeaveNode& operator=(const AliHLTHuffmanLeaveNode& other);
~AliHLTHuffmanLeaveNode();
void SetBinaryCode(AliHLTUInt64_t length, std::bitset<64> code) {
fBinaryCodeLength = length;
fBinaryCode = code;
}
void SetLeftChild(AliHLTHuffmanNode* n) {
fLeft = n;
}
void SetRightChild(AliHLTHuffmanNode* n) {
fRight = n;
}
AliHLTUInt64_t GetBinaryCodeLength() const {
return fBinaryCodeLength;
}
const std::bitset<64>& GetBinaryCode() const {
return fBinaryCode;
}
AliHLTHuffmanNode* GetLeftChild() const {
return fLeft;
}
AliHLTHuffmanNode* GetRightChild() const {
return fRight;
}
private:
AliHLTUInt8_t fBinaryCodeLength;
std::bitset<64> fBinaryCode;
AliHLTHuffmanNode* fLeft;
AliHLTHuffmanNode* fRight;
ClassDef(AliHLTHuffmanLeaveNode, 1)
};
class AliHLTHuffman: public TNamed, public AliHLTLogging {
public:
AliHLTHuffman();
AliHLTHuffman(const AliHLTHuffman& other);
AliHLTHuffman(const char* name, UInt_t maxBits);
~AliHLTHuffman();
UInt_t InitMaxCodeLength();
UInt_t GetMaxBits() const {return fMaxBits;}
UInt_t GetMaxValue() const {return fMaxValue;}
UInt_t GetMaxCodeLength() const {return fMaxCodeLength;}
const std::bitset<64>& Encode(const AliHLTUInt64_t v, AliHLTUInt64_t& codeLength) const;
Bool_t DecodeLSB(std::bitset<64> , AliHLTUInt64_t& , AliHLTUInt32_t& length, AliHLTUInt32_t& codeLength) const;
Bool_t DecodeMSB(std::bitset<64> , AliHLTUInt64_t& , AliHLTUInt32_t& length, AliHLTUInt32_t& codeLength) const;
Bool_t FastDecodeMSB(std::bitset<64> bits, AliHLTUInt64_t& value,
AliHLTUInt32_t& length, AliHLTUInt32_t& codeLength) const;
Bool_t AddTrainingValue(const AliHLTUInt64_t value,
const Float_t weight = 1.);
Bool_t GenerateHuffmanTree();
void Print(Option_t* option = "short") const;
AliHLTHuffman& operator =(const AliHLTHuffman& other);
bool CheckConsistency() const;
struct AliHuffmanDecodingNode {
AliHLTHuffmanNode* fParent;
AliHLTInt64_t fValue;
AliHuffmanDecodingNode* fLeft;
AliHuffmanDecodingNode* fRight;
AliHLTUInt8_t fBinaryCodeLength;
};
int EnableDecodingMap();
private:
AliHuffmanDecodingNode* BuildDecodingNode(AliHLTHuffmanNode* node, vector<AliHuffmanDecodingNode>& decodingnodes) const;
UInt_t fMaxBits;
UInt_t fMaxValue;
std::vector<AliHLTHuffmanLeaveNode> fNodes;
AliHLTHuffmanNode* fHuffTopNode;
bool fReverseCode;
UInt_t fMaxCodeLength;
std::vector<AliHuffmanDecodingNode> fDecodingNodes;
AliHuffmanDecodingNode* fDecodingTopNode;
ClassDef(AliHLTHuffman, 4)
};
#endif