From a328553886e719817d871acc622407a310c0504d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 27 Nov 2011 12:32:00 +0000 Subject: [PATCH] Add "apitrace repack" command. --- CMakeLists.txt | 2 + cli/CMakeLists.txt | 1 + cli/cli.hpp | 1 + cli/cli_main.cpp | 3 +- cli/cli_repack.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++ common/trace_file.hpp | 2 + common/trace_file_read.cpp | 59 ++++++++++++++++++++++ common/trace_file_write.cpp | 50 +++++++++++++++++++ common/trace_parser.cpp | 9 +--- scripts/tracerepack.py | 75 ---------------------------- 10 files changed, 235 insertions(+), 83 deletions(-) create mode 100644 cli/cli_repack.cpp create mode 100644 common/trace_file_read.cpp create mode 100644 common/trace_file_write.cpp delete mode 100755 scripts/tracerepack.py diff --git a/CMakeLists.txt b/CMakeLists.txt index c3e8a84..9c0f2f5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,6 +264,8 @@ endif () add_library (common STATIC common/trace_file.cpp + common/trace_file_read.cpp + common/trace_file_write.cpp common/trace_file_zlib.cpp common/trace_file_snappy.cpp common/trace_model.cpp diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 5196467..e9419f9 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable (apitrace cli_diff_state.cpp cli_diff_images.cpp cli_dump.cpp + cli_repack.cpp cli_trace.cpp ) diff --git a/cli/cli.hpp b/cli/cli.hpp index 1461b4d..ba2148b 100644 --- a/cli/cli.hpp +++ b/cli/cli.hpp @@ -44,6 +44,7 @@ extern const Command diff_command; extern const Command diff_state_command; extern const Command diff_images_command; extern const Command dump_command; +extern const Command repack_command; extern const Command trace_command; #endif /* _APITRACE_CLI_HPP_ */ diff --git a/cli/cli_main.cpp b/cli/cli_main.cpp index fb4f88f..8f9392e 100644 --- a/cli/cli_main.cpp +++ b/cli/cli_main.cpp @@ -70,6 +70,7 @@ static const Command * commands[] = { &diff_state_command, &diff_images_command, &dump_command, + &repack_command, &trace_command, &help_command }; @@ -184,5 +185,5 @@ main(int argc, char **argv) std::cerr << "Error: unknown command " << command_name << " (see \"apitrace help\").\n"; - return 1; + return 1; } diff --git a/cli/cli_repack.cpp b/cli/cli_repack.cpp new file mode 100644 index 0000000..918f54a --- /dev/null +++ b/cli/cli_repack.cpp @@ -0,0 +1,116 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * 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 +#include + +#include "cli.hpp" + +#include "trace_file.hpp" + + +static const char *synopsis = "Repack a trace file with Snappy compression."; + +static void +usage(void) +{ + std::cout + << "usage: apitrace repack \n" + << synopsis << "\n" + << "\n" + << "Snappy compression allows for faster replay and smaller memory footprint,\n" + << "at the expense of a slightly smaller compression ratio than zlib\n" + << "\n"; +} + +static int +repack(const char *inFileName, const char *outFileName) +{ + trace::File *inFile = trace::File::createForRead(inFileName); + if (!inFile) { + return 1; + } + + trace::File *outFile = trace::File::createForWrite(outFileName); + if (!outFile) { + delete inFile; + return 1; + } + + size_t size = 8192; + char *buf = new char[size]; + size_t read; + + while ((read = inFile->read(buf, size)) != 0) { + outFile->write(buf, read); + } + + delete [] buf; + delete outFile; + delete inFile; + + return 0; +} + +static int +command(int argc, char *argv[]) +{ + int i; + + for (i = 0; i < argc; ++i) { + const char *arg = argv[i]; + + if (arg[0] != '-') { + break; + } + + if (!strcmp(arg, "--")) { + break; + } else if (strcmp(arg, "--help") == 0) { + usage(); + return 0; + } else { + std::cerr << "error: unknown option " << arg << "\n"; + usage(); + return 1; + } + } + + if (argc != i + 2) { + std::cerr << "error: insufficient number of arguments\n"; + usage(); + return 1; + } + + return repack(argv[i], argv[i + 1]); +} + +const Command repack_command = { + "repack", + synopsis, + usage, + command +}; diff --git a/common/trace_file.hpp b/common/trace_file.hpp index 68f50b4..411eccb 100644 --- a/common/trace_file.hpp +++ b/common/trace_file.hpp @@ -53,6 +53,8 @@ public: static bool isSnappyCompressed(const std::string &filename); static File *createZLib(void); static File *createSnappy(void); + static File *createForRead(const char *filename); + static File *createForWrite(const char *filename); public: File(const std::string &filename = std::string(), File::Mode mode = File::Read); diff --git a/common/trace_file_read.cpp b/common/trace_file_read.cpp new file mode 100644 index 0000000..68bc74a --- /dev/null +++ b/common/trace_file_read.cpp @@ -0,0 +1,59 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * 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 "os.hpp" +#include "trace_file.hpp" + + +using namespace trace; + + +File * +File::createForRead(const char *filename) +{ + File *file; + + if (File::isSnappyCompressed(filename)) { + file = File::createSnappy(); + } else if (File::isZLibCompressed(filename)) { + file = File::createZLib(); + } else { + os::log("error: could not determine %s compression type\n", filename); + return NULL; + } + + if (!file) { + return NULL; + } + + if (!file->open(filename, File::Read)) { + os::log("error: could not open %s for reading\n", filename); + delete file; + return NULL; + } + + return file; +} diff --git a/common/trace_file_write.cpp b/common/trace_file_write.cpp new file mode 100644 index 0000000..4cc8984 --- /dev/null +++ b/common/trace_file_write.cpp @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * 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 "os.hpp" +#include "trace_file.hpp" + + +using namespace trace; + + +File * +File::createForWrite(const char *filename) +{ + File *file; + file = File::createSnappy(); + if (!file) { + return NULL; + } + + if (!file->open(filename, File::Write)) { + os::log("error: could not open %s for writing\n", filename); + delete file; + return NULL; + } + + return file; +} diff --git a/common/trace_parser.cpp b/common/trace_parser.cpp index 7556b14..aabf388 100644 --- a/common/trace_parser.cpp +++ b/common/trace_parser.cpp @@ -52,13 +52,8 @@ Parser::~Parser() { bool Parser::open(const char *filename) { assert(!file); - if (File::isZLibCompressed(filename)) { - file = File::createZLib(); - } else { - file = File::createSnappy(); - } - - if (!file->open(filename, File::Read)) { + file = File::createForRead(filename); + if (!file) { return false; } diff --git a/scripts/tracerepack.py b/scripts/tracerepack.py deleted file mode 100755 index 028eb18..0000000 --- a/scripts/tracerepack.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -########################################################################## -# -# Copyright 2011 Jose Fonseca -# 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. -# -##########################################################################/ - -'''Script to recompress a trace. -''' - - -import optparse -import os.path -import sys -import gzip -import tempfile -import shutil - - -def repack(in_name): - mtime = os.path.getmtime(in_name) - out_name = tempfile.mktemp() - - in_stream = gzip.GzipFile(in_name, 'rb') - out_stream = gzip.GzipFile(out_name, 'wb', compresslevel=9, mtime=mtime) - - shutil.copyfileobj(in_stream, out_stream) - - in_stream.close() - out_stream.close() - - in_size = os.path.getsize(in_name) - out_size = os.path.getsize(out_name) - - print '%u -> %u' % (in_size, out_size) - - if out_size < in_size: - shutil.move(out_name, in_name) - else: - os.unlink(out_name) - - -def main(): - optparser = optparse.OptionParser( - usage='\n\t%prog ...', - version='%%prog') - - (options, args) = optparser.parse_args(sys.argv[1:]) - if not args: - optparser.error("incorrect number of arguments") - - map(repack, args) - - -if __name__ == '__main__': - main() -- 2.7.4