1 #include "trace_snappyfile.hpp"
14 * Snappy at its core is just a compressoin algorithm so we're
15 * creating a new file format which uses snappy compression
16 * to hold the trace data.
18 * The file is composed of a number of chunks, they are:
20 * uint32 - specifying the length of the compressed data
23 * File can contain any number of such chunks.
24 * The default size of an uncompressed chunk is specified in
28 * Currently the default size for a a to-be-compressed data is
29 * 1mb, meaning that the compressed data will be <= 1mb.
30 * The reason it's 1mb is because it seems
31 * to offer a pretty good compression/disk io speed ratio
32 * but that might change.
36 SnappyFile::SnappyFile(const std::string &filename,
43 m_compressedCache = new char[SNAPPY_CHUNK_SIZE];
46 SnappyFile::~SnappyFile()
48 delete [] m_compressedCache;
51 bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode)
53 std::ios_base::openmode fmode = std::fstream::binary;
54 if (mode == File::Write) {
55 fmode |= (std::fstream::out | std::fstream::trunc);
56 createCache(SNAPPY_CHUNK_SIZE);
57 } else if (mode == File::Read) {
58 fmode |= std::fstream::in;
61 m_stream.open(filename.c_str(), fmode);
63 //read in the initial buffer if we're reading
64 if (m_stream.is_open() && mode == File::Read) {
65 // read the snappy file identifier
66 unsigned char byte1, byte2;
69 assert(byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
72 } else if (m_stream.is_open() && mode == File::Write) {
73 // write the snappy file identifier
74 m_stream << SNAPPY_BYTE1;
75 m_stream << SNAPPY_BYTE2;
77 return m_stream.is_open();
80 bool SnappyFile::rawWrite(const void *buffer, int length)
82 if (freeCacheSize() > length) {
83 memcpy(m_cachePtr, buffer, length);
85 } else if (freeCacheSize() == length) {
86 memcpy(m_cachePtr, buffer, length);
90 int sizeToWrite = length;
92 while (sizeToWrite >= freeCacheSize()) {
93 int endSize = freeCacheSize();
94 int offset = length - sizeToWrite;
95 memcpy(m_cachePtr, (char*)buffer + offset, endSize);
96 sizeToWrite -= endSize;
97 m_cachePtr += endSize;
101 int offset = length - sizeToWrite;
102 memcpy(m_cachePtr, (char*)buffer + offset, sizeToWrite);
103 m_cachePtr += sizeToWrite;
110 bool SnappyFile::rawRead(void *buffer, int length)
112 if (m_stream.eof()) {
115 if (freeCacheSize() > length) {
116 memcpy(buffer, m_cachePtr, length);
117 m_cachePtr += length;
118 } else if (freeCacheSize() == length) {
119 memcpy(buffer, m_cachePtr, length);
120 m_cachePtr += length;
123 int sizeToRead = length;
126 int chunkSize = std::min(freeCacheSize(), sizeToRead);
127 offset = length - sizeToRead;
128 memcpy((char*)buffer + offset, m_cachePtr, chunkSize);
129 m_cachePtr += chunkSize;
130 sizeToRead -= chunkSize;
141 int SnappyFile::rawGetc()
149 void SnappyFile::rawClose()
158 void SnappyFile::rawFlush(FlushType type)
160 if (type == FlushDeep) {
166 void SnappyFile::flushCache()
168 if (m_mode == File::Write) {
169 size_t compressedLength;
171 ::snappy::RawCompress(m_cache, SNAPPY_CHUNK_SIZE - freeCacheSize(),
172 m_compressedCache, &compressedLength);
174 writeCompressedLength(compressedLength);
175 m_stream.write(m_compressedCache, compressedLength);
176 m_cachePtr = m_cache;
177 } else if (m_mode == File::Read) {
180 //assert(m_cachePtr == m_cache + m_cacheSize);
181 size_t compressedLength;
182 compressedLength = readCompressedLength();
183 m_stream.read((char*)m_compressedCache, compressedLength);
184 ::snappy::GetUncompressedLength(m_compressedCache, compressedLength,
188 createCache(m_cacheSize);
189 ::snappy::RawUncompress(m_compressedCache, compressedLength,
194 void SnappyFile::createCache(size_t size)
196 m_cache = new char[size];
197 m_cachePtr = m_cache;
201 void SnappyFile::writeCompressedLength(uint32_t value)
203 m_stream.write((char*)&value, sizeof value);
206 uint32_t SnappyFile::readCompressedLength()
209 m_stream.read((char*)&len, sizeof len);