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

Side by Side Diff: net/base/sdch_filter.cc

Issue 40319: Use filter context to track stats better in SDCH filtering (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 9 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
« no previous file with comments | « net/base/sdch_filter.h ('k') | net/base/sdch_filter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 <limits.h> 5 #include <limits.h>
6 #include <ctype.h> 6 #include <ctype.h>
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "net/base/sdch_filter.h" 12 #include "net/base/sdch_filter.h"
13 #include "net/base/sdch_manager.h" 13 #include "net/base/sdch_manager.h"
14 14
15 #include "sdch/open-vcdiff/src/google/vcdecoder.h" 15 #include "sdch/open-vcdiff/src/google/vcdecoder.h"
16 16
17 SdchFilter::SdchFilter(const FilterContext& filter_context) 17 SdchFilter::SdchFilter(const FilterContext& filter_context)
18 : Filter(filter_context), 18 : Filter(filter_context),
19 decoding_status_(DECODING_UNINITIALIZED), 19 decoding_status_(DECODING_UNINITIALIZED),
20 vcdiff_streaming_decoder_(NULL), 20 vcdiff_streaming_decoder_(NULL),
21 dictionary_hash_(), 21 dictionary_hash_(),
22 dictionary_hash_is_plausible_(false), 22 dictionary_hash_is_plausible_(false),
23 dictionary_(NULL), 23 dictionary_(NULL),
24 dest_buffer_excess_(), 24 dest_buffer_excess_(),
25 dest_buffer_excess_index_(0), 25 dest_buffer_excess_index_(0),
26 source_bytes_(0), 26 source_bytes_(0),
27 output_bytes_(0), 27 output_bytes_(0),
28 possible_pass_through_(false) { 28 possible_pass_through_(false),
29 connect_time_(filter_context.GetRequestTime()),
30 was_cached_(filter_context.IsCachedContent()) {
31 bool success = filter_context.GetMimeType(&mime_type_);
32 DCHECK(success);
33 success = filter_context.GetURL(&url_);
34 DCHECK(success);
29 } 35 }
30 36
31 SdchFilter::~SdchFilter() { 37 SdchFilter::~SdchFilter() {
38 // All code here is for gathering stats, and can be removed when SDCH is
39 // considered stable.
40
32 static int filter_use_count = 0; 41 static int filter_use_count = 0;
33 ++filter_use_count; 42 ++filter_use_count;
34 if (META_REFRESH_RECOVERY == decoding_status_) { 43 if (META_REFRESH_RECOVERY == decoding_status_) {
35 UMA_HISTOGRAM_COUNTS("Sdch.FilterUseBeforeDisabling", filter_use_count); 44 UMA_HISTOGRAM_COUNTS("Sdch.FilterUseBeforeDisabling", filter_use_count);
36 } 45 }
37 46
38 if (vcdiff_streaming_decoder_.get()) { 47 if (vcdiff_streaming_decoder_.get()) {
39 if (!vcdiff_streaming_decoder_->FinishDecoding()) { 48 if (!vcdiff_streaming_decoder_->FinishDecoding()) {
40 decoding_status_ = DECODING_ERROR; 49 decoding_status_ = DECODING_ERROR;
41 SdchManager::SdchErrorRecovery(SdchManager::INCOMPLETE_SDCH_CONTENT); 50 SdchManager::SdchErrorRecovery(SdchManager::INCOMPLETE_SDCH_CONTENT);
42 // Make it possible for the user to hit reload, and get non-sdch content. 51 // Make it possible for the user to hit reload, and get non-sdch content.
43 // Note this will "wear off" quickly enough, and is just meant to assure 52 // Note this will "wear off" quickly enough, and is just meant to assure
44 // in some rare case that the user is not stuck. 53 // in some rare case that the user is not stuck.
45 SdchManager::BlacklistDomain(url()); 54 SdchManager::BlacklistDomain(url_);
55 UMA_HISTOGRAM_COUNTS("Sdch.PartialBytesIn",
56 static_cast<int>(filter_context().GetByteReadCount()));
57 UMA_HISTOGRAM_COUNTS("Sdch.PartialVcdiffIn", source_bytes_);
58 UMA_HISTOGRAM_COUNTS("Sdch.PartialVcdiffOut", output_bytes_);
46 } 59 }
47 } 60 }
48 61
49 if (!dest_buffer_excess_.empty()) { 62 if (!dest_buffer_excess_.empty()) {
50 // Filter chaining error, or premature teardown. 63 // Filter chaining error, or premature teardown.
51 SdchManager::SdchErrorRecovery(SdchManager::UNFLUSHED_CONTENT); 64 SdchManager::SdchErrorRecovery(SdchManager::UNFLUSHED_CONTENT);
65 UMA_HISTOGRAM_COUNTS("Sdch.UnflushedBytesIn",
66 static_cast<int>(filter_context().GetByteReadCount()));
67 UMA_HISTOGRAM_COUNTS("Sdch.UnflushedVcdiffIn", source_bytes_);
68 UMA_HISTOGRAM_COUNTS("Sdch.UnflushedVcdiffOut", output_bytes_);
52 } 69 }
53 70
54 if (was_cached()) { 71 if (was_cached_) {
55 // Not a real error, but it is useful to have this tally. 72 // Not a real error, but it is useful to have this tally.
56 // TODO(jar): Remove this stat after SDCH stability is validated. 73 // TODO(jar): Remove this stat after SDCH stability is validated.
57 SdchManager::SdchErrorRecovery(SdchManager::CACHE_DECODED); 74 SdchManager::SdchErrorRecovery(SdchManager::CACHE_DECODED);
58 } else if (base::Time() == connect_time() 75 return; // We don't need timing stats, and we aready got ratios.
59 || read_times_.empty()) { 76 }
77
78 if (base::Time() == connect_time_ || read_times_.empty()) {
60 // Not a real error, but it is useful to have this tally. 79 // Not a real error, but it is useful to have this tally.
61 // TODO(jar): Remove this stat after SDCH stability is validated. 80 // TODO(jar): Remove this stat after SDCH stability is validated.
62 SdchManager::SdchErrorRecovery(SdchManager::MISSING_TIME_STATS); 81 SdchManager::SdchErrorRecovery(SdchManager::MISSING_TIME_STATS);
63 } else { 82 UMA_HISTOGRAM_COUNTS("Sdch.MissingTimeBytesIn",
64 base::TimeDelta duration = read_times_.back() - connect_time(); 83 static_cast<int>(filter_context().GetByteReadCount()));
65 // We clip our logging at 10 minutes to prevent anamolous data from being 84 UMA_HISTOGRAM_COUNTS("Sdch.MissingTimeVcdiffIn", source_bytes_);
66 // considered (per suggestion from Jake Brutlag). 85 return;
67 if (10 >= duration.InMinutes()) {
68 if (DECODING_IN_PROGRESS == decoding_status_) {
69 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_Latency_F", duration,
70 base::TimeDelta::FromMilliseconds(20),
71 base::TimeDelta::FromMinutes(10), 100);
72 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_1st_To_Last",
73 read_times_.back() - read_times_[0],
74 base::TimeDelta::FromMilliseconds(20),
75 base::TimeDelta::FromMinutes(10), 100);
76 if (read_times_.size() > 3) {
77 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_3rd_To_4th",
78 read_times_[3] - read_times_[2],
79 base::TimeDelta::FromMilliseconds(10),
80 base::TimeDelta::FromSeconds(3), 100);
81 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_2nd_To_3rd",
82 read_times_[2] - read_times_[1],
83 base::TimeDelta::FromMilliseconds(10),
84 base::TimeDelta::FromSeconds(3), 100);
85 }
86 UMA_HISTOGRAM_COUNTS_100("Sdch.Network_Decode_Reads",
87 read_times_.size());
88 UMA_HISTOGRAM_COUNTS("Sdch.Network_Decode_Bytes_Read", output_bytes_);
89 } else if (PASS_THROUGH == decoding_status_) {
90 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_Latency_F",
91 duration,
92 base::TimeDelta::FromMilliseconds(20),
93 base::TimeDelta::FromMinutes(10), 100);
94 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_1st_To_Last",
95 read_times_.back() - read_times_[0],
96 base::TimeDelta::FromMilliseconds(20),
97 base::TimeDelta::FromMinutes(10), 100);
98 if (read_times_.size() > 3) {
99 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_3rd_To_4th",
100 read_times_[3] - read_times_[2],
101 base::TimeDelta::FromMilliseconds(10),
102 base::TimeDelta::FromSeconds(3), 100);
103 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_2nd_To_3rd",
104 read_times_[2] - read_times_[1],
105 base::TimeDelta::FromMilliseconds(10),
106 base::TimeDelta::FromSeconds(3), 100);
107 }
108 UMA_HISTOGRAM_COUNTS_100("Sdch.Network_Pass-through_Reads",
109 read_times_.size());
110 }
111 }
112 } 86 }
113 87
114 if (dictionary_) 88 base::TimeDelta duration = read_times_.back() - connect_time_;
115 dictionary_->Release(); 89 // We clip our logging at 10 minutes to prevent anamolous data from being
90 // considered (per suggestion from Jake Brutlag).
91 if (10 < duration.InMinutes()) {
92 SdchManager::SdchErrorRecovery(SdchManager::OVER_10_MINUTES);
93 return;
94 }
95
96 switch (decoding_status_) {
97 case DECODING_IN_PROGRESS: {
98 UMA_HISTOGRAM_PERCENTAGE("Sdch.Network_Decode_Ratio",static_cast<int>(
99 (filter_context().GetByteReadCount() * 100) / output_bytes_));
100 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_Latency_F", duration,
101 base::TimeDelta::FromMilliseconds(20),
102 base::TimeDelta::FromMinutes(10), 100);
103 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_1st_To_Last",
104 read_times_.back() - read_times_[0],
105 base::TimeDelta::FromMilliseconds(20),
106 base::TimeDelta::FromMinutes(10), 100);
107 if (read_times_.size() > 3) {
108 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_3rd_To_4th",
109 read_times_[3] - read_times_[2],
110 base::TimeDelta::FromMilliseconds(10),
111 base::TimeDelta::FromSeconds(3), 100);
112 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Decode_2nd_To_3rd",
113 read_times_[2] - read_times_[1],
114 base::TimeDelta::FromMilliseconds(10),
115 base::TimeDelta::FromSeconds(3), 100);
116 }
117 UMA_HISTOGRAM_COUNTS_100("Sdch.Network_Decode_Reads",
118 read_times_.size());
119 UMA_HISTOGRAM_COUNTS("Sdch.Network_Decode_Bytes_Read", output_bytes_);
120 return;
121 }
122 case PASS_THROUGH: {
123 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_Latency_F",
124 duration,
125 base::TimeDelta::FromMilliseconds(20),
126 base::TimeDelta::FromMinutes(10), 100);
127 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_1st_To_Last",
128 read_times_.back() - read_times_[0],
129 base::TimeDelta::FromMilliseconds(20),
130 base::TimeDelta::FromMinutes(10), 100);
131 if (read_times_.size() > 3) {
132 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_3rd_To_4th",
133 read_times_[3] - read_times_[2],
134 base::TimeDelta::FromMilliseconds(10),
135 base::TimeDelta::FromSeconds(3), 100);
136 UMA_HISTOGRAM_CLIPPED_TIMES("Sdch.Network_Pass-through_2nd_To_3rd",
137 read_times_[2] - read_times_[1],
138 base::TimeDelta::FromMilliseconds(10),
139 base::TimeDelta::FromSeconds(3), 100);
140 }
141 UMA_HISTOGRAM_COUNTS_100("Sdch.Network_Pass-through_Reads",
142 read_times_.size());
143 return;
144 }
145 case DECODING_UNINITIALIZED: {
146 SdchManager::SdchErrorRecovery(SdchManager::UNINITIALIZED);
147 return;
148 }
149 case WAITING_FOR_DICTIONARY_SELECTION: {
150 SdchManager::SdchErrorRecovery(SdchManager::PRIOR_TO_DICTIONARY);
151 return;
152 }
153 case DECODING_ERROR: {
154 SdchManager::SdchErrorRecovery(SdchManager::DECODE_ERROR);
155 return;
156 }
157 case META_REFRESH_RECOVERY: {
158 // Already accounted for when set.
159 return;
160 }
161 } // end of switch.
116 } 162 }
117 163
118 bool SdchFilter::InitDecoding(Filter::FilterType filter_type) { 164 bool SdchFilter::InitDecoding(Filter::FilterType filter_type) {
119 if (decoding_status_ != DECODING_UNINITIALIZED) 165 if (decoding_status_ != DECODING_UNINITIALIZED)
120 return false; 166 return false;
121 167
122 // Handle case where sdch filter is guessed, but not required. 168 // Handle case where sdch filter is guessed, but not required.
123 if (FILTER_TYPE_SDCH_POSSIBLE == filter_type) 169 if (FILTER_TYPE_SDCH_POSSIBLE == filter_type)
124 possible_pass_through_ = true; 170 possible_pass_through_ = true;
125 171
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 // though it is not! 220 // though it is not!
175 // The good news is that error recovery is clear... 221 // The good news is that error recovery is clear...
176 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); 222 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH);
177 decoding_status_ = PASS_THROUGH; 223 decoding_status_ = PASS_THROUGH;
178 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. 224 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned.
179 } else { 225 } else {
180 // We don't have the dictionary that was demanded. 226 // We don't have the dictionary that was demanded.
181 // With very low probability, random garbage data looked like a 227 // With very low probability, random garbage data looked like a
182 // dictionary specifier (8 ASCII characters followed by a null), but 228 // dictionary specifier (8 ASCII characters followed by a null), but
183 // that is sufficiently unlikely that we ignore it. 229 // that is sufficiently unlikely that we ignore it.
184 if (std::string::npos == mime_type().find_first_of("text/html")) { 230 if (std::string::npos == mime_type_.find_first_of("text/html")) {
185 SdchManager::BlacklistDomainForever(url()); 231 SdchManager::BlacklistDomainForever(url_);
186 if (was_cached()) 232 if (was_cached_)
187 SdchManager::SdchErrorRecovery( 233 SdchManager::SdchErrorRecovery(
188 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); 234 SdchManager::CACHED_META_REFRESH_UNSUPPORTED);
189 else 235 else
190 SdchManager::SdchErrorRecovery( 236 SdchManager::SdchErrorRecovery(
191 SdchManager::META_REFRESH_UNSUPPORTED); 237 SdchManager::META_REFRESH_UNSUPPORTED);
192 return FILTER_ERROR; 238 return FILTER_ERROR;
193 } 239 }
194 // HTML content means we can issue a meta-refresh, and get the content 240 // HTML content means we can issue a meta-refresh, and get the content
195 // again, perhaps without SDCH (to be safe). 241 // again, perhaps without SDCH (to be safe).
196 if (was_cached()) { 242 if (was_cached_) {
197 // Cached content is probably a startup tab, so we'll just get fresh 243 // Cached content is probably a startup tab, so we'll just get fresh
198 // content and try again, without disabling sdch. 244 // content and try again, without disabling sdch.
199 SdchManager::SdchErrorRecovery( 245 SdchManager::SdchErrorRecovery(
200 SdchManager::META_REFRESH_CACHED_RECOVERY); 246 SdchManager::META_REFRESH_CACHED_RECOVERY);
201 } else { 247 } else {
202 // Since it wasn't in the cache, we definately need at least some 248 // Since it wasn't in the cache, we definately need at least some
203 // period of blacklisting to get the correct content. 249 // period of blacklisting to get the correct content.
204 SdchManager::BlacklistDomain(url()); 250 SdchManager::BlacklistDomain(url_);
205 SdchManager::SdchErrorRecovery(SdchManager::META_REFRESH_RECOVERY); 251 SdchManager::SdchErrorRecovery(SdchManager::META_REFRESH_RECOVERY);
206 } 252 }
207 decoding_status_ = META_REFRESH_RECOVERY; 253 decoding_status_ = META_REFRESH_RECOVERY;
208 // Issue a meta redirect with SDCH disabled. 254 // Issue a meta redirect with SDCH disabled.
209 dest_buffer_excess_ = kDecompressionErrorHtml; 255 dest_buffer_excess_ = kDecompressionErrorHtml;
210 } 256 }
211 } else { 257 } else {
212 DCHECK(DECODING_IN_PROGRESS == decoding_status_); 258 DCHECK(DECODING_IN_PROGRESS == decoding_status_);
213 } 259 }
214 } 260 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 } 329 }
284 dictionary_hash_.append(next_stream_data_, bytes_needed); 330 dictionary_hash_.append(next_stream_data_, bytes_needed);
285 DCHECK(kServerIdLength == dictionary_hash_.size()); 331 DCHECK(kServerIdLength == dictionary_hash_.size());
286 stream_data_len_ -= bytes_needed; 332 stream_data_len_ -= bytes_needed;
287 DCHECK(0 <= stream_data_len_); 333 DCHECK(0 <= stream_data_len_);
288 if (stream_data_len_ > 0) 334 if (stream_data_len_ > 0)
289 next_stream_data_ += bytes_needed; 335 next_stream_data_ += bytes_needed;
290 else 336 else
291 next_stream_data_ = NULL; 337 next_stream_data_ = NULL;
292 338
293 DCHECK(!dictionary_); 339 DCHECK(!dictionary_.get());
294 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. 340 dictionary_hash_is_plausible_ = true; // Assume plausible, but check.
341
342 SdchManager::Dictionary* dictionary = NULL;
295 if ('\0' == dictionary_hash_[kServerIdLength - 1]) 343 if ('\0' == dictionary_hash_[kServerIdLength - 1])
296 SdchManager::Global()->GetVcdiffDictionary(std::string(dictionary_hash_, 0, 344 SdchManager::Global()->GetVcdiffDictionary(std::string(dictionary_hash_, 0,
297 kServerIdLength - 1), 345 kServerIdLength - 1),
298 url(), &dictionary_); 346 url_, &dictionary);
299 else 347 else
300 dictionary_hash_is_plausible_ = false; 348 dictionary_hash_is_plausible_ = false;
301 349
302 if (!dictionary_) { 350 if (!dictionary) {
303 DCHECK(dictionary_hash_.size() == kServerIdLength); 351 DCHECK(dictionary_hash_.size() == kServerIdLength);
304 // Since dictionary was not found, check to see if hash was even plausible. 352 // Since dictionary was not found, check to see if hash was even plausible.
305 for (size_t i = 0; i < kServerIdLength - 1; ++i) { 353 for (size_t i = 0; i < kServerIdLength - 1; ++i) {
306 char base64_char = dictionary_hash_[i]; 354 char base64_char = dictionary_hash_[i];
307 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) { 355 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) {
308 dictionary_hash_is_plausible_ = false; 356 dictionary_hash_is_plausible_ = false;
309 break; 357 break;
310 } 358 }
311 } 359 }
312 if (dictionary_hash_is_plausible_) 360 if (dictionary_hash_is_plausible_)
313 SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_NOT_FOUND); 361 SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_NOT_FOUND);
314 else 362 else
315 SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_MALFORMED); 363 SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_MALFORMED);
316 decoding_status_ = DECODING_ERROR; 364 decoding_status_ = DECODING_ERROR;
317 return FILTER_ERROR; 365 return FILTER_ERROR;
318 } 366 }
319 dictionary_->AddRef(); 367 dictionary_ = dictionary;
320 vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder); 368 vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
321 vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(), 369 vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(),
322 dictionary_->text().size()); 370 dictionary_->text().size());
323 decoding_status_ = DECODING_IN_PROGRESS; 371 decoding_status_ = DECODING_IN_PROGRESS;
324 return FILTER_OK; 372 return FILTER_OK;
325 } 373 }
326 374
327 int SdchFilter::OutputBufferExcess(char* const dest_buffer, 375 int SdchFilter::OutputBufferExcess(char* const dest_buffer,
328 size_t available_space) { 376 size_t available_space) {
329 if (dest_buffer_excess_.empty()) 377 if (dest_buffer_excess_.empty())
330 return 0; 378 return 0;
331 DCHECK(dest_buffer_excess_.size() > dest_buffer_excess_index_); 379 DCHECK(dest_buffer_excess_.size() > dest_buffer_excess_index_);
332 size_t amount = std::min(available_space, 380 size_t amount = std::min(available_space,
333 dest_buffer_excess_.size() - dest_buffer_excess_index_); 381 dest_buffer_excess_.size() - dest_buffer_excess_index_);
334 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_, 382 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_,
335 amount); 383 amount);
336 dest_buffer_excess_index_ += amount; 384 dest_buffer_excess_index_ += amount;
337 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { 385 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) {
338 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); 386 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_);
339 dest_buffer_excess_.clear(); 387 dest_buffer_excess_.clear();
340 dest_buffer_excess_index_ = 0; 388 dest_buffer_excess_index_ = 0;
341 } 389 }
342 return amount; 390 return amount;
343 } 391 }
OLDNEW
« no previous file with comments | « net/base/sdch_filter.h ('k') | net/base/sdch_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698