Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
page_container_impl.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3 * Author: Sebastian Reiter
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__UG__page_container_impl__
34#define __H__UG__page_container_impl__
35
36#include <algorithm>
37#include "page_container.h"
38
39// a temporary include
40#include "common/log.h"
41
42namespace ug
43{
44
45template <class T, int MAX_PAGE_SIZE, class Allocator>
48 m_numPageEntries((size_t)(MAX_PAGE_SIZE / sizeof(T))),
49 m_size(0)
50{
51}
52
53template <class T, int MAX_PAGE_SIZE, class Allocator>
56 m_numPageEntries((size_t)(MAX_PAGE_SIZE / sizeof(T)))
57{
59}
60
61template <class T, int MAX_PAGE_SIZE, class Allocator>
64{
65 clear();
66 for(size_t i = 0; i < m_pages.size(); ++i){
67 m_alloc.deallocate(m_pages[i], m_numPageEntries);
68 }
69}
70
71template <class T, int MAX_PAGE_SIZE, class Allocator>
74operator=(const PageContainer& pc)
75{
76 assign_container(pc);
77 return *this;
78}
79
80template <class T, int MAX_PAGE_SIZE, class Allocator>
82size() const
83{
84 return m_size;
85}
86
87template <class T, int MAX_PAGE_SIZE, class Allocator>
89capacity() const
90{
91 return m_pages.size() * m_numPageEntries;
92}
93
94template <class T, int MAX_PAGE_SIZE, class Allocator>
96resize(size_t size, const T& val)
97{
98 using namespace std;
99//UG_LOG(" reserving...\n");
100// allocate memory
101 reserve(size);
102//UG_LOG(" constructing...\n");
103// call constructor on new objects
104// to do this with optimal performance,
105// we'll iterate over the pages directly
106 while(m_size < size){
107 T* page = get_page(m_size);
108 size_t offset = get_page_offset(m_size);
109 const size_t maxI = min(m_numPageEntries, offset + size - m_size);
110
111 for(size_t i = offset; i < maxI; ++i)
112 m_alloc.construct(page + i, val);
113
114 m_size += maxI - offset;
115 }
116//UG_LOG(" destroying...\n");
117// if resize shrinks the data array, we have to call the destructors of
118// deleted objects. At this point size <= m_size.
119 while(m_size > size){
120 T* page = get_page(m_size - 1);
121 size_t maxI = get_page_offset(m_size - 1) + 1;
122 size_t minI = 0;
123 const size_t diff = m_size - size;
124 if(maxI > diff)
125 minI = (maxI) - diff;
126
127 for(size_t i = minI; i < maxI; ++i)
128 m_alloc.destroy(page + i);
129
130 m_size -= (maxI - minI);
131 }
132//UG_LOG(" done...\n");
133}
134
135template <class T, int MAX_PAGE_SIZE, class Allocator>
137reserve(size_t size)
138{
139 using namespace std;
140
141 //UG_LOG("*num page entries: " << m_numPageEntries << ", required size: " << size << endl);
142 while(m_pages.size() * m_numPageEntries < size){
143 //UG_LOG("**allocating " << m_numPageEntries << " elems of size " << sizeof(T) << endl);
144 T* buf = m_alloc.allocate(m_numPageEntries);
145 //UG_LOG("**adding a new page (current num pages: " << m_pages.size() << ")\n");
146 m_pages.push_back(buf);
147 }
148 //UG_LOG("*done\n");
149}
150
151template <class T, int MAX_PAGE_SIZE, class Allocator>
157
158template <class T, int MAX_PAGE_SIZE, class Allocator>
160operator[](size_t ind)
161{
162 assert(ind < m_size);
163 return get_page(ind)[get_page_offset(ind)];
164}
165
166template <class T, int MAX_PAGE_SIZE, class Allocator>
168operator[](size_t ind) const
169{
170 assert(ind < m_size);
171 return get_page(ind)[get_page_offset(ind)];
172}
173
174template <class T, int MAX_PAGE_SIZE, class Allocator>
177{
178 m_pages.swap(pc.m_pages);
179 Allocator talloc = m_alloc;
180 m_alloc = pc.m_alloc;
181 pc.m_alloc = talloc;
182
183 size_t tmp = m_size;
184 m_size = pc.m_size;
185 pc.m_size = tmp;
186}
187
188template <class T, int MAX_PAGE_SIZE, class Allocator>
191{
192 using namespace std;
193 clear();
194
195 reserve(pc.m_size);
196
197// copy all entries with optimal performance
198 while(m_size < pc.m_size){
199 T* page = get_page(m_size);
200 T* srcPage = pc.get_page(m_size);
201 size_t offset = get_page_offset(m_size);
202 const size_t maxI = min(m_numPageEntries, offset + pc.m_size - m_size);
203
204 for(size_t i = offset; i < maxI; ++i)
205 m_alloc.construct(page + i, srcPage[i]);
206
207 m_size += maxI;
208 }
209}
210
211template <class T, int MAX_PAGE_SIZE, class Allocator>
213get_page(size_t ind) const
214{
215 assert(get_page_index(ind) < m_pages.size());
216 return m_pages[get_page_index(ind)];
217}
218
219template <class T, int MAX_PAGE_SIZE, class Allocator>
221get_page_index(size_t ind) const
222{
223 return ind / m_numPageEntries;
224}
225
226template <class T, int MAX_PAGE_SIZE, class Allocator>
228get_page_offset(size_t ind) const
229{
230 return ind % m_numPageEntries;
231}
232
233}// end of namespace
234
235#endif
Definition page_container.h:46
size_t capacity() const
Definition page_container_impl.h:89
PageContainer()
Definition page_container_impl.h:47
size_t m_size
Definition page_container.h:92
Allocator m_alloc
Definition page_container.h:93
T * get_page(size_t ind) const
returns the page in which the data for the given index lies
Definition page_container_impl.h:213
void reserve(size_t size)
Definition page_container_impl.h:137
size_t get_page_offset(size_t ind) const
returns the offset that a index has in its page
Definition page_container_impl.h:228
size_t size() const
Definition page_container_impl.h:82
void resize(size_t size, const T &val=T())
Definition page_container_impl.h:96
std::vector< T * > m_pages
Definition page_container.h:90
void clear()
Definition page_container_impl.h:153
~PageContainer()
Definition page_container_impl.h:63
PageContainer & operator=(const PageContainer &pc)
Definition page_container_impl.h:74
size_t get_page_index(size_t ind) const
returns the index of the page in which the data for the given index lies
Definition page_container_impl.h:221
T & operator[](size_t ind)
Definition page_container_impl.h:160
void assign_container(const PageContainer &pc)
Definition page_container_impl.h:190
void swap(PageContainer &pc)
Definition page_container_impl.h:176
Definition smart_pointer.h:814
the ug namespace
bool resize(size_t newRows, size_t newCols)