ROOT logo
//-*- Mode: C++ -*-
// $Id$
#ifndef ALIHLTHUFFMAN_H
#define ALIHLTHUFFMAN_H
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//* See cxx source for full Copyright notice                               *

/// @file   AliHLTHuffman.h
/// @author Thorsten Kollegger, Matthias Richter
/// @date   2011-08-14
/// @brief  Huffman code generator/encoder/decode

#include "AliHLTLogging.h"

#include "TNamed.h"

#include <vector>
#include <bitset>
#include <string>

/**
 * @class AliHLTHuffmanNode
 * Huffman code nodes. This is the base class for two types of nodes,
 * AliHLTHuffmanTreeNode and AliHLTHuffmanLeaveNode. The latter nodes
 * represent the index array of values to huffman codes. The former are
 * used in a tree reaching from the value of highest occuremce to all
 * leaves. The two node types are defined in order to optimize the storage
 * format for the huffman table. Leave nodes don't need persistent pointers
 * to childs, tree nodes don't need persistent binary code values.
 *
 * @ingroup alihlt_base
 */
class AliHLTHuffmanNode: public TObject {
public:
	/// default constructor
	AliHLTHuffmanNode();
	/// copy constructor
	AliHLTHuffmanNode(const AliHLTHuffmanNode& other);
	/// assignment operator
	AliHLTHuffmanNode& operator=(const AliHLTHuffmanNode& other);
	/// destructor
	virtual ~AliHLTHuffmanNode();

	/// set symbol value of node
	void SetValue(AliHLTInt64_t v) {
		fValue = v;
	}
	/// add weight to node
	void AddWeight(Float_t w) {
		fWeight += w;
	}
	/// set weight of node
	void SetWeight(Float_t w) {
		fWeight = w;
	}
	/// return symbol value of node
	AliHLTInt64_t GetValue() const {
		return fValue;
	}
	/// return weight of node
	Float_t GetWeight() const {
		return fWeight;
	}

        /// assign huffman code to this node and its children
        /// bReverse = true the bit corresponding to the parent is shifted and
        /// decoding needs to start from the MSB of the code
	void AssignCode(bool bReverse=false);
	/// set binary huffman code and length of node
	virtual void SetBinaryCode(AliHLTUInt64_t length, std::bitset<64> code) = 0;
	/// set pointer to left child
	virtual void SetLeftChild(AliHLTHuffmanNode* n) = 0;
	/// set pointer to right child
	virtual void SetRightChild(AliHLTHuffmanNode* n) = 0;
	/// Return length of huffman code
	virtual AliHLTUInt64_t GetBinaryCodeLength() const = 0;
	/// Return binary huffman code
	virtual const std::bitset<64>& GetBinaryCode() const = 0;
	/// Return pointer to left Child
	virtual AliHLTHuffmanNode* GetLeftChild() const = 0;
	/// Return pointer to right Child
	virtual AliHLTHuffmanNode* GetRightChild() const = 0;

	/// Print information about node
	void Print(Option_t* option = "") const;
	/// Overload less operator, based on node weights
	Bool_t operator <(const AliHLTHuffmanNode& other) const {
		return (this->GetWeight() < other.GetWeight());
	}
	class less {
	public:
		bool operator()(const AliHLTHuffmanNode* i1,
				const AliHLTHuffmanNode* i2) const {
			//reverse sort, less likely to most likely
			return ((*i1) < (*i2));
		}
	};

private:
	AliHLTInt64_t fValue;        // value
	Float_t fWeight;             // weight

ClassDef(AliHLTHuffmanNode, 1)
};

/**
 * @class AliHLTHuffmanTreeNode
 * Tree nodes store the childs persistently. The binary code is
 * a transient member.
 */
class AliHLTHuffmanTreeNode: public AliHLTHuffmanNode {
public:
	/// default constructor
	AliHLTHuffmanTreeNode();
	/// copy constructor
	AliHLTHuffmanTreeNode(const AliHLTHuffmanTreeNode& other);
	/// assignment operator
	AliHLTHuffmanTreeNode& operator=(const AliHLTHuffmanTreeNode& other);
	/// constructor for internal nodes, based on two input nodes (leaves or internal nodes)
	AliHLTHuffmanTreeNode(AliHLTHuffmanNode* l, AliHLTHuffmanNode* r);
	/// desstructor
	~AliHLTHuffmanTreeNode();

	/// set binary huffman code and length of node
	void SetBinaryCode(AliHLTUInt64_t length, std::bitset<64> code) {
	        fBinaryCodeLength = length;
	        fBinaryCode = code;
	}

	/// set pointer to left child
	void SetLeftChild(AliHLTHuffmanNode* n) {
		fLeft = n;
	}
	/// set pointer to right child
	void SetRightChild(AliHLTHuffmanNode* n) {
		fRight = n;
	}
	/// Return length of huffman code
	AliHLTUInt64_t GetBinaryCodeLength() const {
		return fBinaryCodeLength;
	}
	/// Return binary huffman code
	const std::bitset<64>& GetBinaryCode() const {
		return fBinaryCode;
	}
	/// Return pointer to left Child
	AliHLTHuffmanNode* GetLeftChild() const {
		return fLeft;
	}
	/// Return pointer to right Child
	AliHLTHuffmanNode* GetRightChild() const {
		return fRight;
	}

private:
	AliHLTUInt8_t fBinaryCodeLength; //! code length
	std::bitset<64> fBinaryCode; //! WARNING: this fixed the maximum code length to 128
	AliHLTHuffmanNode* fLeft;    // left neighbor
	AliHLTHuffmanNode* fRight;   // right neighbor

ClassDef(AliHLTHuffmanTreeNode, 1)
};

/**
 * @class AliHLTHuffmanLeaveNode
 * Leave nodes store the binary code persistently, while the childs are transient
 */
class AliHLTHuffmanLeaveNode: public AliHLTHuffmanNode {
public:
	/// default constructor
	AliHLTHuffmanLeaveNode();
	/// copy constructor
	AliHLTHuffmanLeaveNode(const AliHLTHuffmanLeaveNode& other);
	/// assignment operator
	AliHLTHuffmanLeaveNode& operator=(const AliHLTHuffmanLeaveNode& other);
	/// destructor
	~AliHLTHuffmanLeaveNode();

	/// set binary huffman code and length of node
	void SetBinaryCode(AliHLTUInt64_t length, std::bitset<64> code) {
	        fBinaryCodeLength = length;
	        fBinaryCode = code;
	}
	/// set pointer to left child
	void SetLeftChild(AliHLTHuffmanNode* n) {
		fLeft = n;
	}
	/// set pointer to right child
	void SetRightChild(AliHLTHuffmanNode* n) {
		fRight = n;
	}
	/// Return length of huffman code
	AliHLTUInt64_t GetBinaryCodeLength() const {
		return fBinaryCodeLength;
	}
	/// Return binary huffman code
	const std::bitset<64>& GetBinaryCode() const {
		return fBinaryCode;
	}
	/// Return pointer to left Child
	AliHLTHuffmanNode* GetLeftChild() const {
		return fLeft;
	}
	/// Return pointer to right Child
	AliHLTHuffmanNode* GetRightChild() const {
		return fRight;
	}

private:
	AliHLTUInt8_t fBinaryCodeLength; // code length
	std::bitset<64> fBinaryCode; // WARNING: this fixed the maximum code length to 128
	AliHLTHuffmanNode* fLeft;    //! left neighbor
	AliHLTHuffmanNode* fRight;   //! right neighbor

ClassDef(AliHLTHuffmanLeaveNode, 1)
};

/**
 * @class AliHLTHuffman
 * Huffman code generator/encoder/decoder
 *
 * @ingroup alihlt_base
 */
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;}

	/// Return huffman code for a value
	const std::bitset<64>& Encode(const AliHLTUInt64_t v, AliHLTUInt64_t& codeLength) const;

	/// Return value for bit pattern, LSB first
        Bool_t DecodeLSB(std::bitset<64> /*bits*/, AliHLTUInt64_t& /*value*/, AliHLTUInt32_t& length, AliHLTUInt32_t& codeLength) const;
	/// Return value for bit pattern, MSB first
        Bool_t DecodeMSB(std::bitset<64> /*bits*/, AliHLTUInt64_t& /*value*/, AliHLTUInt32_t& length, AliHLTUInt32_t& codeLength) const;
	/// Return value for bit pattern using decoder node array, MSB first
        Bool_t FastDecodeMSB(std::bitset<64> bits, AliHLTUInt64_t& value,
			     AliHLTUInt32_t& length, AliHLTUInt32_t& codeLength) const;

	/// Add a new training value (with optional weight) to the training sample
	Bool_t AddTrainingValue(const AliHLTUInt64_t value,
			const Float_t weight = 1.);
	/// Generate huffman tree from training sample
	Bool_t GenerateHuffmanTree();
	/// Print info about huffman en-/decoder
	void Print(Option_t* option = "short") const;
	/// Overload assignment operator
	AliHLTHuffman& operator =(const AliHLTHuffman& other);

        bool CheckConsistency() const;

        /**
         * Binary structure for fast access of node information
         * in the decoding
         */
        struct AliHuffmanDecodingNode {
	  AliHLTHuffmanNode* fParent;      // parent
          AliHLTInt64_t fValue;            // value
          AliHuffmanDecodingNode* fLeft;    // left neighbor
          AliHuffmanDecodingNode* fRight;   // right neighbor
          AliHLTUInt8_t fBinaryCodeLength; // code length
        };

        int EnableDecodingMap();

private:
        AliHuffmanDecodingNode* BuildDecodingNode(AliHLTHuffmanNode* node, vector<AliHuffmanDecodingNode>& decodingnodes) const;

	UInt_t fMaxBits;    // bit lenght
	UInt_t fMaxValue;   // maximum value
	std::vector<AliHLTHuffmanLeaveNode> fNodes; // array of nodes
	AliHLTHuffmanNode* fHuffTopNode;       // top node
	bool fReverseCode; // indicate the type of the binary code
	UInt_t fMaxCodeLength; //! maximum code length
	std::vector<AliHuffmanDecodingNode> fDecodingNodes; //! array of reduced nodes
	AliHuffmanDecodingNode* fDecodingTopNode; //! top node of reduced nodes

ClassDef(AliHLTHuffman, 4)
};

#endif
 AliHLTHuffman.h:1
 AliHLTHuffman.h:2
 AliHLTHuffman.h:3
 AliHLTHuffman.h:4
 AliHLTHuffman.h:5
 AliHLTHuffman.h:6
 AliHLTHuffman.h:7
 AliHLTHuffman.h:8
 AliHLTHuffman.h:9
 AliHLTHuffman.h:10
 AliHLTHuffman.h:11
 AliHLTHuffman.h:12
 AliHLTHuffman.h:13
 AliHLTHuffman.h:14
 AliHLTHuffman.h:15
 AliHLTHuffman.h:16
 AliHLTHuffman.h:17
 AliHLTHuffman.h:18
 AliHLTHuffman.h:19
 AliHLTHuffman.h:20
 AliHLTHuffman.h:21
 AliHLTHuffman.h:22
 AliHLTHuffman.h:23
 AliHLTHuffman.h:24
 AliHLTHuffman.h:25
 AliHLTHuffman.h:26
 AliHLTHuffman.h:27
 AliHLTHuffman.h:28
 AliHLTHuffman.h:29
 AliHLTHuffman.h:30
 AliHLTHuffman.h:31
 AliHLTHuffman.h:32
 AliHLTHuffman.h:33
 AliHLTHuffman.h:34
 AliHLTHuffman.h:35
 AliHLTHuffman.h:36
 AliHLTHuffman.h:37
 AliHLTHuffman.h:38
 AliHLTHuffman.h:39
 AliHLTHuffman.h:40
 AliHLTHuffman.h:41
 AliHLTHuffman.h:42
 AliHLTHuffman.h:43
 AliHLTHuffman.h:44
 AliHLTHuffman.h:45
 AliHLTHuffman.h:46
 AliHLTHuffman.h:47
 AliHLTHuffman.h:48
 AliHLTHuffman.h:49
 AliHLTHuffman.h:50
 AliHLTHuffman.h:51
 AliHLTHuffman.h:52
 AliHLTHuffman.h:53
 AliHLTHuffman.h:54
 AliHLTHuffman.h:55
 AliHLTHuffman.h:56
 AliHLTHuffman.h:57
 AliHLTHuffman.h:58
 AliHLTHuffman.h:59
 AliHLTHuffman.h:60
 AliHLTHuffman.h:61
 AliHLTHuffman.h:62
 AliHLTHuffman.h:63
 AliHLTHuffman.h:64
 AliHLTHuffman.h:65
 AliHLTHuffman.h:66
 AliHLTHuffman.h:67
 AliHLTHuffman.h:68
 AliHLTHuffman.h:69
 AliHLTHuffman.h:70
 AliHLTHuffman.h:71
 AliHLTHuffman.h:72
 AliHLTHuffman.h:73
 AliHLTHuffman.h:74
 AliHLTHuffman.h:75
 AliHLTHuffman.h:76
 AliHLTHuffman.h:77
 AliHLTHuffman.h:78
 AliHLTHuffman.h:79
 AliHLTHuffman.h:80
 AliHLTHuffman.h:81
 AliHLTHuffman.h:82
 AliHLTHuffman.h:83
 AliHLTHuffman.h:84
 AliHLTHuffman.h:85
 AliHLTHuffman.h:86
 AliHLTHuffman.h:87
 AliHLTHuffman.h:88
 AliHLTHuffman.h:89
 AliHLTHuffman.h:90
 AliHLTHuffman.h:91
 AliHLTHuffman.h:92
 AliHLTHuffman.h:93
 AliHLTHuffman.h:94
 AliHLTHuffman.h:95
 AliHLTHuffman.h:96
 AliHLTHuffman.h:97
 AliHLTHuffman.h:98
 AliHLTHuffman.h:99
 AliHLTHuffman.h:100
 AliHLTHuffman.h:101
 AliHLTHuffman.h:102
 AliHLTHuffman.h:103
 AliHLTHuffman.h:104
 AliHLTHuffman.h:105
 AliHLTHuffman.h:106
 AliHLTHuffman.h:107
 AliHLTHuffman.h:108
 AliHLTHuffman.h:109
 AliHLTHuffman.h:110
 AliHLTHuffman.h:111
 AliHLTHuffman.h:112
 AliHLTHuffman.h:113
 AliHLTHuffman.h:114
 AliHLTHuffman.h:115
 AliHLTHuffman.h:116
 AliHLTHuffman.h:117
 AliHLTHuffman.h:118
 AliHLTHuffman.h:119
 AliHLTHuffman.h:120
 AliHLTHuffman.h:121
 AliHLTHuffman.h:122
 AliHLTHuffman.h:123
 AliHLTHuffman.h:124
 AliHLTHuffman.h:125
 AliHLTHuffman.h:126
 AliHLTHuffman.h:127
 AliHLTHuffman.h:128
 AliHLTHuffman.h:129
 AliHLTHuffman.h:130
 AliHLTHuffman.h:131
 AliHLTHuffman.h:132
 AliHLTHuffman.h:133
 AliHLTHuffman.h:134
 AliHLTHuffman.h:135
 AliHLTHuffman.h:136
 AliHLTHuffman.h:137
 AliHLTHuffman.h:138
 AliHLTHuffman.h:139
 AliHLTHuffman.h:140
 AliHLTHuffman.h:141
 AliHLTHuffman.h:142
 AliHLTHuffman.h:143
 AliHLTHuffman.h:144
 AliHLTHuffman.h:145
 AliHLTHuffman.h:146
 AliHLTHuffman.h:147
 AliHLTHuffman.h:148
 AliHLTHuffman.h:149
 AliHLTHuffman.h:150
 AliHLTHuffman.h:151
 AliHLTHuffman.h:152
 AliHLTHuffman.h:153
 AliHLTHuffman.h:154
 AliHLTHuffman.h:155
 AliHLTHuffman.h:156
 AliHLTHuffman.h:157
 AliHLTHuffman.h:158
 AliHLTHuffman.h:159
 AliHLTHuffman.h:160
 AliHLTHuffman.h:161
 AliHLTHuffman.h:162
 AliHLTHuffman.h:163
 AliHLTHuffman.h:164
 AliHLTHuffman.h:165
 AliHLTHuffman.h:166
 AliHLTHuffman.h:167
 AliHLTHuffman.h:168
 AliHLTHuffman.h:169
 AliHLTHuffman.h:170
 AliHLTHuffman.h:171
 AliHLTHuffman.h:172
 AliHLTHuffman.h:173
 AliHLTHuffman.h:174
 AliHLTHuffman.h:175
 AliHLTHuffman.h:176
 AliHLTHuffman.h:177
 AliHLTHuffman.h:178
 AliHLTHuffman.h:179
 AliHLTHuffman.h:180
 AliHLTHuffman.h:181
 AliHLTHuffman.h:182
 AliHLTHuffman.h:183
 AliHLTHuffman.h:184
 AliHLTHuffman.h:185
 AliHLTHuffman.h:186
 AliHLTHuffman.h:187
 AliHLTHuffman.h:188
 AliHLTHuffman.h:189
 AliHLTHuffman.h:190
 AliHLTHuffman.h:191
 AliHLTHuffman.h:192
 AliHLTHuffman.h:193
 AliHLTHuffman.h:194
 AliHLTHuffman.h:195
 AliHLTHuffman.h:196
 AliHLTHuffman.h:197
 AliHLTHuffman.h:198
 AliHLTHuffman.h:199
 AliHLTHuffman.h:200
 AliHLTHuffman.h:201
 AliHLTHuffman.h:202
 AliHLTHuffman.h:203
 AliHLTHuffman.h:204
 AliHLTHuffman.h:205
 AliHLTHuffman.h:206
 AliHLTHuffman.h:207
 AliHLTHuffman.h:208
 AliHLTHuffman.h:209
 AliHLTHuffman.h:210
 AliHLTHuffman.h:211
 AliHLTHuffman.h:212
 AliHLTHuffman.h:213
 AliHLTHuffman.h:214
 AliHLTHuffman.h:215
 AliHLTHuffman.h:216
 AliHLTHuffman.h:217
 AliHLTHuffman.h:218
 AliHLTHuffman.h:219
 AliHLTHuffman.h:220
 AliHLTHuffman.h:221
 AliHLTHuffman.h:222
 AliHLTHuffman.h:223
 AliHLTHuffman.h:224
 AliHLTHuffman.h:225
 AliHLTHuffman.h:226
 AliHLTHuffman.h:227
 AliHLTHuffman.h:228
 AliHLTHuffman.h:229
 AliHLTHuffman.h:230
 AliHLTHuffman.h:231
 AliHLTHuffman.h:232
 AliHLTHuffman.h:233
 AliHLTHuffman.h:234
 AliHLTHuffman.h:235
 AliHLTHuffman.h:236
 AliHLTHuffman.h:237
 AliHLTHuffman.h:238
 AliHLTHuffman.h:239
 AliHLTHuffman.h:240
 AliHLTHuffman.h:241
 AliHLTHuffman.h:242
 AliHLTHuffman.h:243
 AliHLTHuffman.h:244
 AliHLTHuffman.h:245
 AliHLTHuffman.h:246
 AliHLTHuffman.h:247
 AliHLTHuffman.h:248
 AliHLTHuffman.h:249
 AliHLTHuffman.h:250
 AliHLTHuffman.h:251
 AliHLTHuffman.h:252
 AliHLTHuffman.h:253
 AliHLTHuffman.h:254
 AliHLTHuffman.h:255
 AliHLTHuffman.h:256
 AliHLTHuffman.h:257
 AliHLTHuffman.h:258
 AliHLTHuffman.h:259
 AliHLTHuffman.h:260
 AliHLTHuffman.h:261
 AliHLTHuffman.h:262
 AliHLTHuffman.h:263
 AliHLTHuffman.h:264
 AliHLTHuffman.h:265
 AliHLTHuffman.h:266
 AliHLTHuffman.h:267
 AliHLTHuffman.h:268
 AliHLTHuffman.h:269
 AliHLTHuffman.h:270
 AliHLTHuffman.h:271
 AliHLTHuffman.h:272
 AliHLTHuffman.h:273
 AliHLTHuffman.h:274
 AliHLTHuffman.h:275
 AliHLTHuffman.h:276
 AliHLTHuffman.h:277
 AliHLTHuffman.h:278
 AliHLTHuffman.h:279
 AliHLTHuffman.h:280
 AliHLTHuffman.h:281
 AliHLTHuffman.h:282
 AliHLTHuffman.h:283
 AliHLTHuffman.h:284
 AliHLTHuffman.h:285
 AliHLTHuffman.h:286
 AliHLTHuffman.h:287
 AliHLTHuffman.h:288
 AliHLTHuffman.h:289
 AliHLTHuffman.h:290