| Index: net/base/load_log_util.cc
|
| ===================================================================
|
| --- net/base/load_log_util.cc (revision 0)
|
| +++ net/base/load_log_util.cc (revision 0)
|
| @@ -0,0 +1,179 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/base/load_log_util.h"
|
| +
|
| +#include "base/string_util.h"
|
| +
|
| +namespace net {
|
| +namespace {
|
| +
|
| +class FormatHelper {
|
| + public:
|
| + std::string ToString(const LoadLog* log) {
|
| + entries_.clear();
|
| +
|
| + // Pass 1: Match the start/end of indentation blocks. Fills |entries_|
|
| + // with the results.
|
| + PopulateEntries(log);
|
| +
|
| + // Pass 2: Figure out the maximum width of each column. This allows us
|
| + // to right-justify text within each column.
|
| + size_t max_time_width, max_indentation, max_type_width, max_dt_width;
|
| + GetMaxExtent(
|
| + &max_time_width, &max_indentation, &max_type_width, &max_dt_width);
|
| +
|
| + // Pass 3: Assemble the string.
|
| + std::string result;
|
| +
|
| + const int kSpacesPerIndentation = 2;
|
| +
|
| + for (size_t i = 0; i < entries_.size(); ++i) {
|
| + if (i > 0)
|
| + result += "\n";
|
| +
|
| + int indentation_spaces = entries_[i].indentation * kSpacesPerIndentation;
|
| + std::string event_str = GetEventString(i);
|
| +
|
| + result += StringPrintf("t=%s: %s%s",
|
| + PadStringLeft(GetTimeString(i), max_time_width).c_str(),
|
| + PadStringLeft("", indentation_spaces).c_str(),
|
| + event_str.c_str());
|
| +
|
| + if (entries_[i].event->phase == LoadLog::PHASE_BEGIN) {
|
| + // Summarize how long this block lasted.
|
| + int padding = ((max_indentation - entries_[i].indentation) *
|
| + kSpacesPerIndentation) + (max_type_width - event_str.size());
|
| + result += StringPrintf("%s [dt=%s]",
|
| + PadStringLeft("", padding).c_str(),
|
| + PadStringLeft(GetBlockDtString(i), max_dt_width).c_str());
|
| + }
|
| + }
|
| +
|
| + return result;
|
| + }
|
| +
|
| + private:
|
| + struct Entry {
|
| + explicit Entry(const LoadLog::Event* event)
|
| + : event(event), indentation(0), block_index(-1) {}
|
| +
|
| + const LoadLog::Event* event;
|
| + size_t indentation;
|
| + int block_index; // The index of the matching start / end of block.
|
| + };
|
| +
|
| + void PopulateEntries(const LoadLog* log) {
|
| + int current_indentation = 0;
|
| +
|
| + for (size_t i = 0; i < log->events().size(); ++i) {
|
| + Entry entry(&log->events()[i]);
|
| +
|
| + entry.indentation = current_indentation;
|
| +
|
| + if (entry.event->phase == LoadLog::PHASE_BEGIN) {
|
| + // Indent everything contained in this block.
|
| + current_indentation++;
|
| + }
|
| +
|
| + if (entry.event->phase == LoadLog::PHASE_END) {
|
| + int start_index = FindStartOfBlockIndex(entry);
|
| + if (start_index != -1) {
|
| + // Point the start / end of block at each other.
|
| + entry.block_index = start_index;
|
| + entries_[start_index].block_index = i;
|
| +
|
| + // Restore the indentation prior to the block.
|
| + // (Could be more than 1 level if close of blocks are missing).
|
| + current_indentation = entries_[start_index].indentation;
|
| + entry.indentation = current_indentation;
|
| + }
|
| + }
|
| +
|
| + entries_.push_back(entry);
|
| + }
|
| + }
|
| +
|
| + int FindStartOfBlockIndex(const Entry& entry) {
|
| + DCHECK_EQ(LoadLog::PHASE_END, entry.event->phase);
|
| +
|
| + // Find the matching start of block by scanning backwards.
|
| + for (int i = entries_.size() - 1; i >= 0; --i) {
|
| + if (entries_[i].event->phase == LoadLog::PHASE_BEGIN &&
|
| + entries_[i].event->type == entry.event->type) {
|
| + return i;
|
| + }
|
| + }
|
| + return -1; // Start not found.
|
| + }
|
| +
|
| + void GetMaxExtent(size_t* max_time_width,
|
| + size_t* max_indentation,
|
| + size_t* max_type_width,
|
| + size_t* max_dt_width) {
|
| + *max_time_width = *max_indentation = *max_type_width = *max_dt_width = 0;
|
| + for (size_t i = 0; i < entries_.size(); ++i) {
|
| + *max_time_width = std::max(*max_time_width, GetTimeString(i).size());
|
| + *max_type_width = std::max(*max_type_width, GetEventString(i).size());
|
| + *max_indentation = std::max(*max_indentation, entries_[i].indentation);
|
| +
|
| + if (entries_[i].event->phase == LoadLog::PHASE_BEGIN)
|
| + *max_dt_width = std::max(*max_dt_width, GetBlockDtString(i).size());
|
| + }
|
| + }
|
| +
|
| + std::string GetBlockDtString(size_t start_index) {
|
| + int end_index = entries_[start_index].block_index;
|
| + if (end_index == -1) {
|
| + // Block is not closed, implicitly close it at EOF.
|
| + end_index = entries_.size() - 1;
|
| + }
|
| + int64 dt_ms = (entries_[end_index].event->time -
|
| + entries_[start_index].event->time).InMilliseconds();
|
| +
|
| + return Int64ToString(dt_ms);
|
| + }
|
| +
|
| + std::string GetTimeString(size_t index) {
|
| + int64 t_ms = (entries_[index].event->time -
|
| + base::TimeTicks()).InMilliseconds();
|
| + return Int64ToString(t_ms);
|
| + }
|
| +
|
| + std::string GetEventString(size_t index) {
|
| + const LoadLog::Event* event = entries_[index].event;
|
| + const char* type_str = LoadLog::EventTypeToString(event->type);
|
| +
|
| + switch (event->phase) {
|
| + case LoadLog::PHASE_BEGIN:
|
| + return std::string("+") + type_str;
|
| + case LoadLog::PHASE_END:
|
| + return std::string("-") + type_str;
|
| + case LoadLog::PHASE_NONE:
|
| + return std::string(" ") + type_str;
|
| + default:
|
| + NOTREACHED();
|
| + return std::string();
|
| + }
|
| + }
|
| +
|
| + static std::string PadStringLeft(const std::string& str, size_t width) {
|
| + DCHECK_LE(str.size(), width);
|
| + std::string padding;
|
| + padding.resize(width - str.size(), ' ');
|
| + return padding + str;
|
| + }
|
| +
|
| + std::vector<Entry> entries_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +std::string LoadLogUtil::PrettyPrintAsEventTree(const LoadLog* log) {
|
| + FormatHelper helper;
|
| + return helper.ToString(log);
|
| +}
|
| +
|
| +} // namespace net
|
|
|
| Property changes on: net\base\load_log_util.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|