]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTDataInflaterHuffman.cxx
speedup of cluster decoding by ~60%: more efficient access to data stream and avoidin...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataInflaterHuffman.cxx
CommitLineData
9409b4b1 1// $Id$
2
3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
18
19/// @file AliHLTDataInflaterHuffman.cxx
20/// @author Matthias Richter
21/// @date 2011-09-01
22/// @brief Data inflater implementation for huffman encoded data
23/// @note
24
25#include "AliHLTDataInflaterHuffman.h"
26#include "AliHLTHuffman.h"
27#include "TList.h"
28
29/** ROOT macro for the implementation of ROOT specific class methods */
30ClassImp(AliHLTDataInflaterHuffman)
31
32AliHLTDataInflaterHuffman::AliHLTDataInflaterHuffman()
33 : AliHLTDataInflater()
34 , fHuffmanCoders()
35 , fHuffmanCoderList(NULL)
36 , fCurrentParameter(-1)
70d61ae2 37 , fLegacyMode(-1)
6e848d29 38 , fInput(0)
39 , fInputLength(0)
9409b4b1 40{
41 // see header file for class documentation
42 // or
43 // refer to README to build package
44 // or
45 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
46}
47
48AliHLTDataInflaterHuffman::~AliHLTDataInflaterHuffman()
49{
50 // destructor
7d2d4632 51 if (fHuffmanCoderList) delete fHuffmanCoderList;
52 fHuffmanCoderList=NULL;
9409b4b1 53}
54
55int AliHLTDataInflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength)
56{
57 /// search a parameter definition in the decoder configuration, and set the index
58 /// array, return reference id
59 /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::AddParameterDefinition
60 /// make a common base class
61 if (!name) return -EINVAL;
62 if (!fHuffmanCoderList) return -ENODEV;
63 TObject* pObj=fHuffmanCoderList->FindObject(name);
64 if (!pObj) {
65 HLTError("can not find decoder of id '%s'", name);
66 return -ENOENT;
67 }
68 AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj);
69 if (!pHuffman) {
70 HLTError("object %s has wrong type, expected AliHLTHuffman", name);
71 return -EBADF;
72 }
73 if (pHuffman->GetMaxBits()!=bitLength) {
74 HLTError("mismatch in bitlengt: can not use decoder %s of length %d for encoding of %d bits", pHuffman->GetName(), pHuffman->GetMaxBits(), bitLength);
75 return -EPERM;
76 }
77
78 fHuffmanCoders.push_back(pHuffman);
79 return fHuffmanCoders.size()-1;
80}
81
82int AliHLTDataInflaterHuffman::InitDecoders(TList* decoderlist)
83{
84 /// init list of decoders
85 /// expects to be an external pointer, valid throughout the livetime of
86 /// the instance
87 /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::InitDecoders
88 /// make a common base class
89 if (!decoderlist) return -EINVAL;
90 if (!fHuffmanCoderList) {
91 fHuffmanCoderList=new TList;
92 } else {
93 if (fHuffmanCoderList->GetEntries()>0 && fHuffmanCoderList->IsOwner()) {
94 HLTWarning("list of decoders owns already %d object(s), but disabling ownership now because of new external pointers");
95 }
96 }
97 if (!fHuffmanCoderList) return -ENOMEM;
98 fHuffmanCoderList->SetOwner(kFALSE);
99 TIter next(decoderlist);
100 TObject* pObj=NULL;
101 while ((pObj=next())!=NULL) {
6e848d29 102 AliHLTHuffman* coder=NULL;
103 if ((coder=dynamic_cast<AliHLTHuffman*>(pObj))==NULL) continue;
9409b4b1 104 if (fHuffmanCoderList->FindObject(pObj->GetName())) {
105 HLTError("duplicate entry of name '%s'", pObj->GetName());
106 return -EEXIST;
107 }
108 fHuffmanCoderList->Add(pObj);
6e848d29 109 coder->InitMaxCodeLength();
9409b4b1 110 }
111
112 return fHuffmanCoderList->GetEntries();
113}
114
115bool AliHLTDataInflaterHuffman::NextValue(AliHLTUInt64_t& value, AliHLTUInt32_t& length)
116{
117 /// overloaded from AliHLTDataInflater
118 /// functions reads the sequence of parameters as defined by the decoder
119 /// list, than it starts at the first parameter again
120 value=0;
121 length=0;
70d61ae2 122 if (fLegacyMode!=0) {
9409b4b1 123 if ((++fCurrentParameter)>=(int)fHuffmanCoders.size()) fCurrentParameter=0;
70d61ae2 124 fLegacyMode=1;
125 }
126 if (fHuffmanCoders.size()==0 || fCurrentParameter<0) return false;
6e848d29 127 if (fInputLength<fHuffmanCoders[fCurrentParameter]->GetMaxCodeLength() ||
128 fHuffmanCoders[fCurrentParameter]->GetMaxCodeLength()==0)
129 {
130 AliHLTUInt64_t input=0;
131 AliHLTUInt32_t inputLength=64-fInputLength;
132 if (GetRemainingBitDataSizeBytes()<=sizeof(AliHLTUInt64_t)) {
133 inputLength=8*GetRemainingBitDataSizeBytes();
134 inputLength-=(7-GetCurrentBitInputPosition());
135 }
136 if (64-fInputLength<inputLength) inputLength=64-fInputLength;
137 if (!InputBits(input, inputLength)) return false;
138 input<<=(64-inputLength);
139 input>>=fInputLength;
140 fInput|=input;
141 fInputLength+=inputLength;
142 }
9409b4b1 143 AliHLTUInt32_t codeLength=0;
6e848d29 144 if (!fHuffmanCoders[fCurrentParameter]->DecodeUp(fInput, value, length, codeLength)) return false;
145 if (fInputLength<codeLength) {
9409b4b1 146 HLTError("huffman decoder '%s' pretends to have %d bit(s) decoded, but only %d available",
6e848d29 147 fHuffmanCoders[fCurrentParameter]->GetName(), codeLength, fInputLength);
9409b4b1 148 return false;
149 }
6e848d29 150 fInput<<=codeLength;
151 fInputLength-=codeLength;
9409b4b1 152
153 return true;
154}
7d2d4632 155
6e848d29 156void AliHLTDataInflaterHuffman::Print(Option_t* option) const
157{
158 /// Print info
159 for (vector<AliHLTHuffman*>::const_iterator coder=fHuffmanCoders.begin();
160 coder!=fHuffmanCoders.end(); coder++) {
161 if (!*coder) continue;
162 (*coder)->Print(option);
163 }
164}
165
7d2d4632 166void AliHLTDataInflaterHuffman::Clear(Option_t * option)
167{
168 /// clear the object
169 fCurrentParameter=-1;
6e848d29 170 fInput=0;
171 fInputLength=0;
7d2d4632 172
173 if (strcmp(option, "all")==0) {
174 fHuffmanCoders.clear();
175 if (fHuffmanCoderList) delete fHuffmanCoderList;
176 fHuffmanCoderList=NULL;
177 }
178
179 AliHLTDataInflater::Clear(option);
180}