| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 // Streams classes. | 5 // Streams classes. |
| 6 // | 6 // |
| 7 // These memory-resident streams are used for serializing data into a sequential | 7 // These memory-resident streams are used for serializing data into a sequential |
| 8 // region of memory. | 8 // region of memory. |
| 9 // | 9 // |
| 10 // Streams are divided into SourceStreams for reading and SinkStreams for | 10 // Streams are divided into SourceStreams for reading and SinkStreams for |
| 11 // writing. Streams are aggregated into Sets which allows several streams to be | 11 // writing. Streams are aggregated into Sets which allows several streams to be |
| 12 // used at once. Example: we can write A1, B1, A2, B2 but achieve the memory | 12 // used at once. Example: we can write A1, B1, A2, B2 but achieve the memory |
| 13 // layout A1 A2 B1 B2 by writing 'A's to one stream and 'B's to another. | 13 // layout A1 A2 B1 B2 by writing 'A's to one stream and 'B's to another. |
| 14 // | 14 // |
| 15 // The aggregated streams are important to Courgette's compression efficiency, | 15 // The aggregated streams are important to Courgette's compression efficiency, |
| 16 // we use it to cluster similar kinds of data which helps to generate longer | 16 // we use it to cluster similar kinds of data which helps to generate longer |
| 17 // common subsequences and repeated sequences. | 17 // common subsequences and repeated sequences. |
| 18 | 18 |
| 19 #include "courgette/streams.h" | 19 #include "courgette/streams.h" |
| 20 | 20 |
| 21 #include <io.h> | |
| 22 #include <memory.h> | 21 #include <memory.h> |
| 23 | 22 |
| 24 #include "base/basictypes.h" | 23 #include "base/basictypes.h" |
| 25 | 24 |
| 26 namespace courgette { | 25 namespace courgette { |
| 27 | 26 |
| 28 // Update this version number if the serialization format of a StreamSet | 27 // Update this version number if the serialization format of a StreamSet |
| 29 // changes. | 28 // changes. |
| 30 static const unsigned int kStreamsSerializationFormatVersion = 20090218; | 29 static const unsigned int kStreamsSerializationFormatVersion = 20090218; |
| 31 | 30 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 size_t accumulated_length = 0; | 247 size_t accumulated_length = 0; |
| 249 | 248 |
| 250 for (size_t i = 0; i < count_; ++i) { | 249 for (size_t i = 0; i < count_; ++i) { |
| 251 finger = Varint::Parse32WithLimit(finger, end, &lengths[i]); | 250 finger = Varint::Parse32WithLimit(finger, end, &lengths[i]); |
| 252 if (finger == NULL) | 251 if (finger == NULL) |
| 253 return false; | 252 return false; |
| 254 accumulated_length += lengths[i]; | 253 accumulated_length += lengths[i]; |
| 255 } | 254 } |
| 256 | 255 |
| 257 // Remaining bytes should add up to sum of lengths. | 256 // Remaining bytes should add up to sum of lengths. |
| 258 if (end - finger != accumulated_length) | 257 if (static_cast<size_t>(end - finger) != accumulated_length) |
| 259 return false; | 258 return false; |
| 260 | 259 |
| 261 accumulated_length = finger - start; | 260 accumulated_length = finger - start; |
| 262 for (size_t i = 0; i < count_; ++i) { | 261 for (size_t i = 0; i < count_; ++i) { |
| 263 stream(i)->Init(start + accumulated_length, lengths[i]); | 262 stream(i)->Init(start + accumulated_length, lengths[i]); |
| 264 accumulated_length += lengths[i]; | 263 accumulated_length += lengths[i]; |
| 265 } | 264 } |
| 266 | 265 |
| 267 return true; | 266 return true; |
| 268 } | 267 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 bool SinkStreamSet::CopyTo(SinkStream *combined_stream) { | 327 bool SinkStreamSet::CopyTo(SinkStream *combined_stream) { |
| 329 SinkStream header; | 328 SinkStream header; |
| 330 CopyHeaderTo(&header); | 329 CopyHeaderTo(&header); |
| 331 combined_stream->Append(&header); | 330 combined_stream->Append(&header); |
| 332 for (size_t i = 0; i < count_; ++i) { | 331 for (size_t i = 0; i < count_; ++i) { |
| 333 combined_stream->Append(stream(i)); | 332 combined_stream->Append(stream(i)); |
| 334 } | 333 } |
| 335 return true; | 334 return true; |
| 336 } | 335 } |
| 337 | 336 |
| 338 namespace { | |
| 339 bool Write(int file_descriptor, SinkStream* sink) { | |
| 340 size_t length = sink->Length(); | |
| 341 const void *buffer = sink->Buffer(); | |
| 342 int bytes_written = _write(file_descriptor, buffer, length); | |
| 343 return bytes_written == length; | |
| 344 } | |
| 345 } | |
| 346 | |
| 347 bool SinkStreamSet::CopyToFileDescriptor(int file_descriptor) { | |
| 348 SinkStream header; | |
| 349 CopyHeaderTo(&header); | |
| 350 if (!Write(file_descriptor, &header)) | |
| 351 return false; | |
| 352 for (size_t i = 0; i < count_; ++i) { | |
| 353 if (!Write(file_descriptor, stream(i))) | |
| 354 return false; | |
| 355 } | |
| 356 return true; | |
| 357 } | |
| 358 | |
| 359 bool SinkStreamSet::WriteSet(SinkStreamSet* set) { | 337 bool SinkStreamSet::WriteSet(SinkStreamSet* set) { |
| 360 uint32 lengths[kMaxStreams]; | 338 uint32 lengths[kMaxStreams]; |
| 361 // 'stream_count' includes all non-empty streams and all empty stream numbered | 339 // 'stream_count' includes all non-empty streams and all empty stream numbered |
| 362 // lower than a non-empty stream. | 340 // lower than a non-empty stream. |
| 363 size_t stream_count = 0; | 341 size_t stream_count = 0; |
| 364 for (size_t i = 0; i < kMaxStreams; ++i) { | 342 for (size_t i = 0; i < kMaxStreams; ++i) { |
| 365 SinkStream* stream = set->stream(i); | 343 SinkStream* stream = set->stream(i); |
| 366 lengths[i] = stream->Length(); | 344 lengths[i] = stream->Length(); |
| 367 if (lengths[i] > 0) | 345 if (lengths[i] > 0) |
| 368 stream_count = i + 1; | 346 stream_count = i + 1; |
| 369 } | 347 } |
| 370 | 348 |
| 371 SinkStream* control_stream = this->stream(0); | 349 SinkStream* control_stream = this->stream(0); |
| 372 control_stream->WriteVarint32(stream_count); | 350 control_stream->WriteVarint32(stream_count); |
| 373 for (size_t i = 0; i < stream_count; ++i) { | 351 for (size_t i = 0; i < stream_count; ++i) { |
| 374 control_stream->WriteVarint32(lengths[i]); | 352 control_stream->WriteVarint32(lengths[i]); |
| 375 } | 353 } |
| 376 | 354 |
| 377 for (size_t i = 0; i < stream_count; ++i) { | 355 for (size_t i = 0; i < stream_count; ++i) { |
| 378 this->stream(i)->Append(set->stream(i)); | 356 this->stream(i)->Append(set->stream(i)); |
| 379 } | 357 } |
| 380 return true; | 358 return true; |
| 381 } | 359 } |
| 382 | 360 |
| 383 } // namespace | 361 } // namespace |
| OLD | NEW |