summaryrefslogtreecommitdiff
path: root/src/cnode
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2011-03-17 11:48:54 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2011-03-17 11:48:54 -0700
commiteb9f5718d412022015bb65eb08c30785c79e79e6 (patch)
treebe0b6a9de27965e39c44c5c8a88adf9caa13abf8 /src/cnode
parentcda3f423c311fd30e8cc24e2de67d99baf352b2a (diff)
downloadvyatta-cfg-eb9f5718d412022015bb65eb08c30785c79e79e6.tar.gz
vyatta-cfg-eb9f5718d412022015bb65eb08c30785c79e79e6.zip
add config path abstraction and high-level caching
* part of the config backend cleanup/optimization work. * improves the performance of "load" (w/o commit) by ~55% and "show" by ~15%.
Diffstat (limited to 'src/cnode')
-rw-r--r--src/cnode/cnode-algorithm.cpp126
-rw-r--r--src/cnode/cnode-algorithm.hpp16
-rw-r--r--src/cnode/cnode.cpp25
-rw-r--r--src/cnode/cnode.hpp26
4 files changed, 91 insertions, 102 deletions
diff --git a/src/cnode/cnode-algorithm.cpp b/src/cnode/cnode-algorithm.cpp
index 9256e7c..c6b91f9 100644
--- a/src/cnode/cnode-algorithm.cpp
+++ b/src/cnode/cnode-algorithm.cpp
@@ -40,14 +40,13 @@ const string cnode::WORKING_CFG = "@WORKING";
////// static (internal) functions
static void
_show_diff(const CfgNode *cfg1, const CfgNode *cfg2, int level,
- vector<string>& cur_path, vector<string>& last_ctx,
- bool show_def, bool hide_secret, bool context_diff);
+ Cpath& cur_path, Cpath& last_ctx, bool show_def,
+ bool hide_secret, bool context_diff);
static void
_get_cmds_diff(const CfgNode *cfg1, const CfgNode *cfg2,
- vector<string>& cur_path, vector<vector<string> >& del_list,
- vector<vector<string> >& set_list,
- vector<vector<string> >& com_list);
+ Cpath& cur_path, vector<Cpath>& del_list,
+ vector<Cpath>& set_list, vector<Cpath>& com_list);
/* compare the values of a "multi" node in the two configs. the values and
* the "prefix" of each value are returned in "values" and "pfxs",
@@ -155,21 +154,21 @@ _cmp_non_leaf_nodes(const CfgNode *cfg1, const CfgNode *cfg2,
}
static void
-_add_path_to_list(vector<vector<string> >& list, vector<string>& path,
- const string *nptr, const string *vptr)
+_add_path_to_list(vector<Cpath>& list, Cpath& path, const string *nptr,
+ const string *vptr)
{
if (nptr) {
- path.push_back(*nptr);
+ path.push(*nptr);
}
if (vptr) {
- path.push_back(*vptr);
+ path.push(*vptr);
}
list.push_back(path);
if (vptr) {
- path.pop_back();
+ path.pop();
}
if (nptr) {
- path.pop_back();
+ path.pop();
}
}
@@ -221,7 +220,7 @@ _diff_print_indent(const CfgNode *cfg1, const CfgNode *cfg2, int level,
* like in JUNOS "show | compare".
*/
static void
-_diff_print_context(vector<string>& cur_path, vector<string>& last_ctx)
+_diff_print_context(Cpath& cur_path, Cpath& last_ctx)
{
if (last_ctx == cur_path) {
// don't repeat the context if it's still the same as the last one
@@ -230,7 +229,7 @@ _diff_print_context(vector<string>& cur_path, vector<string>& last_ctx)
last_ctx = cur_path;
printf("[edit");
for (size_t i = 0; i < cur_path.size(); i++) {
- printf(" %s", cur_path[i].c_str());
+ printf(" %s", cur_path[i]);
}
printf("]\n");
}
@@ -249,8 +248,7 @@ _diff_print_context(vector<string>& cur_path, vector<string>& last_ctx)
*/
static bool
_diff_print_comment(const CfgNode *cfg1, const CfgNode *cfg2, int level,
- vector<string>& cur_path, vector<string>& last_ctx,
- bool context_diff)
+ Cpath& cur_path, Cpath& last_ctx, bool context_diff)
{
const char *pfx_diff = PFX_DIFF_NONE.c_str();
string comment = "";
@@ -307,8 +305,8 @@ _diff_print_comment(const CfgNode *cfg1, const CfgNode *cfg2, int level,
static bool
_diff_check_and_show_leaf(const CfgNode *cfg1, const CfgNode *cfg2, int level,
- vector<string>& cur_path, vector<string>& last_ctx,
- bool show_def, bool hide_secret, bool context_diff)
+ Cpath& cur_path, Cpath& last_ctx, bool show_def,
+ bool hide_secret, bool context_diff)
{
if ((cfg1 && !cfg1->isLeaf()) || (cfg2 && !cfg2->isLeaf())) {
// not a leaf node
@@ -424,8 +422,8 @@ _diff_check_and_show_leaf(const CfgNode *cfg1, const CfgNode *cfg2, int level,
static void
_diff_show_other(const CfgNode *cfg1, const CfgNode *cfg2, int level,
- vector<string>& cur_path, vector<string>& last_ctx,
- bool show_def, bool hide_secret, bool context_diff)
+ Cpath& cur_path, Cpath& last_ctx, bool show_def,
+ bool hide_secret, bool context_diff)
{
bool orig_cdiff = context_diff;
const char *pfx_diff = PFX_DIFF_NONE.c_str();
@@ -522,9 +520,9 @@ _diff_show_other(const CfgNode *cfg1, const CfgNode *cfg2, int level,
}
}
- cur_path.push_back(name);
+ cur_path.push(name);
if (is_value) {
- cur_path.push_back(value);
+ cur_path.push(value);
}
} else {
next_level = (level >= 0 ? level : 0);
@@ -537,9 +535,9 @@ _diff_show_other(const CfgNode *cfg1, const CfgNode *cfg2, int level,
// finish printing "this" node if necessary
if (print_this) {
- cur_path.pop_back();
+ cur_path.pop();
if (is_value) {
- cur_path.pop_back();
+ cur_path.pop();
}
if (!orig_cdiff || pfx_diff != PFX_DIFF_NONE.c_str()) {
/* not context diff OR there is a difference => print closing '}'
@@ -556,8 +554,8 @@ _diff_show_other(const CfgNode *cfg1, const CfgNode *cfg2, int level,
static void
_show_diff(const CfgNode *cfg1, const CfgNode *cfg2, int level,
- vector<string>& cur_path, vector<string>& last_ctx,
- bool show_def, bool hide_secret, bool context_diff)
+ Cpath& cur_path, Cpath& last_ctx, bool show_def,
+ bool hide_secret, bool context_diff)
{
// if doesn't exist, treat as NULL
if (cfg1 && !cfg1->exists()) {
@@ -613,8 +611,8 @@ _show_diff(const CfgNode *cfg1, const CfgNode *cfg2, int level,
static void
_get_comment_diff_cmd(const CfgNode *cfg1, const CfgNode *cfg2,
- vector<string>& cur_path,
- vector<vector<string> >& com_list, const string *val)
+ Cpath& cur_path, vector<Cpath>& com_list,
+ const string *val)
{
const string *comment = NULL;
const string *name = NULL;
@@ -652,22 +650,20 @@ _get_comment_diff_cmd(const CfgNode *cfg1, const CfgNode *cfg2,
}
if (comment) {
if (val) {
- cur_path.push_back(*name);
+ cur_path.push(*name);
name = val;
}
_add_path_to_list(com_list, cur_path, name, comment);
if (val) {
- cur_path.pop_back();
+ cur_path.pop();
}
}
}
static bool
_get_cmds_diff_leaf(const CfgNode *cfg1, const CfgNode *cfg2,
- vector<string>& cur_path,
- vector<vector<string> >& del_list,
- vector<vector<string> >& set_list,
- vector<vector<string> >& com_list)
+ Cpath& cur_path, vector<Cpath>& del_list,
+ vector<Cpath>& set_list, vector<Cpath>& com_list)
{
if ((cfg1 && !cfg1->isLeaf()) || (cfg2 && !cfg2->isLeaf())) {
// not a leaf node
@@ -675,7 +671,7 @@ _get_cmds_diff_leaf(const CfgNode *cfg1, const CfgNode *cfg2,
}
const CfgNode *cfg = NULL;
- vector<vector<string> > *list = NULL;
+ vector<Cpath> *list = NULL;
if (cfg1) {
cfg = cfg1;
if (!cfg2) {
@@ -736,12 +732,10 @@ _get_cmds_diff_leaf(const CfgNode *cfg1, const CfgNode *cfg2,
static void
_get_cmds_diff_other(const CfgNode *cfg1, const CfgNode *cfg2,
- vector<string>& cur_path,
- vector<vector<string> >& del_list,
- vector<vector<string> >& set_list,
- vector<vector<string> >& com_list)
+ Cpath& cur_path, vector<Cpath>& del_list,
+ vector<Cpath>& set_list, vector<Cpath>& com_list)
{
- vector<vector<string> > *list = NULL;
+ vector<Cpath> *list = NULL;
if (cfg1) {
if (!cfg2) {
// exists in cfg1 but not in cfg2 => delete and stop recursion
@@ -773,9 +767,9 @@ _get_cmds_diff_other(const CfgNode *cfg1, const CfgNode *cfg2,
const string *val = (is_value ? &value : NULL);
_get_comment_diff_cmd(cfg1, cfg2, cur_path, com_list, val);
- cur_path.push_back(name);
+ cur_path.push(name);
if (is_value) {
- cur_path.push_back(value);
+ cur_path.push(value);
}
}
for (size_t i = 0; i < rcnodes1.size(); i++) {
@@ -784,17 +778,16 @@ _get_cmds_diff_other(const CfgNode *cfg1, const CfgNode *cfg2,
}
if (add_this) {
if (is_value) {
- cur_path.pop_back();
+ cur_path.pop();
}
- cur_path.pop_back();
+ cur_path.pop();
}
}
static void
_get_cmds_diff(const CfgNode *cfg1, const CfgNode *cfg2,
- vector<string>& cur_path, vector<vector<string> >& del_list,
- vector<vector<string> >& set_list,
- vector<vector<string> >& com_list)
+ Cpath& cur_path, vector<Cpath>& del_list,
+ vector<Cpath>& set_list, vector<Cpath>& com_list)
{
// if doesn't exist, treat as NULL
if (cfg1 && !cfg1->exists()) {
@@ -820,12 +813,12 @@ _get_cmds_diff(const CfgNode *cfg1, const CfgNode *cfg2,
}
static void
-_print_cmds_list(const char *op, vector<vector<string> >& list)
+_print_cmds_list(const char *op, vector<Cpath>& list)
{
for (size_t i = 0; i < list.size(); i++) {
printf("%s", op);
for (size_t j = 0; j < list[i].size(); j++) {
- printf(" '%s'", list[i][j].c_str());
+ printf(" '%s'", list[i][j]);
}
printf("\n");
}
@@ -834,8 +827,8 @@ _print_cmds_list(const char *op, vector<vector<string> >& list)
////// algorithms
void
cnode::show_cfg_diff(const CfgNode& cfg1, const CfgNode& cfg2,
- vector<string>& cur_path, bool show_def,
- bool hide_secret, bool context_diff)
+ Cpath& cur_path, bool show_def, bool hide_secret,
+ bool context_diff)
{
if (cfg1.isInvalid() || cfg2.isInvalid()) {
printf("Specified configuration path is not valid\n");
@@ -847,7 +840,7 @@ cnode::show_cfg_diff(const CfgNode& cfg1, const CfgNode& cfg2,
return;
}
// use an invalid value for initial last_ctx
- vector<string> last_ctx(1, "");
+ Cpath last_ctx;
_show_diff(&cfg1, &cfg2, -1, cur_path, last_ctx, show_def, hide_secret,
context_diff);
}
@@ -855,17 +848,17 @@ cnode::show_cfg_diff(const CfgNode& cfg1, const CfgNode& cfg2,
void
cnode::show_cfg(const CfgNode& cfg, bool show_def, bool hide_secret)
{
- vector<string> cur_path;
+ Cpath cur_path;
show_cfg_diff(cfg, cfg, cur_path, show_def, hide_secret);
}
void
cnode::show_cmds_diff(const CfgNode& cfg1, const CfgNode& cfg2)
{
- vector<string> cur_path;
- vector<vector<string> > del_list;
- vector<vector<string> > set_list;
- vector<vector<string> > com_list;
+ Cpath cur_path;
+ vector<Cpath> del_list;
+ vector<Cpath> set_list;
+ vector<Cpath> com_list;
_get_cmds_diff(&cfg1, &cfg2, cur_path, del_list, set_list, com_list);
_print_cmds_list("delete", del_list);
@@ -881,32 +874,31 @@ cnode::show_cmds(const CfgNode& cfg)
void
cnode::get_cmds_diff(const CfgNode& cfg1, const CfgNode& cfg2,
- vector<vector<string> >& del_list,
- vector<vector<string> >& set_list,
- vector<vector<string> >& com_list)
+ vector<Cpath>& del_list, vector<Cpath>& set_list,
+ vector<Cpath>& com_list)
{
- vector<string> cur_path;
+ Cpath cur_path;
_get_cmds_diff(&cfg1, &cfg2, cur_path, del_list, set_list, com_list);
}
void
-cnode::get_cmds(const CfgNode& cfg, vector<vector<string> >& set_list,
- vector<vector<string> >& com_list)
+cnode::get_cmds(const CfgNode& cfg, vector<Cpath>& set_list,
+ vector<Cpath>& com_list)
{
- vector<string> cur_path;
- vector<vector<string> > del_list;
+ Cpath cur_path;
+ vector<Cpath> del_list;
_get_cmds_diff(&cfg, &cfg, cur_path, del_list, set_list, com_list);
}
void
cnode::showConfig(const string& cfg1, const string& cfg2,
- const vector<string>& path, bool show_def, bool hide_secret,
+ const Cpath& path, bool show_def, bool hide_secret,
bool context_diff, bool show_cmds)
{
tr1::shared_ptr<CfgNode> aroot, wroot, croot1, croot2;
tr1::shared_ptr<Cstore> cstore;
- vector<string> rpath(path);
- vector<string> cur_path;
+ Cpath rpath(path);
+ Cpath cur_path;
if ((cfg1 == ACTIVE_CFG || cfg1 == WORKING_CFG)
&& (cfg2 == ACTIVE_CFG || cfg2 == WORKING_CFG)) {
diff --git a/src/cnode/cnode-algorithm.hpp b/src/cnode/cnode-algorithm.hpp
index c473d6a..2f8995d 100644
--- a/src/cnode/cnode-algorithm.hpp
+++ b/src/cnode/cnode-algorithm.hpp
@@ -22,9 +22,8 @@
namespace cnode {
void show_cfg_diff(const CfgNode& cfg1, const CfgNode& cfg2,
- vector<string>& cur_path,
- bool show_def = false, bool hide_secret = false,
- bool context_diff = false);
+ Cpath& cur_path, bool show_def = false,
+ bool hide_secret = false, bool context_diff = false);
void show_cfg(const CfgNode& cfg, bool show_def = false,
bool hide_secret = false);
@@ -32,17 +31,16 @@ void show_cmds_diff(const CfgNode& cfg1, const CfgNode& cfg2);
void show_cmds(const CfgNode& cfg);
void get_cmds_diff(const CfgNode& cfg1, const CfgNode& cfg2,
- vector<vector<string> >& del_list,
- vector<vector<string> >& set_list,
- vector<vector<string> >& com_list);
-void get_cmds(const CfgNode& cfg, vector<vector<string> >& set_list,
- vector<vector<string> >& com_list);
+ vector<Cpath>& del_list, vector<Cpath>& set_list,
+ vector<Cpath>& com_list);
+void get_cmds(const CfgNode& cfg, vector<Cpath>& set_list,
+ vector<Cpath>& com_list);
extern const string ACTIVE_CFG;
extern const string WORKING_CFG;
void showConfig(const string& cfg1, const string& cfg2,
- const vector<string>& path, bool show_def = false,
+ const Cpath& path, bool show_def = false,
bool hide_secret = false, bool context_diff = false,
bool show_cmds = false);
diff --git a/src/cnode/cnode.cpp b/src/cnode/cnode.cpp
index f484fb1..cd4f6cf 100644
--- a/src/cnode/cnode.cpp
+++ b/src/cnode/cnode.cpp
@@ -28,20 +28,19 @@ using namespace cnode;
////// constructors/destructors
-CfgNode::CfgNode(vector<string>& path_comps, char *name, char *val,
- char *comment, int deact, Cstore *cstore,
- bool tag_if_invalid)
+CfgNode::CfgNode(Cpath& path_comps, char *name, char *val, char *comment,
+ int deact, Cstore *cstore, bool tag_if_invalid)
: _is_tag(false), _is_leaf(false), _is_multi(false), _is_value(false),
_is_default(false), _is_deactivated(false), _is_leaf_typeless(false),
_is_invalid(false), _is_empty(true), _exists(true)
{
if (name && name[0]) {
// name must be non-empty
- path_comps.push_back(name);
+ path_comps.push(name);
}
if (val) {
// value could be empty
- path_comps.push_back(val);
+ path_comps.push(val);
}
while (1) {
@@ -50,7 +49,7 @@ CfgNode::CfgNode(vector<string>& path_comps, char *name, char *val,
break;
}
- auto_ptr<Ctemplate> def(cstore->parseTmpl(path_comps, false));
+ tr1::shared_ptr<Ctemplate> def(cstore->parseTmpl(path_comps, false));
if (def.get()) {
// got the def
_is_tag = def->isTag();
@@ -106,16 +105,16 @@ CfgNode::CfgNode(vector<string>& path_comps, char *name, char *val,
} else {
_value = val;
}
- path_comps.pop_back();
+ path_comps.pop();
}
if (name && name[0]) {
_name = name;
- path_comps.pop_back();
+ path_comps.pop();
}
}
-CfgNode::CfgNode(Cstore& cstore, vector<string>& path_comps,
- bool active, bool recursive)
+CfgNode::CfgNode(Cstore& cstore, Cpath& path_comps, bool active,
+ bool recursive)
: _is_tag(false), _is_leaf(false), _is_multi(false), _is_value(false),
_is_default(false), _is_deactivated(false), _is_leaf_typeless(false),
_is_invalid(false), _is_empty(false), _exists(true)
@@ -124,7 +123,7 @@ CfgNode::CfgNode(Cstore& cstore, vector<string>& path_comps,
* "root", treat it as an intermediate node.
*/
if (path_comps.size() > 0) {
- auto_ptr<Ctemplate> def(cstore.parseTmpl(path_comps, false));
+ tr1::shared_ptr<Ctemplate> def(cstore.parseTmpl(path_comps, false));
if (def.get()) {
// got the def
if (!cstore.cfgPathExists(path_comps, active)) {
@@ -202,10 +201,10 @@ CfgNode::CfgNode(Cstore& cstore, vector<string>& path_comps,
// recurse
for (size_t i = 0; i < cnodes.size(); i++) {
- path_comps.push_back(cnodes[i]);
+ path_comps.push(cnodes[i]);
CfgNode *cn = new CfgNode(cstore, path_comps, active, recursive);
_child_nodes.push_back(cn);
- path_comps.pop_back();
+ path_comps.pop();
}
}
diff --git a/src/cnode/cnode.hpp b/src/cnode/cnode.hpp
index b7afc36..a684514 100644
--- a/src/cnode/cnode.hpp
+++ b/src/cnode/cnode.hpp
@@ -27,10 +27,10 @@ using namespace cstore;
class CfgNode {
public:
- CfgNode(vector<string>& path_comps, char *name, char *val, char *comment,
+ CfgNode(Cpath& path_comps, char *name, char *val, char *comment,
int deact, Cstore *cstore, bool tag_if_invalid = false);
- CfgNode(Cstore& cstore, std::vector<string>& path_comps,
- bool active = false, bool recursive = true);
+ CfgNode(Cstore& cstore, Cpath& path_comps, bool active = false,
+ bool recursive = true);
~CfgNode() {};
bool isTag() const { return _is_tag; }
@@ -44,11 +44,11 @@ public:
bool isEmpty() const { return _is_empty; }
bool exists() const { return _exists; }
- const std::string& getName() const { return _name; }
- const std::string& getValue() const { return _value; }
- const std::vector<std::string>& getValues() const { return _values; }
- const std::string& getComment() const { return _comment; }
- const std::vector<CfgNode *>& getChildNodes() const { return _child_nodes; }
+ const string& getName() const { return _name; }
+ const string& getValue() const { return _value; }
+ const vector<string>& getValues() const { return _values; }
+ const string& getComment() const { return _comment; }
+ const vector<CfgNode *>& getChildNodes() const { return _child_nodes; }
void addMultiValue(char *val) { _values.push_back(val); }
void addChildNode(CfgNode *cnode) {
@@ -68,11 +68,11 @@ private:
bool _is_invalid;
bool _is_empty;
bool _exists;
- std::string _name;
- std::string _value;
- std::vector<std::string> _values;
- std::string _comment;
- std::vector<CfgNode *> _child_nodes;
+ string _name;
+ string _value;
+ vector<string> _values;
+ string _comment;
+ vector<CfgNode *> _child_nodes;
};
} // namespace cnode