| 492 | } |
| 493 | |
| 494 | const Edge* Graph::AddEdge(Node* source, int x, Node* dest, int y) { |
| 495 | TF_DCHECK_OK(IsValidNode(source)) << source->DebugString(); |
| 496 | TF_DCHECK_OK(IsValidNode(dest)) << dest->DebugString(); |
| 497 | |
| 498 | // source/sink must only be linked via control slots, and |
| 499 | // control slots must only be linked to control slots. |
| 500 | if (source == source_node() || dest == sink_node() || x == kControlSlot || |
| 501 | y == kControlSlot) { |
| 502 | DCHECK_EQ(x, kControlSlot) << source->DebugString(); |
| 503 | DCHECK_EQ(y, kControlSlot) << dest->DebugString(); |
| 504 | } |
| 505 | |
| 506 | Edge* e = nullptr; |
| 507 | if (free_edges_.empty()) { |
| 508 | e = new (arena_.Alloc(sizeof(Edge))) Edge; // placement new |
| 509 | } else { |
| 510 | e = free_edges_.back(); |
| 511 | free_edges_.pop_back(); |
| 512 | } |
| 513 | e->id_ = edges_.size(); |
| 514 | e->src_ = source; |
| 515 | e->dst_ = dest; |
| 516 | e->src_output_ = x; |
| 517 | e->dst_input_ = y; |
| 518 | CHECK(source->out_edges_.insert(e).second); |
| 519 | CHECK(dest->in_edges_.insert(e).second); |
| 520 | edges_.push_back(e); |
| 521 | ++num_edges_; |
| 522 | return e; |
| 523 | } |
| 524 | |
| 525 | void Graph::RemoveEdge(const Edge* e) { |
| 526 | TF_DCHECK_OK(IsValidNode(e->src_)) << e->src_->DebugString(); |