00001 #ifndef CacheDFDecoder_HPP
00002 #define CacheDFDecoder_HPP
00003
00008 #include "io/codec/decoder/CacheDecoderBase.hpp"
00009 #include "util/Formatter.hpp"
00010 #include "io/FDRepr.hpp"
00011 #include "common/debug.hpp"
00012
00013 #include <stack>
00014 #include <string>
00015
00017 template <class FR = FDRepr>
00018 class CacheDFDecoder : public CacheDecoderBase<FR>
00019 {
00020 public:
00021
00022 class params_t : public CacheDecoderBase<FR>::params_t
00023 {
00024 public:
00025 std::streamsize support_buffer_size;
00026 params_t()
00027 {
00028 support_buffer_size = 64;
00029 }
00030 };
00031
00032 CacheDFDecoder(const params_t* par) :
00033 CacheDecoderBase<FR>(par),
00034 support_buffer_size(par->support_buffer_size)
00035 {
00036 support_buffer = new char[support_buffer_size];
00037 positions.push(0);
00038 }
00039 ~CacheDFDecoder()
00040 {
00041 delete[] support_buffer;
00042 }
00043
00044 static bool DINLINE isDFO()
00045 {
00046 return true;
00047 }
00048
00049 void pushItem(const item_t item);
00050
00051 void write(counter_t support);
00052
00065 void writeNEE( counter_t support,
00066 const std::vector<item_t>& nee_items);
00067
00068 void pushItemWithWrite(const item_t item, counter_t support)
00069 {
00070 pushItem(item);
00071 write(support);
00072 }
00073 void pushItemWithPrevSupport(const item_t item);
00074 void popItem()
00075 {
00076 assert(!positions.empty());
00077 positions.pop();
00078 }
00079 void popAll()
00080 {
00081 while( !positions.empty() )
00082 positions.pop();
00083 positions.push(0);
00084 }
00085
00086 std::string getCurrentPatternAsString()
00087 {
00088 return std::string(this->buffer, positions.top());
00089 }
00090
00092 void hint(std::string hint)
00093 {
00094 writeToFile(hint.data(), hint.length());
00095 }
00096
00097 private:
00098 std::stack<std::streamsize> positions;
00099
00101 char* support_buffer;
00102
00104 std::streamsize support_buffer_size;
00105
00107 size_t support_length;
00108 };
00109
00110 template <class FR> inline void
00111 CacheDFDecoder<FR>::pushItem(const item_t item)
00112 {
00113 register std::streamsize length = this->code_inverse[item].second,
00114 pos = positions.top();
00115 memcpy( &(this->buffer)[pos], this->code_inverse[item].first,
00116 length );
00117 pos += length;
00118 this->buffer[pos++] = ' ';
00119 positions.push(pos);
00120 }
00121
00122 template <class FR> inline void
00123 CacheDFDecoder<FR>::write(counter_t support)
00124 {
00125 register std::streamsize pos = positions.top();
00126 this->buffer[pos++] = '(';
00127 register std::streamsize supp_pos(support_buffer_size);
00128 Formatter::IntToStringBack(support, support_buffer, supp_pos);
00129 support_length = support_buffer_size - supp_pos;
00130 memcpy( &(this->buffer)[pos], &support_buffer[supp_pos],
00131 support_length );
00132 pos += support_length;
00133 this->buffer[pos++] = ')';
00134 this->buffer[pos++] = '\n';
00135 writeToFile( this->buffer, pos );
00136 }
00137
00138 template <class FR> inline void
00139 CacheDFDecoder<FR>::writeNEE( counter_t support,
00140 const std::vector<item_t>& nee_items)
00141 {
00142 std::vector<bool>::size_type size = nee_items.size();
00143 std::vector<bool> pattern( size , false);
00144 std::vector<bool>::size_type index;
00145
00146 do
00147 {
00148 write(support);
00149 index=0;
00150 while(index < size && pattern[index] == true )
00151 {
00152 pattern[index] = false;
00153 popItem();
00154 index++;
00155 }
00156 if( index == size )
00157 break;
00158 else
00159 {
00160 pattern[index] = true;
00161 pushItem(nee_items[index]);
00162 }
00163 }
00164 while(true);
00165 }
00166
00167 template <class FR>inline void
00168 CacheDFDecoder<FR>::
00169 pushItemWithPrevSupport(item_t item)
00170 {
00171 pushItem(item);
00172 register std::streamsize pos = positions.top();
00173 this->buffer[pos++] = '(';
00174 memcpy( &(this->buffer)[pos],
00175 &support_buffer[support_buffer_size - support_length],
00176 support_length );
00177 pos += support_length;
00178 this->buffer[pos++] = ')';
00179 this->buffer[pos++] = '\n';
00180 writeToFile( this->buffer, pos );
00181
00182 }
00183 #endif