Chromium Code Reviews| Index: content/browser/renderer_host/duplicate_resource_handler.cc |
| =================================================================== |
| --- content/browser/renderer_host/duplicate_resource_handler.cc (revision 0) |
| +++ content/browser/renderer_host/duplicate_resource_handler.cc (revision 0) |
| @@ -0,0 +1,96 @@ |
| +// Copyright (c) 2012 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 "content/browser/renderer_host/duplicate_resource_handler.h" |
| + |
| +#include <string> |
| + |
| +#include "base/logging.h" |
| +#include "base/metrics/histogram.h" |
| +#include "content/browser/renderer_host/resource_request_info_impl.h" |
| +#include "net/base/io_buffer.h" |
| +#include "third_party/smhasher/src/MurmurHash3.h" |
| + |
| + |
| +namespace content { |
| + |
| +namespace{ |
| + |
| +std::set<uint32>* GetSetOfHashes() { |
| + static std::set<uint32> seen_resources; |
| + return &seen_resources; |
| +} |
| + |
| +} // namespace |
| + |
| +DuplicateResourceHandler::DuplicateResourceHandler( |
| + scoped_ptr<ResourceHandler> next_handler, |
| + net::URLRequest* request) |
| + : LayeredResourceHandler(next_handler.Pass()), |
| + bytes_read_(0), |
| + bytes_hit_(0), |
| + bytes_miss_(0), |
| + read_buffer_size_(0), // keep track of bytes in read buffer |
| + read_buffer_(new net::IOBuffer(kReadBufSize)), |
| + request_(request) { |
| +} |
| + |
| +DuplicateResourceHandler::~DuplicateResourceHandler() { |
| +} |
| + |
| +/*bool DuplicateResourceHandler::OnWillStart(int request_id, |
| + const GURL& url, |
| + bool* defer) { |
| + return true; |
| +}*/ |
| + |
| +bool DuplicateResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, |
| + int* buf_size, int min_size) { |
| + DCHECK_EQ(-1, min_size); |
| + |
| + *buf = read_buffer_.get(); |
| + *buf_size = kReadBufSize; |
| + return true; |
|
gavinp
2012/07/13 21:16:04
I'm pretty sure you always want to pass through.
|
| + |
| +} |
| + |
| +bool DuplicateResourceHandler::OnReadCompleted(int request_id, int bytes_read, |
| + bool* defer) { |
| + /*if (!next_handler_->OnReadCompleted(request_id, bytes_read, defer)) |
| + return false;*/ |
| + |
| + //DVLOG(4) << "read_buffer_ is " << read_buffer_.get(); |
| + //DVLOG(4) << "read_buffer_->data() is " << read_buffer_->data(); |
| + |
| + // find hash of resource |
| + uint32 buf_hash; |
| + MurmurHash3_x86_32(read_buffer_->data(), bytes_read, 0x0, &buf_hash); |
| + |
| + |
| + const bool did_we_find_it = GetSetOfHashes()->find(buf_hash) != GetSetOfHashes()->end(); |
| + UMA_HISTOGRAM_BOOLEAN("Duplicate.HitRate", did_we_find_it); |
| + |
| + // if element is in hash |
| + if (did_we_find_it) { |
| + bytes_hit_ += bytes_read; |
| + |
| + } else { |
| + bytes_miss_ += bytes_read; |
| + GetSetOfHashes()->insert(buf_hash); |
| + } |
| + |
| + bytes_read_ += bytes_read; |
| + return true; |
| +} |
| + |
| +bool DuplicateResourceHandler::OnResponseCompleted( |
| + int request_id, |
| + const net::URLRequestStatus& status, |
| + const std::string& security_info) { |
| + |
| + read_buffer_ = NULL; |
| + return next_handler_->OnResponseCompleted(request_id, status, security_info); |
| +} |
| + |
| +} //namespace content |