00001
00023 #ifndef CAVITY_H_
00024 #define CAVITY_H_
00025
00026 #include "Tuple.h"
00027 #include "Element.h"
00028 #include <set>
00029 #include <vector>
00030
00031 class Cavity {
00032 typedef Galois::PerIterAllocTy::rebind<GNode>::other PerIterGNodeAlloc;
00033 typedef std::set<GNode, std::less<GNode>, PerIterGNodeAlloc> GNodeSet;
00034 typedef std::deque<GNode, PerIterGNodeAlloc> GNodeDeque;
00035
00036 Graph* graph;
00037
00038 GNodeSet oldNodes;
00039 GNodeSet deletingNodes;
00040 GNode node;
00041 Tuple tuple;
00042 Galois::PerIterAllocTy& _cnx;
00043
00044 public:
00045 typedef std::vector<GNode, PerIterGNodeAlloc> GNodeVector;
00046
00047 Cavity(Graph* g, GNode& n, Tuple& t, Galois::PerIterAllocTy& cnx):
00048 graph(g),
00049 oldNodes(std::less<GNode>(), cnx),
00050 deletingNodes(std::less<GNode>(), cnx),
00051 node(n),
00052 tuple(t),
00053 _cnx(cnx)
00054 {}
00055
00056 void build() {
00057 GNodeDeque frontier(_cnx);
00058
00059 frontier.push_back(node);
00060 while (!frontier.empty()){
00061 GNode curr = frontier.back();
00062 frontier.pop_back();
00063 for (Graph::neighbor_iterator ii = graph->neighbor_begin(curr, Galois::CHECK_CONFLICT),
00064 ee = graph->neighbor_end(curr, Galois::CHECK_CONFLICT);
00065 ii != ee; ++ii) {
00066 GNode neighbor = *ii;
00067 Element& neighborElement = neighbor.getData(Galois::CHECK_CONFLICT);
00068
00069 if (!graph->containsNode(neighbor) || neighbor == node || deletingNodes.find(neighbor) != deletingNodes.end()) {
00070 continue;
00071 }
00072 if (neighborElement.getBDim() && neighborElement.inCircle(tuple)) {
00073 deletingNodes.insert(neighbor);
00074 frontier.push_back(neighbor);
00075 } else {
00076 oldNodes.insert(curr);
00077 }
00078 }
00079 }
00080 }
00081
00082 void update(GNodeVector* newNodes){
00083 Element& nodeData = node.getData(Galois::NONE);
00084 nodeData.getTuples().pop_back();
00085
00086
00087 for (GNodeSet::iterator it=oldNodes.begin(); it != oldNodes.end(); it++)
00088 {
00089 GNode oldNode = *it;
00090 for (Graph::neighbor_iterator ii = graph->neighbor_begin(oldNode, Galois::NONE), ee = graph->neighbor_end(oldNode, Galois::NONE); ii != ee; ++ii)
00091 {
00092 GNode neighbor = *ii;
00093 Element& neighborElement = neighbor.getData(Galois::NONE);
00094 if (!neighborElement.getBDim() || !neighborElement.inCircle(tuple))
00095 {
00096
00097 int index = graph->getEdgeData(neighbor, oldNode, Galois::NONE);
00098
00099 Element e(tuple, neighborElement.getPoint(index), neighborElement.getPoint((index + 1) % 3));
00100 GNode nnode = graph->createNode(e);
00101 graph->addNode(nnode, Galois::NONE);
00102 graph->addEdge(nnode, neighbor, 1, Galois::NONE);
00103 graph->addEdge(neighbor, nnode, index, Galois::NONE);
00104
00105 newNodes->push_back(nnode);
00106 Element& nnode_data = nnode.getData(Galois::NONE);
00107
00108
00109 Element& oldNodeData = oldNode.getData(Galois::NONE);
00110 TupleList& ntuples = nnode_data.getTuples();
00111 TupleList& tuples = oldNodeData.getTuples();
00112 if (!tuples.empty()) {
00113 TupleList newTuples;
00114 for(TupleList::iterator list_iter = tuples.begin(); list_iter != tuples.end(); ++list_iter)
00115 {
00116 Tuple t=*list_iter;
00117 if (nnode_data.elementContains(t)) {
00118
00119 ntuples.push_back(t);
00120 } else {
00121 newTuples.push_back(t);
00122 }
00123 }
00124
00125 tuples.swap(newTuples);
00126 }
00127 }
00128 }
00129 }
00130
00131 for (int i=0; i<newNodes->size(); i++)
00132 {
00133 GNode n1 = (*newNodes)[i];
00134 Element& newNodeData = n1.getData(Galois::NONE);
00135 for (int j=i+1; j<newNodes->size(); j++)
00136 {
00137 if (i != j)
00138 {
00139 GNode n2 = (*newNodes)[j];;
00140 Element& e = n2.getData(Galois::NONE);
00141
00142 bool found = false;
00143 int indexForNewNode = -1;
00144 int indexForNode = -1;
00145
00146 for (int x=2; x>=1; x--) {
00147 for (int y=2; y>=1; y--) {
00148 if (newNodeData.getPoint(x) == e.getPoint(y)) {
00149 indexForNewNode = x & 2, indexForNode = y & 2, found = true;
00150 }
00151 }
00152 }
00153
00154 if (found)
00155 {
00156 graph->addEdge(n1, n2, indexForNewNode, Galois::CHECK_CONFLICT);
00157 graph->addEdge(n2, n1, indexForNode, Galois::CHECK_CONFLICT);
00158 }
00159 }
00160 }
00161 }
00162
00163 deletingNodes.insert(node);
00164
00165 int size = newNodes->size();
00166 for (GNodeSet::iterator iter = deletingNodes.begin();
00167 iter != deletingNodes.end(); ++iter) {
00168 GNode dnode = *iter;
00169 TupleList& tuples = dnode.getData(Galois::NONE).getTuples();
00170
00171 for(TupleList::reverse_iterator list_iter = tuples.rbegin(), end = tuples.rend(); list_iter != end; ++list_iter)
00172 {
00173 Tuple tup=*list_iter;
00174 for (int i = 0; i < size; i++) {
00175 Element& element = (*newNodes)[i].getData(Galois::NONE);
00176 if ((element.elementContains(tup))) {
00177 element.addTuple(tup);
00178 if (i != 0) {
00179 GNode newNode = (*newNodes)[i];
00180 (*newNodes)[i] = (*newNodes)[0];
00181 (*newNodes)[0] = newNode;
00182 }
00183 break;
00184 }
00185 }
00186 }
00187
00188 Element& nodeData = dnode.getData(Galois::NONE);
00189 nodeData.getTuples().clear();
00190 graph->removeNode(dnode, Galois::NONE);
00191 }
00192
00193 for (GNodeVector::iterator iter = newNodes->begin(); iter != newNodes->end(); )
00194 {
00195 if ((*iter).getData(Galois::NONE).getTuples().empty())
00196 iter = newNodes->erase(iter);
00197 else
00198 iter++;
00199 }
00200 }
00201 };
00202
00203 #endif