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

Unified Diff: courgette/third_party/bsdiff/paged_array.h

Issue 2008553007: [Courgette] PagedArray: Add Iterators and Parametrize Page Size as int Template. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add operators > and >= to make Clang std::sort() happy. Created 4 years, 7 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 | « no previous file | courgette/third_party/bsdiff/paged_array_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: courgette/third_party/bsdiff/paged_array.h
diff --git a/courgette/third_party/bsdiff/paged_array.h b/courgette/third_party/bsdiff/paged_array.h
index 27c3c0b37db7fbfce7038aed7728f7a333477526..251ea973c6da22ac9ebf225b004d8d8571f96318 100644
--- a/courgette/third_party/bsdiff/paged_array.h
+++ b/courgette/third_party/bsdiff/paged_array.h
@@ -11,32 +11,189 @@
#ifndef COURGETTE_THIRD_PARTY_BSDIFF_PAGED_ARRAY_H_
#define COURGETTE_THIRD_PARTY_BSDIFF_PAGED_ARRAY_H_
-#include <stddef.h>
+#include <cstddef>
+#include <iterator>
+#include <type_traits>
+#include "base/logging.h"
#include "base/macros.h"
#include "base/process/memory.h"
namespace courgette {
+// Page size of 2^18 * sizeof(T) is 1MB for T = int32_t.
+constexpr int kPagedArrayDefaultPageLogSize = 18;
+
+template <typename T, int LOG_PAGE_SIZE = kPagedArrayDefaultPageLogSize>
+class PagedArray;
+
+// A random access iterator with pointer-like semantics, for PagedArray.
+template <typename ContainerType, typename T>
+class PagedArray_iterator {
+ public:
+ using ThisType = PagedArray_iterator<ContainerType, T>;
+ using difference_type = ptrdiff_t;
+ using value_type = typename std::remove_const<T>::type;
+ using reference = T&;
+ using pointer = T*;
+ using iterator_category = std::random_access_iterator_tag;
+
+ PagedArray_iterator() : array_(nullptr), index_(0U) {}
+ PagedArray_iterator(ContainerType* array, size_t index)
+ : array_(array), index_(index) {}
+
+ template <typename ContainerType2, typename T2>
+ PagedArray_iterator(const PagedArray_iterator<ContainerType2, T2>& it)
+ : array_(it.array_), index_(it.index_) {}
+
+ PagedArray_iterator(std::nullptr_t) : array_(nullptr), index_(0) {}
+
+ ~PagedArray_iterator() = default;
+
+ reference operator*() const { return (*array_)[index_]; }
+ reference operator[](size_t idx) const { return (*array_)[index_ + idx]; }
+ pointer operator->() const { return &(*array_)[index_]; }
+
+ ThisType& operator=(std::nullptr_t) {
+ array_ = nullptr;
+ index_ = 0;
+ return *this;
+ }
+
+ ThisType& operator++() {
+ ++index_;
+ return *this;
+ }
+ ThisType& operator--() {
+ --index_;
+ return *this;
+ }
+
+ ThisType operator++(int) { return ThisType(array_, index_++); }
+ ThisType operator--(int) { return ThisType(array_, index_--); }
+
+ ThisType& operator+=(difference_type delta) {
+ index_ += delta;
+ return *this;
+ }
+ ThisType& operator-=(difference_type delta) {
+ index_ -= delta;
+ return *this;
+ }
+
+ ThisType operator+(difference_type offset) const {
+ return ThisType(array_, index_ + offset);
+ }
+ ThisType operator-(difference_type offset) const {
+ return ThisType(array_, index_ - offset);
+ }
+
+ template <typename ContainerType2, typename T2>
+ bool operator==(const PagedArray_iterator<ContainerType2, T2>& it) const {
+ return index_ == it.index_ && array_ == it.array_;
+ }
+ bool operator==(std::nullptr_t) const {
+ return index_ == 0 && array_ == nullptr;
+ }
+ template <typename ContainerType2, typename T2>
+ bool operator!=(const PagedArray_iterator<ContainerType2, T2>& it) const {
+ return !(*this == it);
+ }
+
+ template <typename ContainerType2, typename T2>
+ bool operator<(const PagedArray_iterator<ContainerType2, T2>& it) const {
+#ifndef NDEBUG
+ // For performance, skip the |array_| check in Release builds.
+ if (array_ != it.array_)
+ return false;
+#endif
+ return index_ < it.index_;
+ }
+ template <typename ContainerType2, typename T2>
+ bool operator<=(const PagedArray_iterator<ContainerType2, T2>& it) const {
+#ifndef NDEBUG
+ // For performance, skip the |array_| check in Release builds.
+ if (array_ != it.array_)
+ return false;
+#endif
+ return index_ <= it.index_;
+ }
+ template <typename ContainerType2, typename T2>
+ bool operator>(const PagedArray_iterator<ContainerType2, T2>& it) const {
+#ifndef NDEBUG
+ // For performance, skip the |array_| check in Release builds.
+ if (array_ != it.array_)
+ return false;
+#endif
+ return index_ > it.index_;
+ }
+ template <typename ContainerType2, typename T2>
+ bool operator>=(const PagedArray_iterator<ContainerType2, T2>& it) const {
+#ifndef NDEBUG
+ // For performance, skip the |array_| check in Release builds.
+ if (array_ != it.array_)
+ return false;
+#endif
+ return index_ >= it.index_;
+ }
+
+ template <typename ContainerType2, typename T2>
+ difference_type operator-(
+ const PagedArray_iterator<ContainerType2, T2>& it) const {
+ return index_ - it.index_;
+ }
+
+ private:
+ template <typename, typename>
+ friend class PagedArray_iterator;
+
+ ContainerType* array_;
+ size_t index_;
+};
+
// PagedArray implements an array stored using many fixed-size pages.
-template <typename T>
+template <typename T, int LOG_PAGE_SIZE>
class PagedArray {
enum {
- // Page size in elements. Page size of 2^18 * sizeof(T) is 1MB for T = int.
- kLogPageSize = 18,
- kPageSize = 1 << kLogPageSize
+ // Page size in elements.
+ kLogPageSize = LOG_PAGE_SIZE,
+ kPageSize = 1 << LOG_PAGE_SIZE
};
public:
- PagedArray() : pages_(NULL), page_count_(0) {}
+ using ThisType = PagedArray<T, LOG_PAGE_SIZE>;
+ using const_iterator = PagedArray_iterator<const ThisType, const T>;
+ using iterator = PagedArray_iterator<ThisType, T>;
+ PagedArray() = default;
~PagedArray() { clear(); }
+ iterator begin() { return iterator(this, 0); }
+ iterator end() { return iterator(this, size_); }
+ const_iterator begin() const { return const_iterator(this, 0); }
+ const_iterator end() const { return const_iterator(this, size_); }
+
T& operator[](size_t i) {
size_t page = i >> kLogPageSize;
size_t offset = i & (kPageSize - 1);
- // It is tempting to add a DCHECK(page < page_count_), but that makes
- // bsdiff_create run 2x slower (even when compiled optimized.)
+#ifndef NDEBUG
+ // Without the #ifndef, DCHECK() will significaltly slow down bsdiff_create
+ // even in optimized Release build (about 1.4x).
+ DCHECK(page < page_count_);
+#endif
+ return pages_[page][offset];
+ }
+
+ const T& operator[](size_t i) const {
+ // Duplicating code here for performance. If we use common code for this
+ // then bsdiff_create slows down by ~5% in optimized Release build.
+ size_t page = i >> kLogPageSize;
+ size_t offset = i & (kPageSize - 1);
+#ifndef NDEBUG
+ // Without the #ifndef, DCHECK() will significaltly slow down bsdiff_create
+ // even in optimized Release build (about 1.4x).
+ DCHECK(page < page_count_);
+#endif
return pages_[page][offset];
}
@@ -44,7 +201,8 @@ class PagedArray {
// allocation fails.
bool Allocate(size_t size) {
clear();
- size_t pages_needed = (size + kPageSize - 1) >> kLogPageSize;
+ size_ = size;
+ size_t pages_needed = (size_ + kPageSize - 1) >> kLogPageSize;
if (!base::UncheckedMalloc(sizeof(T*) * pages_needed,
reinterpret_cast<void**>(&pages_))) {
return false;
@@ -64,22 +222,24 @@ class PagedArray {
// Releases all storage. May be called more than once.
void clear() {
- if (pages_ != NULL) {
+ if (pages_ != nullptr) {
while (page_count_ != 0) {
--page_count_;
free(pages_[page_count_]);
}
free(pages_);
- pages_ = NULL;
+ pages_ = nullptr;
}
}
private:
- T** pages_;
- size_t page_count_;
+ T** pages_ = nullptr;
+ size_t size_ = 0U;
+ size_t page_count_ = 0U;
DISALLOW_COPY_AND_ASSIGN(PagedArray);
};
} // namespace courgette
+
#endif // COURGETTE_THIRD_PARTY_BSDIFF_PAGED_ARRAY_H_
« no previous file with comments | « no previous file | courgette/third_party/bsdiff/paged_array_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698