summaryrefslogtreecommitdiff
path: root/src/commit/commit-algorithm.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/commit/commit-algorithm.hpp')
-rw-r--r--src/commit/commit-algorithm.hpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/commit/commit-algorithm.hpp b/src/commit/commit-algorithm.hpp
new file mode 100644
index 0000000..3bc89a7
--- /dev/null
+++ b/src/commit/commit-algorithm.hpp
@@ -0,0 +1,196 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _COMMIT_ALGORITHM_HPP_
+#define _COMMIT_ALGORITHM_HPP_
+#include <vector>
+#include <string>
+#include <queue>
+#include <tr1/memory>
+
+#include <cnode/cnode-util.hpp>
+#include <cstore/cpath.hpp>
+#include <cstore/ctemplate.hpp>
+
+// 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
+};
+
+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<std::string>& values,
+ const std::vector<CommitState>& 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<cstore::Ctemplate> def);
+ std::tr1::shared_ptr<cstore::Ctemplate> 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<cstore::Ctemplate> _def;
+ Cpath _commit_path;
+ CommitState _commit_state;
+ std::vector<std::string> _commit_values;
+ std::vector<CommitState> _commit_values_states;
+ std::pair<std::string, std::string> _commit_value;
+ std::pair<bool, bool> _commit_default;
+ bool _commit_create_failed;
+ bool _commit_child_delete_failed;
+ bool _commit_subtree_changed;
+};
+
+class PrioNode : public TreeNode<PrioNode> {
+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();
+
+#if 0
+ // XXX testing
+ void print(size_t lvl) {
+#define INDENT for(size_t xyz = 0; xyz < lvl; xyz++) { printf(" "); };
+ INDENT;
+ if (_node) {
+ printf("[%s]\n", _node->getCommitPath().to_string().c_str());
+ } else {
+ printf("[---]\n");
+ }
+ INDENT; printf("|cp[%s]\n",
+ (_cfg_parent
+ ? _cfg_parent->getCommitPath().to_string().c_str()
+ : NULL));
+ if (_node) {
+ INDENT; printf("======\n");
+ _node->rprint(lvl);
+ INDENT; printf("======\n");
+ }
+#undef INDENT
+ }
+ void rprint(size_t lvl) {
+ print(lvl);
+ for (size_t i = 0; i < numChildNodes(); i++) {
+ childAt(i)->rprint(lvl + 1);
+ }
+ }
+#endif
+
+private:
+ CfgNode *_node;
+ CfgNode *_cfg_parent;
+ bool _succeeded;
+ bool _subtree_failure;
+ bool _subtree_success;
+};
+
+template<bool for_delete> struct PrioNodeCmp {
+ inline bool operator()(PrioNode *a, PrioNode *b) {
+ return _is_after(a, b, Int2Type<for_delete>());
+ }
+
+ /* 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<false>) {
+ return (a->getPriority() > b->getPriority());
+ }
+ inline bool _is_after(PrioNode *a, PrioNode *b, Int2Type<true>) {
+ return (a->getPriority() < b->getPriority());
+ }
+};
+
+typedef std::priority_queue<PrioNode *, std::vector<PrioNode *>,
+ PrioNodeCmp<false> > PrioQueueT;
+typedef std::priority_queue<PrioNode *, std::vector<PrioNode *>,
+ PrioNodeCmp<true> > DelPrioQueueT;
+
+typedef std::pair<CommitState, std::tr1::shared_ptr<Cpath> >
+ CommittedPathT;
+typedef std::vector<CommittedPathT> CommittedPathListT;
+
+// exported functions
+CfgNode *getCommitTree(CfgNode *cfg1, CfgNode *cfg2, const Cpath& cur_path);
+bool isCommitPathEffective(Cstore& cs, const Cpath& pcomps,
+ std::tr1::shared_ptr<Ctemplate> def,
+ bool in_active, bool in_working);
+bool doCommit(Cstore& cs, CfgNode& cfg1, CfgNode& cfg2);
+
+} // namespace commit
+
+#endif /* _COMMIT_ALGORITHM_HPP_ */
+