OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 # | |
3 # Copyright 2009 The Native Client Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can | |
5 # be found in the LICENSE file. | |
6 # Copyright 2009, Google Inc. | |
7 # | |
8 | |
9 """ | |
10 Table minimization algorithm. | |
11 """ | |
12 | |
13 def optimize_rows(rows): | |
14 """Breaks rows up into batches, and attempts to minimize each batch, | |
15 using _optimize_rows_for_single_action. | |
16 """ | |
17 rows_by_action = dict() | |
18 for row in rows: | |
19 if (row.action, row.arch) in rows_by_action: | |
20 rows_by_action[(row.action, row.arch)].append(row) | |
21 else: | |
22 rows_by_action[(row.action, row.arch)] = [row] | |
23 | |
24 optimized_rows = [] | |
25 for row_group in rows_by_action.itervalues(): | |
26 optimized_rows.extend(_optimize_rows_for_single_action(row_group)) | |
27 | |
28 _remove_unused_columns(optimized_rows) | |
29 return optimized_rows | |
30 | |
31 def _optimize_rows_for_single_action(rows): | |
32 """Performs basic automatic minimization on the given rows. | |
33 | |
34 Repeatedly selects a pair of rows to merge. Recurses until no suitable pair | |
35 can be found. It's not real smart, and is O(n^2). | |
36 | |
37 A pair of rows is compatible if all columns are equal, or if exactly one | |
38 row differs but is_strictly_compatible. | |
39 """ | |
40 for (i, j) in each_index_pair(rows): | |
41 row_i, row_j = rows[i], rows[j] | |
42 | |
43 if row_i.can_merge(row_j): | |
44 new_rows = list(rows) | |
45 del new_rows[j] | |
46 del new_rows[i] | |
47 new_rows.append(row_i + row_j) | |
48 return _optimize_rows_for_single_action(new_rows) | |
49 | |
50 # No changes made: | |
51 return rows | |
52 | |
53 def _remove_unused_columns(rows): | |
54 num_cols = len(rows[0].patterns) | |
55 used = [False] * num_cols | |
56 | |
57 for r in rows: | |
58 for i in range(0, num_cols): | |
59 if r.patterns[i].mask != 0: | |
60 used[i] = True | |
61 | |
62 if not True in used: | |
63 # Always preserve at least one column | |
64 used[0] = True | |
65 | |
66 for col in range(num_cols - 1, 0 - 1, -1): | |
67 for r in rows: | |
68 if not used[col]: | |
69 del r.patterns[col] | |
70 | |
71 | |
72 def each_index_pair(sequence): | |
73 """Utility function: Generates each unique index pair in sequence.""" | |
74 for i in range(0, len(sequence)): | |
75 for j in range(i + 1, len(sequence)): | |
76 yield (i, j) | |
OLD | NEW |