Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/browser/chromeos/file_system_provider/fileapi/buffering_file_stream_reader.cc

Issue 470323003: [fsp] Improve performance for reading small chunks of data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/file_system_provider/fileapi/buffering_file_st ream_reader.h" 5 #include "chrome/browser/chromeos/file_system_provider/fileapi/buffering_file_st ream_reader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
11 #include "storage/browser/fileapi/file_system_backend.h"
11 12
12 namespace chromeos { 13 namespace chromeos {
13 namespace file_system_provider { 14 namespace file_system_provider {
14 15
15 BufferingFileStreamReader::BufferingFileStreamReader( 16 BufferingFileStreamReader::BufferingFileStreamReader(
16 scoped_ptr<storage::FileStreamReader> file_stream_reader, 17 scoped_ptr<storage::FileStreamReader> file_stream_reader,
17 int buffer_size) 18 int preloading_buffer_length,
19 int64 max_bytes_to_read)
18 : file_stream_reader_(file_stream_reader.Pass()), 20 : file_stream_reader_(file_stream_reader.Pass()),
19 buffer_size_(buffer_size), 21 preloading_buffer_length_(preloading_buffer_length),
20 preloading_buffer_(new net::IOBuffer(buffer_size_)), 22 max_bytes_to_read_(max_bytes_to_read),
23 bytes_read_(0),
24 preloading_buffer_(new net::IOBuffer(preloading_buffer_length)),
21 preloading_buffer_offset_(0), 25 preloading_buffer_offset_(0),
22 buffered_bytes_(0), 26 preloaded_bytes_(0),
23 weak_ptr_factory_(this) { 27 weak_ptr_factory_(this) {
24 } 28 }
25 29
26 BufferingFileStreamReader::~BufferingFileStreamReader() { 30 BufferingFileStreamReader::~BufferingFileStreamReader() {
27 } 31 }
28 32
29 int BufferingFileStreamReader::Read(net::IOBuffer* buffer, 33 int BufferingFileStreamReader::Read(net::IOBuffer* buffer,
30 int buffer_length, 34 int buffer_length,
31 const net::CompletionCallback& callback) { 35 const net::CompletionCallback& callback) {
32 // Return as much as available in the internal buffer. It may be less than 36 // Return as much as available in the internal buffer. It may be less than
33 // |buffer_length|, what is valid. 37 // |buffer_length|, what is valid.
34 const int bytes_read = 38 const int bytes_read =
35 CopyFromPreloadingBuffer(make_scoped_refptr(buffer), buffer_length); 39 CopyFromPreloadingBuffer(make_scoped_refptr(buffer), buffer_length);
36 if (bytes_read) 40 if (bytes_read)
37 return bytes_read; 41 return bytes_read;
38 42
39 // If the internal buffer is empty, and more bytes than the internal buffer 43 // If the internal buffer is empty, and more bytes than the internal buffer
40 // size is requested, then call the internal file stream reader directly. 44 // size is requested, then call the internal file stream reader directly.
41 if (buffer_length >= buffer_size_) { 45 if (buffer_length >= preloading_buffer_length_) {
42 const int result = 46 const int result = file_stream_reader_->Read(
43 file_stream_reader_->Read(buffer, buffer_length, callback); 47 buffer,
48 buffer_length,
49 base::Bind(&BufferingFileStreamReader::OnReadCompleted,
50 weak_ptr_factory_.GetWeakPtr(),
51 callback));
44 DCHECK_EQ(result, net::ERR_IO_PENDING); 52 DCHECK_EQ(result, net::ERR_IO_PENDING);
45 return result; 53 return result;
46 } 54 }
47 55
48 // Nothing copied, so contents have to be preloaded. 56 // Nothing copied, so contents have to be preloaded.
49 Preload(base::Bind(&BufferingFileStreamReader::OnPreloadCompleted, 57 Preload(base::Bind(&BufferingFileStreamReader::OnReadCompleted,
50 weak_ptr_factory_.GetWeakPtr(), 58 weak_ptr_factory_.GetWeakPtr(),
51 make_scoped_refptr(buffer), 59 base::Bind(&BufferingFileStreamReader::OnPreloadCompleted,
52 buffer_length, 60 weak_ptr_factory_.GetWeakPtr(),
53 callback)); 61 make_scoped_refptr(buffer),
62 buffer_length,
63 callback)));
54 64
55 return net::ERR_IO_PENDING; 65 return net::ERR_IO_PENDING;
56 } 66 }
57 67
58 int64 BufferingFileStreamReader::GetLength( 68 int64 BufferingFileStreamReader::GetLength(
59 const net::Int64CompletionCallback& callback) { 69 const net::Int64CompletionCallback& callback) {
60 const int64 result = file_stream_reader_->GetLength(callback); 70 const int64 result = file_stream_reader_->GetLength(callback);
61 DCHECK_EQ(net::ERR_IO_PENDING, result); 71 DCHECK_EQ(net::ERR_IO_PENDING, result);
62 72
63 return result; 73 return result;
64 } 74 }
65 75
66 int BufferingFileStreamReader::CopyFromPreloadingBuffer( 76 int BufferingFileStreamReader::CopyFromPreloadingBuffer(
67 scoped_refptr<net::IOBuffer> buffer, 77 scoped_refptr<net::IOBuffer> buffer,
68 int buffer_length) { 78 int buffer_length) {
69 const int read_bytes = std::min(buffer_length, buffered_bytes_); 79 const int read_bytes = std::min(buffer_length, preloaded_bytes_);
70 80
71 memcpy(buffer->data(), 81 memcpy(buffer->data(),
72 preloading_buffer_->data() + preloading_buffer_offset_, 82 preloading_buffer_->data() + preloading_buffer_offset_,
73 read_bytes); 83 read_bytes);
74 preloading_buffer_offset_ += read_bytes; 84 preloading_buffer_offset_ += read_bytes;
75 buffered_bytes_ -= read_bytes; 85 preloaded_bytes_ -= read_bytes;
76 86
77 return read_bytes; 87 return read_bytes;
78 } 88 }
79 89
80 void BufferingFileStreamReader::Preload( 90 void BufferingFileStreamReader::Preload(
81 const net::CompletionCallback& callback) { 91 const net::CompletionCallback& callback) {
82 // TODO(mtomasz): Dynamically calculate the chunk size. Start from a small 92 const int preload_bytes =
83 // one, then increase for consecutive requests. That would improve performance 93 std::min(static_cast<int64>(preloading_buffer_length_),
84 // when reading just small chunks, instead of the entire file. 94 max_bytes_to_read_ - bytes_read_);
85 const int preload_bytes = buffer_size_;
86 95
87 const int result = file_stream_reader_->Read( 96 const int result = file_stream_reader_->Read(
88 preloading_buffer_.get(), preload_bytes, callback); 97 preloading_buffer_.get(), preload_bytes, callback);
89 DCHECK_EQ(result, net::ERR_IO_PENDING); 98 DCHECK_EQ(result, net::ERR_IO_PENDING);
90 } 99 }
91 100
92 void BufferingFileStreamReader::OnPreloadCompleted( 101 void BufferingFileStreamReader::OnPreloadCompleted(
93 scoped_refptr<net::IOBuffer> buffer, 102 scoped_refptr<net::IOBuffer> buffer,
94 int buffer_length, 103 int buffer_length,
95 const net::CompletionCallback& callback, 104 const net::CompletionCallback& callback,
96 int result) { 105 int result) {
97 if (result < 0) { 106 if (result < 0) {
98 callback.Run(result); 107 callback.Run(result);
99 return; 108 return;
100 } 109 }
101 110
102 preloading_buffer_offset_ = 0; 111 preloading_buffer_offset_ = 0;
103 buffered_bytes_ = result; 112 preloaded_bytes_ = result;
104 113
105 callback.Run(CopyFromPreloadingBuffer(buffer, buffer_length)); 114 callback.Run(CopyFromPreloadingBuffer(buffer, buffer_length));
106 } 115 }
107 116
117 void BufferingFileStreamReader::OnReadCompleted(
118 const net::CompletionCallback& callback,
119 int result) {
120 if (result < 0) {
121 callback.Run(result);
122 return;
123 }
124
125 // If more bytes than declared in |max_bytes_to_read_| was read in total, then
126 // emit an
127 // error.
128 if (result > max_bytes_to_read_ - bytes_read_) {
129 callback.Run(net::ERR_FAILED);
130 return;
131 }
132
133 bytes_read_ += result;
134 DCHECK_LE(bytes_read_, max_bytes_to_read_);
135
136 callback.Run(result);
137 }
138
108 } // namespace file_system_provider 139 } // namespace file_system_provider
109 } // namespace chromeos 140 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698