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

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: Fixed. Created 6 years, 4 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 11
12 namespace chromeos { 12 namespace chromeos {
13 namespace file_system_provider { 13 namespace file_system_provider {
14 14
15 BufferingFileStreamReader::BufferingFileStreamReader( 15 BufferingFileStreamReader::BufferingFileStreamReader(
16 scoped_ptr<storage::FileStreamReader> file_stream_reader, 16 scoped_ptr<storage::FileStreamReader> file_stream_reader,
17 int buffer_size) 17 int preloading_buffer_length,
18 int64 bytes_to_read)
18 : file_stream_reader_(file_stream_reader.Pass()), 19 : file_stream_reader_(file_stream_reader.Pass()),
19 buffer_size_(buffer_size), 20 preloading_buffer_length_(preloading_buffer_length),
20 preloading_buffer_(new net::IOBuffer(buffer_size_)), 21 bytes_to_read_(bytes_to_read),
22 bytes_read_(0),
23 preloading_buffer_(new net::IOBuffer(preloading_buffer_length)),
21 preloading_buffer_offset_(0), 24 preloading_buffer_offset_(0),
22 buffered_bytes_(0), 25 preloaded_bytes_(0),
23 weak_ptr_factory_(this) { 26 weak_ptr_factory_(this) {
24 } 27 }
25 28
26 BufferingFileStreamReader::~BufferingFileStreamReader() { 29 BufferingFileStreamReader::~BufferingFileStreamReader() {
27 } 30 }
28 31
29 int BufferingFileStreamReader::Read(net::IOBuffer* buffer, 32 int BufferingFileStreamReader::Read(net::IOBuffer* buffer,
30 int buffer_length, 33 int buffer_length,
31 const net::CompletionCallback& callback) { 34 const net::CompletionCallback& callback) {
32 // Return as much as available in the internal buffer. It may be less than 35 // Return as much as available in the internal buffer. It may be less than
33 // |buffer_length|, what is valid. 36 // |buffer_length|, what is valid.
34 const int bytes_read = 37 const int bytes_read =
35 CopyFromPreloadingBuffer(make_scoped_refptr(buffer), buffer_length); 38 CopyFromPreloadingBuffer(make_scoped_refptr(buffer), buffer_length);
36 if (bytes_read) 39 if (bytes_read)
37 return bytes_read; 40 return bytes_read;
38 41
39 // If the internal buffer is empty, and more bytes than the internal buffer 42 // 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. 43 // size is requested, then call the internal file stream reader directly.
41 if (buffer_length >= buffer_size_) { 44 if (buffer_length >= preloading_buffer_length_) {
42 const int result = 45 const int result = file_stream_reader_->Read(
43 file_stream_reader_->Read(buffer, buffer_length, callback); 46 buffer,
47 buffer_length,
48 base::Bind(&BufferingFileStreamReader::OnReadCompleted,
49 weak_ptr_factory_.GetWeakPtr(),
50 callback));
44 DCHECK_EQ(result, net::ERR_IO_PENDING); 51 DCHECK_EQ(result, net::ERR_IO_PENDING);
45 return result; 52 return result;
46 } 53 }
47 54
48 // Nothing copied, so contents have to be preloaded. 55 // Nothing copied, so contents have to be preloaded.
49 Preload(base::Bind(&BufferingFileStreamReader::OnPreloadCompleted, 56 Preload(base::Bind(&BufferingFileStreamReader::OnReadCompleted,
50 weak_ptr_factory_.GetWeakPtr(), 57 weak_ptr_factory_.GetWeakPtr(),
51 make_scoped_refptr(buffer), 58 base::Bind(&BufferingFileStreamReader::OnPreloadCompleted,
52 buffer_length, 59 weak_ptr_factory_.GetWeakPtr(),
53 callback)); 60 make_scoped_refptr(buffer),
61 buffer_length,
62 callback)));
54 63
55 return net::ERR_IO_PENDING; 64 return net::ERR_IO_PENDING;
56 } 65 }
57 66
58 int64 BufferingFileStreamReader::GetLength( 67 int64 BufferingFileStreamReader::GetLength(
59 const net::Int64CompletionCallback& callback) { 68 const net::Int64CompletionCallback& callback) {
60 const int64 result = file_stream_reader_->GetLength(callback); 69 const int64 result = file_stream_reader_->GetLength(callback);
61 DCHECK_EQ(net::ERR_IO_PENDING, result); 70 DCHECK_EQ(net::ERR_IO_PENDING, result);
62 71
63 return result; 72 return result;
64 } 73 }
65 74
66 int BufferingFileStreamReader::CopyFromPreloadingBuffer( 75 int BufferingFileStreamReader::CopyFromPreloadingBuffer(
67 scoped_refptr<net::IOBuffer> buffer, 76 scoped_refptr<net::IOBuffer> buffer,
68 int buffer_length) { 77 int buffer_length) {
69 const int read_bytes = std::min(buffer_length, buffered_bytes_); 78 const int read_bytes = std::min(buffer_length, preloaded_bytes_);
70 79
71 memcpy(buffer->data(), 80 memcpy(buffer->data(),
72 preloading_buffer_->data() + preloading_buffer_offset_, 81 preloading_buffer_->data() + preloading_buffer_offset_,
73 read_bytes); 82 read_bytes);
74 preloading_buffer_offset_ += read_bytes; 83 preloading_buffer_offset_ += read_bytes;
75 buffered_bytes_ -= read_bytes; 84 preloaded_bytes_ -= read_bytes;
76 85
77 return read_bytes; 86 return read_bytes;
78 } 87 }
79 88
80 void BufferingFileStreamReader::Preload( 89 void BufferingFileStreamReader::Preload(
81 const net::CompletionCallback& callback) { 90 const net::CompletionCallback& callback) {
82 // TODO(mtomasz): Dynamically calculate the chunk size. Start from a small 91 const int preload_bytes =
83 // one, then increase for consecutive requests. That would improve performance 92 bytes_to_read_ != -1
84 // when reading just small chunks, instead of the entire file. 93 ? std::min(static_cast<int64>(preloading_buffer_length_),
85 const int preload_bytes = buffer_size_; 94 bytes_to_read_ - bytes_read_)
95 : preloading_buffer_length_;
86 96
87 const int result = 97 const int result =
88 file_stream_reader_->Read(preloading_buffer_, preload_bytes, callback); 98 file_stream_reader_->Read(preloading_buffer_, preload_bytes, callback);
89 DCHECK_EQ(result, net::ERR_IO_PENDING); 99 DCHECK_EQ(result, net::ERR_IO_PENDING);
90 } 100 }
91 101
92 void BufferingFileStreamReader::OnPreloadCompleted( 102 void BufferingFileStreamReader::OnPreloadCompleted(
93 scoped_refptr<net::IOBuffer> buffer, 103 scoped_refptr<net::IOBuffer> buffer,
94 int buffer_length, 104 int buffer_length,
95 const net::CompletionCallback& callback, 105 const net::CompletionCallback& callback,
96 int result) { 106 int result) {
97 if (result < 0) { 107 if (result < 0) {
98 callback.Run(result); 108 callback.Run(result);
99 return; 109 return;
100 } 110 }
101 111
102 preloading_buffer_offset_ = 0; 112 preloading_buffer_offset_ = 0;
103 buffered_bytes_ = result; 113 preloaded_bytes_ = result;
104 114
105 callback.Run(CopyFromPreloadingBuffer(buffer, buffer_length)); 115 callback.Run(CopyFromPreloadingBuffer(buffer, buffer_length));
106 } 116 }
107 117
118 void BufferingFileStreamReader::OnReadCompleted(
119 const net::CompletionCallback& callback,
120 int result) {
121 if (result < 0) {
122 callback.Run(result);
123 return;
124 }
125
126 // If more bytes than declared in |bytes_to_read_| was read in total, then
127 // emit an error, since there is no easy way to guarantee that the target
128 // file is not corrupted.
129 if (bytes_to_read_ != -1 && result > bytes_to_read_ - bytes_read_) {
130 callback.Run(net::ERR_FAILED);
131 return;
132 }
133
134 bytes_read_ += result;
135 DCHECK(bytes_read_ <= bytes_to_read_ || bytes_to_read_ == -1);
136
137 callback.Run(result);
138 }
139
108 } // namespace file_system_provider 140 } // namespace file_system_provider
109 } // namespace chromeos 141 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698