ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Tree-M/MT/MTentry.cpp
Revision: 1.1
Committed: Sun May 6 00:45:52 2001 UTC (23 years, 1 month ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*********************************************************************
2     * *
3     * Copyright (c) 1997,1998, 1999 *
4     * Multimedia DB Group and DEIS - CSITE-CNR, *
5     * University of Bologna, Bologna, ITALY. *
6     * *
7     * All Rights Reserved. *
8     * *
9     * Permission to use, copy, and distribute this software and its *
10     * documentation for NON-COMMERCIAL purposes and without fee is *
11     * hereby granted provided that this copyright notice appears in *
12     * all copies. *
13     * *
14     * THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE *
15     * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING *
16     * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, *
17     * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHOR *
18     * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A *
19     * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS *
20     * DERIVATIVES. *
21     * *
22     *********************************************************************/
23    
24     #include "MTentry.h"
25     #include "MT.h"
26    
27     tb_function TB_FUNCTION=MIN_R_INCR;
28    
29     int sizeofEntry() {
30     if(sizeofObject()) return(sizeofObject()+3*sizeof(double)+2*sizeof(BOOL)); // compressedEntry is: Object, rmin, rmax, distance, splitted, recomp
31     return 0;
32     }
33    
34     GiSTpenalty *
35     MTentry::Penalty(const GiSTentry &newEntry) const
36     {
37     double retval;
38     assert(newEntry.IsA()==MTENTRY_CLASS);
39     const MTentry& e=(const MTentry &)newEntry;
40     double dist=object().distance(e.object())+e.maxradius();
41    
42     // printf("Distance between %s & %s=%f\n", object().name, e.object().name, dist);
43     // return area enlargement
44     switch(TB_FUNCTION) {
45     case MIN_R_INCR: {
46     retval=dist-maxradius();
47     if(retval<0) retval=-maxDist()+dist;
48     // if the entry can fit in (more than) a node without enlarging its radius, we assign it to its nearest node
49     break;
50     }
51     case MIN_OVERLAP: {
52     retval=0;
53     for (int i=0; i<Node()->NumEntries(); i++) { // compute total overlap for this node
54     const MTentry& sibling=(const MTentry &)*(*(Node()))[i].Ptr();
55     double cost=sibling.maxradius()+dist-object().distance(sibling.object());
56    
57     retval+=MAX(cost, 0);
58     }
59     break;
60     }
61     }
62     // cout << "Penalty for " << newEntry << " in " << this << " = " << retval << " (distance = " << dist << ")" << endl;
63     return new MTpenalty(retval, dist);
64     }
65    
66     GiSTpenalty *
67     MTentry::Penalty(const GiSTentry &newEntry, MTpenalty *minPenalty) const
68     // in this case we can avoid to compute some distances by using some stored information:
69     // minPenalty (the minimum penalty achieved so far),
70     // newEntry.key->distance (the distance of the entry from the parent of this entry, stored in the SearchMinPenalty method),
71     // and maxradius.
72     {
73     double retval;
74     assert(newEntry.IsA()==MTENTRY_CLASS);
75     const MTentry& e=(const MTentry &)newEntry;
76     double dist;
77    
78     // printf("Distance between %s & %s=%f\n", object().name, e.object().name, dist);
79     // return area enlargement
80     switch(TB_FUNCTION) {
81     case MIN_R_INCR: {
82     if(((MTkey *)newEntry.Key())->distance>0) { // in this case is possible to prune some entries using triangular inequality
83     double distPen=fabs(((MTkey *)newEntry.Key())->distance-Key()->distance)-maxradius();
84     MTpenalty *tmpPen;
85    
86     if(distPen>=0) tmpPen=new MTpenalty(distPen, 0);
87     else tmpPen=new MTpenalty(distPen+maxradius()-maxDist(), 0);
88     if((minPenalty!=NULL)&&!((*tmpPen)<(*minPenalty))) {
89     delete tmpPen;
90     return new MTpenalty(MAXDOUBLE, 0); // ... and we avoid to compute this distance
91     }
92     delete tmpPen;
93     }
94     dist=object().distance(e.object())+e.maxradius(); // compute the distance
95     retval=dist-maxradius();
96     if(retval<0) retval=-maxDist()+dist;
97     // if the entry can fit in (more than) a node without enlarging its radius, we assign it to its nearest node
98     break;
99     }
100     case MIN_OVERLAP: {
101     retval=0;
102     dist=object().distance(e.object())+e.maxradius();
103     for (int i=0; i<Node()->NumEntries(); i++) { // compute total overlap for this node
104     const MTentry& sibling=(const MTentry &)*(*(Node()))[i].Ptr();
105     double cost=sibling.maxradius()+dist-object().distance(sibling.object());
106    
107     retval+=MAX(cost, 0);
108     }
109     break;
110     }
111     }
112     // cout << "Penalty for " << newEntry << " in " << this << " = " << retval << " (distance = " << dist << ")" << endl;
113     return new MTpenalty(retval, dist);
114     }
115    
116     GiSTcompressedEntry
117     MTentry::Compress() const
118     {
119     GiSTcompressedEntry compressedEntry;
120     double rmin=((MTkey *)key)->minradius(), rmax=((MTkey *)key)->maxradius(), dist=((MTkey *)key)->distance;
121     int sizeofObject=((MTkey *)key)->object().CompressedLength();
122     BOOL splitted=((MTkey *)key)->splitted, recomp=((MTkey *)key)->recomp;
123    
124     compressedEntry.key=new char[CompressedLength()];
125     ((MTkey *)key)->object().Compress(compressedEntry.key); // compress the object
126     memcpy(compressedEntry.key+sizeofObject, &rmin, sizeof(double));
127     memcpy(compressedEntry.key+sizeofObject+sizeof(double), &rmax, sizeof(double));
128     memcpy(compressedEntry.key+sizeofObject+2*sizeof(double), &dist, sizeof(double));
129     memcpy(compressedEntry.key+sizeofObject+3*sizeof(double), &splitted, sizeof(BOOL));
130     memcpy(compressedEntry.key+sizeofObject+3*sizeof(double)+sizeof(BOOL), &recomp, sizeof(BOOL));
131     // Object obj(compressedEntry.key); // decompress the object
132     compressedEntry.keyLen=CompressedLength();
133     compressedEntry.ptr=ptr;
134     return compressedEntry;
135     }
136    
137     void
138     MTentry::Decompress(const GiSTcompressedEntry entry)
139     {
140     Object obj(entry.key); // decompress the object
141     double rmin, rmax, dist;
142     int sizeofObject=obj.CompressedLength();
143     BOOL splitted, recomp;
144    
145     memcpy(&rmin, entry.key+sizeofObject, sizeof(double));
146     memcpy(&rmax, entry.key+sizeofObject+sizeof(double), sizeof(double));
147     memcpy(&dist, entry.key+sizeofObject+2*sizeof(double), sizeof(double));
148     memcpy(&dist, entry.key+sizeofObject+2*sizeof(double), sizeof(double));
149     memcpy(&splitted, entry.key+sizeofObject+3*sizeof(double), sizeof(BOOL));
150     memcpy(&recomp, entry.key+sizeofObject+3*sizeof(double)+sizeof(BOOL), sizeof(BOOL));
151     key=new MTkey(obj, rmin, rmax, dist, splitted, recomp);
152     ptr=entry.ptr;
153     }