ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Tree-M/PMT.cpp
Revision: 1.5
Committed: Sun May 27 13:40:57 2001 UTC (22 years, 11 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +0 -3 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include <cstdlib>
2
3 #include "MT/MT.h"
4 #include "MT/MTpredicate.h"
5 #include "PMT.h"
6
7 const PMT *current_pmt;
8 int IOread, IOwrite;
9 dist2sim hfunction; // argl. using c++ without any clue.
10
11 /*
12 static double *
13 kdup (double *k, int ndims)
14 {
15 double *n = new double [ndims];
16
17 memcpy (n, k, ndims * sizeof (double));
18 return n;
19 }
20 */
21
22 double *Object::data() const
23 {
24 double *d = new double [NDIMS];
25
26 for (int i = NDIMS; i--; )
27 d[i] = int2double(k[i]);
28
29 return d;
30 }
31
32 double Object::distance(const Object& other) const
33 {
34 if (ACC->distfast)
35 {
36 velem dist = 0;
37
38 for (int i = NDIMS; i--; )
39 {
40 long d = other.k[i] - k[i];
41
42 dist += (velem)(d*d);
43 }
44
45 return dist * ACC->distmul;
46 }
47 else
48 {
49 double dist = 0.;
50
51 for (int i = NDIMS; i--; )
52 {
53 double d = int2double(other.k[i]) - int2double(k[i]);
54
55 dist += (velem)(d*d);
56 }
57
58 return dist;
59 }
60 }
61
62
63 Object::Object(double *pkey)
64 {
65 k = new velem[NDIMS];
66
67 // discretize the vector
68 for (int i = NDIMS; i--; )
69 k[i] = double2int (pkey[i]);
70
71 free (pkey);
72 }
73
74 Object::Object(char *key)
75 {
76 unsigned char *c = (unsigned char *)key;
77
78 k = new velem [NDIMS];
79
80 for (int i = 0; i < NDIMS; i++)
81 {
82 velem elem = 0;
83
84 switch (ACC->elemsize)
85 {
86 case 4: elem |= *c++ << 24;
87 case 3: elem |= *c++ << 16;
88 case 2: elem |= *c++ << 8;
89 case 1: elem |= *c++ << 0;
90 break;
91 default:
92 abort ();
93 }
94
95 k[i] = elem;
96 }
97 }
98
99 void Object::Compress(char *key)
100 {
101 unsigned char *c = (unsigned char *)key;
102
103 for (int i = 0; i < NDIMS; i++)
104 {
105 velem elem = k[i];
106
107 switch (ACC->elemsize)
108 {
109 case 4: *c++ = (elem >> 24) & 0xff;
110 case 3: *c++ = (elem >> 16) & 0xff;
111 case 2: *c++ = (elem >> 8) & 0xff;
112 case 1: *c++ = (elem >> 0) & 0xff;
113 break;
114 default:
115 abort ();
116 }
117 }
118 }
119
120 #define SETCUR current_pmt = this
121
122 PMT::PMT(int ndims, double min, double max, double steps, unsigned int pagesize)
123 {
124 steps--;
125
126 assert (min <= 0);
127
128 this->ndims = ndims;
129 this->min = min;
130 this->max = max;
131 this->steps = steps;
132
133 this->vzero = (velem)floor (- min * steps / max);
134
135 if (steps < (1<<8))
136 elemsize = 1;
137 else if (steps < (1<<16))
138 elemsize = 2;
139 else if (steps < (1<<24))
140 elemsize = 3;
141 else
142 elemsize = 4;
143
144 maxDist = (max - min) * (max - min) * ndims;
145
146 if (elemsize <= 2
147 && floor (steps * steps * 0.5 + 1) < velem(1<<31) / velem(ndims))
148 {
149 distfast = 1;
150 distmul = maxDist / double(steps * steps * ndims);
151 }
152 else
153 distfast = 0;
154
155 SETCUR;
156 mt = new MT (pagesize);
157 }
158
159 PMT::~PMT()
160 {
161 SETCUR;
162 mt->Sync();
163 delete mt;
164 }
165
166 void PMT::create(const char *path)
167 {
168 SETCUR;
169 mt->Create(path);
170 }
171
172 void PMT::open(const char *path)
173 {
174 SETCUR;
175 mt->Open(path);
176 }
177
178 void PMT::insert(double *k, int data)
179 {
180 SETCUR;
181 Object o(k);
182 const MTkey key(o, 0, 0);
183 const MTentry entry(key, data);
184 mt->Insert(entry);
185 }
186
187 void PMT::sync()
188 {
189 SETCUR;
190 mt->Sync();
191 }
192
193 double PMT::distance(double *k1, double *k2) const
194 {
195 SETCUR;
196 Object o1(k1), o2(k2);
197 return o1.distance(o2);
198 }
199
200
201 void PMT::range(double *k, double r) const
202 {
203 SETCUR;
204 Object o(k);
205 Pred p(o);
206 SimpleQuery q(&p, r);
207 GiSTlist<MTentry *> res = mt->RangeSearch(q);
208
209 while(!res.IsEmpty())
210 {
211 MTentry *e = res.RemoveFront ();
212 double *data = e->Key()->obj.data ();
213 add_result(e->Ptr(), data, ndims);
214 delete data;
215 delete e;
216 }
217 }
218
219 void PMT::top(double *k, int n) const
220 {
221 SETCUR;
222 Object o(k);
223 Pred p(o);
224 TopQuery q(&p, n);
225 MTentry **res = mt->TopSearch(q);
226
227 for (int i=0; i < n; i++)
228 {
229 MTentry *e = res[i];
230 add_result(e->Ptr(), e->Key()->obj.data(), ndims);
231 delete e;
232 }
233 }
234
235 int PMT::maxlevel() const
236 {
237 SETCUR;
238 return mt->MaxLevel();
239 }