Is my approach of validation right?

Yang model:

container a {
  list b {
    key id; // 1~8192
    ...
    list c {
      key num; // 1~8192
      leaf name;
      leaf funcion {
        type string; // enable or disable
        must "(current() = 'enable' and count(/a/b/c[name=current()/../name]) <=1)"
      		+" or current() = 'disable'" {
          error-message "xxxxx";
        }
      }
    }
  }
}

It takes a long time to complete validation, when count(b) = 8192 and count© = 8192.

The following is what i did to improve the validation performance.

1st attempt --> tailf:sencondary-index
the leaf of /a/b/c/function is defined mandatory false. Suppose that the function could be changed to mandatory true, it still have to iterate the list b at least.

2nd attempt --> talif:unique-selector
My thought is that could confd add a unique-selector when the function leaf valued enable. I did try tailf:annotate and when to make unique-selector work even if i known this could not work.

3rd attempt --> hook handler and hidden leaf

container a {
  list enabled-functions { // hidden
    key name;
    leaf enabled-funcion-counter;
  }
  list b {
    key id; // 1~8192
    ...
    list c {
      key num; // 1~8192
      leaf name;
      leaf funcion {
        type string; // enable or disable
        must "(boolean(/a/enabled-functions[name = ../name]) " 
	    +"and /a/enabled-functions[name = ../name]/enabled-funcion-counter = 0) "
            +"or not(/a/enabled-functions[name = ../name])" {
          error-message "xxxxx";
        }
      }
    }
  }
}

I add a set-hook to the path /a/b/c/function and do the things below.

set /a/b/c/function enable enabled-funcion-counter++

when the function value is enable in running cdb:

delete  /a/b/c/function    enabled-funcion-counter--
delete  /a/b/c             enabled-funcion-counter--

this is complicated but i have no other ways to make sure there is no performance problem.

I hope i have discribed my annoyance clearly and i am looking forward to your help.

If I am understanding what you are attempting to do with your must statement, it looks as though you are trying to ensure that the name is unique. What you may want to do instead is to use the YANG “unique” keyword to make sure the leaf name is always unique.

Thanks for your reply.
I am sorry that i did not explain clearly about what i want to do.

container a {
    list b {
      list c {
        key num;
        leaf name;
        leaf function;
      } 
    }
}

You may understand it by the CLI commands:

set a b 1 c 1 name 123 function disable
set a b 1 c 2 name 123 function disable 
set a b 1 c 3 name 123 function enable
commit OK 
set a b 2 c 1 name 123 function disable
set a b 2 c 2 name 123 function disable
commit OK
set a b 2 c 3 name 123 function enable
commit Aborted

The must statement could also be written like this:
count(/a/b/c[name='xxx' and function='enable']) <=1

It is easy to write the MUST condition, which brought a performance problem when size(list b) = 8192 and size(list c) =8192.

In view of the “xpath.trace” log, the getNext() will be called 8192*8192 times at worst.(I did a test when size(list b) = 1000 and size(list c) = 1000.)

As the above-mentioned facts I gave up the MUST statement and the validate point CALLBACK, because I have to iterate all list b and list c saved in the candidate cdb using MAAPI by keypath. ( eg: /a/b{i}/c{j} )

In order to avoid this kind of loop, i turned to the HOOK CALLBACK.

list enabled-functions { // hidden
    key name;
    leaf enabled-funcion-counter;
  }

This list is defined hidden, which is only updated when CRUD operations occurred at the node like the following:

set a b 1 c 1 name 123 function disable ->  hook:do nothing
set a b 1 c 2 name 123 function enable  ->  hook:set enabled-functions 123 enabled-funcion-counter oldvaue++

When deletion happened, set enabled-funcion-counter oldvalue–.

Is the HOOK a good idea ?

PS:
the YANG “unique” would not work at the nested list.
In the user-guide, find “tailf:unique-selector context-path”.

Yes sometimes using a validation callback can be better performing than using a ‘must’ statement, particularly for these kinds of nested lists. The code that handles the ‘must’ statement checking has to be generic to handle every kind of case, so it sometimes can’t take advantage of obvious optimizations, and sometimes using external code that can be ‘smarter’ about how to do the validation is the way to go.