X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=trace_snappyfile.cpp;h=ad0a57749a784ae7148ee056e4115c6f360980b2;hb=35c2793ac758997a0a1c2e558d384ab94754987d;hp=457f7e9529604d211ba86ce82e3900a4d80486af;hpb=b5f2ee344ef2914ca141608107c571ec0c28c6a6;p=apitrace diff --git a/trace_snappyfile.cpp b/trace_snappyfile.cpp index 457f7e9..ad0a577 100644 --- a/trace_snappyfile.cpp +++ b/trace_snappyfile.cpp @@ -1,3 +1,29 @@ +/************************************************************************** + * + * Copyright 2011 Zack Rusin + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + #include "trace_snappyfile.hpp" #include @@ -7,6 +33,32 @@ using namespace Trace; +/* + * Snappy file format. + * ------------------- + * + * Snappy at its core is just a compressoin algorithm so we're + * creating a new file format which uses snappy compression + * to hold the trace data. + * + * The file is composed of a number of chunks, they are: + * chunk { + * uint32 - specifying the length of the compressed data + * compressed data + * } + * File can contain any number of such chunks. + * The default size of an uncompressed chunk is specified in + * SNAPPY_CHUNK_SIZE. + * + * Note: + * Currently the default size for a a to-be-compressed data is + * 1mb, meaning that the compressed data will be <= 1mb. + * The reason it's 1mb is because it seems + * to offer a pretty good compression/disk io speed ratio + * but that might change. + * + */ + SnappyFile::SnappyFile(const std::string &filename, File::Mode mode) : File(), @@ -83,16 +135,13 @@ bool SnappyFile::rawWrite(const void *buffer, int length) bool SnappyFile::rawRead(void *buffer, int length) { - if (m_stream.eof()) { + if (endOfData()) { return false; } - if (freeCacheSize() > length) { - memcpy(buffer, m_cachePtr, length); - m_cachePtr += length; - } else if (freeCacheSize() == length) { + + if (freeCacheSize() >= length) { memcpy(buffer, m_cachePtr, length); m_cachePtr += length; - flushCache(); } else { int sizeToRead = length; int offset = 0; @@ -129,11 +178,9 @@ void SnappyFile::rawClose() m_cachePtr = NULL; } -void SnappyFile::rawFlush(FlushType type) +void SnappyFile::rawFlush() { - if (type == FlushDeep) { - flushCache(); - } + flushCache(); m_stream.flush(); } @@ -145,7 +192,7 @@ void SnappyFile::flushCache() ::snappy::RawCompress(m_cache, SNAPPY_CHUNK_SIZE - freeCacheSize(), m_compressedCache, &compressedLength); - m_stream << compressedLength; + writeCompressedLength(compressedLength); m_stream.write(m_compressedCache, compressedLength); m_cachePtr = m_cache; } else if (m_mode == File::Read) { @@ -153,8 +200,16 @@ void SnappyFile::flushCache() return; //assert(m_cachePtr == m_cache + m_cacheSize); size_t compressedLength; - m_stream >> compressedLength; + compressedLength = readCompressedLength(); m_stream.read((char*)m_compressedCache, compressedLength); + /* + * The reason we peek here is because the last read will + * read all the way until the last character, but that will not + * trigger m_stream.eof() to be set, so by calling peek + * we assure that if we in fact have read the entire stream + * then the m_stream.eof() is always set. + */ + m_stream.peek(); ::snappy::GetUncompressedLength(m_compressedCache, compressedLength, &m_cacheSize); if (m_cache) @@ -171,3 +226,15 @@ void SnappyFile::createCache(size_t size) m_cachePtr = m_cache; m_cacheSize = size; } + +void SnappyFile::writeCompressedLength(uint32_t value) +{ + m_stream.write((const char*)&value, sizeof value); +} + +uint32_t SnappyFile::readCompressedLength() +{ + uint32_t len; + m_stream.read((char*)&len, sizeof len); + return len; +}