| 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 |