| 41 | |
| 42 | template<class View> |
| 43 | forceinline ExecStatus |
| 44 | Graph<View>::init(Space& home, ViewArray<View>& x) { |
| 45 | using namespace ViewValGraph; |
| 46 | n_view = x.size(); |
| 47 | view = home.alloc<ViewNode<View>*>(n_view); |
| 48 | |
| 49 | // Find value information for construction of view value graph |
| 50 | int min = x[0].min(); |
| 51 | int max = x[0].max(); |
| 52 | for (int i=1; i<n_view; i++) { |
| 53 | min = std::min(min,x[i].min()); |
| 54 | max = std::max(max,x[i].max()); |
| 55 | } |
| 56 | |
| 57 | unsigned int width = static_cast<unsigned int>(max-min+1); |
| 58 | |
| 59 | // Definitely not enough values |
| 60 | if (width < static_cast<unsigned int>(n_view)) |
| 61 | return ES_FAILED; |
| 62 | |
| 63 | // Initialize view nodes |
| 64 | for (int i=0; i<n_view; i++) |
| 65 | view[i] = new (home) ViewNode<View>(x[i]); |
| 66 | |
| 67 | Region r; |
| 68 | |
| 69 | if (static_cast<unsigned int>(n_view)*4 >= width) { |
| 70 | // Values are dense: use a mapping |
| 71 | ValNode<View>** val2node = r.alloc<ValNode<View>* >(width); |
| 72 | |
| 73 | for (unsigned int i=0U; i<width; i++) |
| 74 | val2node[i]=nullptr; |
| 75 | |
| 76 | for (int i=0; i<n_view; i++) { |
| 77 | Edge<View>** edge_p = view[i]->val_edges_ref(); |
| 78 | for (ViewValues<View> xi(x[i]); xi(); ++xi) { |
| 79 | if (val2node[xi.val()-min] == nullptr) |
| 80 | val2node[xi.val()-min] = new (home) ValNode<View>(xi.val()); |
| 81 | *edge_p = new (home) Edge<View>(val2node[xi.val()-min],view[i]); |
| 82 | edge_p = (*edge_p)->next_edge_ref(); |
| 83 | } |
| 84 | *edge_p = nullptr; |
| 85 | } |
| 86 | |
| 87 | for (unsigned int i=width; i--; ) |
| 88 | if (val2node[i] != nullptr) { |
| 89 | val2node[i]->next_val(val); |
| 90 | val = val2node[i]; |
| 91 | n_val++; |
| 92 | } |
| 93 | |
| 94 | } else { |
| 95 | // Values are sparse |
| 96 | for (int i=0; i<n_view; i++) |
| 97 | ViewValGraph::Graph<View>::init(home,view[i]); |
| 98 | } |
| 99 | |
| 100 | if (n_val < n_view) |
no test coverage detected