1 /**************************************************************************
2 ***
3 *** Copyright (c) 2000-2006 Regents of the University of Michigan,
4 ***               Saurabh N. Adya, Hayward Chan, Jarrod A. Roy
5 ***               and Igor L. Markov
6 ***
7 ***  Contact author(s): sadya@umich.edu, imarkov@umich.edu
8 ***  Original Affiliation:   University of Michigan, EECS Dept.
9 ***                          Ann Arbor, MI 48109-2122 USA
10 ***
11 ***  Permission is hereby granted, free of charge, to any person obtaining
12 ***  a copy of this software and associated documentation files (the
13 ***  "Software"), to deal in the Software without restriction, including
14 ***  without limitation
15 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 ***  and/or sell copies of the Software, and to permit persons to whom the
17 ***  Software is furnished to do so, subject to the following conditions:
18 ***
19 ***  The above copyright notice and this permission notice shall be included
20 ***  in all copies or substantial portions of the Software.
21 ***
22 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
24 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
27 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
28 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 ***
30 ***
31 ***************************************************************************/
32 
33 #ifndef BTREECOMPACT_H
34 #define BTREECOMPACT_H
35 
36 #include <algorithm>
37 
38 #include "btree.h"
39 
40 namespace parquetfp {
41 
42 // --------------------------------------------------------
43 class BTreeCompactor : public BTree
44 {
45  public:
46   inline BTreeCompactor(const BTree& orig_tree);
47   inline void operator=(const BTree& new_tree);
48   inline void slimAssign(const BTree& new_tree);  // suffices if evaluation
49                                                   // follows
50 
51   inline int compact();
52   void build_orth_tree();
53 
54   const std::vector<BTreeNode>& orth_tree;
55 
56   void out_orth_dot(const std::string& file) const;
57   void out_orth_plot(const std::string& file) const;
58 
59  private:
60   std::vector<BTreeNode> in_orth_tree;  // [NUM_BLOCKS] ~ in_tree[NUM_BLOCKS+1]
61                                         // [NUM_BLOCKS+1] ~ in_tree[NUM_BLOCKS]
62 
63   void build_orth_tree_add_block(int treePtr);
64 
65   // (a) swap NUM_BLK vs. NUM_BLK+1
66   // (b) fix parent of BL-block
67   // used by build_orth_tree() only!!!
68   inline static void fix_orth_tree(std::vector<BTreeNode>& orth_tree);
69 };
70 // --------------------------------------------------------
71 
72 // =========================
73 //      IMPLEMENTATIONS
74 // =========================
BTreeCompactor(const BTree & orig_tree)75 BTreeCompactor::BTreeCompactor(const BTree& orig_tree)
76     : BTree(orig_tree),
77       orth_tree(in_orth_tree),
78       in_orth_tree(orig_tree.tree.size())
79 {
80   int vec_size = in_orth_tree.size();
81   for (int i = 0; i < vec_size; i++) {
82     in_orth_tree[i].parent = Undefined;
83     in_orth_tree[i].left = Undefined;
84     in_orth_tree[i].right = Undefined;
85     in_orth_tree[i].block_index = orig_tree.tree[i].block_index;
86     in_orth_tree[i].orient = OrientedPacking::flip(
87         OrientedPacking::ORIENT(orig_tree.tree[i].orient));
88   }
89 }
90 // --------------------------------------------------------
91 inline void BTreeCompactor::operator=(const BTree& new_tree)
92 {
93   this->BTree::operator=(new_tree);
94   for (unsigned int i = 0; i < in_orth_tree.size(); i++) {
95     in_orth_tree[i].parent = Undefined;
96     in_orth_tree[i].left = Undefined;
97     in_orth_tree[i].right = Undefined;
98     in_orth_tree[i].block_index = new_tree.tree[i].block_index;
99     in_orth_tree[i].orient = OrientedPacking::flip(
100         OrientedPacking::ORIENT(new_tree.tree[i].orient));
101   }
102 }
103 // --------------------------------------------------------
slimAssign(const BTree & new_tree)104 inline void BTreeCompactor::slimAssign(const BTree& new_tree)
105 {
106   in_tree = new_tree.tree;
107   in_blockArea = new_tree.blockArea();
108   for (unsigned int i = 0; i < in_orth_tree.size(); i++) {
109     in_orth_tree[i].parent = Undefined;
110     in_orth_tree[i].left = Undefined;
111     in_orth_tree[i].right = Undefined;
112     in_orth_tree[i].block_index = new_tree.tree[i].block_index;
113     in_orth_tree[i].orient = OrientedPacking::flip(
114         OrientedPacking::ORIENT(new_tree.tree[i].orient));
115   }
116 }
117 // --------------------------------------------------------
compact()118 inline int BTreeCompactor::compact()
119 {
120   if (getNumObstacles()) {
121     // <aaronnn> if obstacles are present, don't allow compaction
122     return 0;
123   }
124 
125   std::vector<float> orig_xloc(in_xloc);
126   std::vector<float> orig_yloc(in_yloc);
127 
128   build_orth_tree();
129   swap_ranges(in_tree.begin(), in_tree.end(), in_orth_tree.begin());
130 
131   //   save_dot("compact-1_orig.dot");
132   //   save_plot("compact-1_orig.plot");
133   //   out_orth_dot("compact-1_orth.dot");
134   //   out_orth_plot("compact-1_orth.plot");
135 
136   //    cout << "-----here1: after build_orth_tree()-----" << endl;
137   //    cout << "in_tree: " << endl;
138   //    OutputBTree(cout, in_tree);
139   //    cout << endl << endl;
140   //    cout << "in_orth_tree:" << endl;
141   //    OutputBTree(cout, in_orth_tree);
142   //    cout << endl << endl;
143 
144   build_orth_tree();
145   swap_ranges(in_tree.begin(), in_tree.end(), in_orth_tree.begin());
146 
147   //   save_dot("compact-2_orig.dot");
148   //   save_plot("compact-2_orig.plot");
149   //   out_orth_dot("compact-2_orth.dot");
150   //   out_orth_plot("compact-2_orth.plot");
151   //    cout << "-----here2: after build_orth_tree()-----" << endl;
152   //    cout << "in_tree: " << endl;
153   //    OutputBTree(cout, in_tree);
154   //    cout << endl << endl;
155   //    cout << "in_orth_tree: " << endl;
156   //    OutputBTree(cout, in_orth_tree);
157   //    cout << endl << endl;
158   //    cout << "-----flipped packing-----" << endl;
159   //    OutputPacking(cout, BTreeOrientedPacking(*this));
160 
161   //    ofstream outfile;
162   //    outfile.open("dummy_flipped");
163   //    Save_bbb(outfile, BTreeOrientedPacking(*this));
164   //    outfile.close();
165 
166   build_orth_tree();
167 
168   //   save_dot("compact-3_orig.dot");
169   //   save_plot("compact-3_orig.plot");
170   //   out_orth_dot("compact-3_orth.dot");
171   //   out_orth_plot("compact-3_orth.plot");
172 
173   //     exit(1);
174 
175   int count = 0;
176   for (int i = 0; i < NUM_BLOCKS; i++) {
177     if ((orig_xloc[i] != in_xloc[i]) || (orig_yloc[i] != in_yloc[i]))
178       count++;
179   }
180   return count;
181 }
182 // --------------------------------------------------------
fix_orth_tree(std::vector<BTree::BTreeNode> & orth_tree)183 inline void BTreeCompactor::fix_orth_tree(
184     std::vector<BTree::BTreeNode>& orth_tree)
185 {
186   // fix the tree s.t. in_tree[NUM_BLOCKS] corresponds to the root
187   const int NUM_BLOCKS = orth_tree.size() - 2;
188   int bottomLeftBlock = orth_tree[NUM_BLOCKS + 1].left;
189 
190   orth_tree[bottomLeftBlock].parent = NUM_BLOCKS;
191   std::iter_swap(&(orth_tree[NUM_BLOCKS]), &(orth_tree[NUM_BLOCKS + 1]));
192 }
193 
194 // --------------------------------------------------------
195 
196 }  // namespace parquetfp
197 
198 #endif
199