MemFast.hpp 3.26 KB
Newer Older
incardon's avatar
incardon committed
1
/*
2
 * MemFast.hpp
incardon's avatar
incardon committed
3
4
5
6
7
 *
 *  Created on: Mar 22, 2015
 *      Author: Pietro Incardona
 */

incardon's avatar
incardon committed
8
9
#ifndef MEMFAST_HPP_
#define MEMFAST_HPP_
incardon's avatar
incardon committed
10

11
#include "CellList.hpp"
12
#include "Space/SpaceBox.hpp"
incardon's avatar
incardon committed
13
#include "util/mathutil.hpp"
14
#include "Space/Shape/HyperCube.hpp"
Yaroslav's avatar
Yaroslav committed
15
#include "CellListIterator.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
16
#include <unordered_map>
17
#include "util/common.hpp"
incardon's avatar
incardon committed
18

incardon's avatar
incardon committed
19

incardon's avatar
incardon committed
20

incardon's avatar
incardon committed
21
template<unsigned int dim, typename T>
22
class Mem_fast
incardon's avatar
incardon committed
23
{
Pietro Incardona's avatar
Pietro Incardona committed
24
	//! Number of slot for each cell
incardon's avatar
incardon committed
25
26
	size_t slot;

Pietro Incardona's avatar
Pietro Incardona committed
27
	//! number of particle in each cell list
incardon's avatar
incardon committed
28
29
	openfpm::vector<size_t> cl_n;

incardon's avatar
incardon committed
30
31
	typedef typename openfpm::vector<size_t> base;

Pietro Incardona's avatar
Pietro Incardona committed
32
33
	//! elements that each cell store (each cell can store a number
	//! of elements == slot )
incardon's avatar
incardon committed
34
35
	base cl_base;

Pietro Incardona's avatar
Pietro Incardona committed
36
37
38
39
	/*! \brief realloc the data structures
	 *
	 *
	 */
incardon's avatar
incardon committed
40
	inline void realloc()
41
42
43
	{
		// we do not have enough slots reallocate the basic structure with more
		// slots
44
		base cl_base_(2*slot * cl_n.size());
45
46
47
48
49

		// copy cl_base
		for (size_t i = 0 ; i < cl_n.size() ; i++)
		{
			for (size_t j = 0 ; j < cl_n.get(i) ; j++)
50
				cl_base_.get(2*i*slot + j) = cl_base.get(slot * i + j);
51
52
		}

53
54
55
		// Double the number of slots
		slot *= 2;

56
		// swap the memory
57
		cl_base.swap(cl_base_);
58
59
	}

60
protected:
Pietro Incardona's avatar
Pietro Incardona committed
61

incardon's avatar
incardon committed
62
	inline void init_to_zero(size_t slot, size_t tot_n_cell)
63
64
	{
		this->slot = slot;
Pietro Incardona's avatar
Pietro Incardona committed
65

66
		// create the array that store the number of particle on each cell and se it to 0
Pietro Incardona's avatar
Pietro Incardona committed
67

incardon's avatar
incardon committed
68
		cl_n.resize(tot_n_cell);
69
70
71
72
		cl_n.fill(0);

		// create the array that store the cell id

incardon's avatar
incardon committed
73
		cl_base.resize(tot_n_cell * slot);
incardon's avatar
incardon committed
74
75
	}

incardon's avatar
incardon committed
76
	inline void operator=(const Mem_fast & mem)
Pietro Incardona's avatar
Pietro Incardona committed
77
	{
78
		slot = mem.slot;
Pietro Incardona's avatar
Pietro Incardona committed
79

80
81
		cl_n = mem.cl_n;
		cl_base = mem.cl_base;
Pietro Incardona's avatar
Pietro Incardona committed
82
83
	}

incardon's avatar
incardon committed
84
	inline void addCell(size_t cell_id, typename base::value_type ele)
incardon's avatar
incardon committed
85
86
87
	{
		// Get the number of element the cell is storing

88
		size_t nl = getNelements(cell_id);
incardon's avatar
incardon committed
89
90
91

		if (nl + 1 >= slot)
		{
92
93
			realloc();
		}
incardon's avatar
incardon committed
94

95
		// we have enough slot to store another neighbor element
incardon's avatar
incardon committed
96

97
98
99
		cl_base.get(slot * cell_id + cl_n.get(cell_id)) = ele;
		cl_n.get(cell_id)++;
	}
incardon's avatar
incardon committed
100

incardon's avatar
incardon committed
101
	inline void add(size_t cell_id, typename base::value_type ele)
102
	{
incardon's avatar
incardon committed
103
104
		// add the element to the cell

incardon's avatar
incardon committed
105
		this->addCell(cell_id,ele);
incardon's avatar
incardon committed
106
	}
107

incardon's avatar
incardon committed
108
	inline auto get(size_t cell, size_t ele) -> decltype(cl_base.get(cell * slot + ele)) &
incardon's avatar
incardon committed
109
	{
110
		return cl_base.get(cell * slot + ele);
incardon's avatar
incardon committed
111
112
	}

incardon's avatar
incardon committed
113
	inline auto get(size_t cell, size_t ele) const -> decltype(cl_base.get(cell * slot + ele)) &
incardon's avatar
incardon committed
114
115
116
117
118
	{
		return cl_base.get(cell * slot + ele);
	}

	inline void remove(size_t cell, size_t ele)
Pietro Incardona's avatar
Pietro Incardona committed
119
	{
120
		cl_n.get(cell)--;
Pietro Incardona's avatar
Pietro Incardona committed
121
122
	}

incardon's avatar
incardon committed
123
	inline size_t getNelements(const size_t cell_id) const
incardon's avatar
incardon committed
124
	{
125
		return cl_n.get(cell_id);
incardon's avatar
incardon committed
126
127
	}

incardon's avatar
incardon committed
128
	inline void swap(Mem_fast & mem)
129
	{
130
131
		cl_n.swap(mem.cl_n);
		cl_base.swap(mem.cl_base);
132

133
134
		size_t cl_slot_tmp = mem.slot;
		mem.slot = slot;
135
		slot = cl_slot_tmp;
136
	}
Yaroslav's avatar
Yaroslav committed
137

incardon's avatar
incardon committed
138
	inline void swap(Mem_fast && mem)
139
140
141
142
143
144
145
	{
		slot = mem.slot;

		cl_n.swap(mem.cl_n);
		cl_base.swap(mem.cl_base);
	}

incardon's avatar
incardon committed
146
	inline void clear()
tonynsyde's avatar
tonynsyde committed
147
	{
Pietro Incardona's avatar
Pietro Incardona committed
148
149
		for (size_t i = 0 ; i < cl_n.size() ; i++)
			cl_n.get(i) = 0;
tonynsyde's avatar
tonynsyde committed
150
	}
151

incardon's avatar
incardon committed
152
	inline const size_t & getStartId(size_t cell_id) const
153
	{
incardon's avatar
incardon committed
154
		return cl_base.get(cell_id*slot);
155
156
	}

incardon's avatar
incardon committed
157
	inline const size_t & getStopId(size_t cell_id) const
158
	{
incardon's avatar
incardon committed
159
		return cl_base.get(cell_id*slot+cl_n.get(cell_id));
160
161
	}

incardon's avatar
incardon committed
162
	inline const size_t & get_lin(const size_t * part_id) const
163
	{
164
		return *part_id;
165
166
	}

167
public:
168

incardon's avatar
incardon committed
169
	inline Mem_fast(size_t slot)
170
171
	:slot(slot)
	{}
incardon's avatar
incardon committed
172

incardon's avatar
incardon committed
173
	inline void set_slot(size_t slot)
incardon's avatar
incardon committed
174
175
176
	{
		this->slot = slot;
	}
incardon's avatar
incardon committed
177

incardon's avatar
incardon committed
178
179
180
181
};


#endif /* CELLLISTSTANDARD_HPP_ */