diff options
author | Ruslan Kovalev <ruslan.a.kovalev@gmail.com> | 2022-02-10 16:46:45 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:45 +0300 |
commit | 9123176b341b6f2658cff5132482b8237c1416c8 (patch) | |
tree | 49e222ea1c5804306084bb3ae065bb702625360f /library/cpp/containers/paged_vector/paged_vector.h | |
parent | 59e19371de37995fcb36beb16cd6ec030af960bc (diff) | |
download | ydb-9123176b341b6f2658cff5132482b8237c1416c8.tar.gz |
Restoring authorship annotation for Ruslan Kovalev <ruslan.a.kovalev@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/containers/paged_vector/paged_vector.h')
-rw-r--r-- | library/cpp/containers/paged_vector/paged_vector.h | 210 |
1 files changed, 105 insertions, 105 deletions
diff --git a/library/cpp/containers/paged_vector/paged_vector.h b/library/cpp/containers/paged_vector/paged_vector.h index 9730b00670..6a3657d3ea 100644 --- a/library/cpp/containers/paged_vector/paged_vector.h +++ b/library/cpp/containers/paged_vector/paged_vector.h @@ -1,15 +1,15 @@ -#pragma once - -#include <util/generic/ptr.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> - +#pragma once + +#include <util/generic/ptr.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> + #include <iterator> -namespace NPagedVector { +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 { @@ -19,119 +19,119 @@ namespace NPagedVector { 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>> { @@ -141,19 +141,19 @@ namespace std { typedef T& reference; typedef random_access_iterator_tag iterator_category; }; - -} - -namespace NPagedVector { + +} + +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; @@ -162,99 +162,99 @@ namespace NPagedVector { 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(); + 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(); } @@ -262,23 +262,23 @@ namespace NPagedVector { explicit operator bool() const noexcept { return !empty(); } - + void emplace_back() { PrepareAppend(); CurrentPage().emplace_back(); } - + void push_back(const_reference t) { - PrepareAppend(); + 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; @@ -303,15 +303,15 @@ namespace NPagedVector { 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()); @@ -319,114 +319,114 @@ namespace NPagedVector { 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()); } - + 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()); } }; - + 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"); - } - -} + } + +} |