ug4
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 
42 namespace ug
43 {
44 
45 template <class T, int MAX_PAGE_SIZE, class Allocator>
47 PageContainer() :
48  m_numPageEntries((size_t)(MAX_PAGE_SIZE / sizeof(T))),
49  m_size(0)
50 {
51 }
52 
53 template <class T, int MAX_PAGE_SIZE, class Allocator>
55 PageContainer(const PageContainer& pc) :
56  m_numPageEntries((size_t)(MAX_PAGE_SIZE / sizeof(T)))
57 {
58  assign_container(pc);
59 }
60 
61 template <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 
71 template <class T, int MAX_PAGE_SIZE, class Allocator>
74 operator=(const PageContainer& pc)
75 {
76  assign_container(pc);
77  return *this;
78 }
79 
80 template <class T, int MAX_PAGE_SIZE, class Allocator>
82 size() const
83 {
84  return m_size;
85 }
86 
87 template <class T, int MAX_PAGE_SIZE, class Allocator>
89 capacity() const
90 {
91  return m_pages.size() * m_numPageEntries;
92 }
93 
94 template <class T, int MAX_PAGE_SIZE, class Allocator>
96 resize(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 
135 template <class T, int MAX_PAGE_SIZE, class Allocator>
137 reserve(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 
151 template <class T, int MAX_PAGE_SIZE, class Allocator>
153 clear()
154 {
155  resize(0);
156 }
157 
158 template <class T, int MAX_PAGE_SIZE, class Allocator>
160 operator[](size_t ind)
161 {
162  assert(ind < m_size);
163  return get_page(ind)[get_page_offset(ind)];
164 }
165 
166 template <class T, int MAX_PAGE_SIZE, class Allocator>
168 operator[](size_t ind) const
169 {
170  assert(ind < m_size);
171  return get_page(ind)[get_page_offset(ind)];
172 }
173 
174 template <class T, int MAX_PAGE_SIZE, class Allocator>
176 swap(PageContainer& pc)
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 
188 template <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 
211 template <class T, int MAX_PAGE_SIZE, class Allocator>
213 get_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 
219 template <class T, int MAX_PAGE_SIZE, class Allocator>
221 get_page_index(size_t ind) const
222 {
223  return ind / m_numPageEntries;
224 }
225 
226 template <class T, int MAX_PAGE_SIZE, class Allocator>
228 get_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)