DSC
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros
kernel.h
1 //
2 // Deformabel Simplicial Complex (DSC) method
3 // Copyright (C) 2013 Technical University of Denmark
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // See licence.txt for a copy of the GNU General Public License.
16 
17 #pragma once
18 
19 #include <cassert>
20 #include <iostream>
21 #include <vector>
22 #include <set>
23 
24 #include "kernel_iterator.h"
25 
26 namespace is_mesh
27 {
28 
29  class ISMesh;
30 
34  namespace util
35  {
36 
41  template< typename key_t_, typename value_t_ >
43  {
44  using value_type = value_t_;
45 
46  enum state_type { VALID, MARKED, EMPTY, EXCLUDED };
47 
48  kernel_element() : value(nullptr), state{kernel_element::EMPTY} { }
49 
50  kernel_element(const kernel_element& ke) = delete;
51 
52  kernel_element(kernel_element&& ke) : value{std::move(ke.value)}, state{ke.state} {
53  }
54 
55  kernel_element&& operator=(kernel_element&& other) {
56  if (this != &other) {
57  value = std::move(other.value);
58  state = other.state;
59  }
60  return *this;
61  }
62 
63  value_type value;
64  state_type state;
65  };
66  }
67 
79  template<typename key_type, typename value_type>
80  class kernel
81  {
82  public:
84  using kernel_key_type = key_type;
87  using const_iterator = iterator const;
88 
89  friend class kernel_iterator<kernel_type>;
90 
91  bool readonly = false;
92 
93  private:
94  std::vector<kernel_element> m_data;
95  std::vector<key_type> m_data_freelist;
96  std::vector<key_type> m_data_marked_for_deletion;
97  private:
105  kernel_element& lookup(key_type k)
106  {
107 // assume key_type is integer type
108  assert(k >= 0 || !"looked up with negative element");
109  assert((int)k < m_data.size() || !"k out of range");
110  return m_data[k];
111  }
112 
118  kernel_element& get_next_free_cell(unsigned int &key)
119  {
120  if (m_data_freelist.size()==0){
121  key = (unsigned int)m_data.size();
122  m_data.emplace_back();
123  return m_data.back();
124  } else {
125  key = (unsigned int)m_data_freelist.back();
126  m_data_freelist.pop_back();
127  return m_data[key];
128  }
129  }
130  public:
131 
138  kernel(size_t reservedSize =64)
139  {
140  m_data.reserve(reservedSize);
141  }
142 
147  {
148  }
149 
153  size_t size() const { return m_data.size() - m_data_freelist.size(); }
154 
155 
159  size_t capacity() const { return m_data.size(); }
160 
164  bool empty() { return size() == 0; }
165 
174  template<typename... Values>
175  const_iterator create(ISMesh* isMesh, Values... values)
176  {
177  assert(!readonly);
178  unsigned int key;
179  kernel_element& cur = get_next_free_cell(key);
180 
181  assert(cur.state != kernel_element::VALID || !"Cannot create new element, duplicate key.");
182  assert(cur.state != kernel_element::MARKED || !"Attempted to overwrite a marked element.");
183  assert(cur.state != kernel_element::EXCLUDED || !"Attempted to overwrite an excluded element.");
184 
185  cur.value = value_type{isMesh, values...};
186  cur.state = kernel_element::VALID;
187  return iterator(this, key);
188  }
189 
193  const_iterator end() const
194  {
195  return iterator(this, key_type{(unsigned int)m_data.size()});
196  }
197 
201  const_iterator begin() const
202  {
203  unsigned int i = 0;
204  // find first valid element (if any)
205  for (;i<m_data.size();i++){
206  if (m_data[i].state == kernel_element::VALID){
207  break;
208  }
209  }
210  return iterator(this, key_type{i});
211  }
212 
219  void erase(key_type const & k)
220  {
221  assert(!readonly);
222  kernel_element& p = lookup(k);
223  assert (p.state == kernel_element::VALID || p.state == kernel_element::EXCLUDED || !"Attempted to remove a non-valid element!");
224  if (p.state != kernel_element::VALID && p.state != kernel_element::EXCLUDED )
225  {
226  //No element with that key.
227  return;
228  }
229  p.state = kernel_element::MARKED;
230  m_data_marked_for_deletion.push_back(k);
231  }
232 
239  void erase(const iterator& it)
240  {
241  assert(!readonly);
242  erase(it.key());
243  }
244 
248  void clear()
249  {
250  assert(!readonly);
251  m_data.clear();
252  m_data_freelist.clear();
253  m_data_marked_for_deletion.clear();
254  }
255 
262  {
263  if (is_valid(k))
264  return iterator(this, k);
265  else
266  return end();
267  }
268 
275  {
276  if (k>=m_data.size()){
277  return end();
278  }
279  iterator res(this, k);
280  if (!is_valid(k) || is_excluded(k)){
281  res++;
282  }
283  assert(res == end() || is_valid(res.key()));
284  return res;
285  }
286 
294  value_type & get(key_type k)
295  {
296  kernel_element& tmp = lookup(k);
297  assert(tmp.state == kernel_element::VALID || tmp.state == kernel_element::EXCLUDED);
298  return tmp.value;
299  }
300 
308  const value_type &get(key_type k) const
309  {
310  return const_cast<kernel_type *>(this)->get(k);
311  }
312 
316  char * data(){
317  return (char*)m_data.data();
318  }
319 
326  bool is_valid(key_type k)
327  {
328  kernel_element& tmp = lookup(k);
329  if (tmp.state == kernel_element::VALID || tmp.state == kernel_element::EXCLUDED ) return true;
330  return false;
331  }
332 
336  bool is_excluded(key_type k){
337  kernel_element& tmp = lookup(k);
338  if (tmp.state == kernel_element::EXCLUDED ) return true;
339  return false;
340  }
341 
345  std::vector<key_type> commit_all()
346  {
347  assert(!readonly);
348  std::vector<key_type> deletedKeys = m_data_marked_for_deletion;
349  for (auto key : m_data_marked_for_deletion){
350  auto & p = m_data[key];
351 
352  //m_alloc.destroy(&p); // needed?
353  p.state = kernel_element::EMPTY;
354  m_data_freelist.push_back(key);
355  }
356  m_data_marked_for_deletion.clear();
357  return deletedKeys;
358  }
359 
360  void revert_excluded(){
361  assert(!readonly);
362  for (auto &e : m_data){
363  if (e.state == kernel_element::state_type::EXCLUDED){
364  e.state = kernel_element::state_type::VALID;
365  }
366  }
367  }
368 
369  void exclude_using_include_set(std::set<key_type> include_set){
370  assert(!readonly);
371  for (unsigned int i=0;i<m_data.size();i++){
372  auto& e= m_data[i];
373  key_type k{i};
374  if (e.state == kernel_element::state_type::VALID){
375  if (include_set.find(k) == include_set.end()) {
376  e.state = kernel_element::state_type::EXCLUDED;
377  }
378  }
379  };
380  }
381 
389  std::vector<key_type> garbage_collect()
390  {
391  assert(!readonly);
392  return commit_all();
393  }
394  };
395 }
void erase(key_type const &k)
Definition: kernel.h:219
size_t size() const
Definition: kernel.h:153
Definition: kernel_iterator.h:22
bool is_excluded(key_type k)
Definition: kernel.h:336
char * data()
Definition: kernel.h:316
~kernel()
Definition: kernel.h:146
size_t capacity() const
Definition: kernel.h:159
key_type key() const
Definition: kernel_iterator.h:52
void erase(const iterator &it)
Definition: kernel.h:239
void clear()
Definition: kernel.h:248
std::vector< key_type > garbage_collect()
Definition: kernel.h:389
kernel(size_t reservedSize=64)
Definition: kernel.h:138
iterator find_iterator(key_type k)
Definition: kernel.h:261
bool is_valid(key_type k)
Definition: kernel.h:326
const_iterator create(ISMesh *isMesh, Values...values)
Definition: kernel.h:175
bool empty()
Definition: kernel.h:164
iterator find_valid_iterator(key_type k)
Definition: kernel.h:274
Definition: kernel.h:42
Definition: kernel.h:80
const_iterator end() const
Definition: kernel.h:193
std::vector< key_type > commit_all()
Definition: kernel.h:345
Definition: is_mesh.h:40
const_iterator begin() const
Definition: kernel.h:201