More performance tweaks
This commit is contained in:
parent
8c36083e16
commit
6a0628141a
9 changed files with 63 additions and 24 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -32,6 +32,15 @@
|
||||||
* Two config options control:
|
* Two config options control:
|
||||||
* CLICON_XML_CHANGELOG enables the yang changelog feature
|
* CLICON_XML_CHANGELOG enables the yang changelog feature
|
||||||
* CLICON_XML_CHANGELOG_FILE where the changelog resides
|
* CLICON_XML_CHANGELOG_FILE where the changelog resides
|
||||||
|
* Optimization work
|
||||||
|
* Improved performance of validation of (large) lists
|
||||||
|
* A scaling of [large lists](doc/scaling) report is added
|
||||||
|
* New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy
|
||||||
|
* xml_diff rewritten to work linearly instead of O(2)
|
||||||
|
* New xml_insert function using tree search. The new code uses this in insertion xmldb_put and defaults. (Note previous xml_insert renamed to xml_wrap_all)
|
||||||
|
* A yang type regex cache added, this helps the performance by avoiding re-running the `regcomp` command on every iteration.
|
||||||
|
* An XML namespace cache added (see `xml2ns()`)
|
||||||
|
* Better performance of XML whitespace parsing/scanning.
|
||||||
|
|
||||||
### API changes on existing features (you may need to change your code)
|
### API changes on existing features (you may need to change your code)
|
||||||
|
|
||||||
|
|
@ -102,12 +111,7 @@
|
||||||
|
|
||||||
### Minor changes
|
### Minor changes
|
||||||
|
|
||||||
* A scaling of [large lists](doc/scaling) report is added
|
|
||||||
* A new "hello world" example is added
|
* A new "hello world" example is added
|
||||||
* Optimized validation of large lists
|
|
||||||
* New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy
|
|
||||||
* xml_diff rewritten to work linearly instead of O(2)
|
|
||||||
* New xml_insert function using tree search. The new code uses this in insertion xmldb_put and defaults. (Note previous xml_insert renamed to xml_wrap_all)
|
|
||||||
* Experimental customized error output strings, see [lib/clixon/clixon_err_string.h]
|
* Experimental customized error output strings, see [lib/clixon/clixon_err_string.h]
|
||||||
* Empty leaf values, eg <a></a> are now checked at validation.
|
* Empty leaf values, eg <a></a> are now checked at validation.
|
||||||
* Empty values were skipped in validation.
|
* Empty values were skipped in validation.
|
||||||
|
|
|
||||||
|
|
@ -694,8 +694,9 @@ main(int argc,
|
||||||
/* Call backend plugin_start with user -- options */
|
/* Call backend plugin_start with user -- options */
|
||||||
if (clixon_plugin_start(h) < 0)
|
if (clixon_plugin_start(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
/* -1 option to run only once */
|
||||||
if (once)
|
if (once)
|
||||||
goto done;
|
goto ok;
|
||||||
|
|
||||||
/* Daemonize and initiate logging. Note error is initiated here to make
|
/* Daemonize and initiate logging. Note error is initiated here to make
|
||||||
demonized errors OK. Before this stage, errors are logged on stderr
|
demonized errors OK. Before this stage, errors are logged on stderr
|
||||||
|
|
@ -733,6 +734,7 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
if (event_loop() < 0)
|
if (event_loop() < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cbret)
|
if (cbret)
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ startup_extraxml(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (xt==NULL /* || xml_child_nr(xt)==0 */ ) /* This gives SEGV in test_feature */
|
if (xt==NULL || xml_child_nr(xt)==0)
|
||||||
goto ok;
|
goto ok;
|
||||||
/* Write (potentially modified) xml tree xt back to tmp
|
/* Write (potentially modified) xml tree xt back to tmp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ Olof Hagsand, 2019-04-17
|
||||||
|
|
||||||
## 1. Background
|
## 1. Background
|
||||||
|
|
||||||
CIixon can handle large configurations. Here, large number of elements
|
Clixon can handle large configurations. Here, large number of elements
|
||||||
in a "flat" list is presented. There are other scaling usecases,
|
in a "flat" list is presented. There are other scaling usecases,
|
||||||
such as large configuratin "depth", large number of requesting
|
such as large configuratin "depth", large number of requesting
|
||||||
clients, etc.
|
clients, etc.
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,8 @@ When the startup process is completed, a startup status is set and is accessible
|
||||||
|
|
||||||
If the startup fails, the backend looks for a `failsafe` configuration
|
If the startup fails, the backend looks for a `failsafe` configuration
|
||||||
in `CLICON_XMLDB_DIR/failsafe_db`. If such a config is not found, the
|
in `CLICON_XMLDB_DIR/failsafe_db`. If such a config is not found, the
|
||||||
backend terminates.
|
backend terminates. In this mode, running and startup mode should be
|
||||||
|
unchanged.
|
||||||
|
|
||||||
If the failsafe is found, the failsafe config is loaded and
|
If the failsafe is found, the failsafe config is loaded and
|
||||||
committed into the running db.
|
committed into the running db.
|
||||||
|
|
@ -405,6 +406,7 @@ running |--------+------------> GOTO EXTRA XML
|
||||||
|
|
||||||
### Running mode
|
### Running mode
|
||||||
|
|
||||||
|
On failure, running is restored to initial state
|
||||||
```
|
```
|
||||||
running ----+ |----------+--------> GOTO EXTRA XML
|
running ----+ |----------+--------> GOTO EXTRA XML
|
||||||
\ copy parse validate OK / commit
|
\ copy parse validate OK / commit
|
||||||
|
|
@ -420,7 +422,7 @@ running |--------+------------> GOTO EXTRA XML
|
||||||
startup -------+--+-------+------------+
|
startup -------+--+-------+------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
### Failure
|
### Failure if failsafe
|
||||||
```
|
```
|
||||||
failsafe ----------------------+
|
failsafe ----------------------+
|
||||||
reset \ commit
|
reset \ commit
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ LIBS = @LIBS@
|
||||||
|
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
SUBDIRS = main
|
SUBDIRS = main hello
|
||||||
|
|
||||||
.PHONY: all clean depend install $(SUBDIRS)
|
.PHONY: all clean depend install $(SUBDIRS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,14 +188,15 @@ xmldb_copy(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *fromfile = NULL;
|
char *fromfile = NULL;
|
||||||
char *tofile = NULL;
|
char *tofile = NULL;
|
||||||
db_elmnt *de1 = NULL;
|
db_elmnt *de1 = NULL; /* from */
|
||||||
db_elmnt *de2 = NULL;
|
db_elmnt *de2 = NULL; /* to */
|
||||||
db_elmnt de0 = {0,};
|
db_elmnt de0 = {0,};
|
||||||
cxobj *x1 = NULL;
|
cxobj *x1 = NULL; /* from */
|
||||||
cxobj *x2 = NULL;
|
cxobj *x2 = NULL; /* to */
|
||||||
|
|
||||||
/* XXX lock */
|
/* XXX lock */
|
||||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||||
|
/* Copy in-memory cache */
|
||||||
/* 1. "to" xml tree in x1 */
|
/* 1. "to" xml tree in x1 */
|
||||||
if ((de1 = clicon_db_elmnt_get(h, from)) != NULL)
|
if ((de1 = clicon_db_elmnt_get(h, from)) != NULL)
|
||||||
x1 = de1->de_xml;
|
x1 = de1->de_xml;
|
||||||
|
|
@ -208,7 +209,7 @@ xmldb_copy(clicon_handle h,
|
||||||
xml_free(x2);
|
xml_free(x2);
|
||||||
x2 = NULL;
|
x2 = NULL;
|
||||||
}
|
}
|
||||||
else if (x2 == NULL){ /* create x2 and copy x1 to it */
|
else if (x2 == NULL){ /* create x2 and copy from x1 */
|
||||||
if ((x2 = xml_new(xml_name(x1), NULL, xml_spec(x1))) == NULL)
|
if ((x2 = xml_new(xml_name(x1), NULL, xml_spec(x1))) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_copy(x1, x2) < 0)
|
if (xml_copy(x1, x2) < 0)
|
||||||
|
|
@ -221,13 +222,14 @@ xmldb_copy(clicon_handle h,
|
||||||
if (xml_copy(x1, x2) < 0)
|
if (xml_copy(x1, x2) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (x1 || x2){
|
/* always set cache although not strictly necessary in case 1
|
||||||
|
* above, but logic gets complicated due to differences with
|
||||||
|
* de and de->de_xml */
|
||||||
if (de2)
|
if (de2)
|
||||||
de0 = *de2;
|
de0 = *de2;
|
||||||
de0.de_xml = x2; /* The new tree */
|
de0.de_xml = x2; /* The new tree */
|
||||||
clicon_db_elmnt_set(h, to, &de0);
|
clicon_db_elmnt_set(h, to, &de0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Copy the files themselves (above only in-memory cache) */
|
/* Copy the files themselves (above only in-memory cache) */
|
||||||
if (xmldb_db2file(h, from, &fromfile) < 0)
|
if (xmldb_db2file(h, from, &fromfile) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ new(){
|
||||||
# - expected command return value (0 if OK)
|
# - expected command return value (0 if OK)
|
||||||
# - expected stdout outcome,
|
# - expected stdout outcome,
|
||||||
# - expected2 stdout outcome,
|
# - expected2 stdout outcome,
|
||||||
|
# Example: expectfn "$clixon_cli -1 -f $cfg show conf cli" 0 "^$"
|
||||||
expectfn(){
|
expectfn(){
|
||||||
cmd=$1
|
cmd=$1
|
||||||
retval=$2
|
retval=$2
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||||
|
|
||||||
# Number of list/leaf-list entries in file
|
# Number of list/leaf-list entries in file
|
||||||
: ${perfnr:=2000}
|
: ${perfnr:=10000}
|
||||||
|
|
||||||
# Number of requests made get/put
|
# Number of requests made get/put
|
||||||
: ${perfreq:=100}
|
: ${perfreq:=100}
|
||||||
|
|
@ -50,9 +50,36 @@ cat <<EOF > $cfg
|
||||||
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
||||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||||
<CLICON_XMLDB_PRETTY>false</CLICON_XMLDB_PRETTY>
|
<CLICON_XMLDB_PRETTY>false</CLICON_XMLDB_PRETTY>
|
||||||
|
<CLICON_CLI_MODE>example</CLICON_CLI_MODE>
|
||||||
|
<CLICON_CLI_DIR>/usr/local/lib/example/cli</CLICON_CLI_DIR>
|
||||||
|
<CLICON_CLISPEC_DIR>/usr/local/lib/example/clispec</CLICON_CLISPEC_DIR>
|
||||||
|
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
||||||
|
<CLICON_CLI_GENMODEL_TYPE>VARS</CLICON_CLI_GENMODEL_TYPE>
|
||||||
|
<CLICON_CLI_LINESCROLLING>0</CLICON_CLI_LINESCROLLING>
|
||||||
</clixon-config>
|
</clixon-config>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Try startup mode w startup
|
||||||
|
for mode in startup running; do
|
||||||
|
file=$dir/${mode}_db
|
||||||
|
sudo touch $file
|
||||||
|
sudo chmod 666 $file
|
||||||
|
new "generate large startup config ($file) with $perfnr list entries in mode $mode"
|
||||||
|
echo -n "<config><x xmlns=\"urn:example:clixon\">" > $file
|
||||||
|
for (( i=0; i<$perfnr; i++ )); do
|
||||||
|
echo -n "<y><a>$i</a><b>$i</b></y>" >> $file
|
||||||
|
done
|
||||||
|
echo "</x></config>" >> $file
|
||||||
|
|
||||||
|
new "Startup backend once -s $mode -f $cfg -y $fyang"
|
||||||
|
# Cannot use start_backend here due to expected error case
|
||||||
|
time sudo $clixon_backend -F1 -D $DBG -s $mode -f $cfg -y $fyang # 2> /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
new "Startup backend once -s $mode -f $cfg -y $fyang"
|
||||||
|
# Cannot use start_backend here due to expected error case
|
||||||
|
time sudo $clixon_backend -F1 -D $DBG -s $mode -f $cfg -y $fyang # 2> /dev/null
|
||||||
|
|
||||||
new "test params: -f $cfg -y $fyang"
|
new "test params: -f $cfg -y $fyang"
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
|
|
@ -184,4 +211,5 @@ fi
|
||||||
# kill backend
|
# kill backend
|
||||||
stop_backend -f $cfg
|
stop_backend -f $cfg
|
||||||
|
|
||||||
|
|
||||||
rm -rf $dir
|
rm -rf $dir
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue