HPCToolkit
DataCompressionLayer.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL: https://hpctoolkit.googlecode.com/svn/branches/hpctoolkit-hpcserver/src/tool/hpcserver/CompressingDataSocketLayer.cpp $
6 // $Id: CompressingDataSocketLayer.cpp 4286 2013-07-09 19:03:59Z felipet1326@gmail.com $
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL: https://hpctoolkit.googlecode.com/svn/branches/hpctoolkit-hpcserver/src/tool/hpcserver/CompressingDataSocketLayer.cpp $
51 //
52 // Purpose:
53 // Compresses data to a memory-based buffer.
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 #include "ByteUtilities.hpp"
61 #include "DataCompressionLayer.hpp"
62 #include "DebugUtils.hpp"
63 
64 #include <iostream> //For cerr
65 #include <cassert>
66 #include <algorithm> //For copy
67 #include <zlib.h>
68 
69 using namespace std;
70 namespace TraceviewerServer
71 {
72 
73  DataCompressionLayer::DataCompressionLayer()
74  {
75 
76  //See: http://www.zlib.net/zpipe.c
77 
78  bufferIndex = 0;
79  posInCompBuffer = 0;
80 
81  inBuf = new char[BUFFER_SIZE];
82  outBuf = new unsigned char[BUFFER_SIZE];
83  outBufferCurrentSize = BUFFER_SIZE;
84 
85  progMonitor = NULL;
86 
87  compressor.zalloc = Z_NULL;
88  compressor.zfree = Z_NULL;
89  compressor.opaque = Z_NULL;
90  int ret = deflateInit(&compressor, -1);
91  if (ret != Z_OK)
92  throw ret;
93 
94  }
95 
96  DataCompressionLayer::DataCompressionLayer(z_stream customCompressor, ProgressBar* _progMonitor)
97  {
98  bufferIndex = 0;
99  posInCompBuffer = 0;
100 
101  inBuf = new char[BUFFER_SIZE];
102  outBuf = new unsigned char[BUFFER_SIZE];
103  outBufferCurrentSize = BUFFER_SIZE;
104 
105  progMonitor = _progMonitor;
106  compressor = customCompressor;
107  }
108 
109  void DataCompressionLayer::writeInt(int toWrite)
110  {
111  makeRoom(4);
112  ByteUtilities::writeInt(inBuf + bufferIndex, toWrite);
113  bufferIndex += 4;
114  pInc(4);
115  }
116  void DataCompressionLayer::writeLong(uint64_t toWrite)
117  {
118  makeRoom(8);
119  ByteUtilities::writeLong(inBuf + bufferIndex, toWrite);
120  bufferIndex += 8;
121  pInc(8);
122  }
123  void DataCompressionLayer::writeDouble(double toWrite)
124  {
125  makeRoom(8);
126  ByteUtilities::writeLong(inBuf + bufferIndex, ByteUtilities::convertDoubleToLong(toWrite));
127  bufferIndex += 8;
128  pInc(8);
129  }
130  void DataCompressionLayer::writeFile(FILE* toWrite)
131  {
132  while (!feof(toWrite))
133  {
134  makeRoom(BUFFER_SIZE);
135  assert(bufferIndex == 0);
136  unsigned int read= fread(inBuf, sizeof(char), BUFFER_SIZE, toWrite);
137  bufferIndex += read;
138  pInc(read);
139  }
140  flush();
141  }
142  void DataCompressionLayer::flush()
143  {
144  softFlush(Z_FINISH);
145  }
146  void DataCompressionLayer::makeRoom(int count)
147  {
148  if (count + bufferIndex > BUFFER_SIZE)
149  softFlush(Z_NO_FLUSH);
150  }
151  void DataCompressionLayer::softFlush(int flushType)
152  {
153 
154  /* run deflate() on input until output buffer not full, finish
155  compression if all of source has been read in */
156 
157  //Adapted from http://www.zlib.net/zpipe.c
158  compressor.avail_in = bufferIndex;
159  compressor.next_in = (unsigned char*)inBuf;
160  do
161  {
162  compressor.avail_out = outBufferCurrentSize - posInCompBuffer;
163  assert(outBufferCurrentSize > posInCompBuffer);
164  DEBUGCOUT(2) << "Avail out: " << outBufferCurrentSize - posInCompBuffer<<endl;
165  compressor.next_out = outBuf + posInCompBuffer;
166  int ret = deflate(&compressor, flushType); /* no bad return value */
167  if (ret == Z_STREAM_ERROR)
168  cerr<<"zlib stream error."<<endl; /* state not clobbered */
169 
170  posInCompBuffer = outBufferCurrentSize - compressor.avail_out;
171  if (posInCompBuffer == outBufferCurrentSize)
172  //Shoot, our output buffer is full...
173  growOutputBuffer();
174 
175  } while (compressor.avail_out == 0);
176  assert(compressor.avail_in == 0);
177 
178  bufferIndex = 0;
179  }
180 
181  void DataCompressionLayer::growOutputBuffer()
182  {
183  unsigned char* newBuffer = new unsigned char[outBufferCurrentSize * BUFFER_GROW_FACTOR];
184  copy(outBuf, outBuf + outBufferCurrentSize, newBuffer);
185 
186  delete[] outBuf;
187 
188  outBufferCurrentSize*= BUFFER_GROW_FACTOR;
189  outBuf = newBuffer;
190  }
191 
192  void DataCompressionLayer::pInc(unsigned int count)
193  {
194  if (progMonitor != NULL)
195  progMonitor->incrementProgress(count);
196  }
197 
198  unsigned char* DataCompressionLayer::getOutputBuffer()
199  {
200  return outBuf;
201  }
202  int DataCompressionLayer::getOutputLength()
203  {
204  return posInCompBuffer;
205  }
206  DataCompressionLayer::~DataCompressionLayer()
207  {
208  deflateEnd(&compressor);
209  delete[] inBuf;
210  delete[] outBuf;
211  }
212 
213 } /* namespace TraceviewerServer */
#define BUFFER_SIZE
Definition: perf_mmap.h:66
void copy(const char *dst,...)
Definition: FileUtil.cpp:233
#define BUFFER_GROW_FACTOR
size_t MONITOR_EXT_WRAP_NAME() fread(void *ptr, size_t size, size_t count, FILE *stream)
Definition: io-over.c:226
#define DEBUGCOUT(a)
Definition: DebugUtils.hpp:72
ssize_t MONITOR_EXT_WRAP_NAME() read(int fd, void *buf, size_t count)
Definition: io-over.c:152
#define NULL
Definition: ElfHelper.cpp:85