3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Thorsten Kollegger <kollegge@ikf.uni-frankfurt.de> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTDataDeflaterHuffman.cxx
20 /// @author Thorsten Kollegger, Matthias Richter
22 /// @brief Deflater implementation using huffman code
24 #include "AliHLTDataDeflaterHuffman.h"
25 #include "AliHLTHuffman.h"
26 #include "TObjArray.h"
34 /** ROOT macro for the implementation of ROOT specific class methods */
35 ClassImp(AliHLTDataDeflaterHuffman)
37 AliHLTDataDeflaterHuffman::AliHLTDataDeflaterHuffman(bool bTrainingMode)
38 : AliHLTDataDeflater()
40 , fHuffmanCoderList(NULL)
41 , fTrainingMode(bTrainingMode)
43 // see header file for class documentation
45 // refer to README to build package
47 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
49 HLTInfo("using DataDeflaterHuffman in training mode");
53 AliHLTDataDeflaterHuffman::~AliHLTDataDeflaterHuffman()
56 if (fHuffmanCoderList) delete fHuffmanCoderList;
57 fHuffmanCoderList=NULL;
62 int AliHLTDataDeflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength)
64 /// search a parameter definition in the decoder configuration, and set the index
65 /// array, return reference id
67 return AddTrainingParameter(name, bitLength);
69 if (!name) return -EINVAL;
70 if (!fHuffmanCoderList) return -ENODEV;
71 TObject* pObj=fHuffmanCoderList->FindObject(name);
73 HLTError("can not find decoder of id '%s'", name);
76 AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj);
78 HLTError("object %s has wrong type, expected AliHLTHuffman", name);
81 if (pHuffman->GetMaxBits()!=bitLength) {
82 HLTError("mismatch in bitlengt: can not use decoder %s of length %d for encoding of %d bits", pHuffman->GetName(), pHuffman->GetMaxBits(), bitLength);
86 fHuffmanCoders.push_back(pHuffman);
87 return fHuffmanCoders.size()-1;
90 int AliHLTDataDeflaterHuffman::InitDecoders(TList* decoderlist)
92 /// init list of decoders
93 /// expects to be an external pointer, valid throughout the livetime of
95 if (!decoderlist) return -EINVAL;
96 if (!fHuffmanCoderList) {
97 fHuffmanCoderList=new TList;
99 if (fHuffmanCoderList->GetEntries()>0 && fHuffmanCoderList->IsOwner()) {
100 HLTWarning("list of decoders owns already %d object(s), but disabling ownership now because of new external pointers");
103 if (!fHuffmanCoderList) return -ENOMEM;
104 fHuffmanCoderList->SetOwner(kFALSE);
105 TIter next(decoderlist);
107 while ((pObj=next())!=NULL) {
108 if (dynamic_cast<AliHLTHuffman*>(pObj)==NULL) continue;
109 if (fHuffmanCoderList->FindObject(pObj->GetName())) {
110 HLTError("duplicate entry of name '%s'", pObj->GetName());
113 fHuffmanCoderList->Add(pObj);
116 return fHuffmanCoderList->GetEntries();
119 bool AliHLTDataDeflaterHuffman::OutputParameterBits( int memberId, AliHLTUInt64_t const & value )
121 // write huffman encoded bit pattern of a member to the current byte and position
122 if (IsTrainingMode())
123 return AddTrainingValue(memberId, value);
125 if (memberId>=(int)fHuffmanCoders.size()) {
129 AliHLTUInt64_t length = 0;
130 const std::bitset<64>& v=fHuffmanCoders[memberId]->Encode((value>fHuffmanCoders[memberId]->GetMaxValue())?fHuffmanCoders[memberId]->GetMaxValue():value, length);
131 //cout << fHuffmanCoders[memberId]->GetName() << " value " << value << ": code lenght " << length << " " << v << endl;
133 return OutputBits(v, length);
138 int AliHLTDataDeflaterHuffman::AddTrainingParameter(const char* name, unsigned bitLength)
140 /// add a parameter definition for huffman training
142 /// returns index in the array
143 if (!fHuffmanCoderList) {
144 fHuffmanCoderList=new TList;
145 if (!fHuffmanCoderList) return -ENOMEM;
146 // always set ownership for the new list since it is supposed to
147 // contain only internal pointers
148 fHuffmanCoderList->SetOwner();
149 } else if (!fHuffmanCoderList->IsOwner()) {
150 // not sure about the pointers which are already in the list
151 if (fHuffmanCoderList->GetEntries()>0) {
152 HLTWarning("skip setting ownership because list contains already %d object(s), possible memory leak at cleanup");
154 fHuffmanCoderList->SetOwner();
157 AliHLTHuffman* pHuffman=new AliHLTHuffman(name, bitLength);
158 if (!pHuffman) return -ENOMEM;
159 fHuffmanCoderList->Add(pHuffman);
161 fHuffmanCoders.push_back(pHuffman);
162 return fHuffmanCoders.size()-1;
165 bool AliHLTDataDeflaterHuffman::AddTrainingValue( int memberId, AliHLTUInt64_t const & value )
167 /// add a training value for the specified parameter
168 if (memberId>=(int)fHuffmanCoders.size()) {
171 return fHuffmanCoders[memberId]->AddTrainingValue(value);
174 const TList* AliHLTDataDeflaterHuffman::GenerateHuffmanTree()
176 /// generate the huffman tree
177 for (unsigned i=0; i<fHuffmanCoders.size(); i++) {
178 if (!fHuffmanCoders[i]->GenerateHuffmanTree()) {
179 HLTError("failed to generate huffman tree for parameter %s", fHuffmanCoders[i]->GetName());
182 return fHuffmanCoderList;
185 void AliHLTDataDeflaterHuffman::Clear(Option_t * option)
189 AliHLTDataDeflater::Clear(option);
192 void AliHLTDataDeflaterHuffman::Print(Option_t *option) const
198 void AliHLTDataDeflaterHuffman::Print(ostream& out, Option_t * /*option*/) const
201 out << "AliHLTDataDeflaterHuffman:" << endl;
202 for (vector<AliHLTHuffman*>::const_iterator it=fHuffmanCoders.begin();
203 it!=fHuffmanCoders.end(); it++) {
204 (*it)->Print("short"); cout << endl;
206 if (fHuffmanCoders.size()==0 && fHuffmanCoderList && fHuffmanCoderList->GetEntries()>0) {
207 TIter next(fHuffmanCoderList);
209 while ((pObj=next())) {
210 pObj->Print("short"); cout << endl;
215 TObject *AliHLTDataDeflaterHuffman::FindObject(const char *name) const
217 /// find object: 'DeflaterConfiguration'
218 if (strcmp(name, "DeflaterConfiguration")==0) {
219 for (unsigned i=0; i<fHuffmanCoders.size(); i++) {
220 if (!fHuffmanCoders[i]->GenerateHuffmanTree()) {
221 HLTError("generation of huffman tree for parameter '%s' failed", fHuffmanCoders[i]->GetName());
224 if (!fHuffmanCoders[i]->CheckConsistency()) {
225 HLTError("consistency check of huffman tree for parameter '%s' failed", fHuffmanCoders[i]->GetName());
229 return fHuffmanCoderList;
235 void AliHLTDataDeflaterHuffman::SaveAs(const char *filename, Option_t *option) const
237 /// save data according to option
238 TString remainingOptions;
239 bool bWriteHuffmanConf=false; // write the huffman configuration
240 TString strOption(option);
241 std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
243 for (int i=0; i<tokens->GetEntriesFast(); i++) {
244 if (!tokens->At(i)) continue;
246 TString arg=tokens->At(i)->GetName();
249 if (arg.BeginsWith(key)) {
250 bWriteHuffmanConf=true;
254 if (!remainingOptions.IsNull()) remainingOptions+=" ";
255 remainingOptions+=arg;
259 if (bWriteHuffmanConf) {
260 std::auto_ptr<TFile> output(TFile::Open(filename, "RECREATE"));
261 if (!output.get() || output->IsZombie()) {
262 HLTError("can not open file %s from writing", filename);
266 if (!fHuffmanCoderList || fHuffmanCoderList->GetEntries()==0) {
267 HLTError("no huffman instances available for writing");
271 for (unsigned i=0; i<fHuffmanCoders.size(); i++) {
272 if (!fHuffmanCoders[i]->GenerateHuffmanTree()) {
273 HLTError("generation of huffman tree for parameter '%s' failed", fHuffmanCoders[i]->GetName());
278 fHuffmanCoderList->Write("DeflaterConfiguration", TObject::kSingleKey);
282 return AliHLTDataDeflater::SaveAs(remainingOptions);
285 ostream& operator<<(ostream &out, const AliHLTDataDeflaterHuffman& me)