/* * Copyright (C) 2011 Vyatta, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _COMMIT_ALGORITHM_HPP_ #define _COMMIT_ALGORITHM_HPP_ #include #include #include #include #include #include #include // forward decl namespace cnode { class CfgNode; } namespace cstore { class Cstore; } namespace commit { using namespace cnode; using namespace cstore; enum CommitState { COMMIT_STATE_UNCHANGED, COMMIT_STATE_ADDED, COMMIT_STATE_DELETED, COMMIT_STATE_CHANGED }; enum CommitTreeTraversalOrder { PRE_ORDER, POST_ORDER }; enum CommitHook { PRE_COMMIT, POST_COMMIT, LAST // not a valid hook }; class CommitData { public: CommitData(); virtual ~CommitData() {} // setters void setCommitState(CommitState s); void setCommitPath(const Cpath& p, bool is_val, const std::string& val, const std::string& name); void setCommitMultiValues(const std::vector& values, const std::vector& states); void setCommitValue(const std::string& val1, const std::string& val2, bool def1, bool def2); void setCommitChildDeleteFailed(); void setCommitCreateFailed(); void setCommitSubtreeChanged(); // getters CommitState getCommitState() const; Cpath getCommitPath() const; size_t numCommitMultiValues() const; std::string commitMultiValueAt(size_t idx) const; CommitState commitMultiStateAt(size_t idx) const; std::string commitValueBefore() const; std::string commitValueAfter() const; bool commitChildDeleteFailed() const; bool commitCreateFailed() const; bool commitSubtreeChanged() const; // for tmpl stuff void setTmpl(std::tr1::shared_ptr def); std::tr1::shared_ptr getTmpl() const; const vtw_def *getDef() const; unsigned int getPriority() const; void setPriority(unsigned int p); const vtw_node *getActions(vtw_act_type act, bool raw = false) const; bool isBeginEndNode() const; private: std::tr1::shared_ptr _def; Cpath _commit_path; CommitState _commit_state; std::vector _commit_values; std::vector _commit_values_states; std::pair _commit_value; std::pair _commit_default; bool _commit_create_failed; bool _commit_child_delete_failed; bool _commit_subtree_changed; }; class PrioNode : public TreeNode { public: PrioNode(CfgNode *n); ~PrioNode() {} CfgNode *getCfgNode(); unsigned int getPriority() const; CommitState getCommitState() const; Cpath getCommitPath() const; bool parentCreateFailed() const; bool succeeded() const; bool hasSubtreeFailure() const; bool hasSubtreeSuccess() const; void setCfgParent(CfgNode *p); void setSucceeded(bool succeeded); void setSubtreeFailure(); void setSubtreeSuccess(); private: CfgNode *_node; CfgNode *_cfg_parent; bool _succeeded; bool _subtree_failure; bool _subtree_success; }; template struct PrioNodeCmp { inline bool operator()(PrioNode *a, PrioNode *b) { return _is_after(a, b, Int2Type()); } /* note: if comparing "for delete", use "<". if not for delete, use ">". * if two nodes have the same priority, the ordering between them * is not defined, i.e., can be either. */ inline bool _is_after(PrioNode *a, PrioNode *b, Int2Type) { return (a->getPriority() > b->getPriority()); } inline bool _is_after(PrioNode *a, PrioNode *b, Int2Type) { return (a->getPriority() < b->getPriority()); } }; typedef std::priority_queue, PrioNodeCmp > PrioQueueT; typedef std::priority_queue, PrioNodeCmp > DelPrioQueueT; typedef std::pair > CommittedPathT; typedef std::vector CommittedPathListT; // exported functions const char *getCommitHookDir(CommitHook hook); CfgNode *getCommitTree(CfgNode *cfg1, CfgNode *cfg2, const Cpath& cur_path); bool isCommitPathEffective(Cstore& cs, const Cpath& pcomps, std::tr1::shared_ptr def, bool in_active, bool in_working); bool doCommit(Cstore& cs, CfgNode& cfg1, CfgNode& cfg2); } // namespace commit #endif /* _COMMIT_ALGORITHM_HPP_ */