diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/containers/paged_vector/paged_vector.h | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/containers/paged_vector/paged_vector.h')
-rw-r--r-- | library/cpp/containers/paged_vector/paged_vector.h | 812 |
1 files changed, 406 insertions, 406 deletions
diff --git a/library/cpp/containers/paged_vector/paged_vector.h b/library/cpp/containers/paged_vector/paged_vector.h index 6a3657d3ea..dbd1486a71 100644 --- a/library/cpp/containers/paged_vector/paged_vector.h +++ b/library/cpp/containers/paged_vector/paged_vector.h @@ -4,429 +4,429 @@ #include <util/generic/vector.h> #include <util/generic/yexception.h> -#include <iterator> - +#include <iterator> + namespace NPagedVector { - template <class T, ui32 PageSize = 1u << 20, class A = std::allocator<T>> - class TPagedVector; - - namespace NPrivate { - template <class T, class TT, ui32 PageSize, class A> - struct TPagedVectorIterator { - private: - friend class TPagedVector<TT, PageSize, A>; - typedef TPagedVector<TT, PageSize, A> TVec; - typedef TPagedVectorIterator<T, TT, PageSize, A> TSelf; - size_t Offset; - TVec* Vector; - - template <class T1, class TT1, ui32 PageSize1, class A1> - friend struct TPagedVectorIterator; - - public: - TPagedVectorIterator() - : Offset() - , Vector() - { - } - - TPagedVectorIterator(TVec* vector, size_t offset) - : Offset(offset) - , Vector(vector) - { - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - TPagedVectorIterator(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) - : Offset(it.Offset) - , Vector(it.Vector) - { - } - - T& operator*() const { - return (*Vector)[Offset]; - } - - T* operator->() const { - return &(**this); - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - bool operator==(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return Offset == it.Offset; - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - bool operator!=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return !(*this == it); - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - bool operator<(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return Offset < it.Offset; - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - bool operator<=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return Offset <= it.Offset; - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - bool operator>(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return !(*this <= it); - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - bool operator>=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return !(*this < it); - } - - template <class T1, class TT1, ui32 PageSize1, class A1> - ptrdiff_t operator-(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { - return Offset - it.Offset; - } - - TSelf& operator+=(ptrdiff_t off) { - Offset += off; - return *this; - } - - TSelf& operator-=(ptrdiff_t off) { - return this->operator+=(-off); - } - - TSelf& operator++() { - return this->operator+=(1); - } - - TSelf& operator--() { - return this->operator+=(-1); - } - - TSelf operator++(int) { - TSelf it = *this; - this->operator+=(1); - return it; - } - - TSelf operator--(int) { - TSelf it = *this; - this->operator+=(-1); - return it; - } - - TSelf operator+(ptrdiff_t off) { - TSelf res = *this; - res += off; - return res; - } - - TSelf operator-(ptrdiff_t off) { - return this->operator+(-off); - } - - size_t GetOffset() { - return Offset; - } - }; + template <class T, ui32 PageSize = 1u << 20, class A = std::allocator<T>> + class TPagedVector; + + namespace NPrivate { + template <class T, class TT, ui32 PageSize, class A> + struct TPagedVectorIterator { + private: + friend class TPagedVector<TT, PageSize, A>; + typedef TPagedVector<TT, PageSize, A> TVec; + typedef TPagedVectorIterator<T, TT, PageSize, A> TSelf; + size_t Offset; + TVec* Vector; + + template <class T1, class TT1, ui32 PageSize1, class A1> + friend struct TPagedVectorIterator; + + public: + TPagedVectorIterator() + : Offset() + , Vector() + { + } + + TPagedVectorIterator(TVec* vector, size_t offset) + : Offset(offset) + , Vector(vector) + { + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + TPagedVectorIterator(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) + : Offset(it.Offset) + , Vector(it.Vector) + { + } + + T& operator*() const { + return (*Vector)[Offset]; + } + + T* operator->() const { + return &(**this); + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + bool operator==(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return Offset == it.Offset; + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + bool operator!=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return !(*this == it); + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + bool operator<(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return Offset < it.Offset; + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + bool operator<=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return Offset <= it.Offset; + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + bool operator>(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return !(*this <= it); + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + bool operator>=(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return !(*this < it); + } + + template <class T1, class TT1, ui32 PageSize1, class A1> + ptrdiff_t operator-(const TPagedVectorIterator<T1, TT1, PageSize1, A1>& it) const { + return Offset - it.Offset; + } + + TSelf& operator+=(ptrdiff_t off) { + Offset += off; + return *this; + } + + TSelf& operator-=(ptrdiff_t off) { + return this->operator+=(-off); + } + + TSelf& operator++() { + return this->operator+=(1); + } + + TSelf& operator--() { + return this->operator+=(-1); + } + + TSelf operator++(int) { + TSelf it = *this; + this->operator+=(1); + return it; + } + + TSelf operator--(int) { + TSelf it = *this; + this->operator+=(-1); + return it; + } + + TSelf operator+(ptrdiff_t off) { + TSelf res = *this; + res += off; + return res; + } + + TSelf operator-(ptrdiff_t off) { + return this->operator+(-off); + } + + size_t GetOffset() { + return Offset; + } + }; } } -namespace std { - template <class T, class TT, ui32 PageSize, class A> - struct iterator_traits<NPagedVector::NPrivate::TPagedVectorIterator<T, TT, PageSize, A>> { - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef random_access_iterator_tag iterator_category; - }; +namespace std { + template <class T, class TT, ui32 PageSize, class A> + struct iterator_traits<NPagedVector::NPrivate::TPagedVectorIterator<T, TT, PageSize, A>> { + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef random_access_iterator_tag iterator_category; + }; } namespace NPagedVector { - //2-level radix tree - template <class T, ui32 PageSize, class A> - class TPagedVector: private TVector<TSimpleSharedPtr<TVector<T, A>>, A> { - static_assert(PageSize, "expect PageSize"); - - typedef TVector<T, A> TPage; - typedef TVector<TSimpleSharedPtr<TPage>, A> TPages; - typedef TPagedVector<T, PageSize, A> TSelf; - - public: - typedef NPrivate::TPagedVectorIterator<T, T, PageSize, A> iterator; - typedef NPrivate::TPagedVectorIterator<const T, T, PageSize, A> const_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef T value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - - TPagedVector() = default; - - template <typename TIter> - TPagedVector(TIter b, TIter e) { - append(b, e); - } - - iterator begin() { - return iterator(this, 0); - } - - const_iterator begin() const { - return const_iterator((TSelf*)this, 0); - } - - iterator end() { - return iterator(this, size()); - } - - const_iterator end() const { - return const_iterator((TSelf*)this, size()); - } - - reverse_iterator rbegin() { - return reverse_iterator(end()); - } - - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - - reverse_iterator rend() { - return reverse_iterator(begin()); - } - - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - - void swap(TSelf& v) { - TPages::swap((TPages&)v); - } - - private: - static size_t PageNumber(size_t idx) { - return idx / PageSize; - } - - static size_t InPageIndex(size_t idx) { - return idx % PageSize; - } - - static size_t Index(size_t pnum, size_t poff) { - return pnum * PageSize + poff; - } - - TPage& PageAt(size_t pnum) const { - return *TPages::at(pnum); - } - - TPage& CurrentPage() const { - return *TPages::back(); - } - - size_t CurrentPageSize() const { - return TPages::empty() ? 0 : CurrentPage().size(); - } - - size_t NPages() const { - return TPages::size(); - } - - void AllocateNewPage() { - TPages::push_back(new TPage()); - CurrentPage().reserve(PageSize); - } - - void MakeNewPage() { + //2-level radix tree + template <class T, ui32 PageSize, class A> + class TPagedVector: private TVector<TSimpleSharedPtr<TVector<T, A>>, A> { + static_assert(PageSize, "expect PageSize"); + + typedef TVector<T, A> TPage; + typedef TVector<TSimpleSharedPtr<TPage>, A> TPages; + typedef TPagedVector<T, PageSize, A> TSelf; + + public: + typedef NPrivate::TPagedVectorIterator<T, T, PageSize, A> iterator; + typedef NPrivate::TPagedVectorIterator<const T, T, PageSize, A> const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef T value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + TPagedVector() = default; + + template <typename TIter> + TPagedVector(TIter b, TIter e) { + append(b, e); + } + + iterator begin() { + return iterator(this, 0); + } + + const_iterator begin() const { + return const_iterator((TSelf*)this, 0); + } + + iterator end() { + return iterator(this, size()); + } + + const_iterator end() const { + return const_iterator((TSelf*)this, size()); + } + + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() { + return reverse_iterator(begin()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + void swap(TSelf& v) { + TPages::swap((TPages&)v); + } + + private: + static size_t PageNumber(size_t idx) { + return idx / PageSize; + } + + static size_t InPageIndex(size_t idx) { + return idx % PageSize; + } + + static size_t Index(size_t pnum, size_t poff) { + return pnum * PageSize + poff; + } + + TPage& PageAt(size_t pnum) const { + return *TPages::at(pnum); + } + + TPage& CurrentPage() const { + return *TPages::back(); + } + + size_t CurrentPageSize() const { + return TPages::empty() ? 0 : CurrentPage().size(); + } + + size_t NPages() const { + return TPages::size(); + } + + void AllocateNewPage() { + TPages::push_back(new TPage()); + CurrentPage().reserve(PageSize); + } + + void MakeNewPage() { AllocateNewPage(); - CurrentPage().resize(PageSize); - } - - void PrepareAppend() { - if (TPages::empty() || CurrentPage().size() + 1 > PageSize) - AllocateNewPage(); - } - - public: - size_t size() const { - return empty() ? 0 : (NPages() - 1) * PageSize + CurrentPage().size(); - } - - bool empty() const { - return TPages::empty() || 1 == NPages() && CurrentPage().empty(); - } - - explicit operator bool() const noexcept { - return !empty(); - } - - void emplace_back() { - PrepareAppend(); - CurrentPage().emplace_back(); - } - - void push_back(const_reference t) { - PrepareAppend(); - CurrentPage().push_back(t); - } - - void pop_back() { - if (CurrentPage().empty()) - TPages::pop_back(); - CurrentPage().pop_back(); - } - - template <typename TIter> - void append(TIter b, TIter e) { - size_t sz = e - b; - size_t sz1 = Min<size_t>(sz, PageSize - CurrentPageSize()); - size_t sz2 = (sz - sz1) / PageSize; - size_t sz3 = (sz - sz1) % PageSize; - - if (sz1) { - PrepareAppend(); - TPage& p = CurrentPage(); - p.insert(p.end(), b, b + sz1); - } - - for (size_t i = 0; i < sz2; ++i) { - AllocateNewPage(); - TPage& p = CurrentPage(); - p.insert(p.end(), b + sz1 + i * PageSize, b + sz1 + (i + 1) * PageSize); - } - - if (sz3) { - AllocateNewPage(); - TPage& p = CurrentPage(); - p.insert(p.end(), b + sz1 + sz2 * PageSize, e); - } - } - - iterator erase(iterator it) { - size_t pnum = PageNumber(it.Offset); - size_t pidx = InPageIndex(it.Offset); - - if (CurrentPage().empty()) - TPages::pop_back(); - - for (size_t p = NPages() - 1; p > pnum; --p) { - PageAt(p - 1).push_back(PageAt(p).front()); - PageAt(p).erase(PageAt(p).begin()); - } - - PageAt(pnum).erase(PageAt(pnum).begin() + pidx); - return it; - } - - iterator erase(iterator b, iterator e) { - // todo : suboptimal! - while (b != e) { - b = erase(b); - --e; - } - - return b; - } - - iterator insert(iterator it, const value_type& v) { - size_t pnum = PageNumber(it.Offset); - size_t pidx = InPageIndex(it.Offset); - + CurrentPage().resize(PageSize); + } + + void PrepareAppend() { + if (TPages::empty() || CurrentPage().size() + 1 > PageSize) + AllocateNewPage(); + } + + public: + size_t size() const { + return empty() ? 0 : (NPages() - 1) * PageSize + CurrentPage().size(); + } + + bool empty() const { + return TPages::empty() || 1 == NPages() && CurrentPage().empty(); + } + + explicit operator bool() const noexcept { + return !empty(); + } + + void emplace_back() { + PrepareAppend(); + CurrentPage().emplace_back(); + } + + void push_back(const_reference t) { PrepareAppend(); + CurrentPage().push_back(t); + } + + void pop_back() { + if (CurrentPage().empty()) + TPages::pop_back(); + CurrentPage().pop_back(); + } + + template <typename TIter> + void append(TIter b, TIter e) { + size_t sz = e - b; + size_t sz1 = Min<size_t>(sz, PageSize - CurrentPageSize()); + size_t sz2 = (sz - sz1) / PageSize; + size_t sz3 = (sz - sz1) % PageSize; + + if (sz1) { + PrepareAppend(); + TPage& p = CurrentPage(); + p.insert(p.end(), b, b + sz1); + } + + for (size_t i = 0; i < sz2; ++i) { + AllocateNewPage(); + TPage& p = CurrentPage(); + p.insert(p.end(), b + sz1 + i * PageSize, b + sz1 + (i + 1) * PageSize); + } + + if (sz3) { + AllocateNewPage(); + TPage& p = CurrentPage(); + p.insert(p.end(), b + sz1 + sz2 * PageSize, e); + } + } + + iterator erase(iterator it) { + size_t pnum = PageNumber(it.Offset); + size_t pidx = InPageIndex(it.Offset); + + if (CurrentPage().empty()) + TPages::pop_back(); + + for (size_t p = NPages() - 1; p > pnum; --p) { + PageAt(p - 1).push_back(PageAt(p).front()); + PageAt(p).erase(PageAt(p).begin()); + } + + PageAt(pnum).erase(PageAt(pnum).begin() + pidx); + return it; + } + + iterator erase(iterator b, iterator e) { + // todo : suboptimal! + while (b != e) { + b = erase(b); + --e; + } + + return b; + } + + iterator insert(iterator it, const value_type& v) { + size_t pnum = PageNumber(it.Offset); + size_t pidx = InPageIndex(it.Offset); + + PrepareAppend(); + + for (size_t p = NPages() - 1; p > pnum; --p) { + PageAt(p).insert(PageAt(p).begin(), PageAt(p - 1).back()); + PageAt(p - 1).pop_back(); + } + + PageAt(pnum).insert(PageAt(pnum).begin() + pidx, v); + return it; + } + + template <typename TIter> + void insert(iterator it, TIter b, TIter e) { + // todo : suboptimal! + for (; b != e; ++b, ++it) + it = insert(it, *b); + } + + reference front() { + return TPages::front()->front(); + } + + const_reference front() const { + return TPages::front()->front(); + } + + reference back() { + return CurrentPage().back(); + } + + const_reference back() const { + return CurrentPage().back(); + } + + void clear() { + TPages::clear(); + } + + void resize(size_t sz) { + if (sz == size()) + return; + + const size_t npages = NPages(); + const size_t newwholepages = sz / PageSize; + const size_t pagepart = sz % PageSize; + const size_t newpages = newwholepages + bool(pagepart); + + if (npages && newwholepages >= npages) + CurrentPage().resize(PageSize); + + if (newpages < npages) + TPages::resize(newpages); + else + for (size_t i = npages; i < newpages; ++i) + MakeNewPage(); + + if (pagepart) + CurrentPage().resize(pagepart); + + Y_VERIFY(sz == size(), "%" PRIu64 " %" PRIu64, (ui64)sz, (ui64)size()); + } - for (size_t p = NPages() - 1; p > pnum; --p) { - PageAt(p).insert(PageAt(p).begin(), PageAt(p - 1).back()); - PageAt(p - 1).pop_back(); - } + reference at(size_t idx) { + return TPages::at(PageNumber(idx))->at(InPageIndex(idx)); + } - PageAt(pnum).insert(PageAt(pnum).begin() + pidx, v); - return it; - } + const_reference at(size_t idx) const { + return TPages::at(PageNumber(idx))->at(InPageIndex(idx)); + } - template <typename TIter> - void insert(iterator it, TIter b, TIter e) { - // todo : suboptimal! - for (; b != e; ++b, ++it) - it = insert(it, *b); - } + reference operator[](size_t idx) { + return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx)); + } - reference front() { - return TPages::front()->front(); - } + const_reference operator[](size_t idx) const { + return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx)); + } - const_reference front() const { - return TPages::front()->front(); - } + friend bool operator==(const TSelf& a, const TSelf& b) { + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); + } - reference back() { - return CurrentPage().back(); - } - - const_reference back() const { - return CurrentPage().back(); - } - - void clear() { - TPages::clear(); - } - - void resize(size_t sz) { - if (sz == size()) - return; - - const size_t npages = NPages(); - const size_t newwholepages = sz / PageSize; - const size_t pagepart = sz % PageSize; - const size_t newpages = newwholepages + bool(pagepart); - - if (npages && newwholepages >= npages) - CurrentPage().resize(PageSize); - - if (newpages < npages) - TPages::resize(newpages); - else - for (size_t i = npages; i < newpages; ++i) - MakeNewPage(); - - if (pagepart) - CurrentPage().resize(pagepart); - - Y_VERIFY(sz == size(), "%" PRIu64 " %" PRIu64, (ui64)sz, (ui64)size()); - } - - reference at(size_t idx) { - return TPages::at(PageNumber(idx))->at(InPageIndex(idx)); - } - - const_reference at(size_t idx) const { - return TPages::at(PageNumber(idx))->at(InPageIndex(idx)); - } - - reference operator[](size_t idx) { - return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx)); - } - - const_reference operator[](size_t idx) const { - return TPages::operator[](PageNumber(idx))->operator[](InPageIndex(idx)); - } - - friend bool operator==(const TSelf& a, const TSelf& b) { - return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); - } - - friend bool operator<(const TSelf& a, const TSelf& b) { - return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); - } - }; + friend bool operator<(const TSelf& a, const TSelf& b) { + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); + } + }; - namespace NPrivate { - typedef std::is_same<std::random_access_iterator_tag, std::iterator_traits< - TPagedVector<ui32>::iterator>::iterator_category> - TIteratorCheck; - static_assert(TIteratorCheck::value, "expect TIteratorCheck::Result"); + namespace NPrivate { + typedef std::is_same<std::random_access_iterator_tag, std::iterator_traits< + TPagedVector<ui32>::iterator>::iterator_category> + TIteratorCheck; + static_assert(TIteratorCheck::value, "expect TIteratorCheck::Result"); } } |