Subversion Repositories spk

Rev

Go to most recent revision | Details | 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.
9
  pp_node means "point point node" because it does contain bob_dom_point :)
10
 
11
  if you add a point into this map:
12
 
13
  - I will take the X coordinate
14
  - I will take its 1th byte (left most) of the coordinate and try to find it in list.
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;
57
			bob_dom_point *pnt;
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:
112
		typedef ext::array<bob_dom_point*> point_array;
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
 
133
				bob_dom_point * operator *() { return m_node->pnt; }
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:
168
		point_bucket _addPoint(bob_dom_point *pnt)
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;
200
		typedef int_list::const_iterator const_index_iterator;
201
 
202
		iterator begin() { return m_points.begin(); }
203
		iterator end() { return m_points.end(); }
204
 
205
		const_index_iterator indexBegin() const { return m_uniqueIndexes.begin(); }
206
		const_index_iterator indexEnd() const { return m_uniqueIndexes.end(); }
207
 
208
		//>>>>>>>>>>>>>
209
		//bob_point_bst map2;
210
		//<<<<<<<<<<<<<
211
 
212
		size_t m_compCount;
213
 
214
		void create(size_t size)
215
		{
216
			m_points.resize(size, 0);
217
			m_indexes.resize(size);
218
			m_pointSize=0;
219
			m_compCount=0;
220
		}
221
 
222
		void addPoint(bob_dom_point * pnt)
223
		{
224
			point_bucket pb=_addPoint(pnt);
225
 
226
			if(pb.size() == 1){
227
				pb.index((int)m_uniqueIndexes.size());
228
				m_uniqueIndexes.push_back(m_pointSize);
229
			}
230
			m_points[m_pointSize]=pnt;
231
			m_indexes[m_pointSize]=pb.index();
232
			m_pointSize++;
233
 
234
			//map2.addPoint(pnt);
235
		}
236
 
237
		// c-tor
238
		bob_point_map() { m_pointSize=0; m_unique_it=m_uniqueIndexes.end(); }
239
		// d-tor
240
		~bob_point_map() { clear(); }
241
 
242
		void clear()
243
		{
244
			deleteChilds(&m_root); m_root.child=0;
245
 
246
			for(point_array::iterator &it=m_points.begin(); it!=m_points.end(); ++it){
247
				delete *it;
248
			}
249
			m_points.clear();
250
			m_indexes.clear();
251
			m_pointSize=0;
252
 
253
			m_unique_it=m_uniqueIndexes.end();
254
		}
255
 
256
		bob_dom_point * operator[](int idx) { return m_points[idx]; }
257
		const bob_dom_point * operator[](int idx) const { return m_points[idx]; }
258
 
259
		int uniqueIndex(int idx) const { return (size_t)idx < m_points.size() ? m_indexes[idx] : -1; }
260
 
261
		size_t pointsSize() const { return m_points.size(); }
262
		size_t uniquePointsSize() const { return m_uniqueIndexes.size(); }
263
 
264
		bob_dom_point * nextUniquePoint()
265
		{
266
			++m_unique_it;
267
			bob_dom_point *p=(m_unique_it!=m_uniqueIndexes.end() ? m_points[*m_unique_it] : 0);
268
			return p;
269
		}
270
};
271
 
272
#endif // !defined(BOB_POINT_MAP_INCLUDED)