Commit 214024d8 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Remove content/browser/loader/resource_buffer.*

It was used by the non-Mojo loading path, which was removed quite a
while back.

Bug: none
Change-Id: I86c7b9b7cc950b3f89a00fcb57ff4f95a9a328b9
Reviewed-on: https://chromium-review.googlesource.com/1112465Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569996}
parent 0a4de8ea
......@@ -1014,8 +1014,6 @@ jumbo_source_set("browser") {
"loader/prefetch_url_loader.h",
"loader/prefetch_url_loader_service.cc",
"loader/prefetch_url_loader_service.h",
"loader/resource_buffer.cc",
"loader/resource_buffer.h",
"loader/resource_controller.h",
"loader/resource_dispatcher_host_impl.cc",
"loader/resource_dispatcher_host_impl.h",
......
// 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/loader/resource_buffer.h"
#include <math.h>
#include "base/logging.h"
namespace content {
// A circular buffer allocator.
//
// We keep track of the starting offset (alloc_start_) and the ending offset
// (alloc_end_). There are two layouts to keep in mind:
//
// #1:
// ------------[XXXXXXXXXXXXXXXXXXXXXXX]----
// ^ ^
// start end
//
// #2:
// XXXXXXXXXX]---------------------[XXXXXXXX
// ^ ^
// end start
//
// If end <= start, then we have the buffer wraparound case (depicted second).
// If the buffer is empty, then start and end will be set to -1.
//
// Allocations are always contiguous.
ResourceBuffer::ResourceBuffer()
: buf_size_(0),
min_alloc_size_(0),
max_alloc_size_(0),
alloc_start_(-1),
alloc_end_(-1) {
}
ResourceBuffer::~ResourceBuffer() {
}
bool ResourceBuffer::Initialize(int buffer_size,
int min_allocation_size,
int max_allocation_size) {
CHECK(!IsInitialized());
// It would be wasteful if these are not multiples of min_allocation_size.
CHECK_EQ(0, buffer_size % min_allocation_size);
CHECK_EQ(0, max_allocation_size % min_allocation_size);
buf_size_ = buffer_size;
min_alloc_size_ = min_allocation_size;
max_alloc_size_ = max_allocation_size;
return shared_mem_.CreateAndMapAnonymous(buf_size_);
}
bool ResourceBuffer::IsInitialized() const {
return shared_mem_.memory() != nullptr;
}
base::SharedMemory& ResourceBuffer::GetSharedMemory() {
CHECK(IsInitialized());
return shared_mem_;
}
bool ResourceBuffer::CanAllocate() const {
CHECK(IsInitialized());
if (alloc_start_ == -1)
return true;
int diff = alloc_end_ - alloc_start_;
if (diff > 0)
return (buf_size_ - diff) >= min_alloc_size_;
return -diff >= min_alloc_size_;
}
char* ResourceBuffer::Allocate(int* size) {
CHECK(CanAllocate());
int alloc_offset = 0;
int alloc_size;
if (alloc_start_ == -1) {
// This is the first allocation.
alloc_start_ = 0;
alloc_end_ = buf_size_;
alloc_size = buf_size_;
} else if (alloc_start_ < alloc_end_) {
// Append the next allocation if it fits. Otherwise, wraparound.
//
// NOTE: We could look to see if a larger allocation is possible by
// wrapping around sooner, but instead we just look to fill the space at
// the end of the buffer provided that meets the min_alloc_size_
// requirement.
//
if ((buf_size_ - alloc_end_) >= min_alloc_size_) {
alloc_offset = alloc_end_;
alloc_size = buf_size_ - alloc_end_;
alloc_end_ = buf_size_;
} else {
// It must be possible to allocate a least min_alloc_size_.
CHECK(alloc_start_ >= min_alloc_size_);
alloc_size = alloc_start_;
alloc_end_ = alloc_start_;
}
} else {
// This is the wraparound case.
CHECK(alloc_end_ < alloc_start_);
alloc_offset = alloc_end_;
alloc_size = alloc_start_ - alloc_end_;
alloc_end_ = alloc_start_;
}
// Make sure alloc_size does not exceed max_alloc_size_. We store the
// current value of alloc_size, so that we can use ShrinkLastAllocation to
// trim it back. This allows us to reuse the alloc_end_ adjustment logic.
alloc_sizes_.push(alloc_size);
if (alloc_size > max_alloc_size_) {
alloc_size = max_alloc_size_;
ShrinkLastAllocation(alloc_size);
}
*size = alloc_size;
return static_cast<char*>(shared_mem_.memory()) + alloc_offset;
}
int ResourceBuffer::GetLastAllocationOffset() const {
CHECK(!alloc_sizes_.empty());
CHECK(alloc_end_ >= alloc_sizes_.back());
return alloc_end_ - alloc_sizes_.back();
}
void ResourceBuffer::ShrinkLastAllocation(int new_size) {
CHECK(!alloc_sizes_.empty());
int aligned_size = (new_size / min_alloc_size_) * min_alloc_size_;
if (aligned_size < new_size)
aligned_size += min_alloc_size_;
CHECK_LE(new_size, aligned_size);
CHECK_GE(alloc_sizes_.back(), aligned_size);
int* last_allocation_size = &alloc_sizes_.back();
alloc_end_ -= (*last_allocation_size - aligned_size);
*last_allocation_size = aligned_size;
}
void ResourceBuffer::RecycleLeastRecentlyAllocated() {
CHECK(!alloc_sizes_.empty());
int allocation_size = alloc_sizes_.front();
alloc_sizes_.pop();
alloc_start_ += allocation_size;
CHECK(alloc_start_ <= buf_size_);
if (alloc_start_ == alloc_end_) {
CHECK(alloc_sizes_.empty());
alloc_start_ = -1;
alloc_end_ = -1;
} else if (alloc_start_ == buf_size_) {
CHECK(!alloc_sizes_.empty());
alloc_start_ = 0;
}
}
} // namespace content
// 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.
#ifndef CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
#define CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "content/common/content_export.h"
namespace content {
// ResourceBuffer implements a simple "circular buffer" allocation strategy.
// Allocations are recycled in FIFO order.
//
// You can think of the ResourceBuffer as a FIFO. The Allocate method reserves
// space in the buffer. Allocate may be called multiple times until the buffer
// is fully reserved (at which point CanAllocate returns false). Allocations
// are freed in FIFO order via a call to RecycleLeastRecentlyAllocated.
//
// ResourceBuffer is reference-counted for the benefit of consumers, who need
// to ensure that ResourceBuffer stays alive while they are using its memory.
//
// EXAMPLE USAGE:
//
// // Writes data into the ResourceBuffer, and returns the location (byte
// // offset and count) of the bytes written into the ResourceBuffer's shared
// // memory buffer.
// void WriteToBuffer(ResourceBuffer* buf, int* offset, int* count) {
// DCHECK(buf->CanAllocate());
//
// *offset = -1;
// *count = 0;
//
// int size;
// char* ptr = buf->Allocate(&size);
// if (!ptr) { /* handle error */ }
//
// int bytes_read = static_cast<int>(fread(ptr, 1, size, file_pointer_));
// if (!bytes_read) { /* handle error */ }
//
// if (bytes_read < size)
// buf->ShrinkLastAllocation(bytes_read);
//
// *offset = buf->GetLastAllocationOffset();
// *count = bytes_read;
// }
//
// NOTE: As the above example illustrates, the ResourceBuffer keeps track of
// the last allocation made. Calling ShrinkLastAllocation is optional, as it
// just helps the ResourceBuffer optimize storage and be more aggressive about
// returning larger allocations from the Allocate method.
//
class CONTENT_EXPORT ResourceBuffer
: public base::RefCountedThreadSafe<ResourceBuffer> {
public:
ResourceBuffer();
// Initialize the shared memory buffer. It will be buffer_size bytes in
// length. The min/max_allocation_size parameters control the behavior of
// the Allocate method. It will prefer to return segments that are
// max_allocation_size in length, but will return segments less than that if
// space is limited. It will not return allocations smaller than
// min_allocation_size.
bool Initialize(int buffer_size,
int min_allocation_size,
int max_allocation_size);
bool IsInitialized() const;
// Returns a reference to the underlying shared memory.
base::SharedMemory& GetSharedMemory();
// Returns true if Allocate will succeed.
bool CanAllocate() const;
// Returns a pointer into the shared memory buffer or NULL if the buffer is
// already fully allocated. The returned size will be max_allocation_size
// unless the buffer is close to being full.
char* Allocate(int* size);
// Returns the offset into the shared memory buffer where the last allocation
// returned by Allocate can be found.
int GetLastAllocationOffset() const;
// Called to reduce the size of the last allocation returned by Allocate. It
// is OK for new_size to match the current size of the last allocation.
void ShrinkLastAllocation(int new_size);
// Called to allow reuse of memory that was previously allocated. See notes
// above the class for more details about this method.
void RecycleLeastRecentlyAllocated();
private:
friend class base::RefCountedThreadSafe<ResourceBuffer>;
~ResourceBuffer();
base::SharedMemory shared_mem_;
int buf_size_;
int min_alloc_size_;
int max_alloc_size_;
// These point to the range of the shared memory that is currently allocated.
// If alloc_start_ is -1, then the range is empty and nothing is allocated.
// Otherwise, alloc_start_ points to the start of the allocated range, and
// alloc_end_ points just beyond the end of the previous allocation. In the
// wraparound case, alloc_end_ <= alloc_start_. See resource_buffer.cc for
// more details about these members.
int alloc_start_;
int alloc_end_;
base::queue<int> alloc_sizes_;
DISALLOW_COPY_AND_ASSIGN(ResourceBuffer);
};
} // namespace content
#endif // CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
// 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/loader/resource_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
TEST(ResourceBufferTest, BasicAllocations) {
scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
EXPECT_TRUE(buf->Initialize(100, 5, 10));
EXPECT_TRUE(buf->CanAllocate());
// First allocation
{
int size;
char* ptr = buf->Allocate(&size);
EXPECT_TRUE(ptr);
EXPECT_EQ(10, size);
EXPECT_TRUE(buf->CanAllocate());
EXPECT_EQ(0, buf->GetLastAllocationOffset());
buf->ShrinkLastAllocation(2); // Less than our min allocation size.
EXPECT_EQ(0, buf->GetLastAllocationOffset());
EXPECT_TRUE(buf->CanAllocate());
}
// Second allocation
{
int size;
char* ptr = buf->Allocate(&size);
EXPECT_TRUE(ptr);
EXPECT_EQ(10, size);
EXPECT_TRUE(buf->CanAllocate());
EXPECT_EQ(5, buf->GetLastAllocationOffset());
buf->ShrinkLastAllocation(4);
EXPECT_EQ(5, buf->GetLastAllocationOffset());
EXPECT_TRUE(buf->CanAllocate());
}
}
TEST(ResourceBufferTest, AllocateAndRecycle) {
scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
EXPECT_TRUE(buf->Initialize(100, 5, 10));
int size;
buf->Allocate(&size);
EXPECT_EQ(0, buf->GetLastAllocationOffset());
buf->RecycleLeastRecentlyAllocated();
// Offset should again be 0.
buf->Allocate(&size);
EXPECT_EQ(0, buf->GetLastAllocationOffset());
}
TEST(ResourceBufferTest, WrapAround) {
scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
EXPECT_TRUE(buf->Initialize(20, 10, 10));
int size;
buf->Allocate(&size);
EXPECT_EQ(10, size);
buf->Allocate(&size);
EXPECT_EQ(10, size);
// Create hole at the beginnning. Next allocation should go there.
buf->RecycleLeastRecentlyAllocated();
buf->Allocate(&size);
EXPECT_EQ(10, size);
EXPECT_EQ(0, buf->GetLastAllocationOffset());
}
TEST(ResourceBufferTest, WrapAround2) {
scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
EXPECT_TRUE(buf->Initialize(30, 10, 10));
int size;
buf->Allocate(&size);
EXPECT_EQ(10, size);
buf->Allocate(&size);
EXPECT_EQ(10, size);
buf->Allocate(&size);
EXPECT_EQ(10, size);
EXPECT_FALSE(buf->CanAllocate());
// Create holes at first and second slots.
buf->RecycleLeastRecentlyAllocated();
buf->RecycleLeastRecentlyAllocated();
EXPECT_TRUE(buf->CanAllocate());
buf->Allocate(&size);
EXPECT_EQ(10, size);
EXPECT_EQ(0, buf->GetLastAllocationOffset());
buf->Allocate(&size);
EXPECT_EQ(10, size);
EXPECT_EQ(10, buf->GetLastAllocationOffset());
EXPECT_FALSE(buf->CanAllocate());
}
TEST(ResourceBufferTest, Full) {
scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
EXPECT_TRUE(buf->Initialize(20, 10, 10));
int size;
buf->Allocate(&size);
EXPECT_EQ(10, size);
buf->Allocate(&size);
EXPECT_EQ(10, size);
// Full.
EXPECT_FALSE(buf->CanAllocate());
// Still full, even if there is a small hole at the end.
buf->ShrinkLastAllocation(5);
EXPECT_FALSE(buf->CanAllocate());
}
} // namespace content
......@@ -1375,7 +1375,6 @@ test("content_unittests") {
"../browser/loader/mojo_async_resource_handler_unittest.cc",
"../browser/loader/navigation_url_loader_impl_unittest.cc",
"../browser/loader/navigation_url_loader_unittest.cc",
"../browser/loader/resource_buffer_unittest.cc",
"../browser/loader/resource_dispatcher_host_unittest.cc",
"../browser/loader/resource_loader_unittest.cc",
"../browser/loader/source_stream_to_data_pipe_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment