Introduction to nvlist part 2 - dnvlist

Oct. 24, 2017, 7:16 p.m.

One of the assumptions of nvlist is that during fetch functions (like get or take) an application knows what elements are on the list, otherwise read operations fail and the application will be aborted. If an element is optional then it is necessary to check if the element exists using the exist functions.

nvlist_t *nvl;
const char *name, *n;

nvl = nvlist_recv(sock, 0);
if (nvl == NULL) {
    err(1, "Unable to recv nvlist");
}

name = nvlist_get_string(nvl, "somename");
n = NULL;
if (nvlist_exists_string(nvl, "n")) {
    n = nvlist_get_string(nvl, "n");
}

As shown above nvlist is received over the socket. There is an assumption that the first string exists in nvlist. If that’s not the case the program will be aborted and a core dump will be created. Next verification takes place if the string element of name n exists on the list. If not the element is not fetched, if it exists the get operation is performed.

This process seems straightforward, unfortunately there is a slight downside. If there are a lot of elements in nvlist traversing on nvlist can take a while (It’s a linked list so the complexity is O(n)), because there is a check if an element exists on the list (using nvlist_exists_string) and after that there is a decision to fetch it (using nvlist_get_string), due to this there is a need to traverse the list twice.

Due to this, the dnvlist extension to nvlist was introduced. Dnvlist allows to fetch element and check its presence in one operation. D in the dnv name stand for ‘default’, and because of that the last argument in the function will be returned if the element does not exist on the list. So the code above can be improved in performance by simplifying it with dnv:
nvlist_t *nvl;
const char *name, *n;
nvl = nvlist_recv(sock, 0);
if (nvl == NULL) {
    err(1, "Unable to recv nvlist");
}

name = nvlist_get_string(nvl, "somename");
n = dnvlist_get_string(nvl, "n", NULL);
In this case an assumption is that somename element exists on the list and the program will be aborted if not. Next in the case of ‘n’ element the assumption is that it can exist, but if not n will be initialized by NULL value.

dnvlist is a very handy extension to the nvlist library which can boost the performance of an application and simplify the code, so it should be used in every case of check and get situation in nvlist.