Performance issue with leafref usage with no-command

Hi, I am facing performance issue while using leafref in my yang model.
Following is a simpler version similar to the yang model I am using

list a1{
    key name;
	leaf name {
	    type string;
	}
       list a2{
	   key id;
	   leaf id {
			type uint16;
		}
		container a3{
			container a4{
				leaf mirror {
					type leafref {
                                            path "/M:b1/M:stringTOindex[M:vname = current()/../../../../name]/M:a2/M:id";
                                        }
				   }
			  }
		}
	}
}

container b1{
	list stringTOindex {
		key vname;
		leaf vname {
                    type string;
                }
               list a2{
		key id;
		leaf id {
		type uint16;
	 }
             container a3{
		container a4{
			leaf mirror {
                                    type uint16;
                             }
                      }
             }
	 }
}

I have created 2 entries of a1. e.g v1 and v2.
The same will be set in the list as b1.stringTOindex[0].vname=v1 and b1.stringTOindex[1].vname=v2

For v1 and v2; i have following config

a1[0].name = v1

a1[1].name = v2
a1[1].a2[0].id = 10
a1[1].a2[1].id = 20
a1[1].a2[2].id = 30

Now, when i run “no command” for v1 e,g “no a1 v1”; it iterates though v2 also till the mirror leaves for all the 3 ids. In such case, for thousands of a1 entries; to delete 1 entry; it will go through all other entries.

If i remove the leafref in mirror leaf I dont see the iteration. To fix this temporarily; I have added validate function. However, it does not give me the cli display options while doing tab at mirror.

So, i need help to understand and fix this issue. Why leafref is making it iterate through all the existing a1 enties; where as we are concerned about id inside a particular a1 entry.

Following is the snippet of the log

confd commit progress db=running usid=18 thandle=139:   validate: validation over the change set done
confd commit progress db=running usid=18 thandle=139:   validate: run dependency-triggered validation...
get_next request for callpoint a1View path /A:B/a1
get_next succeeded for callpoint a1View path /A:B/a1
get_next request for callpoint a1View path /A:B/a1{v2}/a2
get_next succeeded for callpoint a1View path /A:B/a1{v2}/a2
get_elem request for callpoint a1View path /A:B/a1{v2}/a2{10}/a3/a4/mirror
get_elem succeeded for callpoint a1View path /A:B/a1{v2}/a2{10}/a3/a4/mirror
get_next request for callpoint a1View path /A:B/a1{v2}/a2
get_next succeeded for callpoint a1View path /A:B/a1{v2}/a2
get_elem request for callpoint a1View path /A:B/a1{v2}/a2{20}/a3/a4/mirror
get_elem succeeded for callpoint a1View path /A:B/a1{v2}/a2{20}//a3/a4/mirror
get_next request for callpoint a1View path /A:B/a1{v2}/a2
get_next succeeded for callpoint a1View path /A:B/a1{v2}/a2
get_elem request for callpoint a1View path /A:B/a1{v2}/a2{30}//a3/a4/mirror
get_elem succeeded for callpoint a1View path /A:B/a1{v2}/a2{30}/a3/a4/mirror
get_next request for callpoint a1View path /A:B/a1{v2}/a2
get_next succeeded for callpoint a1View path /A:B/a1{v2}/a2
get_next request for callpoint a1View path /A:B/a1
get_next succeeded for callpoint a1View path /A:B/a1
confd commit progress db=running usid=18 thandle=139:   validate: dependency-triggered validation done

tailf:cli-full-no

Specifies that an auto-rendered ‘no’-command should be considered complete, ie, no additional leaves or
containers can be entered on the same command line.
Used in I- and C-style CLIs.
The cli-full-no statement can be used in: leaf, leaf-list, list, tailf:symlink, container, and refine.

not sure if you have checked this does this help ?.

rgds
Balaji Kamal Kannadassan

Hi Balaji,
Thanks for the reply.
However, as I understood “tailf:cli-full-no” is related to the CLI while running a no-command. It will consider any no-command is complete even without additional leaves.

But my requirement is to remove the looping/iteration created due to the leafref while running no-command. Also, I still want the option of adding leaf in the no-command.

Please correct if i missed anything. But i feel the usage of “tailf:cli-full-no” is not related to the iteration.

Thanks
Manisha

Can anyone from the group help me in this issue?

Not sure what causes this. Just for clarification, what is your callpoint a1View used for? I can see calls to get_next, get_elem, but your data model does not contain config false.

Maybe to fix TAB completion, you can add CLI completion point to your validation point workaround.

Hi mnovak,
Thanks for the reply.
We are doing some mapping (keymap and pathmap); for which we have registered this callpoint a1View.

@Maybe to fix TAB completion, you can add CLI completion point to your validation point workaround.
Are you referring to completionpoint “Customizing CLI completion”?

Hello,

yes, /clispec/$MODE/modifications/completion or /clispec/$MODE/modifications/simpleType/capi/completionpoint (whichever is more appropriate for your usecase).

By saying:

We are doing some mapping (keymap and pathmap)

do you mean custom (non native ConfD) view:keymap and view:pathmap annotations?
(Which is transformation.)

Hi
Yes, i just tried tailf:cli-completion-actionpoint in my yang and i got the desired results.
Thank you very much.

Yes, we are using view:keymap and view:pathmap annotations

Thanks,
Manisha.

Hi @mk2017 and @mnovak, I encounter the same issue.
The vlan is leaf-referenced by almost all other nodes, such as interface/vlan. If “delete vlan” , confd will iterate all the interface,which is the huge list, to check whether leafref nodes are configured with this vlan-id. Excluding the workaround above to replace leafref by validate and completion, is there any other solution? whether use confd CDB and not use the external data provider will address such issue?
Much appreciated.

Yes, in CDB leafref should be faster than in external DATABASE. In case the interface list is huge, this still can take some time.

For optimization, you need to have some helper table (hidden to user in the datamodel) , which would keep mapping between vlan-> list of interfaces (it can be placed under vlan list). This helper table can be filled/updated during transaction hook (when you add, delete vlan to the interface; when vlan is not assigned to any interface, it will not be in this table). When deleting vlan, validation can take a look if vlan exists in the helper table (means some interface has vlan assigned) and end with error.

@ jhu
In my case, it was confd CDB and not an external db and as @ mnovak mentioned, it still took long time for a long list.
I fixed the issue by using tab-completion and validation using hidden helper data model (as @ mnovak mentioned)
Let us know if you find any better solution.

Thanks @mk2017 and @mnovak, how to implement the helper table? Can you share me an example? much appreciated.

By “Helper table” it is meant that its a kind of copy of the original model but not exactly same. This table is hidden from user. You can update it in registered call-back fundtions.
You can refer Chapter 10. Transformations, Hooks, Hidden Data and Symlinks in confd-use-guide to know more about it.

@mk2017, @mnovak, Thanks for your help. I go through <Chapter 10. Transformations, Hooks, Hidden Data and Symlinks > and read your comments again. My understanding is using “hook” under each nodes which are leaf-refer vlan, and the backend code in external data provider implements the hook callback and hidden helper table, right? If so, sounds like it’s hard to decorate hook for my cases, because there are many nodes under different xpath, such as /config/interface/ethernet/vlan, /config/interface/ont-ethernt/vlan, etc.
Please correct me if something wrong or missed.
Much appreicated.