Skip to content

Commit d1c6787

Browse files
committed
Implement shrink_to_fit on memblock and vector containers
Change margin allocation strategy to pow2 growth from +64 reserve will now use margin allocation by default, resize is still exact
1 parent 18a140a commit d1c6787

File tree

7 files changed

+30
-9
lines changed

7 files changed

+30
-9
lines changed

bvt/bvt02.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ void TestMB (void)
6767
WriteCML (a);
6868
a.resize (strTestLen + strTestLen / 2);
6969
WriteCML (a);
70+
cout << "Capacity " << a.capacity();
71+
a.shrink_to_fit();
72+
cout << ", shrunk " << a.capacity() << endl;
7073
}
7174

7275
StdBvtMain (TestMB)

bvt/bvt02.std

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ memblock{28}: ab---TESTTESTTESTpqrs=======
77
memblock{50}: ab---TESTTESTTESTpqrs=====-+=-+=-+=-+=-+=-+=-+=-+=
88
memblock{0}:
99
memblock{39}: ab---TESTTESTTESTpqrs=====-+=-+=-+=-+=-
10+
Capacity 64, shrunk 39

bvt/bvt04.std

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(1)
2-
Reserved to capacity() == 20 (1 used, SIZE_MAX/elsize max)
2+
Reserved to capacity() == 32 (1 used, SIZE_MAX/elsize max)
33
(1,2,3,4,5,6,7,8,9,10,11,12,13,13,14,15,16,17,18)
44
front() = 1, back() = 18
55
(2,3,4,5,6,7,8,9,10,11,12,13,13,14,15,16,17)

bvt/bvt07.std

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
abcdefghijklmnopqrstuvwxyz
33
123456789012345678901234567890
44
12345678901234567890
5-
s3.size() = 20, max_size() = (SIZE_MAX/elsize)-1, capacity() = 48
5+
s3.size() = 20, max_size() = (SIZE_MAX/elsize)-1, capacity() = 63
66
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$
77
HelloWorld
88
Concatenated HelloWorld string.

memblock.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void memblock::reserve (size_type newSize, bool bExact)
8888
if ((newSize += minimumFreeCapacity()) <= m_Capacity)
8989
return;
9090
pointer oldBlock (is_linked() ? NULL : data());
91-
const size_t alignedSize (Align (newSize, 64));
91+
const size_t alignedSize (NextPow2 (newSize));
9292
if (!bExact)
9393
newSize = alignedSize;
9494
pointer newBlock = (pointer) realloc (oldBlock, newSize);
@@ -100,6 +100,17 @@ void memblock::reserve (size_type newSize, bool bExact)
100100
m_Capacity = newSize;
101101
}
102102

103+
/// Reduces capacity to match size
104+
void memblock::shrink_to_fit (void)
105+
{
106+
if (is_linked())
107+
return;
108+
pointer newBlock = (pointer) realloc (begin(), size());
109+
if (!newBlock)
110+
throw bad_alloc (size());
111+
m_Capacity = size();
112+
}
113+
103114
/// Shifts the data in the linked block from \p start to \p start + \p n.
104115
memblock::iterator memblock::insert (iterator start, size_type n)
105116
{

memblock.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class memblock : public memlink {
3434
inline const memblock& operator= (const memblock& l) { assign (l); return (*this); }
3535
inline void swap (memblock& l) { memlink::swap (l); ::ustl::swap (m_Capacity, l.m_Capacity); }
3636
void assign (const void* p, size_type n);
37-
void reserve (size_type newSize, bool bExact = true);
37+
void reserve (size_type newSize, bool bExact = false);
3838
void resize (size_type newSize, bool bExact = true);
3939
iterator insert (iterator start, size_type size);
4040
iterator erase (iterator start, size_type size);
@@ -44,6 +44,7 @@ class memblock : public memlink {
4444
inline size_type max_size (void) const { return (is_linked() ? memlink::max_size() : SIZE_MAX); }
4545
inline void manage (memlink& l) { manage (l.begin(), l.size()); }
4646
void deallocate (void) noexcept;
47+
void shrink_to_fit (void);
4748
void manage (void* p, size_type n);
4849
void copy_link (void);
4950
void read (istream& is);

uvector.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class vector {
4747
inline operator cmemlink (void) const { return (cmemlink (m_Data)); }
4848
inline operator cmemlink (void) { return (cmemlink (m_Data)); }
4949
inline operator memlink (void) { return (memlink (m_Data)); }
50-
inline void reserve (size_type n, bool bExact = true);
50+
inline void reserve (size_type n, bool bExact = false);
5151
inline void resize (size_type n, bool bExact = true);
5252
inline size_type capacity (void) const { return (m_Data.capacity() / sizeof(T)); }
5353
inline size_type size (void) const { return (m_Data.size() / sizeof(T)); }
@@ -57,10 +57,14 @@ class vector {
5757
inline const_iterator begin (void) const { return (const_iterator (m_Data.begin())); }
5858
inline iterator end (void) { return (iterator (m_Data.end())); }
5959
inline const_iterator end (void) const { return (const_iterator (m_Data.end())); }
60-
inline reverse_iterator rbegin (void) { return (reverse_iterator (end())); }
61-
inline const_reverse_iterator rbegin (void) const { return (const_reverse_iterator (end())); }
62-
inline reverse_iterator rend (void) { return (reverse_iterator (begin())); }
63-
inline const_reverse_iterator rend (void) const { return (const_reverse_iterator (begin())); }
60+
inline const_iterator cbegin (void) const { return (begin()); }
61+
inline const_iterator cend (void) const { return (end()); }
62+
inline reverse_iterator rbegin (void) { return (reverse_iterator (end())); }
63+
inline const_reverse_iterator rbegin (void) const { return (const_reverse_iterator (end())); }
64+
inline reverse_iterator rend (void) { return (reverse_iterator (begin())); }
65+
inline const_reverse_iterator rend (void) const { return (const_reverse_iterator (begin())); }
66+
inline const_reverse_iterator crbegin (void) const { return (rbegin()); }
67+
inline const_reverse_iterator crend (void) const { return (rend()); }
6468
inline iterator iat (size_type i) { assert (i <= size()); return (begin() + i); }
6569
inline const_iterator iat (size_type i) const { assert (i <= size()); return (begin() + i); }
6670
inline reference at (size_type i) { assert (i < size()); return (begin()[i]); }
@@ -74,6 +78,7 @@ class vector {
7478
inline void push_back (const T& v = T());
7579
inline void pop_back (void) { m_Data.memlink::resize (m_Data.size() - sizeof(T)); }
7680
inline void clear (void) { m_Data.clear(); }
81+
inline void shrink_to_fit (void) { m_Data.shrink_to_fit(); }
7782
inline void deallocate (void) noexcept;
7883
inline void assign (const_iterator i1, const_iterator i2);
7984
inline void assign (size_type n, const T& v);

0 commit comments

Comments
 (0)