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

Unified Diff: pdf/chunk_stream.h

Issue 2349753003: Improve linearized pdf load/show time. (Closed)
Patch Set: rebase Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pdf/DEPS ('k') | pdf/chunk_stream.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pdf/chunk_stream.h
diff --git a/pdf/chunk_stream.h b/pdf/chunk_stream.h
index d2d8d2a13d4a4343bc5acadb263e1a5c0b83bd09..b8b3c831e900df736a606acea002cf0aa329fd3f 100644
--- a/pdf/chunk_stream.h
+++ b/pdf/chunk_stream.h
@@ -6,46 +6,103 @@
#define PDF_CHUNK_STREAM_H_
#include <stddef.h>
+#include <string.h>
-#include <map>
-#include <utility>
+#include <algorithm>
+#include <array>
+#include <memory>
#include <vector>
+#include "pdf/range_set.h"
+
namespace chrome_pdf {
// This class collects a chunks of data into one data stream. Client can check
// if data in certain range is available, and get missing chunks of data.
+template <uint32_t N>
class ChunkStream {
public:
- ChunkStream();
- ~ChunkStream();
+ static constexpr uint32_t kChunkSize = N;
+ using ChunkData = typename std::array<unsigned char, N>;
- void Clear();
+ ChunkStream() {}
+ ~ChunkStream() {}
- void Preallocate(size_t stream_size);
- size_t GetSize() const;
+ void SetChunkData(uint32_t chunk_index, std::unique_ptr<ChunkData> data) {
+ if (!data)
+ return;
+ if (chunk_index >= data_.size()) {
+ data_.resize(chunk_index + 1);
+ }
+ if (!data_[chunk_index]) {
+ ++filled_chunks_count_;
+ }
+ data_[chunk_index] = std::move(data);
+ filled_chunks_.Union(gfx::Range(chunk_index, chunk_index + 1));
+ }
- bool WriteData(size_t offset, void* buffer, size_t size);
- bool ReadData(size_t offset, size_t size, void* buffer) const;
+ bool ReadData(const gfx::Range& range, void* buffer) const {
+ if (!IsRangeAvailable(range)) {
+ return false;
+ }
+ unsigned char* data_buffer = static_cast<unsigned char*>(buffer);
+ uint32_t start = range.start();
+ while (start != range.end()) {
+ const uint32_t chunk_index = GetChunkIndex(start);
+ const uint32_t chunk_start = start % kChunkSize;
+ const uint32_t len =
+ std::min(kChunkSize - chunk_start, range.end() - start);
+ memcpy(data_buffer, data_[chunk_index]->data() + chunk_start, len);
+ data_buffer += len;
+ start += len;
+ }
+ return true;
+ }
- // Returns vector of pairs where first is an offset, second is a size.
- bool GetMissedRanges(size_t offset, size_t size,
- std::vector<std::pair<size_t, size_t> >* ranges) const;
- bool IsRangeAvailable(size_t offset, size_t size) const;
- size_t GetFirstMissingByte() const;
+ uint32_t GetChunkIndex(uint32_t offset) const { return offset / kChunkSize; }
- // Finds the first byte of the missing byte interval that offset belongs to.
- size_t GetFirstMissingByteInInterval(size_t offset) const;
- // Returns the last byte of the missing byte interval that offset belongs to.
- size_t GetLastMissingByteInInterval(size_t offset) const;
+ gfx::Range GetChunksRange(uint32_t offset, uint32_t size) const {
+ return gfx::Range(GetChunkIndex(offset),
+ GetChunkIndex(offset + size + kChunkSize - 1));
+ }
- private:
- std::vector<unsigned char> data_;
+ bool IsRangeAvailable(const gfx::Range& range) const {
+ if (!range.IsValid() || range.is_reversed() ||
+ (eof_pos_ > 0 && eof_pos_ < range.end()))
+ return false;
+ if (range.is_empty())
+ return true;
+ const gfx::Range chunks_range(GetChunkIndex(range.start()),
+ GetChunkIndex(range.end() + kChunkSize - 1));
+ return filled_chunks_.Contains(chunks_range);
+ }
+
+ void set_eof_pos(uint32_t eof_pos) { eof_pos_ = eof_pos; }
+ uint32_t eof_pos() const { return eof_pos_; }
+
+ const RangeSet& filled_chunks() const { return filled_chunks_; }
- // Pair, first - begining of the chunk, second - size of the chunk.
- std::map<size_t, size_t> chunks_;
+ bool IsComplete() const {
+ return eof_pos_ > 0 && IsRangeAvailable(gfx::Range(0, eof_pos_));
+ }
- size_t stream_size_;
+ void Clear() {
+ data_.clear();
+ eof_pos_ = 0;
+ filled_chunks_.Clear();
+ filled_chunks_count_ = 0;
+ }
+
+ uint32_t filled_chunks_count() const { return filled_chunks_count_; }
+ uint32_t total_chunks_count() const {
+ return GetChunkIndex(eof_pos_ + kChunkSize - 1);
+ }
+
+ private:
+ std::vector<std::unique_ptr<ChunkData>> data_;
+ uint32_t eof_pos_ = 0;
+ RangeSet filled_chunks_;
+ uint32_t filled_chunks_count_ = 0;
};
}; // namespace chrome_pdf
« no previous file with comments | « pdf/DEPS ('k') | pdf/chunk_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698