| 214 | }; |
| 215 | |
| 216 | class GraphWriter { |
| 217 | public: |
| 218 | static Status Save(Sqlite* db, SqliteTransaction* txn, IdAllocator* ids, |
| 219 | GraphDef* graph, uint64 now, int64 run_id, int64* graph_id) |
| 220 | SQLITE_EXCLUSIVE_TRANSACTIONS_REQUIRED(*db) { |
| 221 | TF_RETURN_IF_ERROR(ids->CreateNewId(graph_id)); |
| 222 | GraphWriter saver{db, txn, graph, now, *graph_id}; |
| 223 | saver.MapNameToNodeId(); |
| 224 | TF_RETURN_WITH_CONTEXT_IF_ERROR(saver.SaveNodeInputs(), "SaveNodeInputs"); |
| 225 | TF_RETURN_WITH_CONTEXT_IF_ERROR(saver.SaveNodes(), "SaveNodes"); |
| 226 | TF_RETURN_WITH_CONTEXT_IF_ERROR(saver.SaveGraph(run_id), "SaveGraph"); |
| 227 | return Status::OK(); |
| 228 | } |
| 229 | |
| 230 | private: |
| 231 | GraphWriter(Sqlite* db, SqliteTransaction* txn, GraphDef* graph, uint64 now, |
| 232 | int64 graph_id) |
| 233 | : db_(db), txn_(txn), graph_(graph), now_(now), graph_id_(graph_id) {} |
| 234 | |
| 235 | void MapNameToNodeId() { |
| 236 | size_t toto = static_cast<size_t>(graph_->node_size()); |
| 237 | name_copies_.reserve(toto); |
| 238 | name_to_node_id_.reserve(toto); |
| 239 | for (int node_id = 0; node_id < graph_->node_size(); ++node_id) { |
| 240 | // Copy name into memory region, since we call clear_name() later. |
| 241 | // Then wrap in StringPiece so we can compare slices without copy. |
| 242 | name_copies_.emplace_back(graph_->node(node_id).name()); |
| 243 | name_to_node_id_.emplace(name_copies_.back(), node_id); |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | Status SaveNodeInputs() { |
| 248 | const char* sql = R"sql( |
| 249 | INSERT INTO NodeInputs ( |
| 250 | graph_id, |
| 251 | node_id, |
| 252 | idx, |
| 253 | input_node_id, |
| 254 | input_node_idx, |
| 255 | is_control |
| 256 | ) VALUES (?, ?, ?, ?, ?, ?) |
| 257 | )sql"; |
| 258 | SqliteStatement insert; |
| 259 | TF_RETURN_IF_ERROR(db_->Prepare(sql, &insert)); |
| 260 | for (int node_id = 0; node_id < graph_->node_size(); ++node_id) { |
| 261 | const NodeDef& node = graph_->node(node_id); |
| 262 | for (int idx = 0; idx < node.input_size(); ++idx) { |
| 263 | StringPiece name = node.input(idx); |
| 264 | int64 input_node_id; |
| 265 | int64 input_node_idx = 0; |
| 266 | int64 is_control = 0; |
| 267 | size_t i = name.rfind(':'); |
| 268 | if (i != StringPiece::npos) { |
| 269 | if (!strings::safe_strto64(name.substr(i + 1, name.size() - i - 1), |
| 270 | &input_node_idx)) { |
| 271 | return errors::DataLoss("Bad NodeDef.input: ", name); |
| 272 | } |
| 273 | name.remove_suffix(name.size() - i); |
nothing calls this directly
no test coverage detected