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

# User Rev Content
1 root 1.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 root 1.4 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 root 1.1 double Object::distance(const Object& other) const
33     {
34 root 1.4 if (ACC->distfast)
35     {
36     velem dist = 0;
37 root 1.1
38 root 1.4 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 root 1.1
55 root 1.4 dist += (velem)(d*d);
56     }
57 root 1.1
58 root 1.4 return dist;
59     }
60 root 1.1 }
61    
62 root 1.3
63     Object::Object(double *pkey)
64     {
65 root 1.4 k = new velem[NDIMS];
66 root 1.3
67     // discretize the vector
68     for (int i = NDIMS; i--; )
69 root 1.4 k[i] = double2int (pkey[i]);
70    
71     free (pkey);
72 root 1.3 }
73    
74 root 1.1 Object::Object(char *key)
75     {
76     unsigned char *c = (unsigned char *)key;
77    
78 root 1.4 k = new velem [NDIMS];
79 root 1.1
80     for (int i = 0; i < NDIMS; i++)
81     {
82 root 1.4 velem elem = 0;
83 root 1.1
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 root 1.4 k[i] = elem;
96 root 1.1 }
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 root 1.4 velem elem = k[i];
106 root 1.1
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 root 1.4 PMT::PMT(int ndims, double min, double max, double steps, unsigned int pagesize)
123 root 1.1 {
124 root 1.4 steps--;
125    
126     assert (min <= 0);
127    
128 root 1.1 this->ndims = ndims;
129     this->min = min;
130     this->max = max;
131     this->steps = steps;
132    
133 root 1.4 this->vzero = (velem)floor (- min * steps / max);
134    
135     if (steps < (1<<8))
136 root 1.1 elemsize = 1;
137 root 1.4 else if (steps < (1<<16))
138 root 1.1 elemsize = 2;
139 root 1.4 else if (steps < (1<<24))
140 root 1.1 elemsize = 3;
141     else
142     elemsize = 4;
143    
144     maxDist = (max - min) * (max - min) * ndims;
145    
146 root 1.4 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 root 1.1 SETCUR;
156 root 1.4 mt = new MT (pagesize);
157 root 1.1 }
158    
159     PMT::~PMT()
160     {
161     SETCUR;
162 root 1.4 mt->Sync();
163 root 1.1 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 root 1.4 void PMT::sync()
188     {
189     SETCUR;
190     mt->Sync();
191     }
192    
193 root 1.1 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 root 1.2 while(!res.IsEmpty())
210     {
211     MTentry *e = res.RemoveFront ();
212 root 1.4 double *data = e->Key()->obj.data ();
213     add_result(e->Ptr(), data, ndims);
214     delete data;
215 root 1.2 delete e;
216     }
217     }
218 root 1.1
219 root 1.2 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 root 1.1
227 root 1.2 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 root 1.1 }
234    
235 root 1.2 int PMT::maxlevel() const
236 root 1.1 {
237 root 1.2 SETCUR;
238     return mt->MaxLevel();
239 root 1.1 }