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

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

Issue 502973005: [fsp] Buffer consecutive Write() calls. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed. 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/file_system_provider/fileapi/buffering_file_st ream_writer.h"
6
7 #include <algorithm>
8
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
11
12 namespace chromeos {
13 namespace file_system_provider {
14
15 BufferingFileStreamWriter::BufferingFileStreamWriter(
16 scoped_ptr<storage::FileStreamWriter> file_stream_writer,
17 int intermediate_buffer_length)
18 : file_stream_writer_(file_stream_writer.Pass()),
19 intermediate_buffer_length_(intermediate_buffer_length),
20 intermediate_buffer_(new net::IOBuffer(intermediate_buffer_length_)),
21 buffered_bytes_(0),
22 weak_ptr_factory_(this) {
23 }
24
25 BufferingFileStreamWriter::~BufferingFileStreamWriter() {
26 }
27
28 int BufferingFileStreamWriter::Write(net::IOBuffer* buffer,
29 int buffer_length,
30 const net::CompletionCallback& callback) {
31 // If |buffer_length| is larger than the intermediate buffer, then call the
32 // internal file stream writer directly. Note, that the intermediate buffer
33 // (used for buffering) must be flushed first.
34 if (buffer_length > intermediate_buffer_length_) {
35 if (buffered_bytes_) {
36 FlushIntermediateBuffer(
37 base::Bind(&BufferingFileStreamWriter::
38 OnFlushIntermediateBufferForDirectWriteCompleted,
39 weak_ptr_factory_.GetWeakPtr(),
40 make_scoped_refptr(buffer),
41 buffer_length,
42 callback));
43 } else {
44 // Nothing to flush, so skip it.
45 OnFlushIntermediateBufferForDirectWriteCompleted(
46 make_scoped_refptr(buffer), buffer_length, callback, net::OK);
47 }
48 return net::ERR_IO_PENDING;
49 }
50
51 // Buffer consecutive writes to larger chunks.
52 const int buffer_bytes =
53 std::min(intermediate_buffer_length_ - buffered_bytes_, buffer_length);
54
55 CopyToIntermediateBuffer(
56 make_scoped_refptr(buffer), 0 /* offset */, buffer_bytes);
57 const int bytes_left = buffer_length - buffer_bytes;
58
59 if (buffered_bytes_ == intermediate_buffer_length_) {
60 FlushIntermediateBuffer(
61 base::Bind(&BufferingFileStreamWriter::
62 OnFlushIntermediateBufferForBufferedWriteCompleted,
63 weak_ptr_factory_.GetWeakPtr(),
64 make_scoped_refptr(buffer),
65 buffer_bytes,
66 bytes_left,
67 callback));
68 return net::ERR_IO_PENDING;
69 }
70
71 // Optimistically return a success.
72 return buffer_length;
73 }
74
75 int BufferingFileStreamWriter::Cancel(const net::CompletionCallback& callback) {
76 return file_stream_writer_->Cancel(callback);
hashimoto 2014/09/11 07:52:16 Could you add a comment to describe how this imple
mtomasz 2014/09/17 04:59:40 Done.
77 }
78
79 int BufferingFileStreamWriter::Flush(const net::CompletionCallback& callback) {
80 // Flush all the buffered bytes first, then invoke Flush() on the inner file
81 // stream writer.
82 FlushIntermediateBuffer(base::Bind(
83 &BufferingFileStreamWriter::OnFlushIntermediateBufferForFlushCompleted,
84 weak_ptr_factory_.GetWeakPtr(),
85 callback));
86 return net::ERR_IO_PENDING;
87 }
88
89 void BufferingFileStreamWriter::CopyToIntermediateBuffer(
90 scoped_refptr<net::IOBuffer> buffer,
91 int offset,
hashimoto 2014/09/11 07:52:16 It's ambiguous whether |offset| is for the argumen
mtomasz 2014/09/17 04:59:40 It's clearly described in the header file.
92 int length) {
93 DCHECK_GE(intermediate_buffer_length_, offset + length + buffered_bytes_);
hashimoto 2014/09/11 07:52:16 What does the value of "offset + length + buffered
mtomasz 2014/09/17 04:59:40 Position of the last byte to be written. This DCHE
hashimoto 2014/09/22 12:10:31 Then shouldn't this be buffer_length + buffered_by
mtomasz 2014/09/24 01:45:31 That's right. Fixed.
94 memcpy(intermediate_buffer_->data() + buffered_bytes_,
95 buffer->data() + offset,
96 length);
97 buffered_bytes_ += length;
98 }
99
100 void BufferingFileStreamWriter::FlushIntermediateBuffer(
101 const net::CompletionCallback& callback) {
102 const int result = file_stream_writer_->Write(
103 intermediate_buffer_,
104 buffered_bytes_,
105 base::Bind(&BufferingFileStreamWriter::OnFlushIntermediateBufferCompleted,
106 weak_ptr_factory_.GetWeakPtr(),
107 buffered_bytes_,
108 callback));
109 DCHECK_EQ(net::ERR_IO_PENDING, result);
110 }
111
112 void BufferingFileStreamWriter::OnFlushIntermediateBufferCompleted(
113 int length,
114 const net::CompletionCallback& callback,
115 int result) {
116 if (result < 0) {
117 callback.Run(result);
118 return;
119 }
120
121 buffered_bytes_ = 0;
122
123 DCHECK_EQ(length, result) << "Partial writes are not supported.";
124 callback.Run(net::OK);
125 }
126
127 void
128 BufferingFileStreamWriter::OnFlushIntermediateBufferForDirectWriteCompleted(
129 scoped_refptr<net::IOBuffer> buffer,
130 int length,
131 const net::CompletionCallback& callback,
132 int result) {
133 if (result < 0) {
134 callback.Run(result);
135 return;
136 }
137
138 // Write all bytes directly.
139 DCHECK_EQ(net::OK, result);
hashimoto 2014/09/11 07:52:16 nit: Why are you checking this here and in the met
mtomasz 2014/09/17 04:59:40 It's not possible, but since FlushIntermediateBuff
hashimoto 2014/09/22 12:10:31 I still don't see any reason to check |result| whi
mtomasz 2014/09/24 01:45:31 Yeah, seems not really helping much here. Removed.
140 DCHECK_EQ(0, buffered_bytes_);
141 const int write_result = file_stream_writer_->Write(buffer, length, callback);
142 DCHECK_EQ(net::ERR_IO_PENDING, write_result);
143 }
144
145 void
146 BufferingFileStreamWriter::OnFlushIntermediateBufferForBufferedWriteCompleted(
147 scoped_refptr<net::IOBuffer> buffer,
148 int buffered_bytes,
149 int bytes_left,
150 const net::CompletionCallback& callback,
151 int result) {
152 if (result < 0) {
153 callback.Run(result);
154 return;
155 }
156
157 // Copy the rest of bytes to the buffer.
158 DCHECK_EQ(net::OK, result);
159 DCHECK_EQ(0, buffered_bytes_);
160 DCHECK_GE(intermediate_buffer_length_, bytes_left);
161 CopyToIntermediateBuffer(buffer, buffered_bytes, bytes_left);
162
163 callback.Run(buffered_bytes + bytes_left);
164 }
165
166 void BufferingFileStreamWriter::OnFlushIntermediateBufferForFlushCompleted(
167 const net::CompletionCallback& callback,
168 int result) {
169 if (result < 0) {
170 callback.Run(result);
171 return;
172 }
173
174 const int flush_result = file_stream_writer_->Flush(callback);
175 DCHECK_EQ(net::ERR_IO_PENDING, flush_result);
176 }
177
178 } // namespace file_system_provider
179 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698