Subversion Repositories spk

Rev

Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
/*
2
  defines bob_point_map - class that is responsible for the tricky
3
  "point compression" when converting from binary to text
4
 
5
  it acts as kind of Search Tree but not binary search tree
6
 
7
  the map itself is created by linked list consisting of p_node objects.
8
  p_node means "point node" although it does not contain any point.
114 cycrow 9
  pp_node means "point point node" because it does contain bob_dom_vertex :)
1 cycrow 10
 
11
  if you add a point into this map:
12
 
13
  - I will take the X coordinate
114 cycrow 14
  - I will take its 1st byte (left most) of the coordinate and try to find it in the list.
1 cycrow 15
  Either I will find it or I will add new p_node object.
16
  - I will take the 2nd byte and try to find it in the previously returned p_node which
17
  is now the "base"
18
  - I will continue with the remaining 3 bytes
19
  - I will repeat this for Y and Z coordinates
20
  - when adding the last byte of the Z coordinate, the last object created is not p_node
21
  but pp_node which also contain the point we are adding to the map
22
 
23
  I "found" this "algorithm" when I looked at raw output of points coords exported in hexadecimal
24
 
25
  It should be rewritten to either AVL or Red Black Tree but I don't understand the way 2-3-4 trees
26
  (RB trees) are balanced and standard AVL trees are not exactly what I want because I would have to
27
  first find the point and then insert if unsuccessfull.
28
 
29
  Althouhg this map is not as fast as it would probaly could with binary search trees, it's still
30
  damned fast compared to linear search which I and CheckerTwo were using.
31
 
32
*/
33
 
34
#ifndef BOB_POINT_MAP_INCLUDED
35
#define BOB_POINT_MAP_INCLUDED
36
 
37
#include "../common/ext_array.h"
38
#include "../common/ext_simple_list.h"
39
 
40
//#include "bob_point_bst.h"
41
 
42
class bob_point_map
43
{
44
	private:
45
		struct p_node
46
		{
47
			unsigned char id;
48
			p_node *next;
49
			p_node *child;
50
 
51
			p_node() { next=0; child=0;  }
52
		};
53
 
54
		struct pp_node : public p_node
55
		{
56
			int index;
114 cycrow 57
			bob_vertex *pnt;
1 cycrow 58
			pp_node() { pnt=0; index=0; }
59
		};
60
 
61
		p_node m_root;
62
 
63
		p_node * addNode(p_node *parent, unsigned char id)
64
		{
65
			p_node *n, *old;
66
			for(n=parent->child; n!=NULL; old=n, n=n->next){
67
				m_compCount++;
68
				if(n->id==id) return n;
69
			}
70
			if(parent->child==NULL)
71
				n=parent->child=new p_node();
72
			else
73
				n=old->next=new p_node();
74
			n->id=id;
75
			return n;
76
		}
77
 
78
		pp_node * addPPNode(p_node *parent)
79
		{
80
			p_node *n, *old;
81
			pp_node *pp;
82
			for(n=parent->child; n!=NULL; old=n, n=n->next)
83
				;;
84
 
85
			if(parent->child==NULL)
86
				parent->child=pp=new pp_node();
87
			else
88
				old->next=pp=new pp_node();
89
			return pp;
90
		}
91
 
92
		p_node * findNode(p_node *parent, unsigned char id)
93
		{
94
			p_node *ch;
95
			for(ch=parent->child; ch!=NULL; ch=ch->next){
96
				if(ch->id==id) return ch;
97
			}
98
			return NULL;
99
		}
100
 
101
		void deleteChilds(p_node *parent)
102
		{
103
			p_node *ch, *old;
104
			for(old=0, ch=parent->child; ch!=NULL; old=ch, ch=ch->next){
105
				deleteChilds(ch);
106
				delete old;
107
			}
108
			delete old;
109
		}
110
 
111
	private:
114 cycrow 112
		typedef ext::array<bob_vertex*> point_array;
1 cycrow 113
		typedef ext::array<int> int_array;
114
		typedef ext::simple_list<int> int_list;
115
 
116
		point_array m_points; // all points
117
		int_array m_indexes; // converted indexes
118
		int m_pointSize; // size of points
119
 
120
		int_list m_uniqueIndexes; // list of indexes to unique points in points array
121
		int_list::iterator m_unique_it;
122
 
123
	public:
124
		class point_rec
125
		{
126
			private:
127
				const pp_node *m_node;
128
 
129
			public:
130
				point_rec(const pp_node *node) { m_node=node; }
131
				point_rec(const point_rec& other) { m_node=other.m_node; }
132
 
114 cycrow 133
				bob_vertex * operator *() { return m_node->pnt; }
1 cycrow 134
		};
135
 
136
		class point_bucket
137
		{
138
			private:
139
				size_t m_size;
140
				const pp_node *m_first;
141
 
142
			public:
143
				size_t size() const { return m_size; }
144
 
145
				point_bucket(const pp_node *first)
146
				{
147
					m_first=first;
148
					m_size=0;
149
					for(const p_node *n=m_first; n!=0; n=n->next)
150
						m_size++;
151
				}
152
 
153
				point_bucket(const point_bucket& other) { m_size=other.m_size; m_first=other.m_first; }
154
 
155
				int index() { return m_first->index; }
156
				void index(int idx) { ((pp_node*)m_first)->index=idx; }
157
 
158
				point_rec operator[](size_t idx)
159
				{
160
					size_t i;
161
					const p_node *n;
162
					for(n=m_first, i=0; i < idx; i++, n=n->next)
163
						;;
164
					return point_rec((const pp_node*)n);
165
				}
166
		};
167
	private:
114 cycrow 168
		point_bucket _addPoint(bob_vertex *pnt)
1 cycrow 169
		{
170
			p_node *n;
171
			int v;
172
			v=pnt->x;
173
			n=&m_root;
174
			unsigned char id;
175
			for(int i=3; i >= 0; i--){
176
				id=v >> (i * 8);
177
				n=addNode(n, id);
178
			}
179
 
180
			v=pnt->y;
181
			for(int i=3; i >= 0; i--){
182
				id=v >> (i * 8);
183
				n=addNode(n, id);
184
			}
185
 
186
			v=pnt->z;
187
			for(int i=3; i >= 0; i--){
188
				id=v >> (i * 8);
189
				n=addNode(n, id);
190
			}
191
 
192
			pp_node *pp=addPPNode(n);
193
			pp->pnt=pnt;
194
 
195
			return point_bucket((pp_node*)n->child);
196
		}
197
 
198
	public:
199
		typedef point_array::iterator iterator;
114 cycrow 200
		typedef point_array::const_iterator const_iterator;
1 cycrow 201
		typedef int_list::const_iterator const_index_iterator;
202
 
203
		iterator begin() { return m_points.begin(); }
204
		iterator end() { return m_points.end(); }
114 cycrow 205
 
206
		const_iterator begin() const { return m_points.begin(); }
207
		const_iterator end() const { return m_points.end(); }
1 cycrow 208
 
209
		const_index_iterator indexBegin() const { return m_uniqueIndexes.begin(); }
210
		const_index_iterator indexEnd() const { return m_uniqueIndexes.end(); }
211
 
212
		//>>>>>>>>>>>>>
213
		//bob_point_bst map2;
214
		//<<<<<<<<<<<<<
215
 
216
		size_t m_compCount;
217
 
218
		void create(size_t size)
219
		{
220
			m_points.resize(size, 0);
221
			m_indexes.resize(size);
222
			m_pointSize=0;
223
			m_compCount=0;
224
		}
225
 
114 cycrow 226
		void addPoint(bob_vertex * pnt)
1 cycrow 227
		{
228
			point_bucket pb=_addPoint(pnt);
229
 
230
			if(pb.size() == 1){
231
				pb.index((int)m_uniqueIndexes.size());
232
				m_uniqueIndexes.push_back(m_pointSize);
233
			}
234
			m_points[m_pointSize]=pnt;
235
			m_indexes[m_pointSize]=pb.index();
236
			m_pointSize++;
237
 
238
			//map2.addPoint(pnt);
239
		}
240
 
241
		// c-tor
242
		bob_point_map() { m_pointSize=0; m_unique_it=m_uniqueIndexes.end(); }
243
		// d-tor
244
		~bob_point_map() { clear(); }
245
 
246
		void clear()
247
		{
248
			deleteChilds(&m_root); m_root.child=0;
249
 
250
			for(point_array::iterator &it=m_points.begin(); it!=m_points.end(); ++it){
251
				delete *it;
252
			}
253
			m_points.clear();
254
			m_indexes.clear();
255
			m_pointSize=0;
256
 
257
			m_unique_it=m_uniqueIndexes.end();
258
		}
259
 
114 cycrow 260
		bob_vertex * operator[](int idx) { return m_points[idx]; }
261
		const bob_vertex * operator[](int idx) const { return m_points[idx]; }
1 cycrow 262
 
263
		int uniqueIndex(int idx) const { return (size_t)idx < m_points.size() ? m_indexes[idx] : -1; }
264
 
265
		size_t pointsSize() const { return m_points.size(); }
266
		size_t uniquePointsSize() const { return m_uniqueIndexes.size(); }
267
 
114 cycrow 268
		bob_vertex * nextUniquePoint()
1 cycrow 269
		{
270
			++m_unique_it;
114 cycrow 271
			bob_vertex *p=(m_unique_it!=m_uniqueIndexes.end() ? m_points[*m_unique_it] : 0);
1 cycrow 272
			return p;
273
		}
274
};
275
 
276
#endif // !defined(BOB_POINT_MAP_INCLUDED)