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